public void AddEditorTransparents(Object3DControlsLayer layer, List <Object3DView> transparentMeshes, DrawEventArgs e) { if (layer.Scene.SelectedItem != null && layer.Scene.SelectedItem == this) { var parentOfSubtractTargets = this.SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf(); var removeObjects = parentOfSubtractTargets.Children .Where(i => SelectedChildren.Contains(i.ID)) .SelectMany(c => c.VisibleMeshes()) .ToList(); foreach (var item in removeObjects) { var color = item.WorldColor(checkOutputType: true); transparentMeshes.Add(new Object3DView(item, color.WithAlpha(color.Alpha0To1 * .2))); } } }
public void DrawEditor(Object3DControlsLayer layer, List <Object3DView> transparentMeshes, DrawEventArgs e) { if (layer.Scene.SelectedItem != null && layer.Scene.SelectedItem == this) { var parentOfSubtractTargets = this.SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf(); var removeObjects = parentOfSubtractTargets.Children .Where(i => SelectedChildren.Contains(i.ID)) .SelectMany(c => c.VisibleMeshes()) .ToList(); foreach (var item in removeObjects) { transparentMeshes.Add(new Object3DView(item, new Color(item.WorldColor(this.SourceContainer), 80))); } var keepItems = parentOfSubtractTargets.Children .Where(i => !SelectedChildren.Contains(i.ID)) .ToList(); foreach (var keepItem in keepItems) { var drawItem = keepItem; var keepItemResult = this.Children.Where(i => i.OwnerID == keepItem.ID).FirstOrDefault(); drawItem = keepItemResult != null ? keepItemResult : drawItem; foreach (var item in drawItem.VisibleMeshes()) { GLHelper.Render(item.Mesh, item.WorldColor(), item.WorldMatrix(), RenderTypes.Outlines, item.WorldMatrix() * layer.World.ModelviewMatrix); } } } }
private static GuiWidget CreateSelector(SelectedChildren 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 (selectionChanged) { child.Visible = true; } } } } tabContainer.Closed += (s, e) => UpdateSelectColors(); var children = parent.Children.ToList(); var objectChecks = new Dictionary <ICheckbox, IObject3D>(); var radioSiblings = new List <GuiWidget>(); for (int i = 0; i < children.Count; i++) { var itemIndex = i; var child = children[itemIndex]; var 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 = theme.TextColor }; 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 = theme.TextColor }; } objectChecks.Add((ICheckbox)selectWidget, child); rowContainer.AddChild(selectWidget); var 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(); } return(tabContainer); }
private static GuiWidget CreateSourceChildSelector(SelectedChildren childSelector, OperationSourceContainerObject3D sourceContainer, ThemeConfig theme, Action selectionChanged) { GuiWidget tabContainer = new FlowLayoutWidget(FlowDirection.TopToBottom) { Margin = new BorderDouble(0, 3, 0, 0), }; var parentOfSubtractTargets = sourceContainer.SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf(); var sourceChildren = parentOfSubtractTargets.Children.ToList(); var objectChecks = new Dictionary <ICheckbox, IObject3D>(); var radioSiblings = new List <GuiWidget>(); for (int i = 0; i < sourceChildren.Count; i++) { var itemIndex = i; var child = sourceChildren[itemIndex]; var rowContainer = new FlowLayoutWidget() { Padding = new BorderDouble(15, 0, 0, 3) }; GuiWidget selectWidget; if (sourceChildren.Count == 2) { var radioButton = new RadioButton(string.IsNullOrWhiteSpace(child.Name) ? $"{itemIndex}" : $"{child.Name}") { Checked = childSelector.Contains(child.ID), TextColor = theme.TextColor, Margin = 0, }; 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 = theme.TextColor, }; } objectChecks.Add((ICheckbox)selectWidget, child); rowContainer.AddChild(selectWidget); var 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); } } selectionChanged?.Invoke(); } }; tabContainer.AddChild(rowContainer); } return(tabContainer); }
private void SubtractAndReplace(CancellationToken cancellationToken, IProgress <ProgressStatus> reporter) { SourceContainer.Visible = true; RemoveAllButSource(); var parentOfPaintTargets = SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf(); if (parentOfPaintTargets.Children.Count() < 2) { if (parentOfPaintTargets.Children.Count() == 1) { this.Children.Add(SourceContainer.Clone()); SourceContainer.Visible = false; } return; } SubtractObject3D_2.CleanUpSelectedChildrenNames(this); var paintObjects = parentOfPaintTargets.Children .Where((i) => SelectedChildren .Contains(i.ID)) .SelectMany(c => c.VisibleMeshes()) .ToList(); var keepItems = parentOfPaintTargets.Children .Where((i) => !SelectedChildren .Contains(i.ID)); var keepVisibleItems = keepItems.SelectMany(c => c.VisibleMeshes()).ToList(); if (paintObjects.Any() && keepVisibleItems.Any()) { var totalOperations = paintObjects.Count * keepVisibleItems.Count; double amountPerOperation = 1.0 / totalOperations; double ratioCompleted = 0; var progressStatus = new ProgressStatus { Status = "Do CSG" }; foreach (var keep in keepVisibleItems) { var keepResultsMesh = keep.Mesh; var keepWorldMatrix = keep.WorldMatrix(SourceContainer); foreach (var paint in paintObjects) { if (cancellationToken.IsCancellationRequested) { SourceContainer.Visible = true; RemoveAllButSource(); return; } Mesh paintMesh = BooleanProcessing.Do(keepResultsMesh, keepWorldMatrix, // paint data paint.Mesh, paint.WorldMatrix(SourceContainer), // operation type CsgModes.Intersect, Processing, InputResolution, OutputResolution, // reporting data reporter, amountPerOperation, ratioCompleted, progressStatus, cancellationToken); keepResultsMesh = BooleanProcessing.Do(keepResultsMesh, keepWorldMatrix, // point data paint.Mesh, paint.WorldMatrix(SourceContainer), // operation type CsgModes.Subtract, Processing, InputResolution, OutputResolution, // reporting data 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; // store our intersection (paint) results mesh var paintResultsItem = new Object3D() { Mesh = paintMesh, Visible = false, OwnerID = paint.ID }; // copy all the properties but the matrix paintResultsItem.CopyWorldProperties(paint, SourceContainer, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible))); // and add it to this this.Children.Add(paintResultsItem); // report our progress ratioCompleted += amountPerOperation; progressStatus.Progress0To1 = ratioCompleted; reporter?.Report(progressStatus); } // store our results mesh var keepResultsItem = new Object3D() { Mesh = keepResultsMesh, Visible = false, OwnerID = keep.ID }; // copy all the properties but the matrix keepResultsItem.CopyWorldProperties(keep, SourceContainer, 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 Subtract(CancellationToken cancellationToken, IProgress <ProgressStatus> reporter) { SourceContainer.Visible = true; RemoveAllButSource(); var parentOfSubtractTargets = SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf(); if (parentOfSubtractTargets.Children.Count() < 2) { if (parentOfSubtractTargets.Children.Count() == 1) { this.Children.Add(SourceContainer.Clone()); SourceContainer.Visible = false; } return; } CleanUpSelectedChildrenNames(this); var removeVisibleItems = parentOfSubtractTargets.Children .Where((i) => SelectedChildren .Contains(i.ID)) .SelectMany(c => c.VisiblePaths()) .ToList(); var keepItems = parentOfSubtractTargets.Children .Where((i) => !SelectedChildren .Contains(i.ID)); var keepVisibleItems = keepItems.SelectMany(c => c.VisiblePaths()).ToList(); if (removeVisibleItems.Any() && keepVisibleItems.Any()) { var totalOperations = removeVisibleItems.Count * keepVisibleItems.Count; double amountPerOperation = 1.0 / totalOperations; double percentCompleted = 0; var progressStatus = new ProgressStatus { Status = "Do Subtract" }; bool first = true; foreach (var keep in keepVisibleItems) { var resultsVertexSource = (keep as IPathObject).VertexSource.Transform(keep.Matrix); foreach (var remove in removeVisibleItems) { resultsVertexSource = resultsVertexSource.MergePaths(((IPathObject)remove).VertexSource.Transform(remove.Matrix), ClipperLib.ClipType.ctDifference); // report our progress percentCompleted += amountPerOperation; progressStatus.Progress0To1 = percentCompleted; reporter?.Report(progressStatus); } if (first) { this.VertexSource = resultsVertexSource; first = false; } else { this.VertexSource.MergePaths(resultsVertexSource, ClipperLib.ClipType.ctUnion); } } // this.VertexSource = this.VertexSource.Transform(Matrix.Inverted); first = true; foreach (var child in Children) { if (first) { // hide the source item child.Visible = false; first = false; } else { child.Visible = true; } } } }
private void Subtract(CancellationToken cancellationToken, IProgress <ProgressStatus> reporter) { SourceContainer.Visible = true; RemoveAllButSource(); var parentOfSubtractTargets = SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf(); if (parentOfSubtractTargets.Children.Count() < 2) { if (parentOfSubtractTargets.Children.Count() == 1) { this.Children.Add(SourceContainer.Clone()); SourceContainer.Visible = false; } return; } CleanUpSelectedChildrenNames(this); var removeVisibleItems = parentOfSubtractTargets.Children .Where((i) => SelectedChildren .Contains(i.ID)) .SelectMany(c => c.VisibleMeshes()) .ToList(); var keepItems = parentOfSubtractTargets.Children .Where((i) => !SelectedChildren .Contains(i.ID)); var keepVisibleItems = keepItems.SelectMany(c => c.VisibleMeshes()).ToList(); if (removeVisibleItems.Any() && keepVisibleItems.Any()) { var totalOperations = removeVisibleItems.Count * keepVisibleItems.Count; double amountPerOperation = 1.0 / totalOperations; double percentCompleted = 0; var progressStatus = new ProgressStatus { Status = "Do CSG" }; foreach (var keep in keepVisibleItems) { var resultsMesh = keep.Mesh; var keepWorldMatrix = keep.WorldMatrix(SourceContainer); foreach (var remove in removeVisibleItems) { resultsMesh = BooleanProcessing.Do(resultsMesh, keepWorldMatrix, // other mesh remove.Mesh, remove.WorldMatrix(SourceContainer), // operation type BooleanProcessing.CsgModes.Subtract, Processing, InputResolution, OutputResolution, // reporting 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; // report our progress percentCompleted += amountPerOperation; progressStatus.Progress0To1 = percentCompleted; reporter?.Report(progressStatus); } // store our results mesh var resultsItem = new Object3D() { Mesh = resultsMesh, Visible = false, OwnerID = keep.ID }; // copy all the properties but the matrix resultsItem.CopyWorldProperties(keep, SourceContainer, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible))); // and add it to this this.Children.Add(resultsItem); } bool first = true; foreach (var child in Children) { if (first) { // hid the source item child.Visible = false; first = false; } else { child.Visible = true; } } } }
public void DrawEditor(Object3DControlsLayer layer, List <Object3DView> transparentMeshes, DrawEventArgs e) { var parentOfSourceItems = this.SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf(); var sourceItems = parentOfSourceItems.Children.ToList(); foreach (var paintItem in sourceItems) { var paintItemResults = this.Children.Where(i => i.OwnerID == paintItem.ID); var wasSelected = ComputedChildren.Contains(paintItem.ID); var currentlySelected = SelectedChildren.Contains(paintItem.ID); if (currentlySelected) { // if this is selected always paint a transparent source foreach (var item in paintItem.VisibleMeshes()) { transparentMeshes.Add(new Object3DView(item, new Color(item.WorldColor(this.SourceContainer), 80))); } // if it was also selected in before (the results are right) if (wasSelected) { // paint solid results if (paintItemResults != null) { foreach (var paintItemResult in paintItemResults) { foreach (var item in paintItemResult.VisibleMeshes()) { GLHelper.Render(item.Mesh, item.WorldColor(), item.WorldMatrix(), RenderTypes.Outlines, item.WorldMatrix() * layer.World.ModelviewMatrix); } } } } } else if (wasSelected) { // it is not selected now but was selected before (changed state) // pant the solid source foreach (var item in paintItem.VisibleMeshes()) { GLHelper.Render(item.Mesh, item.WorldColor(), item.WorldMatrix(), RenderTypes.Outlines, item.WorldMatrix() * layer.World.ModelviewMatrix); } } else // it is not selected now and was not before (same state) { // paint the results if (paintItemResults != null && paintItemResults.Count() > 0) { foreach (var paintItemResult in paintItemResults) { foreach (var item in paintItemResult.VisibleMeshes()) { GLHelper.Render(item.Mesh, item.WorldColor(), item.WorldMatrix(), RenderTypes.Outlines, item.WorldMatrix() * layer.World.ModelviewMatrix); } } } else // we don't have any results yet { foreach (var item in paintItem.VisibleMeshes()) { GLHelper.Render(item.Mesh, item.WorldColor(), item.WorldMatrix(), RenderTypes.Outlines, item.WorldMatrix() * layer.World.ModelviewMatrix); } } } } }
private static GuiWidget CreateSourceChildSelector(SelectedChildren childSelector, OperationSourceContainerObject3D sourceCantainer, ThemeConfig theme) { GuiWidget tabContainer = new FlowLayoutWidget(FlowDirection.TopToBottom); var sourceChildren = sourceCantainer.SourceContainer.VisibleMeshes().ToList(); var objectChecks = new Dictionary <ICheckbox, IObject3D>(); var radioSiblings = new List <GuiWidget>(); for (int i = 0; i < sourceChildren.Count; i++) { var itemIndex = i; var child = sourceChildren[itemIndex]; var rowContainer = new FlowLayoutWidget(); GuiWidget selectWidget; if (sourceChildren.Count == 2) { var radioButton = new RadioButton(string.IsNullOrWhiteSpace(child.Name) ? $"{itemIndex}" : $"{child.Name}") { Checked = childSelector.Contains(child.Name), TextColor = theme.TextColor }; radioSiblings.Add(radioButton); radioButton.SiblingRadioButtonList = radioSiblings; selectWidget = radioButton; } else { selectWidget = new CheckBox(string.IsNullOrWhiteSpace(child.Name) ? $"{itemIndex}" : $"{child.Name}") { Checked = childSelector.Contains(child.Name), TextColor = theme.TextColor }; } objectChecks.Add((ICheckbox)selectWidget, child); rowContainer.AddChild(selectWidget); var checkBox = selectWidget as ICheckbox; checkBox.CheckedStateChanged += (s, e) => { if (s is ICheckbox checkbox) { if (checkBox.Checked) { if (!childSelector.Contains(objectChecks[checkbox].Name)) { childSelector.Add(objectChecks[checkbox].Name); } } else { if (childSelector.Contains(objectChecks[checkbox].Name)) { childSelector.Remove(objectChecks[checkbox].Name); } } } }; tabContainer.AddChild(rowContainer); } return(tabContainer); }