From 71979e35e9e9b416b1e78c09fe24e030d0093a8b Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Wed, 6 Dec 2017 16:29:31 -0800 Subject: [PATCH] Unify to single GetNonCollidingName Improve it to check for and replace numbers add new calling method Make sure Object3D Close does not end up modifying object in processes Don't try to render meshes with no faces --- ApplicationView/ApplicationController.cs | 50 ++++++++++++------- .../FileSystem/FileSystemContainer.cs | 26 ++-------- Library/Widgets/InsertionGroup.cs | 2 + .../View3D/Actions/MeshWrapperOperation.cs | 3 +- .../View3D/Actions/PaintMaterialEditor.cs | 31 ++++++------ PartPreviewWindow/View3D/SceneActions.cs | 24 ++++++--- PartPreviewWindow/ViewControls3D.cs | 1 + .../SetupStepMakeModelName.cs | 2 +- .../Settings/ProfileManager.cs | 2 +- .../SlicePresetsWindow/SlicePresetsWindow.cs | 22 +------- Submodules/agg-sharp | 2 +- 11 files changed, 78 insertions(+), 87 deletions(-) diff --git a/ApplicationView/ApplicationController.cs b/ApplicationView/ApplicationController.cs index 5bcef76e5..2a4767fbb 100644 --- a/ApplicationView/ApplicationController.cs +++ b/ApplicationView/ApplicationController.cs @@ -280,16 +280,21 @@ namespace MatterHackers.MatterControl () => "Subtract".Localize(), (scene) => { - var difference = new MeshWrapperOperation(scene.SelectedItem.Children) + var children = scene.SelectedItem.Children; + scene.SelectedItem = null; + + var difference = new MeshWrapperOperation(new List (children.Select((i) => i.Clone()))) { ActiveEditor = nameof(SubtractEditor), Name = "Subtract", }; - scene.SelectedItem.Children.Modify((list) => - { - list.Clear(); - }); - scene.Children.Add(difference); + + scene.UndoBuffer.AddAndDo( + new ReplaceCommand( + new List(children), + new List { difference })); + + difference.MakeNameNonColliding(); scene.SelectedItem = difference; } }, @@ -297,17 +302,21 @@ namespace MatterHackers.MatterControl () => "Intersect".Localize(), (scene) => { - var intersection = new MeshWrapperOperation(scene.SelectedItem.Children) + var selectedItems = scene.SelectedItem.Children; + scene.SelectedItem = null; + + var intersection = new MeshWrapperOperation(new List (selectedItems.Select((i) => i.Clone()))) { ActiveEditor = nameof(IntersectionEditor), Name = "Intersect", }; - scene.SelectedItem.Children.Modify((list) => - { - list.Clear(); - }); - scene.Children.Add(intersection); + scene.UndoBuffer.AddAndDo( + new ReplaceCommand( + new List(selectedItems), + new List { intersection })); + + intersection.MakeNameNonColliding(); scene.SelectedItem = intersection; } }, @@ -316,16 +325,21 @@ namespace MatterHackers.MatterControl () => "Paint Material".Localize(), (scene) => { - var materialPaint = new MeshWrapperOperation(scene.SelectedItem.Children) + var selectedItems = scene.SelectedItem.Children; + scene.SelectedItem = null; + + var materialPaint = new MeshWrapperOperation(new List (selectedItems.Select((i) => i.Clone()))) { ActiveEditor = nameof(PaintMaterialEditor), Name = "Material Paint", }; - scene.SelectedItem.Children.Modify((list) => - { - list.Clear(); - }); - scene.Children.Add(materialPaint); + + scene.UndoBuffer.AddAndDo( + new ReplaceCommand( + new List(selectedItems), + new List { materialPaint })); + + materialPaint.MakeNameNonColliding(); scene.SelectedItem = materialPaint; } }, diff --git a/Library/Providers/FileSystem/FileSystemContainer.cs b/Library/Providers/FileSystem/FileSystemContainer.cs index 34f459f51..6ff61ab3f 100644 --- a/Library/Providers/FileSystem/FileSystemContainer.cs +++ b/Library/Providers/FileSystem/FileSystemContainer.cs @@ -34,6 +34,7 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; +using MatterHackers.Agg; using MatterHackers.Agg.Platform; using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; @@ -49,8 +50,6 @@ namespace MatterHackers.MatterControl.Library private bool isActiveContainer; private bool isDirty; - private static Regex fileNameNumberMatch = new Regex("\\(\\d+\\)", RegexOptions.Compiled); - public FileSystemContainer(string path) { this.fullPath = path; @@ -205,29 +204,14 @@ namespace MatterHackers.MatterControl.Library private string GetNonCollidingName(string fileName) { - string incrementedFilePath; - string fileExtension = Path.GetExtension(fileName); - // Switching from .stl, .obj or similar to AMF. Save the file and update the // the filename with an incremented (n) value to reflect the extension change in the UI - fileName = Path.GetFileNameWithoutExtension(fileName); + var similarFileNames = Directory.GetFiles(this.fullPath, $"{Path.GetFileNameWithoutExtension(fileName)}.*"); - // Drop bracketed number sections from our source filename to ensure we don't generate something like "file (1) (1).amf" - if (fileName.Contains("(")) - { - fileName = fileNameNumberMatch.Replace(fileName, "").Trim(); - } + // ; + var validName = agg_basics.GetNonCollidingName(fileName, (testName) => !File.Exists(testName)); - // Generate and search for an incremented file name until no match is found at the target directory - int foundCount = 1; - do - { - incrementedFilePath = Path.Combine(this.fullPath, $"{fileName} ({foundCount++}){fileExtension}"); - - // Continue incrementing while any matching file exists - } while (File.Exists(incrementedFilePath)); - - return incrementedFilePath; + return validName; } public async override void Add(IEnumerable items) diff --git a/Library/Widgets/InsertionGroup.cs b/Library/Widgets/InsertionGroup.cs index 19e7a2017..ffe34c9b3 100644 --- a/Library/Widgets/InsertionGroup.cs +++ b/Library/Widgets/InsertionGroup.cs @@ -121,6 +121,8 @@ namespace MatterHackers.MatterControl.PrintLibrary this.Children.Add(loadedItem); + loadedItem.MakeNameNonColliding(); + // Wait for content to load // Adjust next item position diff --git a/PartPreviewWindow/View3D/Actions/MeshWrapperOperation.cs b/PartPreviewWindow/View3D/Actions/MeshWrapperOperation.cs index 3c9c60d54..c0887efdd 100644 --- a/PartPreviewWindow/View3D/Actions/MeshWrapperOperation.cs +++ b/PartPreviewWindow/View3D/Actions/MeshWrapperOperation.cs @@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using System.Collections.Generic; using System.Linq; using MatterHackers.DataConverters3D; using MatterHackers.PolygonMesh; @@ -39,7 +40,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D { } - public MeshWrapperOperation(SafeList children) + public MeshWrapperOperation(List children) { Children.Modify((list) => { diff --git a/PartPreviewWindow/View3D/Actions/PaintMaterialEditor.cs b/PartPreviewWindow/View3D/Actions/PaintMaterialEditor.cs index 71ea02cf5..735cb976a 100644 --- a/PartPreviewWindow/View3D/Actions/PaintMaterialEditor.cs +++ b/PartPreviewWindow/View3D/Actions/PaintMaterialEditor.cs @@ -153,26 +153,23 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D { foreach (var keep in keepObjects) { - if (paint.MaterialIndex != keep.MaterialIndex) - { - var transformedPaint = Mesh.Copy(paint.Mesh, CancellationToken.None); - transformedPaint.Transform(paint.WorldMatrix()); + var transformedPaint = Mesh.Copy(paint.Mesh, CancellationToken.None); + transformedPaint.Transform(paint.WorldMatrix()); - var transformedKeep = Mesh.Copy(keep.Mesh, CancellationToken.None); - transformedKeep.Transform(keep.WorldMatrix()); + var transformedKeep = Mesh.Copy(keep.Mesh, CancellationToken.None); + transformedKeep.Transform(keep.WorldMatrix()); - // remove the paint from the original - var intersectAndSubtract = PolygonMesh.Csg.CsgOperations.IntersectAndSubtract(transformedKeep, transformedPaint); - var inverseKeep = keep.WorldMatrix(); - inverseKeep.Invert(); - intersectAndSubtract.subtract.Transform(inverseKeep); - keep.Mesh = intersectAndSubtract.subtract; + // remove the paint from the original + var intersectAndSubtract = PolygonMesh.Csg.CsgOperations.IntersectAndSubtract(transformedKeep, transformedPaint); + var inverseKeep = keep.WorldMatrix(); + inverseKeep.Invert(); + intersectAndSubtract.subtract.Transform(inverseKeep); + keep.Mesh = intersectAndSubtract.subtract; - var inverseRemove = paint.WorldMatrix(); - inverseRemove.Invert(); - intersectAndSubtract.intersect.Transform(inverseRemove); - paint.Mesh = intersectAndSubtract.intersect; - } + var inverseRemove = paint.WorldMatrix(); + inverseRemove.Invert(); + intersectAndSubtract.intersect.Transform(inverseRemove); + paint.Mesh = intersectAndSubtract.intersect; } // now set it to the new solid color diff --git a/PartPreviewWindow/View3D/SceneActions.cs b/PartPreviewWindow/View3D/SceneActions.cs index df510508f..2e2ac4e29 100644 --- a/PartPreviewWindow/View3D/SceneActions.cs +++ b/PartPreviewWindow/View3D/SceneActions.cs @@ -32,10 +32,12 @@ using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MatterHackers.Agg; using MatterHackers.Agg.UI; using MatterHackers.DataConverters3D; using MatterHackers.Localizations; using MatterHackers.MeshVisualizer; +using MatterHackers.PolygonMesh; using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.PartPreviewWindow @@ -157,14 +159,24 @@ namespace MatterHackers.MatterControl.PartPreviewWindow // Copy selected item IObject3D newItem = await Task.Run(() => { - // new item can be null by the time this task kicks off - var clonedItem = Scene.SelectedItem?.Clone(); + var originalItem = Scene.SelectedItem; + if (originalItem != null) + { + // new item can be null by the time this task kicks off + var clonedItem = originalItem.Clone(); - // More usefull if it creates the part in the exact positon and then the user can move it. - // Consistent with othre software as well. LBB 2017-12-02 - //PlatingHelper.MoveToOpenPositionRelativeGroup(clonedItem, Scene.Children); + // make the name unique + var newName = agg_basics.GetNonCollidingName(originalItem.Name, Scene.Descendants().Select((d) => d.Name)); + clonedItem.Name = newName; - return clonedItem; + // More usefull if it creates the part in the exact positon and then the user can move it. + // Consistent with othre software as well. LBB 2017-12-02 + //PlatingHelper.MoveToOpenPositionRelativeGroup(clonedItem, Scene.Children); + + return clonedItem; + } + + return null; }); if (view3DWidget.HasBeenClosed) diff --git a/PartPreviewWindow/ViewControls3D.cs b/PartPreviewWindow/ViewControls3D.cs index 99ab18c0d..bbae4a96a 100644 --- a/PartPreviewWindow/ViewControls3D.cs +++ b/PartPreviewWindow/ViewControls3D.cs @@ -316,6 +316,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { var button = new TextButton(namedAction.Title, theme) { + Name = namedAction.Title + " Button", VAnchor = VAnchor.Center, Margin = theme.ButtonSpacing, BackgroundColor = theme.MinimalShade diff --git a/PrinterControls/PrinterConnections/SetupStepMakeModelName.cs b/PrinterControls/PrinterConnections/SetupStepMakeModelName.cs index c5d0070cb..8a9b791b2 100644 --- a/PrinterControls/PrinterConnections/SetupStepMakeModelName.cs +++ b/PrinterControls/PrinterConnections/SetupStepMakeModelName.cs @@ -259,7 +259,7 @@ namespace MatterHackers.MatterControl.PrinterControls.PrinterConnections string mappedMakeText = printerManufacturerSelector.SelectedLabel; var existingPrinterNames = ProfileManager.Instance.ActiveProfiles.Select(p => p.Name); - printerNameInput.Text = agg_basics.GetNonCollidingName(existingPrinterNames, $"{mappedMakeText} {activeModel}"); + printerNameInput.Text = agg_basics.GetNonCollidingName($"{mappedMakeText} {activeModel}", existingPrinterNames); } }); } diff --git a/SlicerConfiguration/Settings/ProfileManager.cs b/SlicerConfiguration/Settings/ProfileManager.cs index f0c29a883..6840a5745 100644 --- a/SlicerConfiguration/Settings/ProfileManager.cs +++ b/SlicerConfiguration/Settings/ProfileManager.cs @@ -350,7 +350,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration var printerInfo = new PrinterInfo { - Name = agg_basics.GetNonCollidingName(existingPrinterNames, fileName), + Name = agg_basics.GetNonCollidingName(fileName, existingPrinterNames), ID = Guid.NewGuid().ToString(), Make = "Other", Model = "Other", diff --git a/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs b/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs index be8b43062..c3b3e6ed4 100644 --- a/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs +++ b/SlicerConfiguration/SlicePresetsWindow/SlicePresetsWindow.cs @@ -161,26 +161,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration }; } - private string GetNonCollidingName(string profileName, IEnumerable existingNames) - { - if (!existingNames.Contains(profileName)) - { - return profileName; - } - else - { - int currentIndex = 1; - string possiblePrinterName; - - do - { - possiblePrinterName = String.Format("{0} ({1})", profileName, currentIndex++); - } while (existingNames.Contains(possiblePrinterName)); - - return possiblePrinterName; - } - } - private FlowLayoutWidget GetBottomRow(TextImageButtonFactory buttonFactory) { var container = new FlowLayoutWidget() @@ -195,7 +175,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration UiThread.RunOnIdle(() => { string sanitizedName = numberMatch.Replace(presetNameInput.Text, "").Trim(); - string newProfileName = GetNonCollidingName(sanitizedName, presetsContext.PresetLayers.Select(preset => preset.ValueOrDefault(SettingsKey.layer_name))); + string newProfileName = agg_basics.GetNonCollidingName(sanitizedName, presetsContext.PresetLayers.Select(preset => preset.ValueOrDefault(SettingsKey.layer_name))); var clonedLayer = presetsContext.PersistenceLayer.Clone(); clonedLayer.Name = newProfileName; diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 207215ac2..612f60db0 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 207215ac28662e4e370a6f71c114a28904974686 +Subproject commit 612f60db00c94d3338ec44389f5643ef09b7316f