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); }
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); } }
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; })); }
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; }
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; }
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; })); }
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 })); }
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; })); }
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; })); }
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; })); }
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)); }
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); }
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; } }