示例#1
0
文件: Curve.cs 项目: deobald/midget
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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();
        }
示例#4
0
        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();
        }
示例#5
0
        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);
        }
示例#6
0
        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);
            }
        }
示例#7
0
        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);
        }
示例#9
0
        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);
        }
示例#10
0
        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));
        }
示例#11
0
        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);
        }
示例#12
0
        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);
        }
示例#13
0
        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;
            }
        }
示例#14
0
        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);
        }
示例#15
0
        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);
            }
        }
示例#16
0
        /// <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);
            }
        }
示例#18
0
 public RenderSingleViewEventArgs(IObject3D initScene, int initFrameNumber)
 {
     this.scene = initScene;
     this.frameNumber = initFrameNumber;
 }
示例#19
0
 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);
        }
示例#21
0
        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;
        }
示例#22
0
        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);
        }
示例#23
0
 public ObjectView(IObject3D source)
 {
     this.Source   = source;
     this.Children = this.Source.Children;
     this.Name     = this.Source.Name;
 }
示例#24
0
 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;
 }
示例#25
0
 public void SelectAdditionalObject(IObject3D obj)
 {
     SelectedObjects.Add(obj);
 }
示例#26
0
 public AddDynamicCommand(IObject3D obj, IDynamic dynamic)
 {
     this.obj = obj;
     this.dynamic = dynamic;
 }
示例#27
0
        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);
        }
示例#28
0
 public void DeselectObject(IObject3D obj)
 {
     SelectedObjects.Remove(obj);
 }
示例#29
0
 public void ChangeParent(IObject3D obj, IObject3D newParent)
 {
     newParent.AddChild(obj);
 }
示例#30
0
 public void AddObject(IObject3D newObject)
 {
     objectList.Add(newObject);
     _scene.AddChild(newObject);
     newObject.Parent = _scene;
 }
示例#31
0
 private SceneManager()
 {
     _scene = new SceneObject();
     objectList = new ArrayList();
     selectedObjects = new SelectedObjectContainer();
 }
示例#32
0
        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;
        }
示例#33
0
        /// <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);
                }
            }
        }
示例#34
0
        public void RemoveObject(IObject3D oldObject)
        {
            objectList.Remove(oldObject);

            // remove object from it's parent
            oldObject.Parent.RemoveChild(oldObject);
        }
示例#35
0
        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;
        }
示例#36
0
        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));
                    }
                }
            }
        }
示例#37
0
 public RotateObject3D(IObject3D item, Vector3 translation, string name = "")
     : this(item, translation.X, translation.Y, translation.Z, name)
 {
 }
示例#38
0
        public void NewScene()
        {
            _scene = new GroupObject();

            // TODO: make a SceneChanged event, 'cuz this is for sucks
            DeviceManager.Instance.UpdateViews();
        }
示例#39
0
        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);
        }
示例#40
0
        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;
        }
示例#41
0
 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);
        }
示例#44
0
        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);
                }
            }
示例#45
0
 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);
        }
示例#47
0
        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)));
                }
            }
        }
示例#48
0
 public ActiveRigid( IObject3D caller)
 {
     this.caller = caller;
 }
示例#49
0
        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);
                }
            }
        }
示例#50
0
 public DynamicEventArgs(IObject3D obj, IDynamic dynamic)
     : base(obj)
 {
     this.dynamic = dynamic;
 }
示例#51
0
        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));
        }
示例#52
0
 public UngroupCommand(IObject3D group)
 {
     this.group = group;
 }
示例#53
0
        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);
        }
示例#54
0
        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));
 }
示例#56
0
文件: Curve.cs 项目: deobald/midget
 // 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;
 }
示例#57
0
 private void AddObject(IObject3D object3D)
 {
     listBox.Items.Add(object3D);
     listBox.SelectedIndex = listBox.Items.Count - 1;
 }
示例#58
0
        /// <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;
        }
示例#59
0
        public void RemoveChild(IObject3D child)
        {
            // will throw exception if child doesn't exist
            _children.Remove(child);

            // remove the parent reference
            child.Parent = null;
        }
示例#60
0
 public ParentChangeCommand(ArrayList objects, IObject3D newParent)
 {
     this.objects = (ArrayList)objects.Clone();
     this.parent = newParent;
 }