diff --git a/MatterControlLib/ApplicationView/SceneOperations.cs b/MatterControlLib/ApplicationView/SceneOperations.cs index dc0c44a95..7625cf208 100644 --- a/MatterControlLib/ApplicationView/SceneOperations.cs +++ b/MatterControlLib/ApplicationView/SceneOperations.cs @@ -100,7 +100,7 @@ namespace MatterHackers.MatterControl // this is for when base is working with generic meshes //IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && !(sceneContext.Scene.SelectedItem.IsPathObject()), // this is for when only IPathObjects are working correctly - IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.DescendantsAndSelf().Where(i => i.IsPathObject()).Any(), + IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.DescendantsAndSelf().Where(i => i is IPathObject3D).Any(), }; } @@ -391,7 +391,7 @@ namespace MatterHackers.MatterControl }, Icon = (theme) => StaticData.Instance.LoadIcon("inflate_path.png", 16, 16).GrayToColor(theme.TextColor).SetPreMultiply(), HelpTextGetter = () => "A path must be selected".Localize().Stars(), - IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(), + IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject3D, }; } @@ -405,7 +405,7 @@ namespace MatterHackers.MatterControl { var scene = sceneContext.Scene; var sceneItem = scene.SelectedItem; - var pathObject = sceneItem.GetVertexSource(); + var pathObject = sceneItem as IPathObject3D; if (pathObject != null) { var extrude = new LinearExtrudeObject3D(); @@ -424,7 +424,7 @@ namespace MatterHackers.MatterControl }, Icon = (theme) => StaticData.Instance.LoadIcon("linear_extrude.png", 16, 16).GrayToColor(theme.TextColor).SetPreMultiply(), HelpTextGetter = () => "A path must be selected".Localize().Stars(), - IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(), + IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject3D, }; } @@ -438,7 +438,7 @@ namespace MatterHackers.MatterControl { var scene = sceneContext.Scene; var sceneItem = scene.SelectedItem; - var pathObject = sceneItem.GetVertexSource(); + var pathObject = sceneItem as IPathObject3D; if (pathObject != null) { var revolve = new RevolveObject3D(); @@ -457,7 +457,7 @@ namespace MatterHackers.MatterControl }, Icon = (theme) => StaticData.Instance.LoadIcon("revolve.png", 16, 16).GrayToColor(theme.TextColor).SetPreMultiply(), HelpTextGetter = () => "A path must be selected".Localize().Stars(), - IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(), + IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject3D, }; } @@ -549,7 +549,7 @@ namespace MatterHackers.MatterControl }, Icon = (theme) => StaticData.Instance.LoadIcon("outline.png", 16, 16).GrayToColor(theme.TextColor).SetPreMultiply(), HelpTextGetter = () => "A path must be selected".Localize().Stars(), - IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(), + IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject3D, }; } @@ -609,7 +609,7 @@ namespace MatterHackers.MatterControl }, Icon = (theme) => StaticData.Instance.LoadIcon("smooth_path.png", 16, 16).GrayToColor(theme.TextColor).SetPreMultiply(), HelpTextGetter = () => "A path must be selected".Localize().Stars(), - IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem.IsPathObject(), + IsEnabled = (sceneContext) => sceneContext.Scene.SelectedItem != null && sceneContext.Scene.SelectedItem is IPathObject3D, }; } @@ -689,28 +689,34 @@ namespace MatterHackers.MatterControl }; } - private static bool BooleanCandidate(IObject3D selectedItem, bool includePaths) - { - if (selectedItem != null) - { - // mesh items - if (selectedItem.VisibleMeshes().Count() > 1 - && selectedItem.VisibleMeshes().All(i => IsMeshObject(i))) - { - return true; - } + /// + /// Determines if the selected item is a candidate for boolean operations. + /// + /// The selected item in the scene. + /// Flag indicating whether to include path items in the check. + /// Returns true if the selected item is a candidate for boolean operations, false otherwise. + private static bool BooleanCandidate(IObject3D selectedItem, bool includePaths) + { + if (selectedItem != null) + { + // all are path items + if (includePaths + && selectedItem.VisibleMeshes().Count() > 1 + && selectedItem.VisibleMeshes().All(i => i is IPathObject3D)) + { + return true; + } - // path items - if (includePaths - && selectedItem.VisiblePaths().Count() > 1 - && selectedItem.VisiblePaths().All(i => IsPathObject(i))) - { - return true; - } - } + // mesh items + if (selectedItem.VisibleMeshes().Count() > 1 + && selectedItem.VisibleMeshes().All(i => IsMeshObject(i))) + { + return true; + } + } - return false; - } + return false; + } private static void Build() { @@ -1066,16 +1072,39 @@ namespace MatterHackers.MatterControl private static bool IsMeshObject(IObject3D item) { - return item != null - && !(item is ImageObject3D) - && !(item.IsPathObject() && item is CurveObject3D_3); + if (item != null) + { + if (item is ImageObject3D) + { + return false; + } + + if (item is IPathObject3D pathObject) + { + if (!pathObject.MeshIsSolidObject) + { + return false; + } + } + + return true; + } + + return false; } private static bool IsPathObject(IObject3D item) { - return item != null - && !(item is ImageObject3D) - && (item.IsPathObject()); + if (item != null) + { + if (item is IPathObject3D pathObject + && !pathObject.MeshIsSolidObject) + { + return true; + } + } + + return false; } private static SceneOperation LayFlatOperation() diff --git a/MatterControlLib/DesignTools/Operations/Image/ImageToPathObject3D_2.cs b/MatterControlLib/DesignTools/Operations/Image/ImageToPathObject3D_2.cs index 3e322f2be..c2e1e1d84 100644 --- a/MatterControlLib/DesignTools/Operations/Image/ImageToPathObject3D_2.cs +++ b/MatterControlLib/DesignTools/Operations/Image/ImageToPathObject3D_2.cs @@ -116,8 +116,9 @@ namespace MatterHackers.MatterControl.DesignTools } } + public override bool MeshIsSolidObject => false; - private AnalysisTypes _featureDetector = AnalysisTypes.Intensity; + private AnalysisTypes _featureDetector = AnalysisTypes.Intensity; [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Tabs)] public AnalysisTypes AnalysisType { diff --git a/MatterControlLib/DesignTools/Operations/Image/PathObject3D.cs b/MatterControlLib/DesignTools/Operations/Image/PathObject3D.cs index 9749551ad..08f130c7c 100644 --- a/MatterControlLib/DesignTools/Operations/Image/PathObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/Image/PathObject3D.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using MatterHackers.Agg.UI; +using MatterHackers.Agg.VertexSource; using MatterHackers.DataConverters3D; using MatterHackers.MatterControl.DesignTools.Operations; using MatterHackers.MatterControl.PartPreviewWindow; @@ -37,7 +38,7 @@ using System.Collections.Generic; namespace MatterHackers.MatterControl.DesignTools { - public class PathObject3D : Object3D, IEditorDraw, IPrimaryOperationsSpecifier + public abstract class PathObject3D : Object3D, IEditorDraw, IPrimaryOperationsSpecifier, IPathObject3D { public void DrawEditor(Object3DControlsLayer layer, DrawEventArgs e) { @@ -49,6 +50,15 @@ namespace MatterHackers.MatterControl.DesignTools return this.GetWorldspaceAabbOfDrawPath(); } + public VertexStorage VertexStorage { get; set; } + + public virtual IVertexSource GetVertexSource() + { + return VertexStorage; + } + + public abstract bool MeshIsSolidObject { get; } + public static IEnumerable GetOperations(Type type) { // path Ids diff --git a/MatterControlLib/DesignTools/Operations/Path/InflatePathObject3D.cs b/MatterControlLib/DesignTools/Operations/Path/InflatePathObject3D.cs index 05a2d50fa..8a67432b9 100644 --- a/MatterControlLib/DesignTools/Operations/Path/InflatePathObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/Path/InflatePathObject3D.cs @@ -63,6 +63,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations [EnumDisplay(Mode = EnumDisplayAttribute.PresentationMode.Buttons)] public ExpandStyles Style { get; set; } = ExpandStyles.Sharp; + public override bool MeshIsSolidObject => false; + public void AddObject3DControls(Object3DControlsLayer object3DControlsLayer) { object3DControlsLayer.AddControls(ControlTypes.Standard2D); diff --git a/MatterControlLib/DesignTools/Operations/Path/LinearExtrudeObject3D.cs b/MatterControlLib/DesignTools/Operations/Path/LinearExtrudeObject3D.cs index 504cbe257..164db040b 100644 --- a/MatterControlLib/DesignTools/Operations/Path/LinearExtrudeObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/Path/LinearExtrudeObject3D.cs @@ -43,7 +43,7 @@ using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.DesignTools.Operations { - public class LinearExtrudeObject3D : Object3D, IPrimaryOperationsSpecifier, IPropertyGridModifier + public class LinearExtrudeObject3D : PathObject3D, IPrimaryOperationsSpecifier, IPropertyGridModifier { [Description("The height of the extrusion")] [Slider(.1, 50, Easing.EaseType.Quadratic, useSnappingGrid: true)] @@ -64,6 +64,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations public override bool CanApply => true; + public override bool MeshIsSolidObject => true; + public override void Apply(UndoBuffer undoBuffer) { if (Mesh == null) diff --git a/MatterControlLib/DesignTools/Operations/Path/OutlinePathObject3D.cs b/MatterControlLib/DesignTools/Operations/Path/OutlinePathObject3D.cs index 2b0eb53ca..267169149 100644 --- a/MatterControlLib/DesignTools/Operations/Path/OutlinePathObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/Path/OutlinePathObject3D.cs @@ -88,6 +88,8 @@ namespace MatterHackers.MatterControl.DesignTools.Operations } } + public override bool MeshIsSolidObject => false; + public void AddObject3DControls(Object3DControlsLayer object3DControlsLayer) { object3DControlsLayer.AddControls(ControlTypes.Standard2D); diff --git a/MatterControlLib/DesignTools/Operations/Path/SmoothPathObject3D.cs b/MatterControlLib/DesignTools/Operations/Path/SmoothPathObject3D.cs index 37cf8e9c4..29a1aab50 100644 --- a/MatterControlLib/DesignTools/Operations/Path/SmoothPathObject3D.cs +++ b/MatterControlLib/DesignTools/Operations/Path/SmoothPathObject3D.cs @@ -59,7 +59,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations [Description("The number of smoothing passes")] public IntOrExpression Iterations { get; set; } = 3; - public void AddObject3DControls(Object3DControlsLayer object3DControlsLayer) + public override bool MeshIsSolidObject => false; + + public void AddObject3DControls(Object3DControlsLayer object3DControlsLayer) { object3DControlsLayer.AddControls(ControlTypes.Standard2D); } diff --git a/MatterControlLib/DesignTools/Primitives/BoxPathObject3D.cs b/MatterControlLib/DesignTools/Primitives/BoxPathObject3D.cs index d1bafde50..12cd7b778 100644 --- a/MatterControlLib/DesignTools/Primitives/BoxPathObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/BoxPathObject3D.cs @@ -47,6 +47,8 @@ namespace MatterHackers.MatterControl.DesignTools.Primitives Color = Operations.Object3DExtensions.PrimitiveColors["Cube"]; } + public override bool MeshIsSolidObject => false; + public static double MinEdgeSize = .001; public string ThumbnailName => "Box"; diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 1e5938882..461e797ff 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 1e59388827f24709eae3e19cf0d94f3a63a4a03b +Subproject commit 461e797ff7e25df7e9b4a6031d396937d7ea6c30