예제 #1
0
        public override void Apply(UndoBuffer undoBuffer)
        {
            var meshWrappers = this.Descendants().Where(o => o.OwnerID == this.ID).ToList();

            // remove all the meshWrappers (collapse the children)
            foreach (var meshWrapper in meshWrappers)
            {
                var parent = meshWrapper.Parent;
                if (meshWrapper.Visible)
                {
                    var newMesh = new Object3D()
                    {
                        Mesh = meshWrapper.Mesh
                    };
                    newMesh.CopyProperties(meshWrapper, Object3DPropertyFlags.All);
                    newMesh.Name = this.Name;
                    parent.Children.Add(newMesh);
                }

                // remove it
                parent.Children.Remove(meshWrapper);
            }

            base.Apply(undoBuffer);
        }
예제 #2
0
        public override void Flatten(UndoBuffer undoBuffer)
        {
            if (Mesh == null)
            {
                Remove(undoBuffer);
            }
            else
            {
                // only keep the mesh and get rid of everything else
                using (RebuildLock())
                {
                    var meshOnlyItem = new Object3D()
                    {
                        Mesh = this.Mesh.Copy(CancellationToken.None)
                    };

                    meshOnlyItem.CopyProperties(this, Object3DPropertyFlags.All);

                    // and replace us with the children
                    undoBuffer.AddAndDo(new ReplaceCommand(new[] { this }, new[] { meshOnlyItem }));
                }

                Invalidate(InvalidateType.Children);
            }
        }
예제 #3
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");

            var rebuildLocks = this.RebuilLockAll();

            var valuesChanged = false;

            // check if we have be initialized
            if (Mode == ReductionMode.Polygon_Count)
            {
                TargetCount   = agg_basics.Clamp(TargetCount, 4, SourcePolygonCount, ref valuesChanged);
                TargetPercent = TargetCount / (double)SourcePolygonCount * 100;
            }
            else
            {
                TargetPercent = agg_basics.Clamp(TargetPercent, 0, 100, ref valuesChanged);
                TargetCount   = (int)(SourcePolygonCount * TargetPercent / 100);
            }

            return(TaskBuilder(
                       "Reduce".Localize(),
                       (reporter, cancellationToken) =>
            {
                SourceContainer.Visible = true;
                RemoveAllButSource();

                foreach (var sourceItem in SourceContainer.VisibleMeshes())
                {
                    var originalMesh = sourceItem.Mesh;
                    var targetCount = (int)(originalMesh.Faces.Count * TargetPercent / 100);
                    var reducedMesh = Reduce(originalMesh, targetCount);

                    var newMesh = new Object3D()
                    {
                        Mesh = reducedMesh,
                        OwnerID = sourceItem.ID
                    };
                    newMesh.CopyProperties(sourceItem, Object3DPropertyFlags.All);
                    this.Children.Add(newMesh);
                }

                SourceContainer.Visible = false;

                UiThread.RunOnIdle(() =>
                {
                    rebuildLocks.Dispose();
                    if (valuesChanged)
                    {
                        Invalidate(InvalidateType.DisplayValues);
                    }
                    Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
                });

                return Task.CompletedTask;
            }));
        }
예제 #4
0
        private void Intersect(CancellationToken cancellationToken, IProgress <ProgressStatus> reporter)
        {
            SourceContainer.Visible = true;
            RemoveAllButSource();

            var participants = SourceContainer.VisibleMeshes();

            if (participants.Count() < 2)
            {
                if (participants.Count() == 1)
                {
                    var newMesh = new Object3D();
                    newMesh.CopyProperties(participants.First(), Object3DPropertyFlags.All);
                    newMesh.Mesh = participants.First().Mesh;
                    this.Children.Add(newMesh);
                    SourceContainer.Visible = false;
                }
                return;
            }

            var first            = participants.First();
            var resultsMesh      = first.Mesh;
            var firstWorldMatrix = first.WorldMatrix(SourceContainer);

            var    totalOperations    = participants.Count() - 1;
            double amountPerOperation = 1.0 / totalOperations;
            double percentCompleted   = 0;

            ProgressStatus progressStatus = new ProgressStatus();

            foreach (var item in participants)
            {
                if (item != first)
                {
                    var itemWorldMatrix = item.WorldMatrix(SourceContainer);
                    resultsMesh = BooleanProcessing.Do(item.Mesh, itemWorldMatrix,
                                                       resultsMesh, firstWorldMatrix,
                                                       2,
                                                       reporter, amountPerOperation, percentCompleted, progressStatus, cancellationToken);
                    // after the first union we are working with the transformed mesh and don't need the first transform
                    firstWorldMatrix = Matrix4X4.Identity;

                    percentCompleted           += amountPerOperation;
                    progressStatus.Progress0To1 = percentCompleted;
                    reporter?.Report(progressStatus);
                }
            }

            var resultsItem = new Object3D()
            {
                Mesh = resultsMesh
            };

            resultsItem.CopyProperties(first, Object3DPropertyFlags.All & (~Object3DPropertyFlags.Matrix));
            this.Children.Add(resultsItem);
            SourceContainer.Visible = false;
        }
예제 #5
0
        private void Merge(IProgress <ProgressStatus> reporter, CancellationToken cancellationToken)
        {
            SourceContainer.Visible = true;
            RemoveAllButSource();

            var participants = SourceContainer.VisiblePaths();

            if (participants.Count() < 2)
            {
                if (participants.Count() == 1)
                {
                    var newMesh = new Object3D();
                    newMesh.CopyProperties(participants.First(), Object3DPropertyFlags.All);
                    newMesh.Mesh = participants.First().Mesh;
                    this.Children.Add(newMesh);
                    SourceContainer.Visible = false;
                }

                return;
            }

            var first = participants.First();
            var resultsVertexSource = (first as IPathObject).VertexSource.Transform(first.Matrix);

            var    totalOperations    = participants.Count() - 1;
            double amountPerOperation = 1.0 / totalOperations;
            double percentCompleted   = 0;

            var progressStatus = new ProgressStatus();

            foreach (var item in participants)
            {
                if (item != first &&
                    item is IPathObject pathItem)
                {
                    var itemVertexSource = pathItem.VertexSource.Transform(item.Matrix);

                    if (union)
                    {
                        resultsVertexSource = resultsVertexSource.Union(itemVertexSource);
                    }
                    else
                    {
                        resultsVertexSource = resultsVertexSource.MergePaths(itemVertexSource, ClipperLib.ClipType.ctIntersection);
                    }

                    percentCompleted           += amountPerOperation;
                    progressStatus.Progress0To1 = percentCompleted;
                    reporter?.Report(progressStatus);
                }
            }

            this.VertexSource = resultsVertexSource;

            SourceContainer.Visible = false;
        }
예제 #6
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");

            var rebuildLocks = this.RebuilLockAll();

            var valuesChanged = false;

            return(TaskBuilder(
                       "Find Slice".Localize(),
                       (reporter, cancellationToken) =>
            {
                var polygons = new Polygons();
                VertexSource = polygons.PolygonToPathStorage();

                var newChildren = new List <Object3D>();
                foreach (var sourceItem in SourceContainer.VisibleMeshes())
                {
                    var meshPolygons = Cut(sourceItem);

                    polygons = polygons.CreateUnion(meshPolygons.polygons);

                    var newMesh = new Object3D()
                    {
                        Mesh = meshPolygons.mesh,
                        OwnerID = sourceItem.ID
                    };
                    newMesh.CopyProperties(sourceItem, Object3DPropertyFlags.All);
                    newChildren.Add(newMesh);
                }

                VertexSource = polygons.PolygonToPathStorage();

                RemoveAllButSource();
                SourceContainer.Visible = false;
                foreach (var child in newChildren)
                {
                    this.Children.Add(child);
                }

                UiThread.RunOnIdle(() =>
                {
                    rebuildLocks.Dispose();
                    if (valuesChanged)
                    {
                        Invalidate(InvalidateType.DisplayValues);
                    }
                    Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
                });

                return Task.CompletedTask;
            }));
        }
예제 #7
0
        public override void Apply(UndoBuffer undoBuffer)
        {
            // change this from a text object to a group
            var newContainer = new Object3D();

            newContainer.CopyProperties(this, Object3DPropertyFlags.All);
            foreach (var child in this.Children)
            {
                newContainer.Children.Add(child.Clone());
            }
            undoBuffer.AddAndDo(new ReplaceCommand(new List <IObject3D> {
                this
            }, new List <IObject3D> {
                newContainer
            }));
        }
예제 #8
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");

            var rebuildLocks = this.RebuilLockAll();

            var valuesChanged = false;

            return(TaskBuilder(
                       "Reduce".Localize(),
                       (reporter, cancellationToken) =>
            {
                var newChildren = new List <Object3D>();
                foreach (var sourceItem in SourceContainer.VisibleMeshes())
                {
                    var originalMesh = sourceItem.Mesh;
                    var reducedMesh = Cut(originalMesh);

                    var newMesh = new Object3D()
                    {
                        Mesh = reducedMesh,
                        OwnerID = sourceItem.ID
                    };
                    newMesh.CopyProperties(sourceItem, Object3DPropertyFlags.All);
                    newChildren.Add(newMesh);
                }

                RemoveAllButSource();
                SourceContainer.Visible = false;
                foreach (var child in newChildren)
                {
                    this.Children.Add(child);
                }

                rebuildLocks.Dispose();

                if (valuesChanged)
                {
                    Invalidate(InvalidateType.DisplayValues);
                }

                Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));

                return Task.CompletedTask;
            }));
        }
예제 #9
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");

            var rebuildLocks = this.RebuilLockAll();

            var valuesChanged = false;

            // check if we have be initialized

            return(TaskBuilder(
                       "Repair".Localize(),
                       (reporter, cancellationToken) =>
            {
                SourceContainer.Visible = true;
                RemoveAllButSource();

                foreach (var sourceItem in SourceContainer.VisibleMeshes())
                {
                    var originalMesh = sourceItem.Mesh;
                    var reducedMesh = Repair(originalMesh, cancellationToken);

                    var newMesh = new Object3D()
                    {
                        Mesh = reducedMesh
                    };
                    newMesh.CopyProperties(sourceItem, Object3DPropertyFlags.All);
                    this.Children.Add(newMesh);
                }

                SourceContainer.Visible = false;
                rebuildLocks.Dispose();

                if (valuesChanged)
                {
                    Invalidate(InvalidateType.DisplayValues);
                }

                Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));

                return Task.CompletedTask;
            }));
        }
예제 #10
0
        public override Task Rebuild()
        {
            this.DebugDepth("Rebuild");

            var rebuildLocks = this.RebuilLockAll();

            var valuesChanged = false;

            return(TaskBuilder(
                       "Hollow".Localize(),
                       (reporter, cancellationToken) =>
            {
                SourceContainer.Visible = true;
                RemoveAllButSource();

                foreach (var sourceItem in SourceContainer.VisibleMeshes())
                {
                    var newMesh = new Object3D()
                    {
                        Mesh = HollowOut(sourceItem.Mesh, this.Distance, this.NumCells)
                    };
                    newMesh.CopyProperties(sourceItem, Object3DPropertyFlags.All);
                    this.Children.Add(newMesh);
                }

                SourceContainer.Visible = false;

                UiThread.RunOnIdle(() =>
                {
                    rebuildLocks.Dispose();
                    if (valuesChanged)
                    {
                        Invalidate(InvalidateType.DisplayValues);
                    }
                    Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
                });

                return Task.CompletedTask;
            }));
        }
예제 #11
0
        private void Combine(CancellationToken cancellationToken, IProgress <ProgressStatus> reporter)
        {
            SourceContainer.Visible = true;
            RemoveAllButSource();

            var participants = SourceContainer.VisibleMeshes();

            if (participants.Count() < 2)
            {
                if (participants.Count() == 1)
                {
                    var newMesh = new Object3D();
                    newMesh.CopyProperties(participants.First(), Object3DPropertyFlags.All);
                    newMesh.Mesh = participants.First().Mesh;
                    this.Children.Add(newMesh);
                    SourceContainer.Visible = false;
                }

                return;
            }

            var items       = participants.Select(i => (i.Mesh, i.WorldMatrix(SourceContainer)));
            var resultsMesh = BooleanProcessing.DoArray(items,
                                                        BooleanProcessing.CsgModes.Union,
                                                        Processing,
                                                        InputResolution,
                                                        OutputResolution,
                                                        reporter,
                                                        cancellationToken);

            var resultsItem = new Object3D()
            {
                Mesh = resultsMesh
            };

            resultsItem.CopyProperties(participants.First(), Object3DPropertyFlags.All & (~Object3DPropertyFlags.Matrix));
            this.Children.Add(resultsItem);
            SourceContainer.Visible = false;
        }
        public override void Apply(UndoBuffer undoBuffer)
        {
            // only keep the mesh and get rid of everything else
            using (RebuildLock())
            {
                var meshOnlyItem = new Object3D()
                {
                    Mesh = this.Mesh.Copy(CancellationToken.None)
                };

                meshOnlyItem.CopyProperties(this, Object3DPropertyFlags.All);

                // and replace us with the children
                undoBuffer.AddAndDo(new ReplaceCommand(new List <IObject3D> {
                    this
                }, new List <IObject3D> {
                    meshOnlyItem
                }));
            }

            Invalidate(new InvalidateArgs(this, InvalidateType.Content));
        }
예제 #13
0
        public override void Flatten(UndoBuffer undoBuffer)
        {
            using (RebuildLock())
            {
                var thisCopy = this.Clone();

                using (thisCopy.RebuilLockAll())
                {
                    var ownedMeshWrappers = thisCopy.Descendants().Where(o => o.OwnerID == thisCopy.ID).ToList();

                    var newMeshObjects = new List <IObject3D>();

                    // remove all the meshWrappers (collapse the children)
                    foreach (var ownedMeshWrapper in ownedMeshWrappers)
                    {
                        var wrapperParent = ownedMeshWrapper.Parent;
                        if (ownedMeshWrapper.Visible)
                        {
                            var newMesh = new Object3D()
                            {
                                Mesh = ownedMeshWrapper.Mesh.Copy(CancellationToken.None)
                            };
                            newMesh.CopyProperties(ownedMeshWrapper, Object3DPropertyFlags.All);
                            // move the mesh to the actual new position
                            var matrix = ownedMeshWrapper.WorldMatrix(thisCopy);
                            newMesh.Mesh.Transform(matrix);
                            // then set the matrix to identity
                            newMesh.Matrix = Matrix4X4.Identity;
                            newMesh.Name   = thisCopy.Name;
                            newMeshObjects.Add(newMesh);
                        }

                        // remove it
                        wrapperParent.Children.Remove(ownedMeshWrapper);
                    }

                    thisCopy.Matrix = Matrix4X4.Identity;

                    thisCopy.Children.Modify(children =>
                    {
                        children.Clear();
                        children.AddRange(newMeshObjects);
                        foreach (var child in children)
                        {
                            child.MakeNameNonColliding();
                        }
                    });

                    List <IObject3D> newChildren = new List <IObject3D>();
                    // push our matrix into a copy of our children
                    foreach (var child in thisCopy.Children)
                    {
                        var newChild = child.Clone();
                        newChildren.Add(newChild);
                        newChild.Matrix *= thisCopy.Matrix;
                        var flags = Object3DPropertyFlags.Visible;
                        if (thisCopy.Color.alpha != 0)
                        {
                            flags |= Object3DPropertyFlags.Color;
                        }
                        if (thisCopy.OutputType != PrintOutputTypes.Default)
                        {
                            flags |= Object3DPropertyFlags.OutputType;
                        }
                        if (thisCopy.MaterialIndex != -1)
                        {
                            flags |= Object3DPropertyFlags.MaterialIndex;
                        }
                        newChild.CopyProperties(thisCopy, flags);
                    }

                    // and replace us with the children
                    var replaceCommand = new ReplaceCommand(new List <IObject3D> {
                        this
                    }, newChildren, false);
                    if (undoBuffer != null)
                    {
                        undoBuffer.AddAndDo(replaceCommand);
                    }
                    else
                    {
                        replaceCommand.Do();
                    }
                }
            }

            Invalidate(InvalidateType.Children);
        }
예제 #14
0
        private void SubtractAndReplace(CancellationToken cancellationToken, IProgress <ProgressStatus> reporter)
        {
            SourceContainer.Visible = true;
            RemoveAllButSource();

            var participants = SourceContainer.VisibleMeshes();

            if (participants.Count() < 2)
            {
                if (participants.Count() == 1)
                {
                    var newMesh = new Object3D();
                    newMesh.CopyProperties(participants.First(), Object3DPropertyFlags.All);
                    newMesh.Mesh = participants.First().Mesh;
                    this.Children.Add(newMesh);
                    SourceContainer.Visible = false;
                }
                return;
            }

            SubtractObject3D_2.CleanUpSelectedChildrenNames(this);

            var paintObjects = this.SourceContainer.VisibleMeshes()
                               .Where((i) => SelectedChildren.Contains(i.Name)).ToList();
            var keepObjects = this.SourceContainer.VisibleMeshes()
                              .Where((i) => !SelectedChildren.Contains(i.Name)).ToList();

            if (paintObjects.Any() &&
                keepObjects.Any())
            {
                var    totalOperations    = paintObjects.Count * keepObjects.Count;
                double amountPerOperation = 1.0 / totalOperations;
                double percentCompleted   = 0;

                ProgressStatus progressStatus = new ProgressStatus();
                progressStatus.Status = "Do CSG";
                foreach (var keep in keepObjects)
                {
                    var keepResultsMesh = keep.Mesh;
                    var keepWorldMatrix = keep.WorldMatrix(SourceContainer);

                    foreach (var paint in paintObjects)
                    {
                        Mesh paintMesh = BooleanProcessing.Do(keepResultsMesh, keepWorldMatrix,
                                                              paint.Mesh, paint.WorldMatrix(SourceContainer),
                                                              2, reporter, amountPerOperation, percentCompleted, progressStatus, cancellationToken);

                        keepResultsMesh = BooleanProcessing.Do(keepResultsMesh, keepWorldMatrix,
                                                               paint.Mesh, paint.WorldMatrix(SourceContainer),
                                                               1, reporter, amountPerOperation, percentCompleted, progressStatus, cancellationToken);

                        // after the first time we get a result the results mesh is in the right coordinate space
                        keepWorldMatrix = Matrix4X4.Identity;

                        // store our intersection (paint) results mesh
                        var paintResultsItem = new Object3D()
                        {
                            Mesh    = paintMesh,
                            Visible = false
                        };
                        // copy all the properties but the matrix
                        paintResultsItem.CopyProperties(paint, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible)));
                        // and add it to this
                        this.Children.Add(paintResultsItem);

                        // report our progress
                        percentCompleted           += amountPerOperation;
                        progressStatus.Progress0To1 = percentCompleted;
                        reporter?.Report(progressStatus);
                    }

                    // store our results mesh
                    var keepResultsItem = new Object3D()
                    {
                        Mesh    = keepResultsMesh,
                        Visible = false
                    };
                    // copy all the properties but the matrix
                    keepResultsItem.CopyProperties(keep, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible)));
                    // and add it to this
                    this.Children.Add(keepResultsItem);
                }

                foreach (var child in Children)
                {
                    child.Visible = true;
                }
                SourceContainer.Visible = false;
            }
        }
        private void Intersect(CancellationToken cancellationToken, IProgress <ProgressStatus> reporter)
        {
            SourceContainer.Visible = true;
            RemoveAllButSource();

            var participants = SourceContainer.VisibleMeshes();

            if (participants.Count() < 2)
            {
                if (participants.Count() == 1)
                {
                    var newMesh = new Object3D();
                    newMesh.CopyProperties(participants.First(), Object3DPropertyFlags.All);
                    newMesh.Mesh = participants.First().Mesh;
                    this.Children.Add(newMesh);
                    SourceContainer.Visible = false;
                }
                return;
            }

            var items = participants.Select(i => (i.Mesh, i.WorldMatrix(SourceContainer)));

#if false
            var resultsMesh = BooleanProcessing.DoArray(items,
                                                        CsgModes.Intersect,
                                                        Processing,
                                                        InputResolution,
                                                        OutputResolution,
                                                        reporter,
                                                        cancellationToken);
#else
            var    totalOperations    = items.Count() - 1;
            double amountPerOperation = 1.0 / totalOperations;
            double ratioCompleted     = 0;

            var progressStatus = new ProgressStatus();

            var resultsMesh     = items.First().Item1;
            var keepWorldMatrix = items.First().Item2;

            bool first = true;
            foreach (var next in items)
            {
                if (first)
                {
                    first = false;
                    continue;
                }

                resultsMesh = BooleanProcessing.Do(resultsMesh,
                                                   keepWorldMatrix,
                                                   // other mesh
                                                   next.Item1,
                                                   next.Item2,
                                                   // operation type
                                                   CsgModes.Intersect,
                                                   Processing,
                                                   InputResolution,
                                                   OutputResolution,
                                                   // reporting
                                                   reporter,
                                                   amountPerOperation,
                                                   ratioCompleted,
                                                   progressStatus,
                                                   cancellationToken);

                // after the first time we get a result the results mesh is in the right coordinate space
                keepWorldMatrix = Matrix4X4.Identity;

                // report our progress
                ratioCompleted += amountPerOperation;
                progressStatus.Progress0To1 = ratioCompleted;
                reporter?.Report(progressStatus);
            }
#endif

            if (resultsMesh != null)
            {
                var resultsItem = new Object3D()
                {
                    Mesh = resultsMesh
                };
                resultsItem.CopyProperties(participants.First(), Object3DPropertyFlags.All & (~Object3DPropertyFlags.Matrix));
                this.Children.Add(resultsItem);
                SourceContainer.Visible = false;
            }
        }