public new void AddChild(IObject3D child) { // init array if no children already exist, delay init to save memory if( _children == null) _children = new ArrayList(); // add the child _children.Add(child); }
public HiddenRenderSurface( DeviceManager initDM, IObject3D initScene, int initWidth, int initHeight) { this.dm = initDM; this.scene = initScene; this.width = initWidth; this.height = initHeight; this.InitRenderTarget(); this.renderView += new RenderSingleViewHandler(dm.OnRenderSingleView); }
public void Execute() { if(objects == null || objects.Count == 0) throw new Exception ("No selected objects"); // group objects group = SceneManager.Instance.Group(objects); Midget.Events.EventFactory.Instance.GenerateGroupEvent(this,objects,group); ICommand select = new SelectObjectCommand(group); select.Execute(); }
public void Execute() { if(parameters == null) obj = ObjectFactory.CreateObject((int)objectType); else obj = ObjectFactory.CreateObject((int)objectType,parameters); Midget.Events.EventFactory.Instance.GenerateCreateObjectEvent(this,obj); SceneManager.Instance.AddObject(obj); ICommand select = new SelectObjectCommand(obj); select.Execute(); }
public FileRenderThread(IObject3D scene, DeviceManager dm, FileRenderSettings initRenderSettings) { this.renderSettings = initRenderSettings; renderSurface = new HiddenRenderSurface(dm, scene, renderSettings.Width, renderSettings.Height); frameCount = renderSettings.StartFrame; thread = new Thread(new ThreadStart(this.Run)); // setup temp directory in case the user chooses to save to a file format other than bitmap tempDirectory = Application.StartupPath + thread.GetHashCode().ToString(); // if not a bitmap make the temp directory if(renderSettings.FileFormat != FileFormat.bmp) Directory.CreateDirectory(tempDirectory); }
private void objectsListBox_SelectedIndexChanged(object sender, EventArgs e) { selected = (IObject3D)objectsListBox.SelectedItem; editObjectsGroupBox.Controls.Clear(); if (selected is null) { return; } var control = selected.Control; if (control != null) { control.Dock = DockStyle.Fill; } editObjectsGroupBox.Controls.Add(control); if (selected is Camera selectedCamera) { scene?.SwitchCamera(selectedCamera); } }
public static IEnumerable <T> Descendants <T>(this IObject3D root) where T : IObject3D { var items = new Stack <IObject3D>(); foreach (var n in root.Children) { items.Push(n); } while (items.Count > 0) { IObject3D item = items.Pop(); if (item is T asType) { yield return(asType); } foreach (var n in item.Children) { items.Push(n); } } }
private void RenderSelection(IObject3D item, Frustum frustum, Color selectionColor) { if (item.Mesh == null) { return; } // Turn off lighting GL.Disable(EnableCap.Lighting); // Only render back faces GL.CullFace(CullFaceMode.Front); // Expand the object var worldMatrix = item.WorldMatrix(); var worldBounds = item.Mesh.GetAxisAlignedBoundingBox(worldMatrix); var worldCenter = worldBounds.Center; double distBetweenPixelsWorldSpace = World.GetWorldUnitsPerScreenPixelAtPosition(worldCenter); var pixelsAccross = worldBounds.Size / distBetweenPixelsWorldSpace; var pixelsWant = pixelsAccross + Vector3.One * 4; var wantMm = pixelsWant * distBetweenPixelsWorldSpace; var scaleMatrix = worldMatrix.ApplyAtPosition(worldCenter, Matrix4X4.CreateScale( wantMm.X / worldBounds.XSize, wantMm.Y / worldBounds.YSize, wantMm.Z / worldBounds.ZSize)); GLHelper.Render(item.Mesh, selectionColor, scaleMatrix, RenderTypes.Shaded, null, darkWireframe); // restore settings GL.CullFace(CullFaceMode.Back); GL.Enable(EnableCap.Lighting); }
public static Vector3 GetPositionToAlignTo(IObject3D objectToAlignTo, FaceAlign boundingFacesToAlignTo, Vector3 extraOffset) { var positionToAlignTo = default(Vector3); if (IsSet(boundingFacesToAlignTo, FaceAlign.Left, FaceAlign.Right)) { positionToAlignTo.X = objectToAlignTo.GetAxisAlignedBoundingBox().MinXYZ.X; } if (IsSet(boundingFacesToAlignTo, FaceAlign.Right, FaceAlign.Left)) { positionToAlignTo.X = objectToAlignTo.GetAxisAlignedBoundingBox().MaxXYZ.X; } if (IsSet(boundingFacesToAlignTo, FaceAlign.Front, FaceAlign.Back)) { positionToAlignTo.Y = objectToAlignTo.GetAxisAlignedBoundingBox().MinXYZ.Y; } if (IsSet(boundingFacesToAlignTo, FaceAlign.Back, FaceAlign.Front)) { positionToAlignTo.Y = objectToAlignTo.GetAxisAlignedBoundingBox().MaxXYZ.Y; } if (IsSet(boundingFacesToAlignTo, FaceAlign.Bottom, FaceAlign.Top)) { positionToAlignTo.Z = objectToAlignTo.GetAxisAlignedBoundingBox().MinXYZ.Z; } if (IsSet(boundingFacesToAlignTo, FaceAlign.Top, FaceAlign.Bottom)) { positionToAlignTo.Z = objectToAlignTo.GetAxisAlignedBoundingBox().MaxXYZ.Z; } return(positionToAlignTo + extraOffset); }
private Vector3 GetDeltaToOtherSideXy(IObject3D selectedItem) { AxisAlignedBoundingBox currentSelectedBounds = selectedItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity); int cornerIndex; Vector3 cornerPosition = GetCornerPosition(selectedItem, out cornerIndex); Vector3 cornerPositionCcw = currentSelectedBounds.GetBottomCorner((cornerIndex + 1) % 4); Vector3 cornerPositionCw = currentSelectedBounds.GetBottomCorner((cornerIndex + 3) % 4); double xDirection = cornerPositionCcw.X - cornerPosition.X; if (xDirection == 0) { xDirection = cornerPositionCw.X - cornerPosition.X; } double yDirection = cornerPositionCcw.Y - cornerPosition.Y; if (yDirection == 0) { yDirection = cornerPositionCw.Y - cornerPosition.Y; } return(new Vector3(xDirection, yDirection, cornerPosition.Z)); }
public static ulong MeshRenderId(this IObject3D root) { ulong hash = 14695981039346656037; using (root.RebuildLock()) { var oldMatrix = root.Matrix; root.Matrix = Matrix4X4.Identity; foreach (var item in root.VisibleMeshes()) { unchecked { hash = item.Mesh.LongHashBeforeClean.GetLongHashCode(hash); hash = item.WorldMatrix(root).GetLongHashCode(hash); hash = item.WorldColor(root).GetLongHashCode(hash); } } root.Matrix = oldMatrix; } return(hash); }
public static void InsertNewItem(this ISceneContext sceneContext, IObject3D newItem) { var scene = sceneContext.Scene; // Reposition first item to bed center if (scene.Children.Count == 0) { var aabb = newItem.GetAxisAlignedBoundingBox(); var center = aabb.Center; newItem.Matrix *= Matrix4X4.CreateTranslation( sceneContext.BedCenter.X - center.X, sceneContext.BedCenter.Y - center.Y, -aabb.MinXYZ.Z); } // Create and perform a new insert operation var insertOperation = new InsertCommand(scene, newItem); insertOperation.Do(); // Store the operation for undo/redo scene.UndoBuffer.Add(insertOperation); }
private void InteractionLayer_AfterDraw(object sender, DrawEventArgs drawEvent) { IObject3D selectedItem = RootSelection; if (selectedItem != null && mouseDownInfo != null) { Matrix4X4 rotationCenterTransform = GetRotationTransform(selectedItem, out double radius); var unitPosition = new Vector3(Math.Cos(mouseDownInfo.AngleOfHit), Math.Sin(mouseDownInfo.AngleOfHit), 0); Vector3 anglePosition = Vector3Ex.Transform(unitPosition * (radius + 100), rotationCenterTransform); Vector2 angleDisplayPosition = InteractionContext.World.GetScreenPosition(anglePosition); var displayAngle = MathHelper.RadiansToDegrees(SnappedRotationAngle); if (!RotatingCW && SnappedRotationAngle > 0) { displayAngle -= 360; } angleTextControl.Value = displayAngle; angleTextControl.OriginRelativeParent = angleDisplayPosition - angleTextControl.LocalBounds.Center; } }
public static async Task <FitToCylinderObject3D> Create(IObject3D itemToFit) { var fitToBounds = new FitToCylinderObject3D(); using (fitToBounds.RebuildLock()) { var startingAabb = itemToFit.GetAxisAlignedBoundingBox(); // add the fit item var scaleItem = new Object3D(); fitToBounds.Children.Add(scaleItem); scaleItem.Children.Add(itemToFit); // create an object that just represents the bounds in the scene var fitBounds = new Object3D() { Visible = false, Color = new Color(Color.Red, 100), Mesh = PlatonicSolids.CreateCube() }; // add the item that holds the bounds fitToBounds.Children.Add(fitBounds); fitToBounds.Diameter = Math.Sqrt(startingAabb.XSize * startingAabb.XSize + startingAabb.YSize * startingAabb.YSize); fitToBounds.SizeZ = startingAabb.ZSize; fitToBounds.SizeZ = startingAabb.ZSize; await fitToBounds.Rebuild(); var finalAabb = fitToBounds.GetAxisAlignedBoundingBox(); fitToBounds.Translate(startingAabb.Center - finalAabb.Center); } return(fitToBounds); }
public static void CopyWorldProperties(this IObject3D copyTo, IObject3D copyFrom, IObject3D root, Object3DPropertyFlags flags, bool includingRoot = true) { if (flags.HasFlag(Object3DPropertyFlags.Matrix)) { copyTo.Matrix = copyFrom.WorldMatrix(root, includingRoot); } if (flags.HasFlag(Object3DPropertyFlags.Color)) { copyTo.Color = copyFrom.WorldColor(root, includingRoot); } if (flags.HasFlag(Object3DPropertyFlags.MaterialIndex)) { copyTo.MaterialIndex = copyFrom.WorldMaterialIndex(root, includingRoot); } if (flags.HasFlag(Object3DPropertyFlags.Name)) { copyTo.Name = copyFrom.Name; } if (flags.HasFlag(Object3DPropertyFlags.OutputType)) { copyTo.OutputType = copyFrom.WorldOutputType(root, includingRoot); } if (flags.HasFlag(Object3DPropertyFlags.Visible)) { copyTo.Visible = copyFrom.WorldVisible(root, includingRoot); } }
/// <summary> /// Union a and b together. This can either return a single item with a mesh on it /// or a group item that has the a and be items as children /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="doMeshCombine"></param> /// <returns></returns> public static IObject3D Plus(this IObject3D a, IObject3D b, bool doMeshCombine = false) { if (doMeshCombine) { var combine = new CombineObject3D_2(); combine.Children.Add(a.Clone()); combine.Children.Add(b.Clone()); combine.Combine(); var finalMesh = combine.VisibleMeshes().First().Mesh; return(new Object3D() { Mesh = finalMesh }); } else { var group = new GroupObject3D(); group.Children.Add(a); group.Children.Add(b); return(group); } }
public static void AddSelectionAsChildren(this IObject3D newParent, InteractiveScene scene, IObject3D selectedItem) { if (selectedItem != null) { List <IObject3D> itemsToReplace; if (selectedItem is SelectionGroupObject3D) { itemsToReplace = selectedItem.Children.ToList(); foreach (var child in itemsToReplace) { newParent.Children.Add(child.Clone()); } } else { itemsToReplace = new List <IObject3D> { selectedItem }; newParent.Children.Add(selectedItem.Clone()); } scene.SelectedItem = null; newParent.MakeNameNonColliding(); scene.UndoBuffer.AddAndDo( new ReplaceCommand( itemsToReplace, new List <IObject3D> { newParent })); SelectModifiedItem(selectedItem, newParent, scene); } }
public RenderSingleViewEventArgs(IObject3D initScene, int initFrameNumber) { this.scene = initScene; this.frameNumber = initFrameNumber; }
public RenameCommand(IObject3D obj, string newName) { this.obj = obj; name = newName; }
private static GuiWidget CreateSelector(ChildrenSelector childSelector, IObject3D parent, ThemeConfig theme) { GuiWidget tabContainer = new FlowLayoutWidget(FlowDirection.TopToBottom); void UpdateSelectColors(bool selectionChanged = false) { foreach (var child in parent.Children.ToList()) { using (child.RebuildLock()) { if (!childSelector.Contains(child.ID) || tabContainer.HasBeenClosed) { child.Color = new Color(child.WorldColor(), 255); } else { child.Color = new Color(child.WorldColor(), 200); } if (selectionChanged) { child.Visible = true; } } } } tabContainer.Closed += (s, e) => UpdateSelectColors(); var children = parent.Children.ToList(); Dictionary <ICheckbox, IObject3D> objectChecks = new Dictionary <ICheckbox, IObject3D>(); List <GuiWidget> radioSiblings = new List <GuiWidget>(); for (int i = 0; i < children.Count; i++) { var itemIndex = i; var child = children[itemIndex]; FlowLayoutWidget rowContainer = new FlowLayoutWidget(); GuiWidget selectWidget; if (children.Count == 2) { var radioButton = new RadioButton(string.IsNullOrWhiteSpace(child.Name) ? $"{itemIndex}" : $"{child.Name}") { Checked = childSelector.Contains(child.ID), TextColor = ActiveTheme.Instance.PrimaryTextColor }; radioSiblings.Add(radioButton); radioButton.SiblingRadioButtonList = radioSiblings; selectWidget = radioButton; } else { selectWidget = new CheckBox(string.IsNullOrWhiteSpace(child.Name) ? $"{itemIndex}" : $"{child.Name}") { Checked = childSelector.Contains(child.ID), TextColor = ActiveTheme.Instance.PrimaryTextColor }; } objectChecks.Add((ICheckbox)selectWidget, child); rowContainer.AddChild(selectWidget); ICheckbox checkBox = selectWidget as ICheckbox; checkBox.CheckedStateChanged += (s, e) => { if (s is ICheckbox checkbox) { if (checkBox.Checked) { if (!childSelector.Contains(objectChecks[checkbox].ID)) { childSelector.Add(objectChecks[checkbox].ID); } } else { if (childSelector.Contains(objectChecks[checkbox].ID)) { childSelector.Remove(objectChecks[checkbox].ID); } } if (parent is MeshWrapperObject3D meshWrapper) { using (meshWrapper.RebuildLock()) { meshWrapper.ResetMeshWrapperMeshes(Object3DPropertyFlags.All, CancellationToken.None); } } UpdateSelectColors(true); } }; tabContainer.AddChild(rowContainer); UpdateSelectColors(); } /* * bool operationApplied = parent.Descendants() * .Where((obj) => obj.OwnerID == parent.ID) * .Where((objId) => objId.Mesh != objId.Children.First().Mesh).Any(); * * bool selectionHasBeenMade = parent.Descendants() * .Where((obj) => obj.OwnerID == parent.ID && obj.OutputType == PrintOutputTypes.Hole) * .Any(); * * if (!operationApplied && !selectionHasBeenMade) * { * // select the last item * if (tabContainer.Descendants().Where((d) => d is ICheckbox).Last() is ICheckbox lastCheckBox) * { * lastCheckBox.Checked = true; * } * } * else * { * updateButton.Enabled = !operationApplied; * } */ return(tabContainer); }
private bool DidColide(IObject3D otherObject) { // check for self if (caller.Equals(otherObject)) { return false; } if ((caller is MeshObject) && (otherObject is MeshObject)) { float callerRadius = 0.0f; // Radius of bounding sphere of object float otherRadius = 0.0f; // Radius of bounding sphere of object // Retrieve the vertex buffer data in the mesh object VertexBuffer vb = ((MeshObject)caller).mesh.VertexBuffer; VertexBuffer vb2 = ((MeshObject)otherObject).mesh.VertexBuffer; // Lock the vertex buffer to generate a simple bounding sphere GraphicsStream vertexData = vb.Lock(0, 0, LockFlags.NoSystemLock); callerRadius = Geometry.ComputeBoundingSphere(vertexData, ((MeshObject)caller).mesh.NumberVertices, ((MeshObject)caller).mesh.VertexFormat, out callerCenter); vb.Unlock(); vb.Dispose(); // Lock the vertex buffer to generate a simple bounding sphere GraphicsStream vertexData2 = vb2.Lock(0, 0, LockFlags.NoSystemLock); otherRadius = Geometry.ComputeBoundingSphere(vertexData2, ((MeshObject)otherObject).mesh.NumberVertices, ((MeshObject)otherObject).mesh.VertexFormat, out otherObjectCenter); vb2.Unlock(); vb2.Dispose(); // these couple of lines scale the bounding sphere down or up compared to the largest scaling of the x, y or z AxisValue callerScaling = caller.Scaling; callerRadius *= Math.Max(Math.Max(callerScaling.X, callerScaling.Y), callerScaling.Z); AxisValue otherObjectScaling = otherObject.Scaling; callerRadius *= Math.Max(Math.Max(otherObjectScaling.X, otherObjectScaling.Y), otherObjectScaling.Z); callerCenter.X = callerCenter.X + caller.Translation.X; callerCenter.Y = callerCenter.Y + caller.Translation.Y; callerCenter.Z = callerCenter.Z + caller.Translation.Z; otherObjectCenter.X = otherObjectCenter.X + otherObject.Translation.X; otherObjectCenter.Y = otherObjectCenter.Y + otherObject.Translation.Y; otherObjectCenter.Z = otherObjectCenter.Z + otherObject.Translation.Z; if (caller.GetVertDist(callerCenter, otherObjectCenter) > (callerRadius + otherRadius)) { return false; } return true; } return false; }
public override void OnMouseMove(Mouse3DEventArgs mouseEvent3D, bool mouseIsOver) { var selectedItem = RootSelection; ActiveSelectedItem = selectedItem; if (MouseIsOver) { xValueDisplayInfo.Visible = true; yValueDisplayInfo.Visible = true; } else if (!hadClickOnControl || (selectedItem != null && selectedItem.Matrix != transformAppliedByThis)) { xValueDisplayInfo.Visible = false; yValueDisplayInfo.Visible = false; } if (MouseDownOnControl && hitPlane != null) { IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay); if (info != null && selectedItem != null) { AxisAlignedBoundingBox originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox(); Vector3 delta = info.HitPosition - initialHitPosition; Vector3 newPosition = originalPointToMove + delta; if (Object3DControlContext.SnapGridDistance > 0) { // snap this position to the grid double snapGridDistance = Object3DControlContext.SnapGridDistance; // snap this position to the grid newPosition.X = ((int)((newPosition.X / snapGridDistance) + .5)) * snapGridDistance; newPosition.Y = ((int)((newPosition.Y / snapGridDistance) + .5)) * snapGridDistance; } Vector3 lockedEdge = GetEdgePosition(selectedItem, (edgeIndex + 2) % 4); Vector3 newSize = Vector3.Zero; if (edgeIndex % 2 == 1) { newSize.X = lockedEdge.X - newPosition.X; if (edgeIndex == 0 || edgeIndex == 3) { newSize.X *= -1; } } else { newSize.Y = lockedEdge.Y - newPosition.Y; if (edgeIndex == 0 || edgeIndex == 1) { newSize.Y *= -1; } } Vector3 scaleAmount = GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, Object3DControlContext.GuiSurface.ModifierKeys); // scale it var scale = Matrix4X4.CreateScale(scaleAmount); selectedItem.Matrix = selectedItem.ApplyAtBoundsCenter(scale); // and keep the locked edge in place Vector3 newLockedEdge = GetEdgePosition(selectedItem, (edgeIndex + 2) % 4); AxisAlignedBoundingBox postScaleBounds = selectedItem.GetAxisAlignedBoundingBox(); newLockedEdge.Z = 0; lockedEdge.Z = mouseDownSelectedBounds.MinXYZ.Z - postScaleBounds.MinXYZ.Z; selectedItem.Matrix *= Matrix4X4.CreateTranslation(lockedEdge - newLockedEdge); Invalidate(); } } if (selectedItem != null) { transformAppliedByThis = selectedItem.Matrix; } base.OnMouseMove(mouseEvent3D, mouseIsOver); }
public ObjectView(IObject3D source) { this.Source = source; this.Children = this.Source.Children; this.Name = this.Source.Name; }
public void Parzor(IObject3D parent) { if ((parent is Particle) || (parent is MeshCtrlPt)) { return; } if (!(parent is SceneObject)) objectList.Add(parent); foreach (IObject3D obj in parent.Children) { Parzor(obj); } return; }
public void SelectAdditionalObject(IObject3D obj) { SelectedObjects.Add(obj); }
public AddDynamicCommand(IObject3D obj, IDynamic dynamic) { this.obj = obj; this.dynamic = dynamic; }
public void LoadScene(string filePath) { Stream stream = File.Open(filePath,FileMode.Open); BinaryFormatter bformatter = new BinaryFormatter(); try { _scene = (SceneObject)bformatter.Deserialize(stream); } finally { stream.Close(); } _scene.Reinitialize(DeviceManager.Instance.Device); Parzor(_scene); }
public void DeselectObject(IObject3D obj) { SelectedObjects.Remove(obj); }
public void ChangeParent(IObject3D obj, IObject3D newParent) { newParent.AddChild(obj); }
public void AddObject(IObject3D newObject) { objectList.Add(newObject); _scene.AddChild(newObject); newObject.Parent = _scene; }
private SceneManager() { _scene = new SceneObject(); objectList = new ArrayList(); selectedObjects = new SelectedObjectContainer(); }
public ArrayList UnGroup(IObject3D group) { // remove all children from this group and move them one level up if (group.Children != null) { ArrayList children = (ArrayList)group.Children.Clone(); while(group.Children.Count > 0) { group.Parent.AddChild((IObject3D)group.Children[0]); } return children; } return null; }
/// <summary> /// Get all values from an object and display them. /// Customize the display for this type of object. /// </summary> /// <param name="obj">The object to get manipulation data from</param> private void FillObjectValues(IObject3D obj) { // fill in this object's modifiers if (obj != null) { lstModifiers.Items.Clear(); foreach (IDynamic dynamic in obj.DynamicsList) { lstModifiers.Items.Add(dynamic); } } }
public void RemoveObject(IObject3D oldObject) { objectList.Remove(oldObject); // remove object from it's parent oldObject.Parent.RemoveChild(oldObject); }
private MidgetTreeNode FindNode(IObject3D obj) { MidgetTreeNode node = (MidgetTreeNode)treeView.Nodes[0]; try { while(node != null) { if(node.Object3d.Equals(obj)) return node; // try to move first child node if(node.Nodes.Count != 0) { node = (MidgetTreeNode)node.Nodes[0]; } // try to go to next sibling else if (node.NextNode != null) { node = (MidgetTreeNode)node.NextNode; } else { node = (MidgetTreeNode)node.Parent; while(node.NextNode == null) { // go to parent node node = (MidgetTreeNode)node.Parent; // if back at top stop if(node == (MidgetTreeNode)treeView.Nodes[0]) return null; } node = (MidgetTreeNode)node.NextNode; } } } catch { return null; } return null; }
private void DrawRotationCompass(IObject3D selectedItem, DrawGlContentEventArgs drawEventArgs) { if (InteractionContext.Scene.SelectedItem == null) { return; } double alphaValue = 1; if (!drawEventArgs.ZBuffered) { alphaValue = .3; } AxisAlignedBoundingBox currentSelectedBounds = selectedItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity); if (currentSelectedBounds.XSize > 100000) { // something is wrong the part is too big (probably in invalid selection) return; } Vector3 controlCenter = GetControlCenter(selectedItem); Vector3 rotationCenter = GetRotationCenter(selectedItem, currentSelectedBounds); if (mouseDownInfo != null) { rotationCenter = mouseDownInfo.SelectedObjectRotationCenter; controlCenter = mouseDownInfo.ControlCenter; } if (mouseMoveInfo != null) { double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(rotationCenter); double radius; Matrix4X4 rotationCenterTransform = GetRotationTransform(selectedItem, out radius); double innerRadius = radius + ringWidth / 2; double outerRadius = innerRadius + ringWidth; double snappingMarkRadius = outerRadius + 20; double startBlue = 0; double endBlue = MathHelper.Tau; double mouseAngle = 0; if (mouseMoveInfo != null) { mouseAngle = mouseMoveInfo.AngleOfHit; } if (mouseDownInfo != null) { mouseAngle = mouseDownInfo.AngleOfHit; } var graphics2DOpenGL = new Graphics2DOpenGL(); if (mouseDownInfo != null || MouseOver) { IVertexSource blueRing = new JoinPaths(new Arc(0, 0, outerRadius, outerRadius, startBlue, endBlue, Arc.Direction.CounterClockWise), new Arc(0, 0, innerRadius, innerRadius, startBlue, endBlue, Arc.Direction.ClockWise)); graphics2DOpenGL.RenderTransformedPath(rotationCenterTransform, blueRing, new Color(Color.Blue, (int)(50 * alphaValue)), drawEventArgs.ZBuffered); // tick 60 marks DrawTickMarks(drawEventArgs, alphaValue, rotationCenterTransform, innerRadius, outerRadius, 60); } if (mouseDownInfo != null) { double startRed = mouseDownInfo.AngleOfHit; double endRed = SnappedRotationAngle + mouseDownInfo.AngleOfHit; if (!rotatingCW) { var temp = startRed; startRed = endRed; endRed = temp; } IVertexSource redAngle = new JoinPaths(new Arc(0, 0, 0, 0, startRed, endRed, Arc.Direction.CounterClockWise), new Arc(0, 0, innerRadius, innerRadius, startRed, endRed, Arc.Direction.ClockWise)); graphics2DOpenGL.RenderTransformedPath(rotationCenterTransform, redAngle, new Color(Color.Red, (int)(70 * alphaValue)), drawEventArgs.ZBuffered); // draw a line to the mouse on the rotation circle if (mouseMoveInfo != null && MouseDownOnControl) { Vector3 unitPosition = new Vector3(Math.Cos(mouseMoveInfo.AngleOfHit), Math.Sin(mouseMoveInfo.AngleOfHit), 0); Vector3 startPosition = Vector3Ex.Transform(unitPosition * innerRadius, rotationCenterTransform); var center = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); if ((mouseMoveInfo.HitPosition - center).Length > rotationTransformScale * innerRadius) { InteractionContext.World.Render3DLine(startPosition, mouseMoveInfo.HitPosition, Color.Red, drawEventArgs.ZBuffered); } DrawSnappingMarks(drawEventArgs, mouseAngle, alphaValue, rotationCenterTransform, snappingMarkRadius, 5, numSnapPoints, GetSnapIndex(selectedItem, numSnapPoints)); } } } }
public RotateObject3D(IObject3D item, Vector3 translation, string name = "") : this(item, translation.X, translation.Y, translation.Z, name) { }
public void NewScene() { _scene = new GroupObject(); // TODO: make a SceneChanged event, 'cuz this is for sucks DeviceManager.Instance.UpdateViews(); }
public SurfacedEditorPage(IObject3D selectedItem) { this.WindowTitle = "MatterControl - " + "Editor Selector".Localize(); this.HeaderText = "Surfaced Editor".Localize(); var tabControl = new SimpleTabs(theme, new GuiWidget()) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Stretch, }; tabControl.TabBar.BackgroundColor = theme.TabBarBackground; tabControl.TabBar.Padding = 0; contentRow.AddChild(tabControl); contentRow.Padding = 0; var editContainer = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Stretch, Padding = theme.DefaultContainerPadding, BackgroundColor = theme.ActiveTabColor }; editWidget = new MHTextEditWidget("", multiLine: true) { HAnchor = HAnchor.Stretch, Name = this.Name }; editWidget.DrawFromHintedCache(); editContainer.AddChild(editWidget); // add the tree view var treeView = new TreeView(theme) { Margin = new BorderDouble(left: 18), }; treeView.AfterSelect += (s, e) => { if (treeView.SelectedNode.Tag is IObject3D contextNode) { editWidget.Text = "$." + string.Join(".", contextNode.AncestorsAndSelf().TakeWhile(o => !(o is ComponentObject3D)).Select(o => $"Children<{o.GetType().Name.ToString()}>").Reverse().ToArray()); } }; treeView.ScrollArea.ChildAdded += (s, e) => { if (e is GuiWidgetEventArgs childEventArgs && childEventArgs.Child is TreeNode treeNode) { treeNode.AlwaysExpandable = true; } }; treeView.Click += (s, e) => { if (treeView.IsDoubleClick(e)) { Console.WriteLine(); } }; treeView.ScrollArea.CloseAllChildren(); var rootNode = Object3DTreeBuilder.BuildTree(selectedItem, theme); treeView.AddChild(rootNode); rootNode.TreeView = treeView; editContainer.AddChild(treeView); var dummyWidget = new GuiWidget() { BackgroundColor = Color.Red }; var editTab = new ToolTab("Edit".Localize(), tabControl, editContainer, theme, hasClose: false) { Name = "Edit Tab" }; tabControl.AddTab(editTab); var previewTab = new ToolTab("Preview".Localize(), tabControl, dummyWidget, theme, hasClose: false) { Name = "Preview Tab" }; tabControl.AddTab(previewTab); tabControl.ActiveTabChanged += (s, e) => { if (tabControl.SelectedTabIndex == 1) { // dummyWidget.Markdown = editWidget.Text; } }; tabControl.SelectedTabIndex = 0; var saveButton = theme.CreateDialogButton("Save".Localize()); saveButton.Click += (s, e) => { this.ValueChanged?.Invoke(this, null); this.DialogWindow.CloseOnIdle(); }; this.AddPageAction(saveButton); }
private void MoveCorrect(IObject3D otherObject, Vector3 velocity) { float velocityBackSegments = 10.0f; float xBack = velocity.X /velocityBackSegments; float yBack = velocity.Y /velocityBackSegments; float zBack = velocity.Z /velocityBackSegments; int count = 1; while (this.DidColide(otherObject)) { count = count ++; caller.Translate(caller.Translation.X-(count* xBack), caller.Translation.Y-(count * yBack), caller.Translation.Z-(count * zBack)); } Vector3 hasTraveled = new Vector3 (-(count* xBack), -(count * yBack), -(count * zBack)); Vector3 normal = new Vector3 (otherObjectCenter.X - callerCenter.X, otherObjectCenter.Y - callerCenter.Y, otherObjectCenter.Z - callerCenter.Z); float a = caller.Translation.X; float b = caller.Translation.Y; float c = caller.Translation.Z; float d = otherObject.Translation.X; float e = otherObject.Translation.Y; float f = otherObject.Translation.Z; Vector3 rebound; rebound.X = caller.Velocity.X * -1; rebound.Y = caller.Velocity.Y * -1; rebound.Z = caller.Velocity.Z * -1; // move active objects being collided with if (otherObject.Rigidity == Rigidity.Active) { Vector3 newVelocity = otherObject.Velocity; newVelocity.X += (caller.Mass / otherObject.Mass) * velocity.X - (velocity.X / otherObject.Dampening); newVelocity.Y += (caller.Mass / otherObject.Mass) * velocity.Y - (velocity.Y / otherObject.Dampening); newVelocity.Z += (caller.Mass / otherObject.Mass) * velocity.Z - (velocity.Z / otherObject.Dampening); otherObject.Velocity = newVelocity; } // change the original moving object's velocity caller.Velocity = rebound * (otherObject.Mass / caller.Mass); // Vector3 rebound; // rebound.X = caller.Velocity.X * -(1.0f + dampening) * caller.Velocity.X * normal.X; // rebound.Y = caller.Velocity.Y * -(1.0f + dampening) * caller.Velocity.Y * normal.Y; // rebound.Z = caller.Velocity.Z * -(1.0f + dampening) * caller.Velocity.Z * normal.Z; // caller.Velocity = rebound; }
public McxContainer(ILibraryAsset libraryAsset) { sourceItem = libraryAsset.CreateContent(null).Result; this.Name = sourceItem.Name; }
public XyCalibrationSelectPage(XyCalibrationWizard calibrationWizard) : base(calibrationWizard) { this.WindowTitle = "Nozzle Offset Calibration Wizard".Localize(); this.HeaderText = "Calibration Print".Localize(); contentRow.Padding = theme.DefaultContainerPadding; // default to normal offset calibrationWizard.Offset = printer.Settings.GetValue <double>(SettingsKey.nozzle_diameter) / 3.0; contentRow.AddChild( new TextWidget( "This wizard will close to print a calibration part and resume after the print completes.".Localize(), textColor: theme.TextColor, pointSize: theme.DefaultFontSize) { Margin = new BorderDouble(bottom: theme.DefaultContainerPadding) }); contentRow.AddChild( new TextWidget( "Calibration Mode".Localize(), textColor: theme.TextColor, pointSize: theme.DefaultFontSize) { Margin = new BorderDouble(0, theme.DefaultContainerPadding) }); var column = new FlowLayoutWidget(FlowDirection.TopToBottom) { Margin = new BorderDouble(left: theme.DefaultContainerPadding), HAnchor = HAnchor.Stretch, }; contentRow.AddChild(column); var coarseText = calibrationWizard.Quality == QualityType.Coarse ? "Initial (Recommended)".Localize() : "Coarse".Localize(); column.AddChild(coarseCalibration = new RadioButton(coarseText, textColor: theme.TextColor, fontSize: theme.DefaultFontSize) { Checked = calibrationWizard.Quality == QualityType.Coarse }); coarseCalibration.CheckedStateChanged += (s, e) => { calibrationWizard.Quality = QualityType.Coarse; calibrationWizard.Offset = printer.Settings.GetValue <double>(SettingsKey.nozzle_diameter); }; var normalText = calibrationWizard.Quality == QualityType.Normal ? "Normal (Recommended)".Localize() : "Normal".Localize(); column.AddChild(normalCalibration = new RadioButton(normalText, textColor: theme.TextColor, fontSize: theme.DefaultFontSize) { Checked = calibrationWizard.Quality == QualityType.Normal }); normalCalibration.CheckedStateChanged += (s, e) => { calibrationWizard.Quality = QualityType.Normal; calibrationWizard.Offset = printer.Settings.GetValue <double>(SettingsKey.nozzle_diameter) / 3.0; }; column.AddChild(fineCalibration = new RadioButton("Fine".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize) { Checked = calibrationWizard.Quality == QualityType.Fine }); fineCalibration.CheckedStateChanged += (s, e) => { calibrationWizard.Quality = QualityType.Fine; calibrationWizard.Offset = printer.Settings.GetValue <double>(SettingsKey.nozzle_diameter) / 9.0; }; int tabIndex = 0; if (printer.Settings.GetValue <double>(SettingsKey.layer_height) < printer.Settings.GetValue <double>(SettingsKey.nozzle_diameter) / 2) { // The layer height is very small and it will be hard to see features. Show a warning. AddSettingsRow(contentRow, printer, "The calibration object will printer better if the layer hight is set to a larger value. It is recommended that your increase it.".Localize(), SettingsKey.layer_height, theme, ref tabIndex); } if (printer.Settings.GetValue <bool>(SettingsKey.create_raft)) { // The layer height is very small and it will be hard to see features. Show a warning. AddSettingsRow(contentRow, printer, "A raft is not needed for the calibration object. It is recommended that you turn it off.".Localize(), SettingsKey.create_raft, theme, ref tabIndex); } this.NextButton.Visible = false; // add in the option to tell the system the printer is already calibrated var alreadyCalibratedButton = theme.CreateDialogButton("Already Calibrated".Localize()); alreadyCalibratedButton.Name = "Already Calibrated Button"; alreadyCalibratedButton.Click += (s, e) => { printer.Settings.SetValue(SettingsKey.xy_offsets_have_been_calibrated, "1"); FinishWizard(); }; this.AddPageAction(alreadyCalibratedButton); var startCalibrationPrint = theme.CreateDialogButton("Start Print".Localize()); startCalibrationPrint.Name = "Start Calibration Print"; startCalibrationPrint.Click += async(s, e) => { var preCalibrationPrintViewMode = printer.ViewState.ViewMode; // create the calibration objects IObject3D item = await CreateCalibrationObject(printer, calibrationWizard); var calibrationObjectPrinter = new CalibrationObjectPrinter(printer, item); // hide this window this.DialogWindow.Visible = false; await calibrationObjectPrinter.PrintCalibrationPart(); // Restore the original DialogWindow this.DialogWindow.Visible = true; // Restore to original view mode printer.ViewState.ViewMode = preCalibrationPrintViewMode; this.MoveToNextPage(); }; this.AcceptButton = startCalibrationPrint; this.AddPageAction(startCalibrationPrint); }
public override async void OnMouseMove(Mouse3DEventArgs mouseEvent3D, bool mouseIsOver) { var selectedItem = RootSelection; ActiveSelectedItem = selectedItem; if (MouseIsOver || MouseDownOnControl) { xValueDisplayInfo.Visible = true; yValueDisplayInfo.Visible = true; } else if (!hadClickOnControl || scaleController.HasChange) { xValueDisplayInfo.Visible = false; yValueDisplayInfo.Visible = false; } if (MouseDownOnControl && hitPlane != null) { var info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay); if (info != null && selectedItem != null) { var lockedEdge = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 2); var delta = info.HitPosition - initialHitPosition; var corner0 = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex); var corner1 = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 1); var corner3 = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 3); var direction01 = (corner0 - corner1).GetNormal(); var direction03 = (corner0 - corner3).GetNormal(); var deltaAlong01 = direction01.Dot(delta); var deltaAlong03 = direction03.Dot(delta); // scale it var newSize = new Vector2(scaleController.InitialState.Width, scaleController.InitialState.Depth); if (quadrantIndex % 2 == 0) { newSize.X += deltaAlong01; newSize.X = Math.Max(Math.Max(newSize.X, .001), Object3DControlContext.SnapGridDistance); newSize.Y += deltaAlong03; newSize.Y = Math.Max(Math.Max(newSize.Y, .001), Object3DControlContext.SnapGridDistance); } else { newSize.X += deltaAlong03; newSize.X = Math.Max(Math.Max(newSize.X, .001), Object3DControlContext.SnapGridDistance); newSize.Y += deltaAlong01; newSize.Y = Math.Max(Math.Max(newSize.Y, .001), Object3DControlContext.SnapGridDistance); } if (Object3DControlContext.SnapGridDistance > 0) { // snap this position to the grid double snapGridDistance = Object3DControlContext.SnapGridDistance; // snap this position to the grid newSize.X = ((int)((newSize.X / snapGridDistance) + .5)) * snapGridDistance; newSize.Y = ((int)((newSize.Y / snapGridDistance) + .5)) * snapGridDistance; } scaleController.ScaleWidthDepth(newSize.X, newSize.Y); await selectedItem.Rebuild(); // and keep the locked edge in place var newLockedEdge = ObjectSpace.GetCornerPosition(selectedItem, quadrantIndex + 2); selectedItem.Matrix *= Matrix4X4.CreateTranslation(lockedEdge - newLockedEdge); Invalidate(); } } base.OnMouseMove(mouseEvent3D, mouseIsOver); }
public void SetActiveItem(IObject3D selectedItem) { this.item = selectedItem; editorPanel.CloseAllChildren(); // Allow caller to clean up with passing null for selectedItem if (item == null) { return; } var selectedItemType = selectedItem.GetType(); editorSectionWidget.Text = selectedItem.Name ?? selectedItemType.Name; HashSet <IObject3DEditor> mappedEditors = ApplicationController.Instance.GetEditorsForType(selectedItemType); var undoBuffer = sceneContext.Scene.UndoBuffer; bool allowOperations = true; if (selectedItem is ComponentObject3D componentObject && componentObject.Finalized) { allowOperations = false; foreach (var selector in componentObject.SurfacedEditors) { // Get the named property via reflection // Selector example: '$.Children<CylinderObject3D>' var match = xpathLikeResolver.Select(componentObject, selector).ToList(); //// TODO: Create editor row for each property //// - Use the type of the property to find a matching editor (ideally all datatype -> editor functionality would resolve consistently) //// - Add editor row for each foreach (var instance in match) { if (instance is IObject3D object3D) { if (ApplicationController.Instance.GetEditorsForType(object3D.GetType())?.FirstOrDefault() is IObject3DEditor editor) { ShowObjectEditor((editor, object3D, object3D.Name), selectedItem, allowOperations: allowOperations); } } else if (JsonPath.JsonPathContext.ReflectionValueSystem.LastMemberValue is ReflectionTarget reflectionTarget) { var context = new PPEContext(); if (reflectionTarget.Source is IObject3D editedChild) { context.item = editedChild; } else { context.item = item; } var editableProperty = new EditableProperty(reflectionTarget.PropertyInfo, reflectionTarget.Source); var editor = PublicPropertyEditor.CreatePropertyEditor(editableProperty, undoBuffer, context, theme); if (editor != null) { editorPanel.AddChild(editor); } } } } // Enforce panel padding foreach (var sectionWidget in editorPanel.Descendants <SectionWidget>()) { sectionWidget.Margin = new BorderDouble(0, theme.DefaultContainerPadding / 2); } }
public static TreeNode BuildTree(IObject3D rootItem, Dictionary <IObject3D, TreeNode> keyValues, ThemeConfig theme) { return(AddTree(BuildItemView(rootItem), null, keyValues, theme)); }
public GuiWidget Create(IObject3D item, ThemeConfig theme) { var mainContainer = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.Stretch }; // TODO: Long term we should have a solution where editors can extend Draw and Undo without this hack var view3DWidget = ApplicationController.Instance.DragDropData.View3DWidget; var undoBuffer = view3DWidget.sceneContext.Scene.UndoBuffer; if (item is IEditorDraw editorDraw) { // TODO: Putting the drawing code in the IObject3D means almost certain bindings to MatterControl in IObject3D. If instead // we had a UI layer object that used binding to register scene drawing hooks for specific types, we could avoid the bindings view3DWidget.InteractionLayer.DrawGlOpaqueContent += editorDraw.DrawEditor; mainContainer.Closed += (s, e) => { view3DWidget.InteractionLayer.DrawGlOpaqueContent -= editorDraw.DrawEditor; }; } if (item != null) { var context = new PPEContext() { item = item }; // CreateEditor AddUnlockLinkIfRequired(context, mainContainer, theme); // Create a field editor for each editable property detected via reflection foreach (var property in GetEditablePropreties(context.item)) { var editor = CreatePropertyEditor(property, undoBuffer, context, theme); if (editor != null) { mainContainer.AddChild(editor); } } AddWebPageLinkIfRequired(context, mainContainer, theme); // add in an Update button if applicable var showUpdate = context.item.GetType().GetCustomAttributes(typeof(ShowUpdateButtonAttribute), true).FirstOrDefault() as ShowUpdateButtonAttribute; if (showUpdate != null) { var updateButton = new TextButton("Update".Localize(), theme) { Margin = 5, BackgroundColor = theme.MinimalShade, HAnchor = HAnchor.Right, VAnchor = VAnchor.Absolute }; updateButton.Click += (s, e) => { context.item.Invalidate(new InvalidateArgs(context.item, InvalidateType.Properties, undoBuffer)); }; mainContainer.AddChild(updateButton); } // Init with custom 'UpdateControls' hooks (context.item as IPropertyGridModifier)?.UpdateControls(new PublicPropertyChange(context, "Update_Button")); } return(mainContainer); }
public override void SetPosition(IObject3D selectedItem, MeshSelectInfo selectInfo) { // create the transform for the box Vector3 edgePosition = GetEdgePosition(selectedItem, edgeIndex); Vector3 boxCenter = edgePosition; double distBetweenPixelsWorldSpace = Object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(edgePosition); switch (edgeIndex) { case 0: boxCenter.Y += selectCubeSize / 2 * distBetweenPixelsWorldSpace; break; case 1: boxCenter.X -= selectCubeSize / 2 * distBetweenPixelsWorldSpace; break; case 2: boxCenter.Y -= selectCubeSize / 2 * distBetweenPixelsWorldSpace; break; case 3: boxCenter.X += selectCubeSize / 2 * distBetweenPixelsWorldSpace; break; } boxCenter.Z += selectCubeSize / 2 * distBetweenPixelsWorldSpace; var centerMatrix = Matrix4X4.CreateTranslation(boxCenter); centerMatrix = Matrix4X4.CreateScale(distBetweenPixelsWorldSpace) * centerMatrix; TotalTransform = centerMatrix; // build the scaling lines lines.Clear(); Vector3 otherSideDelta = GetDeltaToOtherSideXy(selectedItem, edgeIndex); var cornerPosition = GetCornerPosition(selectedItem, edgeIndex); var screen1 = Object3DControlContext.World.GetScreenSpace(cornerPosition); var screen2 = Object3DControlContext.World.GetScreenSpace(GetCornerPosition(selectedItem, (edgeIndex + 1) % 4)); if (screen1.Z < screen2.Z) { if (edgeIndex % 2 == 0) { // left lines double xSign = otherSideDelta.X > 0 ? 1 : -1; var yOtherSide = new Vector3(cornerPosition.X, cornerPosition.Y + otherSideDelta.Y, cornerPosition.Z); lines.Add(Object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(xSign * DistToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(xSign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(yOtherSide - new Vector3(xSign * DistToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(yOtherSide - new Vector3(xSign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0, 0))); } else { // bottom lines double ySign = otherSideDelta.Y > 0 ? 1 : -1; var xOtherSide = new Vector3(cornerPosition.X + otherSideDelta.X, cornerPosition.Y, cornerPosition.Z); lines.Add(Object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(0, ySign * DistToStart * distBetweenPixelsWorldSpace, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(0, ySign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(xOtherSide - new Vector3(0, ySign * DistToStart * distBetweenPixelsWorldSpace, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(xOtherSide - new Vector3(0, ySign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0))); } } else { cornerPosition = GetCornerPosition(selectedItem, (edgeIndex + 2) % 4); if (edgeIndex % 2 == 0) { // right lines double xSign = otherSideDelta.X < 0 ? 1 : -1; var yOtherSide = new Vector3(cornerPosition.X, cornerPosition.Y - otherSideDelta.Y, cornerPosition.Z); // left lines lines.Add(Object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(xSign * DistToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(xSign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(yOtherSide - new Vector3(xSign * DistToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(yOtherSide - new Vector3(xSign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0, 0))); } else { // bottom lines double ySign = otherSideDelta.Y < 0 ? 1 : -1; var xOtherSide = new Vector3(cornerPosition.X - otherSideDelta.X, cornerPosition.Y, cornerPosition.Z); lines.Add(Object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(0, ySign * DistToStart * distBetweenPixelsWorldSpace, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(0, ySign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(xOtherSide - new Vector3(0, ySign * DistToStart * distBetweenPixelsWorldSpace, 0))); lines.Add(Object3DControlContext.World.GetScreenPosition(xOtherSide - new Vector3(0, ySign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0))); } } }
public ActiveRigid( IObject3D caller) { this.caller = caller; }
public static async void DuplicateItem(this ISceneContext sceneContext, double xOffset, IObject3D sourceItem = null) { var scene = sceneContext.Scene; if (sourceItem == null) { var selectedItem = scene.SelectedItem; if (selectedItem != null) { sourceItem = selectedItem; } } if (sourceItem != null) { // Copy selected item IObject3D newItem = await Task.Run(() => { if (sourceItem != null) { if (sourceItem is SelectionGroupObject3D) { // the selection is a group of objects that need to be copied var copyList = sourceItem.Children.ToList(); scene.SelectedItem = null; foreach (var item in copyList) { var clonedItem = item.Clone(); clonedItem.Translate(xOffset); // make the name unique var newName = agg_basics.GetNonCollidingName(item.Name, scene.DescendantsAndSelf().Select((d) => d.Name)); clonedItem.Name = newName; // add it to the scene scene.Children.Add(clonedItem); // add it to the selection scene.AddToSelection(clonedItem); } } else // the selection can be cloned easily { var clonedItem = sourceItem.Clone(); clonedItem.Translate(xOffset); // an empty string is used do denote special name processing for some container types if (!string.IsNullOrWhiteSpace(sourceItem.Name)) { // make the name unique var newName = agg_basics.GetNonCollidingName(sourceItem.Name, scene.DescendantsAndSelf().Select((d) => d.Name)); clonedItem.Name = newName; } // More useful if it creates the part in the exact position and then the user can move it. // Consistent with other software as well. LBB 2017-12-02 // PlatingHelper.MoveToOpenPositionRelativeGroup(clonedItem, Scene.Children); return(clonedItem); } } return(null); }); // it might come back null due to threading if (newItem != null) { sceneContext.InsertNewItem(newItem); } } }
public DynamicEventArgs(IObject3D obj, IDynamic dynamic) : base(obj) { this.dynamic = dynamic; }
public static void MakeLowestFaceFlat(this InteractiveScene scene, IObject3D objectToLayFlatGroup) { var preLayFlatMatrix = objectToLayFlatGroup.Matrix; bool firstVertex = true; IObject3D objectToLayFlat = objectToLayFlatGroup; Vector3Float lowestPosition = Vector3Float.PositiveInfinity; Vector3Float sourceVertexPosition = Vector3Float.NegativeInfinity; IObject3D itemToLayFlat = null; Mesh meshWithLowest = null; var items = objectToLayFlat.VisibleMeshes().Where(i => i.OutputType != PrintOutputTypes.Support); if (!items.Any()) { items = objectToLayFlat.VisibleMeshes(); } // Process each child, checking for the lowest vertex foreach (var itemToCheck in items) { var meshToCheck = itemToCheck.Mesh.GetConvexHull(false); if (meshToCheck == null && meshToCheck.Vertices.Count < 3) { continue; } // find the lowest point on the model for (int testIndex = 0; testIndex < meshToCheck.Vertices.Count; testIndex++) { var vertex = meshToCheck.Vertices[testIndex]; var vertexPosition = vertex.Transform(itemToCheck.WorldMatrix()); if (firstVertex) { meshWithLowest = meshToCheck; lowestPosition = vertexPosition; sourceVertexPosition = vertex; itemToLayFlat = itemToCheck; firstVertex = false; } else if (vertexPosition.Z < lowestPosition.Z) { meshWithLowest = meshToCheck; lowestPosition = vertexPosition; sourceVertexPosition = vertex; itemToLayFlat = itemToCheck; } } } if (meshWithLowest == null) { // didn't find any selected mesh return; } int faceToLayFlat = -1; double largestAreaOfAnyFace = 0; var facesSharingLowestVertex = meshWithLowest.Faces .Select((face, i) => new { face, i }) .Where(faceAndIndex => meshWithLowest.Vertices[faceAndIndex.face.v0] == sourceVertexPosition || meshWithLowest.Vertices[faceAndIndex.face.v1] == sourceVertexPosition || meshWithLowest.Vertices[faceAndIndex.face.v2] == sourceVertexPosition) .Select(j => j.i); var lowestFacesByAngle = facesSharingLowestVertex.OrderBy(i => { var face = meshWithLowest.Faces[i]; var worldNormal = face.normal.TransformNormal(itemToLayFlat.WorldMatrix()); return(worldNormal.CalculateAngle(-Vector3Float.UnitZ)); }); // Check all the faces that are connected to the lowest point to find out which one to lay flat. foreach (var faceIndex in lowestFacesByAngle) { var face = meshWithLowest.Faces[faceIndex]; var worldNormal = face.normal.TransformNormal(itemToLayFlat.WorldMatrix()); var worldAngleDegrees = MathHelper.RadiansToDegrees(worldNormal.CalculateAngle(-Vector3Float.UnitZ)); double largestAreaFound = 0; var faceVeretexIndices = new int[] { face.v0, face.v1, face.v2 }; foreach (var vi in faceVeretexIndices) { if (meshWithLowest.Vertices[vi] != lowestPosition) { var planSurfaceArea = 0.0; foreach (var coPlanarFace in meshWithLowest.GetCoplanerFaces(faceIndex)) { planSurfaceArea += meshWithLowest.GetSurfaceArea(coPlanarFace); } if (largestAreaOfAnyFace == 0 || (planSurfaceArea > largestAreaFound && worldAngleDegrees < 45)) { largestAreaFound = planSurfaceArea; } } } if (largestAreaFound > largestAreaOfAnyFace) { largestAreaOfAnyFace = largestAreaFound; faceToLayFlat = faceIndex; } } double maxDistFromLowestZ = 0; var lowestFace = meshWithLowest.Faces[faceToLayFlat]; var lowestFaceIndices = new int[] { lowestFace.v0, lowestFace.v1, lowestFace.v2 }; var faceVertices = new List <Vector3Float>(); foreach (var vertex in lowestFaceIndices) { var vertexPosition = meshWithLowest.Vertices[vertex].Transform(itemToLayFlat.WorldMatrix()); faceVertices.Add(vertexPosition); maxDistFromLowestZ = Math.Max(maxDistFromLowestZ, vertexPosition.Z - lowestPosition.Z); } if (maxDistFromLowestZ > .001) { var xPositive = (faceVertices[1] - faceVertices[0]).GetNormal(); var yPositive = (faceVertices[2] - faceVertices[0]).GetNormal(); var planeNormal = xPositive.Cross(yPositive).GetNormal(); // this code takes the minimum rotation required and looks much better. Quaternion rotation = new Quaternion(planeNormal, new Vector3Float(0, 0, -1)); Matrix4X4 partLevelMatrix = Matrix4X4.CreateRotation(rotation); // rotate it objectToLayFlat.Matrix = objectToLayFlatGroup.ApplyAtBoundsCenter(partLevelMatrix); } if (objectToLayFlatGroup is Object3D object3D) { AxisAlignedBoundingBox bounds = object3D.GetAxisAlignedBoundingBox(Matrix4X4.Identity, (item) => { return(item.OutputType != PrintOutputTypes.Support); }); Vector3 boundsCenter = (bounds.MaxXYZ + bounds.MinXYZ) / 2; object3D.Matrix *= Matrix4X4.CreateTranslation(new Vector3(0, 0, -boundsCenter.Z + bounds.ZSize / 2)); } else { PlatingHelper.PlaceOnBed(objectToLayFlatGroup); } scene.UndoBuffer.Add(new TransformCommand(objectToLayFlatGroup, preLayFlatMatrix, objectToLayFlatGroup.Matrix)); }
public UngroupCommand(IObject3D group) { this.group = group; }
public GuiWidget Create(IObject3D item, ThemeConfig theme) { var column = new FlowLayoutWidget(FlowDirection.TopToBottom) { HAnchor = HAnchor.MaxFitOrStretch }; var imageObject = item as ImageObject3D; var activeImage = imageObject.Image; var imageSection = new SearchableSectionWidget("Image".Localize(), new FlowLayoutWidget(FlowDirection.TopToBottom), theme, emptyText: "Search Google".Localize()); imageSection.SearchInvoked += (s, e) => { string imageType = " silhouette"; if (item.Parent.GetType().Name.Contains("Lithophane")) { imageType = ""; } ApplicationController.Instance.LaunchBrowser($"http://www.google.com/search?q={e.Data}{imageType}&tbm=isch"); }; theme.ApplyBoxStyle(imageSection, margin: 0); column.AddChild(imageSection); ImageBuffer thumbnailImage = SetImage(theme, imageObject); ImageWidget thumbnailWidget; imageSection.ContentPanel.AddChild(thumbnailWidget = new ImageWidget(thumbnailImage) { Margin = new BorderDouble(bottom: 5), HAnchor = HAnchor.Center }); thumbnailWidget.Click += (s, e) => { if (e.Button == MouseButtons.Right) { var popupMenu = new PopupMenu(theme); var pasteMenu = popupMenu.CreateMenuItem("Paste".Localize()); pasteMenu.Click += (s2, e2) => { activeImage = Clipboard.Instance.GetImage(); thumbnailWidget.Image = activeImage; // Persist string filePath = ApplicationDataStorage.Instance.GetNewLibraryFilePath(".png"); AggContext.ImageIO.SaveImageData( filePath, activeImage); imageObject.AssetPath = filePath; imageObject.Mesh = null; thumbnailWidget.Image = SetImage(theme, imageObject); column.Invalidate(); imageObject.Invalidate(new InvalidateArgs(imageObject, InvalidateType.Image)); }; pasteMenu.Enabled = Clipboard.Instance.ContainsImage; var copyMenu = popupMenu.CreateMenuItem("Copy".Localize()); copyMenu.Click += (s2, e2) => { Clipboard.Instance.SetImage(thumbnailWidget.Image); }; var popupBounds = new RectangleDouble(e.X + 1, e.Y + 1, e.X + 1, e.Y + 1); var systemWindow = column.Parents <SystemWindow>().FirstOrDefault(); systemWindow.ShowPopup( new MatePoint(thumbnailWidget) { Mate = new MateOptions(MateEdge.Left, MateEdge.Bottom), AltMate = new MateOptions(MateEdge.Left, MateEdge.Top) }, new MatePoint(popupMenu) { Mate = new MateOptions(MateEdge.Left, MateEdge.Top), AltMate = new MateOptions(MateEdge.Left, MateEdge.Top) }, altBounds: popupBounds); } }; // add in the invert checkbox and change image button var changeButton = new TextButton("Change".Localize(), theme) { BackgroundColor = theme.MinimalShade }; changeButton.Click += (sender, e) => { UiThread.RunOnIdle(() => { // we do this using to make sure that the stream is closed before we try and insert the Picture AggContext.FileDialogs.OpenFileDialog( new OpenFileDialogParams( "Select an image file|*.jpg;*.png;*.bmp;*.gif;*.pdf", multiSelect: false, title: "Add Image".Localize()), (openParams) => { if (!File.Exists(openParams.FileName)) { return; } imageObject.AssetPath = openParams.FileName; imageObject.Mesh = null; thumbnailWidget.Image = SetImage(theme, imageObject); column.Invalidate(); imageObject.Invalidate(new InvalidateArgs(imageObject, InvalidateType.Image)); }); }); }; var row = new FlowLayoutWidget() { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, }; imageSection.ContentPanel.AddChild(row); // Invert checkbox var invertCheckbox = new CheckBox(new CheckBoxViewText("Invert".Localize(), textColor: theme.Colors.PrimaryTextColor)) { Checked = imageObject.Invert, Margin = new BorderDouble(0), }; invertCheckbox.CheckedStateChanged += (s, e) => { imageObject.Invert = invertCheckbox.Checked; }; row.AddChild(invertCheckbox); row.AddChild(new HorizontalSpacer()); row.AddChild(changeButton); imageObject.Invalidated += (s, e) => { if (e.InvalidateType == InvalidateType.Image && activeImage != imageObject.Image) { thumbnailImage = SetImage(theme, imageObject); thumbnailWidget.Image = thumbnailImage; activeImage = imageObject.Image; } }; return(column); }
public void AddChild(IObject3D child) { // remove this child from any previous parent if (child.Parent != null) { child.Parent.RemoveChild(child); } // init array if no children already exist, delay init to save memory if( _children == null) _children = new ArrayList(); // add the child _children.Add(child); // make child aware of parent child.Parent = this; }
private static GuiWidget CreateImageDisplay(ImageBuffer imageBuffer, IObject3D parent, ThemeConfig theme) { return(new ImageWidget(imageBuffer)); }
// a constructor, that when called has ultimate power over the sphere. public MeshCtrlPt(Device device, float x, float y, float z, float scale, int slices, int stacks, IObject3D owner) { this.device = device; mesh = Mesh.Sphere(device, scale, slices, stacks); name = ValidateName("Control Point", true); this.Translate(x, y, z); if (owner != null) Parent = owner; }
private void AddObject(IObject3D object3D) { listBox.Items.Add(object3D); listBox.SelectedIndex = listBox.Items.Count - 1; }
/// <summary> /// Get all values from an object and display them. /// Customize the display for this type of object. /// </summary> /// <param name="obj">The object to get manipulation data from</param> private void FillObjectValues(IObject3D obj) { // fill in this object's values if (obj != null) { txtCurrentObject.SetText(obj.Name); txtRotateX.SetText(obj.Rotation.X.ToString()); txtRotateY.SetText(obj.Rotation.Y.ToString()); txtRotateZ.SetText(obj.Rotation.Z.ToString()); txtMoveX.SetText(obj.Translation.X.ToString()); txtMoveY.SetText(obj.Translation.Y.ToString()); txtMoveZ.SetText(obj.Translation.Z.ToString()); txtScaleX.SetText(obj.Scaling.X.ToString()); txtScaleY.SetText(obj.Scaling.Y.ToString()); txtScaleZ.SetText(obj.Scaling.Z.ToString()); } propertyGrid.SelectedObject = this.CurrentObject; }
public void RemoveChild(IObject3D child) { // will throw exception if child doesn't exist _children.Remove(child); // remove the parent reference child.Parent = null; }
public ParentChangeCommand(ArrayList objects, IObject3D newParent) { this.objects = (ArrayList)objects.Clone(); this.parent = newParent; }