Merge pull request #3355 from larsbrubaker/design_tools
Improvements in mesh wrapper
This commit is contained in:
commit
dbcdf4b4bd
7 changed files with 119 additions and 86 deletions
|
|
@ -512,7 +512,7 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
OperationType = typeof(CombineObject3D),
|
||||
TitleResolver = () => "Combine".Localize(),
|
||||
Action = (scene) => new CombineObject3D().DoInitialWrapping(scene),
|
||||
Action = (scene) => new CombineObject3D().WrapSelectedItemAndSelect(scene),
|
||||
Icon = AggContext.StaticData.LoadIcon("combine.png").SetPreMultiply(),
|
||||
IsEnabled = (scene) => scene.SelectedItem is SelectionGroup,
|
||||
},
|
||||
|
|
@ -520,7 +520,7 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
OperationType = typeof(SubtractObject3D),
|
||||
TitleResolver = () => "Subtract".Localize(),
|
||||
Action = (scene) => new SubtractObject3D().DoInitialWrapping(scene),
|
||||
Action = (scene) => new SubtractObject3D().WrapSelectedItemAndSelect(scene),
|
||||
Icon = AggContext.StaticData.LoadIcon("subtract.png").SetPreMultiply(),
|
||||
IsEnabled = (scene) => scene.SelectedItem is SelectionGroup,
|
||||
},
|
||||
|
|
@ -528,7 +528,7 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
OperationType = typeof(IntersectionObject3D),
|
||||
TitleResolver = () => "Intersect".Localize(),
|
||||
Action = (scene) => new IntersectionObject3D().DoInitialWrapping(scene),
|
||||
Action = (scene) => new IntersectionObject3D().WrapSelectedItemAndSelect(scene),
|
||||
Icon = AggContext.StaticData.LoadIcon("intersect.png"),
|
||||
IsEnabled = (scene) => scene.SelectedItem is SelectionGroup,
|
||||
},
|
||||
|
|
@ -536,7 +536,7 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
OperationType = typeof(SubtractAndReplaceObject3D),
|
||||
TitleResolver = () => "Subtract & Replace".Localize(),
|
||||
Action = (scene) => new SubtractAndReplaceObject3D().DoInitialWrapping(scene),
|
||||
Action = (scene) => new SubtractAndReplaceObject3D().WrapSelectedItemAndSelect(scene),
|
||||
Icon = AggContext.StaticData.LoadIcon("subtract_and_replace.png").SetPreMultiply(),
|
||||
IsEnabled = (scene) => scene.SelectedItem is SelectionGroup,
|
||||
},
|
||||
|
|
@ -594,7 +594,7 @@ namespace MatterHackers.MatterControl
|
|||
Action = (scene) =>
|
||||
{
|
||||
var pinch = new PinchObject3D();
|
||||
pinch.DoInitialWrapping(scene);
|
||||
pinch.WrapSelectedItemAndSelect(scene);
|
||||
},
|
||||
Icon = AggContext.StaticData.LoadIcon("pinch.png", 16, 16, theme.InvertIcons),
|
||||
IsEnabled = (scene) => scene.HasSelection,
|
||||
|
|
@ -606,7 +606,7 @@ namespace MatterHackers.MatterControl
|
|||
Action = (scene) =>
|
||||
{
|
||||
var curve = new CurveObject3D();
|
||||
curve.DoInitialWrapping(scene);
|
||||
curve.WrapSelectedItemAndSelect(scene);
|
||||
},
|
||||
Icon = AggContext.StaticData.LoadIcon("curve.png", 16, 16, theme.InvertIcons),
|
||||
IsEnabled = (scene) => scene.HasSelection,
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
if (curvedMesh == originalMesh)
|
||||
{
|
||||
// Make sure the mesh we are going to copy is in a good state to be copied (so we maintain vertex count)
|
||||
originalMesh.CleanAndMergeMesh(CancellationToken.None);
|
||||
//originalMesh.CleanAndMergeMesh(CancellationToken.None);
|
||||
curvedMesh = Mesh.Copy(originalMesh, CancellationToken.None);
|
||||
object3Ds.Curved.Mesh = curvedMesh;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
public class PinchObject3D : MeshWrapperObject3D, IPublicPropertyObject
|
||||
{
|
||||
[DisplayName("Back Ratio")]
|
||||
public double PinchRatio { get; set; } = 1;
|
||||
public double PinchRatio { get; set; } = .5;
|
||||
|
||||
public PinchObject3D()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -49,19 +49,39 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
|
||||
public override void Remove(UndoBuffer undoBuffer)
|
||||
{
|
||||
if (Rebuilding)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
|
||||
SetRebuilding(true);
|
||||
// remove all the mesh wrappers that we own
|
||||
var meshWrappers = this.Descendants().Where(o => o.OwnerID == this.ID).ToList();
|
||||
foreach(var meshWrapper in meshWrappers)
|
||||
foreach (var meshWrapper in meshWrappers)
|
||||
{
|
||||
meshWrapper.Remove(undoBuffer);
|
||||
meshWrapper.Remove(null);
|
||||
}
|
||||
foreach(var child in Children)
|
||||
foreach (var child in Children)
|
||||
{
|
||||
child.OutputType = PrintOutputTypes.Default;
|
||||
}
|
||||
|
||||
// collapse our children into our parent
|
||||
base.Remove(undoBuffer);
|
||||
base.Remove(null);
|
||||
SetRebuilding(false);
|
||||
|
||||
Invalidate(new InvalidateArgs(this, InvalidateType.Content));
|
||||
}
|
||||
|
||||
private void SetRebuilding(bool rebuilding)
|
||||
{
|
||||
foreach (var item in this.DescendantsAndSelf())
|
||||
{
|
||||
if (item is Object3D object3D)
|
||||
{
|
||||
object3D.Rebuilding = rebuilding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Apply(UndoBuffer undoBuffer)
|
||||
|
|
@ -90,58 +110,51 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
base.Apply(undoBuffer);
|
||||
}
|
||||
|
||||
public void DoInitialWrapping(InteractiveScene scene)
|
||||
public void WrapSelectedItemAndSelect(InteractiveScene scene)
|
||||
{
|
||||
MeshWrapperObject3D meshWrapper = this;
|
||||
|
||||
Rebuilding = true;
|
||||
var selectedItem = scene.SelectedItem;
|
||||
if (selectedItem != null)
|
||||
if (Rebuilding)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
|
||||
SetRebuilding(true);
|
||||
|
||||
var selectedItems = scene.GetSelectedItems();
|
||||
|
||||
if(selectedItems.Count > 0)
|
||||
{
|
||||
// cleare the selected item
|
||||
scene.SelectedItem = null;
|
||||
|
||||
List<IObject3D> originalItems;
|
||||
var clonedItemsToAdd = new List<IObject3D>(selectedItems.Select((i) => i.Clone()));
|
||||
|
||||
if (selectedItem is SelectionGroup)
|
||||
Children.Modify((list) =>
|
||||
{
|
||||
originalItems = selectedItem.Children.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
originalItems = new List<IObject3D> { selectedItem };
|
||||
}
|
||||
list.Clear();
|
||||
|
||||
var itemsToAdd = new List<IObject3D>(originalItems.Select((i) => i.Clone()));
|
||||
meshWrapper.WrapAndAddAsChildren(itemsToAdd);
|
||||
foreach (var child in clonedItemsToAdd)
|
||||
{
|
||||
list.Add(child);
|
||||
}
|
||||
});
|
||||
|
||||
AddMeshWrapperToAllChildren();
|
||||
|
||||
scene.UndoBuffer.AddAndDo(
|
||||
new ReplaceCommand(
|
||||
new List<IObject3D>(originalItems),
|
||||
new List<IObject3D> { meshWrapper }));
|
||||
new List<IObject3D>(selectedItems),
|
||||
new List<IObject3D> { this }));
|
||||
|
||||
meshWrapper.MakeNameNonColliding();
|
||||
scene.SelectedItem = meshWrapper;
|
||||
this.MakeNameNonColliding();
|
||||
|
||||
// and select this
|
||||
scene.SelectedItem = this;
|
||||
}
|
||||
|
||||
Rebuilding = false;
|
||||
SetRebuilding(false);
|
||||
Rebuild(null);
|
||||
}
|
||||
|
||||
public void WrapAndAddAsChildren(List<IObject3D> children)
|
||||
{
|
||||
Children.Modify((list) =>
|
||||
{
|
||||
list.Clear();
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
list.Add(child);
|
||||
}
|
||||
});
|
||||
|
||||
AddMeshWrapperToAllChildren();
|
||||
}
|
||||
|
||||
private void AddMeshWrapperToAllChildren()
|
||||
{
|
||||
// Wrap every first descendant that has a mesh
|
||||
|
|
@ -173,9 +186,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
// set the mesh back to the child mesh
|
||||
item.Mesh = firstChild.Mesh;
|
||||
// and reset the properties
|
||||
var itemMatrix = item.Matrix;
|
||||
item.CopyProperties(firstChild, flags);
|
||||
item.Matrix = itemMatrix;
|
||||
item.CopyProperties(firstChild, flags & (~Object3DPropertyFlags.Matrix));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,23 +44,42 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
public static class SceneActions
|
||||
{
|
||||
public static async void UngroupSelection(this InteractiveScene Scene)
|
||||
public static List<IObject3D> GetSelectedItems(this InteractiveScene scene)
|
||||
{
|
||||
if (Scene.HasSelection)
|
||||
var selectedItem = scene.SelectedItem;
|
||||
var selectedItems = new List<IObject3D>();
|
||||
if (selectedItem != null)
|
||||
{
|
||||
if (selectedItem is SelectionGroup)
|
||||
{
|
||||
selectedItems = selectedItem.Children.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedItems = new List<IObject3D> { selectedItem };
|
||||
}
|
||||
}
|
||||
|
||||
return selectedItems;
|
||||
}
|
||||
|
||||
public static async void UngroupSelection(this InteractiveScene scene)
|
||||
{
|
||||
if (scene.HasSelection)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
var selectedItem = Scene.SelectedItem;
|
||||
bool isGroupItemType = Scene.HasSelection && selectedItem.Children.Count > 0;
|
||||
var selectedItem = scene.SelectedItem;
|
||||
bool isGroupItemType = scene.HasSelection && selectedItem.Children.Count > 0;
|
||||
|
||||
// If not a Group ItemType, look for mesh volumes and split into distinct objects if found
|
||||
if (!isGroupItemType
|
||||
&& !selectedItem.HasChildren()
|
||||
&& selectedItem.Mesh != null)
|
||||
{
|
||||
var ungroupItem = Scene.SelectedItem;
|
||||
var ungroupItem = scene.SelectedItem;
|
||||
// clear the selection
|
||||
Scene.SelectedItem = null;
|
||||
scene.SelectedItem = null;
|
||||
var ungroupMesh = ungroupItem.Mesh;
|
||||
|
||||
if (!ungroupMesh.Vertices.IsSorted)
|
||||
|
|
@ -77,7 +96,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
if (discreetMeshes.Count == 1)
|
||||
{
|
||||
// restore the selection
|
||||
Scene.SelectedItem = ungroupItem;
|
||||
scene.SelectedItem = ungroupItem;
|
||||
// No further processing needed, nothing to ungroup
|
||||
return;
|
||||
}
|
||||
|
|
@ -90,27 +109,27 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}));
|
||||
|
||||
// add and do the undo data
|
||||
Scene.UndoBuffer.AddAndDo(new ReplaceCommand(new List<IObject3D> { ungroupItem }, addItems));
|
||||
scene.UndoBuffer.AddAndDo(new ReplaceCommand(new List<IObject3D> { ungroupItem }, addItems));
|
||||
}
|
||||
|
||||
if (isGroupItemType)
|
||||
{
|
||||
// Create and perform the delete operation
|
||||
// Store the operation for undo/redo
|
||||
Scene.UndoBuffer.AddAndDo(new UngroupCommand(Scene, Scene.SelectedItem));
|
||||
scene.UndoBuffer.AddAndDo(new UngroupCommand(scene, scene.SelectedItem));
|
||||
}
|
||||
});
|
||||
|
||||
// leave no selection
|
||||
Scene.SelectedItem = null;
|
||||
scene.SelectedItem = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static async void AutoArrangeChildren(this InteractiveScene Scene, View3DWidget view3DWidget)
|
||||
public static async void AutoArrangeChildren(this InteractiveScene scene, View3DWidget view3DWidget)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
PlatingHelper.ArrangeOnBed(Scene.Children.ToList(), Scene, view3DWidget.BedCenter);
|
||||
PlatingHelper.ArrangeOnBed(scene.Children.ToList(), scene, view3DWidget.BedCenter);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -139,13 +158,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}
|
||||
}
|
||||
|
||||
public static async void DuplicateItem(this InteractiveScene Scene, IObject3D sourceItem = null)
|
||||
public static async void DuplicateItem(this InteractiveScene scene, IObject3D sourceItem = null)
|
||||
{
|
||||
if (sourceItem == null)
|
||||
{
|
||||
if (Scene.HasSelection)
|
||||
if (scene.HasSelection)
|
||||
{
|
||||
sourceItem = Scene.SelectedItem;
|
||||
sourceItem = scene.SelectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,17 +179,17 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
// the selection is a group of objects that need to be copied
|
||||
var copyList = sourceItem.Children.ToList();
|
||||
Scene.SelectedItem = null;
|
||||
scene.SelectedItem = null;
|
||||
foreach(var item in copyList)
|
||||
{
|
||||
var clonedItem = item.Clone();
|
||||
// make the name unique
|
||||
var newName = agg_basics.GetNonCollidingName(item.Name, Scene.DescendantsAndSelf().Select((d) => d.Name));
|
||||
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);
|
||||
scene.Children.Add(clonedItem);
|
||||
// add it to the selection
|
||||
Scene.AddToSelection(clonedItem);
|
||||
scene.AddToSelection(clonedItem);
|
||||
}
|
||||
}
|
||||
else // the selection can be cloned easily
|
||||
|
|
@ -178,7 +197,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
var clonedItem = sourceItem.Clone();
|
||||
|
||||
// make the name unique
|
||||
var newName = agg_basics.GetNonCollidingName(sourceItem.Name, Scene.DescendantsAndSelf().Select((d) => d.Name));
|
||||
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.
|
||||
|
|
@ -195,15 +214,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
// it might come back null due to threading
|
||||
if (newItem != null)
|
||||
{
|
||||
Scene.InsertNewItem(newItem);
|
||||
scene.InsertNewItem(newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void InsertNewItem(this InteractiveScene Scene, IObject3D newItem)
|
||||
public static void InsertNewItem(this InteractiveScene scene, IObject3D newItem)
|
||||
{
|
||||
// Reposition first item to bed center
|
||||
if (Scene.Children.Count == 0)
|
||||
if (scene.Children.Count == 0)
|
||||
{
|
||||
var printer = ApplicationController.Instance.ActivePrinter;
|
||||
var aabb = newItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity);
|
||||
|
|
@ -216,24 +235,24 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
}
|
||||
|
||||
// Create and perform a new insert operation
|
||||
var insertOperation = new InsertCommand(Scene, newItem);
|
||||
var insertOperation = new InsertCommand(scene, newItem);
|
||||
insertOperation.Do();
|
||||
|
||||
// Store the operation for undo/redo
|
||||
Scene.UndoBuffer.Add(insertOperation);
|
||||
scene.UndoBuffer.Add(insertOperation);
|
||||
}
|
||||
|
||||
public static void DeleteSelection(this InteractiveScene Scene)
|
||||
public static void DeleteSelection(this InteractiveScene scene)
|
||||
{
|
||||
if (Scene.HasSelection)
|
||||
if (scene.HasSelection)
|
||||
{
|
||||
// Create and perform the delete operation
|
||||
var deleteOperation = new DeleteCommand(Scene, Scene.SelectedItem);
|
||||
var deleteOperation = new DeleteCommand(scene, scene.SelectedItem);
|
||||
|
||||
// Store the operation for undo/redo
|
||||
Scene.UndoBuffer.AddAndDo(deleteOperation);
|
||||
scene.UndoBuffer.AddAndDo(deleteOperation);
|
||||
|
||||
Scene.ClearSelection();
|
||||
scene.ClearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -309,10 +309,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
button.Click += (s, e) =>
|
||||
{
|
||||
namedAction.Action.Invoke(sceneContext.Scene);
|
||||
var partTab = button.Parents<PartTabPage>().FirstOrDefault();
|
||||
var view3D = partTab.Descendants<View3DWidget>().FirstOrDefault();
|
||||
view3D.InteractionLayer.Focus();
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
namedAction.Action.Invoke(sceneContext.Scene);
|
||||
var partTab = button.Parents<PartTabPage>().FirstOrDefault();
|
||||
var view3D = partTab.Descendants<View3DWidget>().FirstOrDefault();
|
||||
view3D.InteractionLayer.Focus();
|
||||
});
|
||||
};
|
||||
this.AddChild(button);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit f02d679414fccc74de9af4d9e299ffa5fc2845e7
|
||||
Subproject commit ffa51299d57405e5ee73204d4f295dcd29b680ea
|
||||
Loading…
Add table
Add a link
Reference in a new issue