refactoring

This commit is contained in:
LarsBrubaker 2020-09-11 19:59:14 -07:00
parent c66838d5e3
commit 1dfe8b3ee5
59 changed files with 1210 additions and 1178 deletions

View file

@ -346,9 +346,9 @@ namespace MatterHackers.MatterControl
keyEvent.SuppressKeyPress = true; keyEvent.SuppressKeyPress = true;
} }
foreach (var interactionVolume in view3D.InteractionLayer.InteractionVolumes) foreach (var object3DControls in view3D.Object3DControlLayer.Object3DControls)
{ {
interactionVolume.CancelOperation(); object3DControls.CancelOperation();
} }
break; break;
@ -628,11 +628,11 @@ namespace MatterHackers.MatterControl
private static void NudgeItem(View3DWidget view3D, IObject3D item, ArrowDirection arrowDirection, KeyEventArgs keyEvent) private static void NudgeItem(View3DWidget view3D, IObject3D item, ArrowDirection arrowDirection, KeyEventArgs keyEvent)
{ {
var world = view3D.InteractionLayer.World; var world = view3D.Object3DControlLayer.World;
var vector3 = default(Vector3); var vector3 = default(Vector3);
var moveDistance = Math.Max(.1, view3D.InteractionLayer.SnapGridDistance); var moveDistance = Math.Max(.1, view3D.Object3DControlLayer.SnapGridDistance);
if (keyEvent.Shift) if (keyEvent.Shift)
{ {

View file

@ -43,7 +43,7 @@ namespace MatterHackers.MatterControl
{ {
public class ExtensionsConfig public class ExtensionsConfig
{ {
private List<IInteractionVolumeProvider> _iaVolumeProviders = new List<IInteractionVolumeProvider>(); private List<IObject3DControlProvider> _iaVolumeProviders = new List<IObject3DControlProvider>();
private LibraryConfig libraryConfig; private LibraryConfig libraryConfig;
@ -75,9 +75,9 @@ namespace MatterHackers.MatterControl
} }
} }
public IEnumerable<IInteractionVolumeProvider> IAVolumeProviders => _iaVolumeProviders; public IEnumerable<IObject3DControlProvider> IAVolumeProviders => _iaVolumeProviders;
public void Register(IInteractionVolumeProvider volumeProvider) public void Register(IObject3DControlProvider volumeProvider)
{ {
_iaVolumeProviders.Add(volumeProvider); _iaVolumeProviders.Add(volumeProvider);
} }

View file

@ -167,7 +167,7 @@ namespace MatterHackers.MatterControl
public Color InactiveTabColor { get; set; } public Color InactiveTabColor { get; set; }
public Color InteractionLayerOverlayColor { get; set; } public Color Object3DControlLayerOverlayColor { get; set; }
public TextWidget CreateHeading(string text) public TextWidget CreateHeading(string text)
{ {

View file

@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project. either expressed or implied, of the FreeBSD Project.
*/ */
using System;
using MatterHackers.Agg; using MatterHackers.Agg;
using MatterHackers.Agg.Transform; using MatterHackers.Agg.Transform;
using MatterHackers.Agg.UI; using MatterHackers.Agg.UI;
@ -34,20 +35,9 @@ using MatterHackers.Agg.VertexSource;
using MatterHackers.RenderOpenGl; using MatterHackers.RenderOpenGl;
using MatterHackers.RenderOpenGl.OpenGl; using MatterHackers.RenderOpenGl.OpenGl;
using MatterHackers.VectorMath; using MatterHackers.VectorMath;
using System;
namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
{ {
public static class Graphics2DOverrides
{
public static void Ring(this Graphics2D graphics2D, Vector2 center, double radius, double width, Color color)
{
var ring = new Ellipse(center, radius);
var ringStroke = new Stroke(ring, width);
graphics2D.Render(ringStroke, color);
}
}
public class RadialColorPicker : GuiWidget public class RadialColorPicker : GuiWidget
{ {
private double colorAngle = 0; private double colorAngle = 0;
@ -64,21 +54,24 @@ namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
if (!TriangleToWidgetTransform(0).Transform(new Vector2(1, .5)).Equals(new Vector2(88, 50), .01)) if (!TriangleToWidgetTransform(0).Transform(new Vector2(1, .5)).Equals(new Vector2(88, 50), .01))
{ {
//throw new Exception("Incorrect transform"); // throw new Exception("Incorrect transform");
} }
if (!TriangleToWidgetTransform(0).InverseTransform(new Vector2(88, 50)).Equals(new Vector2(1, .5), .01)) if (!TriangleToWidgetTransform(0).InverseTransform(new Vector2(88, 50)).Equals(new Vector2(1, .5), .01))
{ {
//throw new Exception("Incorrect transform"); // throw new Exception("Incorrect transform");
} }
if (!TriangleToWidgetTransform(0).Transform(new Vector2(0, .5)).Equals(new Vector2(23.13, 50), .01)) if (!TriangleToWidgetTransform(0).Transform(new Vector2(0, .5)).Equals(new Vector2(23.13, 50), .01))
{ {
//throw new Exception("Incorrect transform"); // throw new Exception("Incorrect transform");
} }
} }
public event EventHandler SelectedColorChanged; public event EventHandler SelectedColorChanged;
public bool mouseDownOnTriangle { get; private set; } public bool MouseDownOnTriangle { get; private set; }
public double RingWidth { get => Width / 10; } public double RingWidth { get => Width / 10; }
public Color SelectedColor public Color SelectedColor
@ -114,7 +107,7 @@ namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
set set
{ {
value.ToColorF().GetHSL(out double h, out double s, out double l); value.ToColorF().GetHSL(out double h, out _, out _);
colorAngle = h * MathHelper.Tau; colorAngle = h * MathHelper.Tau;
} }
} }
@ -138,7 +131,6 @@ namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
public override void OnDraw(Graphics2D graphics2D) public override void OnDraw(Graphics2D graphics2D)
{ {
var center = new Vector2(Width / 2, Height / 2); var center = new Vector2(Width / 2, Height / 2);
var radius = new Vector2(RingRadius, RingRadius);
// draw the big outside ring (color part) // draw the big outside ring (color part)
DrawColorRing(graphics2D, RingRadius, RingWidth); DrawColorRing(graphics2D, RingRadius, RingWidth);
@ -191,22 +183,24 @@ namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
{ {
colorAngle += MathHelper.Tau; colorAngle += MathHelper.Tau;
} }
Invalidate(); Invalidate();
} }
else else
{ {
var trianglePositon = WidgetToUnitTriangle(mouseEvent.Position); var (inside, position) = WidgetToUnitTriangle(mouseEvent.Position);
if (trianglePositon.inside) if (inside)
{ {
mouseDownOnTriangle = true; MouseDownOnTriangle = true;
unitTrianglePosition = trianglePositon.position; unitTrianglePosition = position;
} }
Invalidate(); Invalidate();
} }
} }
if(startColor != SelectedColor) if (startColor != SelectedColor)
{ {
SelectedColorChanged?.Invoke(this, null); SelectedColorChanged?.Invoke(this, null);
} }
@ -228,9 +222,10 @@ namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
{ {
colorAngle += MathHelper.Tau; colorAngle += MathHelper.Tau;
} }
Invalidate(); Invalidate();
} }
else if (mouseDownOnTriangle) else if (MouseDownOnTriangle)
{ {
unitTrianglePosition = WidgetToUnitTriangle(mouseEvent.Position).position; unitTrianglePosition = WidgetToUnitTriangle(mouseEvent.Position).position;
Invalidate(); Invalidate();
@ -247,7 +242,7 @@ namespace MatterHackers.MatterControl.CustomWidgets.ColorPicker
public override void OnMouseUp(MouseEventArgs mouseEvent) public override void OnMouseUp(MouseEventArgs mouseEvent)
{ {
mouseDownOnRing = false; mouseDownOnRing = false;
mouseDownOnTriangle = false; MouseDownOnTriangle = false;
base.OnMouseUp(mouseEvent); base.OnMouseUp(mouseEvent);
} }

View file

@ -44,25 +44,24 @@ using MatterHackers.VectorMath;
namespace MatterHackers.Plugins.EditorTools namespace MatterHackers.Plugins.EditorTools
{ {
public class PathControl : IGLInteractionElement public class PathControl : IObject3DControl
{ {
private IInteractionVolumeContext context; private readonly IObject3DControlContext context;
private ThemeConfig theme; private readonly ThemeConfig theme;
private WorldView world; private readonly WorldView world;
private IObject3D lastItem; private IObject3D lastItem;
private List<VertexPointWidget> targets = new List<VertexPointWidget>(); private readonly List<VertexPointWidget> targets = new List<VertexPointWidget>();
private bool controlsRegistered = false;
private IEnumerable<VertexData> activePoints; private IEnumerable<VertexData> activePoints;
private FlattenCurves flattened; private FlattenCurves flattened;
private bool m_visible; private bool visible;
private PointWidget _activeItem; private PointWidget _activeItem;
public PathControl(IInteractionVolumeContext context) public PathControl(IObject3DControlContext context)
{ {
this.context = context; this.context = context;
theme = MatterControl.AppContext.Theme; theme = MatterControl.AppContext.Theme;
@ -74,16 +73,16 @@ namespace MatterHackers.Plugins.EditorTools
public bool Visible public bool Visible
{ {
get => m_visible; get => visible;
set set
{ {
if (m_visible != value) if (visible != value)
{ {
m_visible = value; visible = value;
foreach (var widget in targets) foreach (var widget in targets)
{ {
widget.Visible = m_visible && !(widget is CurveControlPoint); widget.Visible = visible && !(widget is CurveControlPoint);
} }
} }
} }
@ -119,7 +118,7 @@ namespace MatterHackers.Plugins.EditorTools
{ {
} }
public void DrawGlContent(DrawGlContentEventArgs e) public void Draw(DrawGlContentEventArgs e)
{ {
if (flattened != null if (flattened != null
&& e.Graphics2D is Graphics2DOpenGL glGraphics) && e.Graphics2D is Graphics2DOpenGL glGraphics)
@ -156,6 +155,7 @@ namespace MatterHackers.Plugins.EditorTools
} }
} }
} }
GL.End(); GL.End();
} }
} }
@ -207,9 +207,9 @@ namespace MatterHackers.Plugins.EditorTools
{ {
if (command == ShapePath.FlagsAndCommand.Curve4) if (command == ShapePath.FlagsAndCommand.Curve4)
{ {
//vertexDataManager.AddVertex(x_ctrl1, y_ctrl1, ShapePath.FlagsAndCommand.Curve4); // vertexDataManager.AddVertex(x_ctrl1, y_ctrl1, ShapePath.FlagsAndCommand.Curve4);
//vertexDataManager.AddVertex(x_ctrl2, y_ctrl2, ShapePath.FlagsAndCommand.Curve4); // vertexDataManager.AddVertex(x_ctrl2, y_ctrl2, ShapePath.FlagsAndCommand.Curve4);
//vertexDataManager.AddVertex(x_to, y_to, ShapePath.FlagsAndCommand.Curve4); // vertexDataManager.AddVertex(x_to, y_to, ShapePath.FlagsAndCommand.Curve4);
var lastItem = targets.LastOrDefault(); var lastItem = targets.LastOrDefault();
@ -222,7 +222,6 @@ namespace MatterHackers.Plugins.EditorTools
context.GuiSurface.AddChild(controlPoint2); context.GuiSurface.AddChild(controlPoint2);
targets.Add(controlPoint2); targets.Add(controlPoint2);
command = vertexStorage.vertex(i + 2, out x, out y); command = vertexStorage.vertex(i + 2, out x, out y);
var curveWidget = new Curve4AnchorWidget(context, this, vertexStorage, new Vector3(x, y, 0), command, i + 2) var curveWidget = new Curve4AnchorWidget(context, this, vertexStorage, new Vector3(x, y, 0), command, i + 2)
{ {
@ -236,8 +235,8 @@ namespace MatterHackers.Plugins.EditorTools
curveWidget.LinkedPoint = vertexPointWidget; curveWidget.LinkedPoint = vertexPointWidget;
} }
//controlPoint1.ParentPoint = curveWidget; // controlPoint1.ParentPoint = curveWidget;
//controlPoint2.ParentPoint = curveWidget; // controlPoint2.ParentPoint = curveWidget;
widget = curveWidget; widget = curveWidget;
@ -248,6 +247,7 @@ namespace MatterHackers.Plugins.EditorTools
{ {
widget = new VertexPointWidget(context, this, vertexStorage, new Vector3(x, y, 0), command, i); widget = new VertexPointWidget(context, this, vertexStorage, new Vector3(x, y, 0), command, i);
} }
// widget.Click += (s, e) => // widget.Click += (s, e) =>
targets.Add(widget); targets.Add(widget);
@ -272,23 +272,23 @@ namespace MatterHackers.Plugins.EditorTools
private class CurveControlPoint : VertexPointWidget private class CurveControlPoint : VertexPointWidget
{ {
public CurveControlPoint(IInteractionVolumeContext context, PathControl interactionControl, VertexStorage vertexStorage, Vector3 point, ShapePath.FlagsAndCommand flagsandCommand, int index) public CurveControlPoint(IObject3DControlContext context, PathControl pathControl, VertexStorage vertexStorage, Vector3 point, ShapePath.FlagsAndCommand flagsandCommand, int index)
: base(context, interactionControl, vertexStorage, point, flagsandCommand, index) : base(context, pathControl, vertexStorage, point, flagsandCommand, index)
{ {
this.ClaimSelection = false; this.ClaimSelection = false;
this.Visible = false; this.Visible = false;
this.HandleStyle = HandleStyle.Circle; this.HandleStyle = HandleStyle.Circle;
} }
//public Curve4PointWidget ParentPoint { get; internal set; } // public Curve4PointWidget ParentPoint { get; internal set; }
} }
private class Curve4AnchorWidget : VertexPointWidget private class Curve4AnchorWidget : VertexPointWidget
{ {
private bool _focused; private readonly bool _focused;
public Curve4AnchorWidget(IInteractionVolumeContext context, PathControl interactionControl, VertexStorage vertexStorage, Vector3 point, ShapePath.FlagsAndCommand flagsandCommand, int index) public Curve4AnchorWidget(IObject3DControlContext context, PathControl pathControl, VertexStorage vertexStorage, Vector3 point, ShapePath.FlagsAndCommand flagsandCommand, int index)
: base(context, interactionControl, vertexStorage, point, flagsandCommand, index) : base(context, pathControl, vertexStorage, point, flagsandCommand, index)
{ {
} }
@ -309,14 +309,14 @@ namespace MatterHackers.Plugins.EditorTools
base.OnFocusChanged(e); base.OnFocusChanged(e);
} }
//public VertexPointWidget ControlPoint1 { get; set; } // public VertexPointWidget ControlPoint1 { get; set; }
//public VertexPointWidget ControlPoint2 { get; set; } // public VertexPointWidget ControlPoint2 { get; set; }
} }
private class VertexPointWidget : PointWidget private class VertexPointWidget : PointWidget
{ {
public PathControl PathInteractionControl { get; } public PathControl PathControl { get; }
private readonly ShapePath.FlagsAndCommand command; private readonly ShapePath.FlagsAndCommand command;
@ -325,10 +325,10 @@ namespace MatterHackers.Plugins.EditorTools
private Vector3 controlPointDelta; private Vector3 controlPointDelta;
private readonly int index; private readonly int index;
public VertexPointWidget(IInteractionVolumeContext context, PathControl interactionControl, VertexStorage vertexStorage, Vector3 point, ShapePath.FlagsAndCommand flagsandCommand, int index) public VertexPointWidget(IObject3DControlContext context, PathControl pathControl, VertexStorage vertexStorage, Vector3 point, ShapePath.FlagsAndCommand flagsandCommand, int index)
: base(context, point) : base(context, point)
{ {
this.PathInteractionControl = interactionControl; this.PathControl = pathControl;
this.command = flagsandCommand; this.command = flagsandCommand;
this.index = index; this.index = index;
this.vertexStorage = vertexStorage; this.vertexStorage = vertexStorage;
@ -373,7 +373,7 @@ namespace MatterHackers.Plugins.EditorTools
&& this.PositionWithinLocalBounds(mouseEvent.Position)) && this.PositionWithinLocalBounds(mouseEvent.Position))
{ {
this.Selected = true; this.Selected = true;
this.PathInteractionControl.ActiveItem = this; this.PathControl.ActiveItem = this;
} }
base.OnMouseDown(mouseEvent); base.OnMouseDown(mouseEvent);
@ -394,19 +394,19 @@ namespace MatterHackers.Plugins.EditorTools
public class PointWidget : GuiWidget public class PointWidget : GuiWidget
{ {
private WorldView world; private readonly WorldView world;
private GuiWidget guiSurface; private readonly GuiWidget guiSurface;
private bool mouseInBounds; private bool mouseInBounds;
private GuiWidget systemWindow; private GuiWidget systemWindow;
private bool mouseDownOnWidget; private bool mouseDownOnWidget;
private IInteractionVolumeContext interactionContext; private readonly IObject3DControlContext object3DControlContext;
private static PlaneShape bedPlane = new PlaneShape(Vector3.UnitZ, 0, null); private static readonly PlaneShape BedPlane = new PlaneShape(Vector3.UnitZ, 0, null);
private ThemeConfig theme; private readonly ThemeConfig theme;
public PointWidget(IInteractionVolumeContext interactionContext, Vector3 point) public PointWidget(IObject3DControlContext object3DControlContext, Vector3 point)
{ {
this.theme = MatterControl.AppContext.Theme; this.theme = MatterControl.AppContext.Theme;
this.interactionContext = interactionContext; this.object3DControlContext = object3DControlContext;
this.HAnchor = HAnchor.Absolute; this.HAnchor = HAnchor.Absolute;
this.VAnchor = VAnchor.Absolute; this.VAnchor = VAnchor.Absolute;
this.Width = 8; this.Width = 8;
@ -414,8 +414,8 @@ namespace MatterHackers.Plugins.EditorTools
this.Point = point; this.Point = point;
this.PointColor = theme.PrimaryAccentColor; this.PointColor = theme.PrimaryAccentColor;
world = interactionContext.World; world = object3DControlContext.World;
guiSurface = interactionContext.GuiSurface; guiSurface = object3DControlContext.GuiSurface;
} }
public virtual Vector3 Point { get; set; } public virtual Vector3 Point { get; set; }
@ -462,7 +462,7 @@ namespace MatterHackers.Plugins.EditorTools
Vector2 meshViewerWidgetScreenPosition = this.TransformToParentSpace(guiSurface, localMousePosition); Vector2 meshViewerWidgetScreenPosition = this.TransformToParentSpace(guiSurface, localMousePosition);
Ray ray = world.GetRayForLocalBounds(meshViewerWidgetScreenPosition); Ray ray = world.GetRayForLocalBounds(meshViewerWidgetScreenPosition);
if (bedPlane.GetClosestIntersection(ray) is IntersectInfo info) if (BedPlane.GetClosestIntersection(ray) is IntersectInfo info)
{ {
this.OnDragTo(info); this.OnDragTo(info);
} }

View file

@ -46,7 +46,7 @@ using MatterHackers.VectorMath;
namespace MatterHackers.Plugins.EditorTools namespace MatterHackers.Plugins.EditorTools
{ {
public class RotateCornerControl : InteractionVolume public class RotateCornerControl : Object3DControlBase
{ {
private IObject3D selectedItemOnMouseDown; private IObject3D selectedItemOnMouseDown;
private static readonly VertexStorage Arrows = new VertexStorage("M267.96599,177.26875L276.43374,168.80101C276.43374,170.2123 276.43374,171.62359 276.43374,173.03488C280.02731,173.01874 282.82991,174.13254 286.53647,171.29154C290.08503,168.16609 288.97661,164.24968 289.13534,160.33327L284.90147,160.33327L293.36921,151.86553L301.83695,160.33327L297.60308,160.33327C297.60308,167.38972 298.67653,171.4841 293.23666,177.24919C286.80975,182.82626 283.014,181.02643 276.43374,181.50262L276.43374,185.73649L267.96599,177.26875L267.96599,177.26875z"); private static readonly VertexStorage Arrows = new VertexStorage("M267.96599,177.26875L276.43374,168.80101C276.43374,170.2123 276.43374,171.62359 276.43374,173.03488C280.02731,173.01874 282.82991,174.13254 286.53647,171.29154C290.08503,168.16609 288.97661,164.24968 289.13534,160.33327L284.90147,160.33327L293.36921,151.86553L301.83695,160.33327L297.60308,160.33327C297.60308,167.38972 298.67653,171.4841 293.23666,177.24919C286.80975,182.82626 283.014,181.02643 276.43374,181.50262L276.43374,185.73649L267.96599,177.26875L267.96599,177.26875z");
@ -67,7 +67,7 @@ namespace MatterHackers.Plugins.EditorTools
private double rotationTransformScale = 1; private double rotationTransformScale = 1;
private Vector3 selectCubeSize = new Vector3(30, 30, .1) * GuiWidget.DeviceScale; private Vector3 selectCubeSize = new Vector3(30, 30, .1) * GuiWidget.DeviceScale;
public RotateCornerControl(IInteractionVolumeContext context, int axisIndex) public RotateCornerControl(IObject3DControlContext context, int axisIndex)
: base(context) : base(context)
{ {
theme = MatterControl.AppContext.Theme; theme = MatterControl.AppContext.Theme;
@ -85,7 +85,7 @@ namespace MatterHackers.Plugins.EditorTools
Invalidate(); Invalidate();
}; };
InteractionContext.GuiSurface.AddChild(angleTextControl); object3DControlContext.GuiSurface.AddChild(angleTextControl);
angleTextControl.EditComplete += (s, e) => angleTextControl.EditComplete += (s, e) =>
{ {
@ -113,7 +113,7 @@ namespace MatterHackers.Plugins.EditorTools
lastSnappedRotation = SnappedRotationAngle; lastSnappedRotation = SnappedRotationAngle;
} }
InteractionContext.Scene.AddTransformSnapshot(mouseDownInfo.SelectedObjectTransform); object3DControlContext.Scene.AddTransformSnapshot(mouseDownInfo.SelectedObjectTransform);
} }
}; };
@ -153,7 +153,7 @@ namespace MatterHackers.Plugins.EditorTools
CollisionVolume = rotationHandle.CreateBVHData(); CollisionVolume = rotationHandle.CreateBVHData();
InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw; object3DControlContext.GuiSurface.AfterDraw += Object3DControl_AfterDraw;
} }
public int RotationAxis { get; private set; } public int RotationAxis { get; private set; }
@ -172,7 +172,7 @@ namespace MatterHackers.Plugins.EditorTools
private double SnappedRotationAngle { get; set; } private double SnappedRotationAngle { get; set; }
public override void DrawGlContent(DrawGlContentEventArgs e) public override void Draw(DrawGlContentEventArgs e)
{ {
IObject3D selectedItem = RootSelection; IObject3D selectedItem = RootSelection;
// We only draw rotation controls if something is selected // We only draw rotation controls if something is selected
@ -181,22 +181,22 @@ namespace MatterHackers.Plugins.EditorTools
// make sure the image is initialized // make sure the image is initialized
RenderOpenGl.ImageGlPlugin.GetImageGlPlugin(rotationImageWhite, true); RenderOpenGl.ImageGlPlugin.GetImageGlPlugin(rotationImageWhite, true);
// We only draw the rotation arrows when the user has not selected any interaction volumes (they are not actively scaling or rotating anything). // We only draw the rotation arrows when the user has not selected any Object3DControl volumes (they are not actively scaling or rotating anything).
if (InteractionContext.SelectedInteractionVolume == null) if (object3DControlContext.SelectedObject3DControl == null)
{ {
var color = MouseOver ? theme.PrimaryAccentColor : theme.TextColor; var color = MouseIsOver ? theme.PrimaryAccentColor : theme.TextColor;
GLHelper.Render(rotationHandle, new Color(color, 254), TotalTransform, RenderTypes.Shaded); GLHelper.Render(rotationHandle, new Color(color, 254), TotalTransform, RenderTypes.Shaded);
} }
// If the user is over the control or has clicked on it // If the user is over the control or has clicked on it
if (mouseMoveInfo != null || mouseDownInfo != null if (mouseMoveInfo != null || mouseDownInfo != null
|| MouseOver) || MouseIsOver)
{ {
DrawRotationCompass(selectedItem, e); DrawRotationCompass(selectedItem, e);
} }
} }
base.DrawGlContent(e); base.Draw(e);
} }
public Vector3 GetCornerPosition(IObject3D objectBeingRotated) public Vector3 GetCornerPosition(IObject3D objectBeingRotated)
@ -221,7 +221,7 @@ namespace MatterHackers.Plugins.EditorTools
for (int cornerIndex = 0; cornerIndex < 4; cornerIndex++) for (int cornerIndex = 0; cornerIndex < 4; cornerIndex++)
{ {
Vector3 cornerPosition = currentSelectedBounds.GetBottomCorner(cornerIndex); Vector3 cornerPosition = currentSelectedBounds.GetBottomCorner(cornerIndex);
Vector3 cornerScreenSpace = InteractionContext.World.GetScreenSpace(cornerPosition); Vector3 cornerScreenSpace = object3DControlContext.World.GetScreenSpace(cornerPosition);
if (cornerScreenSpace.Z < bestCornerZ) if (cornerScreenSpace.Z < bestCornerZ)
{ {
zCornerIndex = cornerIndex; zCornerIndex = cornerIndex;
@ -269,7 +269,7 @@ namespace MatterHackers.Plugins.EditorTools
public override void OnMouseDown(Mouse3DEventArgs mouseEvent3D) public override void OnMouseDown(Mouse3DEventArgs mouseEvent3D)
{ {
InteractionContext.Scene.DrawSelection = false; object3DControlContext.Scene.DrawSelection = false;
IObject3D selectedItem = RootSelection; IObject3D selectedItem = RootSelection;
@ -299,7 +299,7 @@ namespace MatterHackers.Plugins.EditorTools
SnappedRotationAngle = 0; SnappedRotationAngle = 0;
RotatingCW = true; RotatingCW = true;
mouseMoveInfo = mouseDownInfo; mouseMoveInfo = mouseDownInfo;
InteractionContext.Scene.ShowSelectionShadow = false; object3DControlContext.Scene.ShowSelectionShadow = false;
mouseMoveInfo = new Mouse3DInfo( mouseMoveInfo = new Mouse3DInfo(
mouseEvent3D.info.HitPosition, mouseEvent3D.info.HitPosition,
@ -366,7 +366,7 @@ namespace MatterHackers.Plugins.EditorTools
{ {
SnappedRotationAngle = snappingIndex * MathHelper.Tau / numSnapPoints; SnappedRotationAngle = snappingIndex * MathHelper.Tau / numSnapPoints;
} }
else if (InteractionContext.GuiSurface.ModifierKeys == Keys.Shift) else if (object3DControlContext.GuiSurface.ModifierKeys == Keys.Shift)
{ {
snapRadians = MathHelper.DegreesToRadians(45); snapRadians = MathHelper.DegreesToRadians(45);
@ -419,17 +419,17 @@ namespace MatterHackers.Plugins.EditorTools
public override void OnMouseUp(Mouse3DEventArgs mouseEvent3D) public override void OnMouseUp(Mouse3DEventArgs mouseEvent3D)
{ {
InteractionContext.Scene.DrawSelection = true; object3DControlContext.Scene.DrawSelection = true;
// if we rotated it // if we rotated it
if (mouseDownInfo != null) if (mouseDownInfo != null)
{ {
// put in the start transform so we can go back to it if we have to // put in the start transform so we can go back to it if we have to
InteractionContext.Scene.AddTransformSnapshot(mouseDownInfo.SelectedObjectTransform); object3DControlContext.Scene.AddTransformSnapshot(mouseDownInfo.SelectedObjectTransform);
} }
if (mouseDownInfo != null) if (mouseDownInfo != null)
{ {
InteractionContext.Scene.ShowSelectionShadow = true; object3DControlContext.Scene.ShowSelectionShadow = true;
} }
base.OnMouseUp(mouseEvent3D); base.OnMouseUp(mouseEvent3D);
@ -444,12 +444,12 @@ namespace MatterHackers.Plugins.EditorTools
{ {
selectedItem.Matrix = mouseDownInfo.SelectedObjectTransform; selectedItem.Matrix = mouseDownInfo.SelectedObjectTransform;
MouseDownOnControl = false; MouseDownOnControl = false;
MouseOver = false; MouseIsOver = false;
mouseDownInfo = null; mouseDownInfo = null;
mouseMoveInfo = null; mouseMoveInfo = null;
InteractionContext.Scene.DrawSelection = true; object3DControlContext.Scene.DrawSelection = true;
InteractionContext.Scene.ShowSelectionShadow = true; object3DControlContext.Scene.ShowSelectionShadow = true;
} }
base.CancelOperation(); base.CancelOperation();
@ -458,7 +458,7 @@ namespace MatterHackers.Plugins.EditorTools
public override void SetPosition(IObject3D selectedItem) public override void SetPosition(IObject3D selectedItem)
{ {
Vector3 boxCenter = GetControlCenter(selectedItem); Vector3 boxCenter = GetControlCenter(selectedItem);
double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(boxCenter); double distBetweenPixelsWorldSpace = object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(boxCenter);
GetCornerPosition(selectedItem, out int cornerIndexOut); GetCornerPosition(selectedItem, out int cornerIndexOut);
@ -514,7 +514,7 @@ namespace MatterHackers.Plugins.EditorTools
private void DrawRotationCompass(IObject3D selectedItem, DrawGlContentEventArgs drawEventArgs) private void DrawRotationCompass(IObject3D selectedItem, DrawGlContentEventArgs drawEventArgs)
{ {
if (InteractionContext.Scene.SelectedItem == null) if (object3DControlContext.Scene.SelectedItem == null)
{ {
return; return;
} }
@ -556,7 +556,7 @@ namespace MatterHackers.Plugins.EditorTools
var graphics2DOpenGL = new Graphics2DOpenGL(); var graphics2DOpenGL = new Graphics2DOpenGL();
if (mouseDownInfo != null || MouseOver) if (mouseDownInfo != null || MouseIsOver)
{ {
IVertexSource blueRing = new JoinPaths(new Arc(0, 0, outerRadius, outerRadius, startBlue, endBlue, Arc.Direction.CounterClockWise), IVertexSource blueRing = new JoinPaths(new Arc(0, 0, outerRadius, outerRadius, startBlue, endBlue, Arc.Direction.CounterClockWise),
new Arc(0, 0, innerRadius, innerRadius, startBlue, endBlue, Arc.Direction.ClockWise)); new Arc(0, 0, innerRadius, innerRadius, startBlue, endBlue, Arc.Direction.ClockWise));
@ -589,7 +589,7 @@ namespace MatterHackers.Plugins.EditorTools
var center = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); var center = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform);
if ((mouseMoveInfo.HitPosition - center).Length > rotationTransformScale * innerRadius) if ((mouseMoveInfo.HitPosition - center).Length > rotationTransformScale * innerRadius)
{ {
InteractionContext.World.Render3DLine(startPosition, mouseMoveInfo.HitPosition, theme.PrimaryAccentColor, drawEventArgs.ZBuffered); object3DControlContext.World.Render3DLine(startPosition, mouseMoveInfo.HitPosition, theme.PrimaryAccentColor, drawEventArgs.ZBuffered);
} }
DrawSnappingMarks(drawEventArgs, mouseAngle, alphaValue, rotationCenterTransform, snappingMarkRadius, numSnapPoints, GetSnapIndex(selectedItem, numSnapPoints)); DrawSnappingMarks(drawEventArgs, mouseAngle, alphaValue, rotationCenterTransform, snappingMarkRadius, numSnapPoints, GetSnapIndex(selectedItem, numSnapPoints));
@ -639,14 +639,14 @@ namespace MatterHackers.Plugins.EditorTools
Vector3 startPosition = Vector3Ex.Transform(unitPosition * innerRadius, rotationCenterTransform); Vector3 startPosition = Vector3Ex.Transform(unitPosition * innerRadius, rotationCenterTransform);
Vector3 endPosition = Vector3Ex.Transform(unitPosition * outerRadius, rotationCenterTransform); Vector3 endPosition = Vector3Ex.Transform(unitPosition * outerRadius, rotationCenterTransform);
InteractionContext.World.Render3DLine(startPosition, endPosition, new Color(theme.TextColor, (int)(254 * alphaValue)), drawEventArgs.ZBuffered); object3DControlContext.World.Render3DLine(startPosition, endPosition, new Color(theme.TextColor, (int)(254 * alphaValue)), drawEventArgs.ZBuffered);
} }
} }
private bool ForceHideAngle() private bool ForceHideAngle()
{ {
return (InteractionContext.HoveredInteractionVolume != this return (object3DControlContext.HoveredObject3DControl != this
&& InteractionContext.HoveredInteractionVolume != null) && object3DControlContext.HoveredObject3DControl != null)
|| RootSelection != selectedItemOnMouseDown; || RootSelection != selectedItemOnMouseDown;
} }
@ -660,7 +660,7 @@ namespace MatterHackers.Plugins.EditorTools
private Vector3 GetControlCenter(IObject3D selectedItem) private Vector3 GetControlCenter(IObject3D selectedItem)
{ {
Vector3 boxCenter = GetCornerPosition(selectedItem); Vector3 boxCenter = GetCornerPosition(selectedItem);
double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(boxCenter); double distBetweenPixelsWorldSpace = object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(boxCenter);
// figure out which way the corner is relative to the bounds // figure out which way the corner is relative to the bounds
Vector3 otherSideDelta = GetDeltaToOtherSideXy(selectedItem); Vector3 otherSideDelta = GetDeltaToOtherSideXy(selectedItem);
@ -728,7 +728,7 @@ namespace MatterHackers.Plugins.EditorTools
controlCenter = mouseDownInfo.ControlCenter; controlCenter = mouseDownInfo.ControlCenter;
} }
double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(rotationCenter); double distBetweenPixelsWorldSpace = object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(rotationCenter);
double lengthFromCenterToControl = (rotationCenter - controlCenter).Length; double lengthFromCenterToControl = (rotationCenter - controlCenter).Length;
radius = lengthFromCenterToControl * (1 / distBetweenPixelsWorldSpace); radius = lengthFromCenterToControl * (1 / distBetweenPixelsWorldSpace);
@ -814,7 +814,7 @@ namespace MatterHackers.Plugins.EditorTools
return -1; return -1;
} }
private void InteractionLayer_AfterDraw(object sender, DrawEventArgs drawEvent) private void Object3DControl_AfterDraw(object sender, DrawEventArgs drawEvent)
{ {
IObject3D selectedItem = RootSelection; IObject3D selectedItem = RootSelection;
if (selectedItem != null if (selectedItem != null
@ -825,7 +825,7 @@ namespace MatterHackers.Plugins.EditorTools
var unitPosition = new Vector3(Math.Cos(mouseDownInfo.AngleOfHit), Math.Sin(mouseDownInfo.AngleOfHit), 0); var unitPosition = new Vector3(Math.Cos(mouseDownInfo.AngleOfHit), Math.Sin(mouseDownInfo.AngleOfHit), 0);
Vector3 anglePosition = Vector3Ex.Transform(unitPosition * (radius + 100 * GuiWidget.DeviceScale), rotationCenterTransform); Vector3 anglePosition = Vector3Ex.Transform(unitPosition * (radius + 100 * GuiWidget.DeviceScale), rotationCenterTransform);
Vector2 angleDisplayPosition = InteractionContext.World.GetScreenPosition(anglePosition); Vector2 angleDisplayPosition = object3DControlContext.World.GetScreenPosition(anglePosition);
var displayAngle = MathHelper.RadiansToDegrees(SnappedRotationAngle); var displayAngle = MathHelper.RadiansToDegrees(SnappedRotationAngle);
if (!RotatingCW && SnappedRotationAngle > 0) if (!RotatingCW && SnappedRotationAngle > 0)

View file

@ -32,9 +32,9 @@ using MatterHackers.MeshVisualizer;
namespace MatterHackers.Plugins.EditorTools namespace MatterHackers.Plugins.EditorTools
{ {
public class RotateCornerPlugins : IInteractionVolumeProvider public class RotateCornerPlugins : IObject3DControlProvider
{ {
public IEnumerable<InteractionVolume> Create(IInteractionVolumeContext context) public IEnumerable<Object3DControlBase> Create(IObject3DControlContext context)
{ {
// X, Y, Z RotateCornerControls // X, Y, Z RotateCornerControls
return new[] return new[]

View file

@ -44,7 +44,7 @@ using MatterHackers.VectorMath;
namespace MatterHackers.Plugins.EditorTools namespace MatterHackers.Plugins.EditorTools
{ {
public class ScaleCornerControl : InteractionVolume public class ScaleCornerControl : Object3DControlBase
{ {
public IObject3D ActiveSelectedItem { get; set; } public IObject3D ActiveSelectedItem { get; set; }
@ -68,7 +68,7 @@ namespace MatterHackers.Plugins.EditorTools
private InlineEditControl yValueDisplayInfo; private InlineEditControl yValueDisplayInfo;
private bool HadClickOnControl; private bool HadClickOnControl;
public ScaleCornerControl(IInteractionVolumeContext context, int cornerIndex) public ScaleCornerControl(IObject3DControlContext context, int cornerIndex)
: base(context) : base(context)
{ {
theme = MatterControl.AppContext.Theme; theme = MatterControl.AppContext.Theme;
@ -105,8 +105,8 @@ namespace MatterHackers.Plugins.EditorTools
} }
}; };
InteractionContext.GuiSurface.AddChild(xValueDisplayInfo); object3DControlContext.GuiSurface.AddChild(xValueDisplayInfo);
InteractionContext.GuiSurface.AddChild(yValueDisplayInfo); object3DControlContext.GuiSurface.AddChild(yValueDisplayInfo);
this.quadrantIndex = cornerIndex; this.quadrantIndex = cornerIndex;
@ -116,7 +116,7 @@ namespace MatterHackers.Plugins.EditorTools
CollisionVolume = minXminYMesh.CreateBVHData(); CollisionVolume = minXminYMesh.CreateBVHData();
InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw; object3DControlContext.GuiSurface.AfterDraw += Object3DControl_AfterDraw;
} }
private void EditComplete(object s, EventArgs e) private void EditComplete(object s, EventArgs e)
@ -132,7 +132,7 @@ namespace MatterHackers.Plugins.EditorTools
newSize.X = xValueDisplayInfo.Value; newSize.X = xValueDisplayInfo.Value;
newSize.Y = yValueDisplayInfo.Value; newSize.Y = yValueDisplayInfo.Value;
Vector3 scaleAmount = GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, InteractionContext.GuiSurface.ModifierKeys); Vector3 scaleAmount = GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, object3DControlContext.GuiSurface.ModifierKeys);
// scale it // scale it
var scale = Matrix4X4.CreateScale(scaleAmount); var scale = Matrix4X4.CreateScale(scaleAmount);
@ -150,16 +150,16 @@ namespace MatterHackers.Plugins.EditorTools
Invalidate(); Invalidate();
InteractionContext.Scene.AddTransformSnapshot(startingTransform); object3DControlContext.Scene.AddTransformSnapshot(startingTransform);
transformAppliedByThis = selectedItem.Matrix; transformAppliedByThis = selectedItem.Matrix;
} }
public override void DrawGlContent(DrawGlContentEventArgs e) public override void Draw(DrawGlContentEventArgs e)
{ {
bool shouldDrawScaleControls = true; bool shouldDrawScaleControls = true;
if (InteractionContext.SelectedInteractionVolume != null if (object3DControlContext.SelectedObject3DControl != null
&& InteractionContext.SelectedInteractionVolume as ScaleCornerControl == null) && object3DControlContext.SelectedObject3DControl as ScaleCornerControl == null)
{ {
shouldDrawScaleControls = false; shouldDrawScaleControls = false;
} }
@ -167,7 +167,7 @@ namespace MatterHackers.Plugins.EditorTools
var selectedItem = RootSelection; var selectedItem = RootSelection;
if (selectedItem != null if (selectedItem != null
&& InteractionContext.Scene.ShowSelectionShadow) && object3DControlContext.Scene.ShowSelectionShadow)
{ {
// Ensures that functions in this scope run against the original instance reference rather than the // Ensures that functions in this scope run against the original instance reference rather than the
// current value, thus avoiding null reference errors that would occur otherwise // current value, thus avoiding null reference errors that would occur otherwise
@ -175,7 +175,7 @@ namespace MatterHackers.Plugins.EditorTools
if (shouldDrawScaleControls) if (shouldDrawScaleControls)
{ {
// don't draw if any other control is dragging // don't draw if any other control is dragging
if (MouseOver) if (MouseIsOver)
{ {
GLHelper.Render(minXminYMesh, theme.PrimaryAccentColor, TotalTransform, RenderTypes.Shaded); GLHelper.Render(minXminYMesh, theme.PrimaryAccentColor, TotalTransform, RenderTypes.Shaded);
} }
@ -191,30 +191,30 @@ namespace MatterHackers.Plugins.EditorTools
Vector3 endPosition = GetCornerPosition(selectedItem, (quadrantIndex + 1) % 4); Vector3 endPosition = GetCornerPosition(selectedItem, (quadrantIndex + 1) % 4);
Frustum clippingFrustum = InteractionContext.World.GetClippingFrustum(); Frustum clippingFrustum = object3DControlContext.World.GetClippingFrustum();
if (clippingFrustum.ClipLine(ref startPosition, ref endPosition)) if (clippingFrustum.ClipLine(ref startPosition, ref endPosition))
{ {
if (e.ZBuffered) if (e.ZBuffered)
{ {
InteractionContext.World.Render3DLine(clippingFrustum, startPosition, endPosition, theme.TextColor); object3DControlContext.World.Render3DLine(clippingFrustum, startPosition, endPosition, theme.TextColor);
} }
else else
{ {
// render on top of everything very lightly // render on top of everything very lightly
InteractionContext.World.Render3DLine(clippingFrustum, startPosition, endPosition, new Color(theme.TextColor, 20), false); object3DControlContext.World.Render3DLine(clippingFrustum, startPosition, endPosition, new Color(theme.TextColor, 20), false);
} }
} }
// Vector3 startScreenSpace = InteractionContext.World.GetScreenSpace(startPosition); // Vector3 startScreenSpace = Object3DControlContext.World.GetScreenSpace(startPosition);
// e.graphics2D.Circle(startScreenSpace.x, startScreenSpace.y, 5, theme.PrimaryAccentColor); // e.graphics2D.Circle(startScreenSpace.x, startScreenSpace.y, 5, theme.PrimaryAccentColor);
// Vector2 startScreenPosition = InteractionContext.World.GetScreenPosition(startPosition); // Vector2 startScreenPosition = Object3DControlContext.World.GetScreenPosition(startPosition);
// e.graphics2D.Circle(startScreenPosition.x, startScreenPosition.y, 5, theme.PrimaryAccentColor); // e.graphics2D.Circle(startScreenPosition.x, startScreenPosition.y, 5, theme.PrimaryAccentColor);
} }
} }
base.DrawGlContent(e); base.Draw(e);
} }
public Vector3 GetCornerPosition(IObject3D item, int quadrantIndex) public Vector3 GetCornerPosition(IObject3D item, int quadrantIndex)
@ -255,7 +255,7 @@ namespace MatterHackers.Plugins.EditorTools
var selectedItem = RootSelection; var selectedItem = RootSelection;
ActiveSelectedItem = selectedItem; ActiveSelectedItem = selectedItem;
if (MouseOver) if (MouseIsOver)
{ {
xValueDisplayInfo.Visible = true; xValueDisplayInfo.Visible = true;
yValueDisplayInfo.Visible = true; yValueDisplayInfo.Visible = true;
@ -280,10 +280,10 @@ namespace MatterHackers.Plugins.EditorTools
Vector3 newPosition = originalPointToMove + delta; Vector3 newPosition = originalPointToMove + delta;
if (InteractionContext.SnapGridDistance > 0) if (object3DControlContext.SnapGridDistance > 0)
{ {
// snap this position to the grid // snap this position to the grid
double snapGridDistance = InteractionContext.SnapGridDistance; double snapGridDistance = object3DControlContext.SnapGridDistance;
// snap this position to the grid // snap this position to the grid
newPosition.X = ((int)((newPosition.X / snapGridDistance) + .5)) * snapGridDistance; newPosition.X = ((int)((newPosition.X / snapGridDistance) + .5)) * snapGridDistance;
@ -305,7 +305,7 @@ namespace MatterHackers.Plugins.EditorTools
newSize.Y *= -1; newSize.Y *= -1;
} }
Vector3 scaleAmount = GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, InteractionContext.GuiSurface.ModifierKeys); Vector3 scaleAmount = GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, object3DControlContext.GuiSurface.ModifierKeys);
// scale it // scale it
var scale = Matrix4X4.CreateScale(scaleAmount); var scale = Matrix4X4.CreateScale(scaleAmount);
@ -337,7 +337,7 @@ namespace MatterHackers.Plugins.EditorTools
{ {
if (HadClickOnControl) if (HadClickOnControl)
{ {
InteractionContext.Scene.AddTransformSnapshot(transformOnMouseDown); object3DControlContext.Scene.AddTransformSnapshot(transformOnMouseDown);
} }
base.OnMouseUp(mouseEvent3D); base.OnMouseUp(mouseEvent3D);
@ -351,10 +351,10 @@ namespace MatterHackers.Plugins.EditorTools
{ {
selectedItem.Matrix = transformOnMouseDown; selectedItem.Matrix = transformOnMouseDown;
MouseDownOnControl = false; MouseDownOnControl = false;
MouseOver = false; MouseIsOver = false;
InteractionContext.Scene.DrawSelection = true; object3DControlContext.Scene.DrawSelection = true;
InteractionContext.Scene.ShowSelectionShadow = true; object3DControlContext.Scene.ShowSelectionShadow = true;
} }
base.CancelOperation(); base.CancelOperation();
@ -363,7 +363,7 @@ namespace MatterHackers.Plugins.EditorTools
public override void SetPosition(IObject3D selectedItem) public override void SetPosition(IObject3D selectedItem)
{ {
Vector3 cornerPosition = GetCornerPosition(selectedItem, quadrantIndex); Vector3 cornerPosition = GetCornerPosition(selectedItem, quadrantIndex);
double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(cornerPosition); double distBetweenPixelsWorldSpace = object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(cornerPosition);
// figure out which way the corner is relative to the bounds // figure out which way the corner is relative to the bounds
Vector3 otherSideDelta = GetDeltaToOtherSideXy(selectedItem, quadrantIndex); Vector3 otherSideDelta = GetDeltaToOtherSideXy(selectedItem, quadrantIndex);
@ -385,18 +385,18 @@ namespace MatterHackers.Plugins.EditorTools
lines.Clear(); lines.Clear();
// left lines // left lines
lines.Add(InteractionContext.World.GetScreenPosition(cornerPosition - new Vector3(xSign * DistToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(xSign * DistToStart * distBetweenPixelsWorldSpace, 0, 0)));
lines.Add(InteractionContext.World.GetScreenPosition(cornerPosition - new Vector3(xSign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(xSign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0, 0)));
lines.Add(InteractionContext.World.GetScreenPosition(yOtherSide - new Vector3(xSign * DistToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(yOtherSide - new Vector3(xSign * DistToStart * distBetweenPixelsWorldSpace, 0, 0)));
lines.Add(InteractionContext.World.GetScreenPosition(yOtherSide - new Vector3(xSign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(yOtherSide - new Vector3(xSign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0, 0)));
// bottom lines // bottom lines
lines.Add(InteractionContext.World.GetScreenPosition(cornerPosition - new Vector3(0, ySign * DistToStart * distBetweenPixelsWorldSpace, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(0, ySign * DistToStart * distBetweenPixelsWorldSpace, 0)));
lines.Add(InteractionContext.World.GetScreenPosition(cornerPosition - new Vector3(0, ySign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(cornerPosition - new Vector3(0, ySign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0)));
lines.Add(InteractionContext.World.GetScreenPosition(xOtherSide - new Vector3(0, ySign * DistToStart * distBetweenPixelsWorldSpace, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(xOtherSide - new Vector3(0, ySign * DistToStart * distBetweenPixelsWorldSpace, 0)));
lines.Add(InteractionContext.World.GetScreenPosition(xOtherSide - new Vector3(0, ySign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(xOtherSide - new Vector3(0, ySign * (DistToStart + LineLength) * distBetweenPixelsWorldSpace, 0)));
} }
public static Vector3 GetScalingConsideringShiftKey(AxisAlignedBoundingBox originalSelectedBounds, public static Vector3 GetScalingConsideringShiftKey(AxisAlignedBoundingBox originalSelectedBounds,
@ -463,8 +463,8 @@ namespace MatterHackers.Plugins.EditorTools
} }
// if another control gets a hover // if another control gets a hover
if (InteractionContext.HoveredInteractionVolume != this if (object3DControlContext.HoveredObject3DControl != this
&& InteractionContext.HoveredInteractionVolume != null) && object3DControlContext.HoveredObject3DControl != null)
{ {
return true; return true;
} }
@ -499,13 +499,13 @@ namespace MatterHackers.Plugins.EditorTools
return new Vector3(xDirection, yDirection, cornerPosition.Z); return new Vector3(xDirection, yDirection, cornerPosition.Z);
} }
private void InteractionLayer_AfterDraw(object sender, DrawEventArgs drawEvent) private void Object3DControl_AfterDraw(object sender, DrawEventArgs drawEvent)
{ {
var selectedItem = RootSelection; var selectedItem = RootSelection;
if (selectedItem != null) if (selectedItem != null)
{ {
if (MouseOver || MouseDownOnControl) if (MouseIsOver || MouseDownOnControl)
{ {
for (int i = 0; i < lines.Count; i += 2) for (int i = 0; i < lines.Count; i += 2)
{ {
@ -515,7 +515,10 @@ namespace MatterHackers.Plugins.EditorTools
for (int i = 0; i < lines.Count; i += 4) for (int i = 0; i < lines.Count; i += 4)
{ {
DrawMeasureLine(drawEvent.Graphics2D, (lines[i] + lines[i + 1]) / 2, (lines[i + 2] + lines[i + 3]) / 2, LineArrows.Both, theme); drawEvent.Graphics2D.DrawMeasureLine((lines[i] + lines[i + 1]) / 2,
(lines[i + 2] + lines[i + 3]) / 2,
LineArrows.Both,
theme);
} }
int j = 4; int j = 4;

View file

@ -32,11 +32,11 @@ using MatterHackers.MeshVisualizer;
namespace MatterHackers.Plugins.EditorTools namespace MatterHackers.Plugins.EditorTools
{ {
public class ScaleCornersPlugin : IInteractionVolumeProvider public class ScaleCornersPlugin : IObject3DControlProvider
{ {
public IEnumerable<InteractionVolume> Create(IInteractionVolumeContext context) public IEnumerable<Object3DControlBase> Create(IObject3DControlContext context)
{ {
return new List<InteractionVolume> return new List<Object3DControlBase>
{ {
new ScaleTopControl(context), new ScaleTopControl(context),
new ScaleCornerControl(context, 0), new ScaleCornerControl(context, 0),

View file

@ -45,7 +45,7 @@ using MatterHackers.VectorMath;
namespace MatterHackers.Plugins.EditorTools namespace MatterHackers.Plugins.EditorTools
{ {
public class ScaleTopControl : InteractionVolume public class ScaleTopControl : Object3DControlBase
{ {
public IObject3D ActiveSelectedItem; public IObject3D ActiveSelectedItem;
protected PlaneShape hitPlane; protected PlaneShape hitPlane;
@ -65,7 +65,7 @@ namespace MatterHackers.Plugins.EditorTools
private InlineEditControl zValueDisplayInfo; private InlineEditControl zValueDisplayInfo;
private bool hadClickOnControl; private bool hadClickOnControl;
public ScaleTopControl(IInteractionVolumeContext context) public ScaleTopControl(IObject3DControlContext context)
: base(context) : base(context)
{ {
theme = MatterControl.AppContext.Theme; theme = MatterControl.AppContext.Theme;
@ -81,8 +81,8 @@ namespace MatterHackers.Plugins.EditorTools
} }
// if another control gets a hover // if another control gets a hover
if (InteractionContext.HoveredInteractionVolume != this if (object3DControlContext.HoveredObject3DControl != this
&& InteractionContext.HoveredInteractionVolume != null) && object3DControlContext.HoveredObject3DControl != null)
{ {
return true; return true;
} }
@ -117,7 +117,7 @@ namespace MatterHackers.Plugins.EditorTools
Vector3 newSize = Vector3.Zero; Vector3 newSize = Vector3.Zero;
newSize.Z = zValueDisplayInfo.Value; newSize.Z = zValueDisplayInfo.Value;
Vector3 scaleAmount = ScaleCornerControl.GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, InteractionContext.GuiSurface.ModifierKeys); Vector3 scaleAmount = ScaleCornerControl.GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, object3DControlContext.GuiSurface.ModifierKeys);
Matrix4X4 scale = Matrix4X4.CreateScale(scaleAmount); Matrix4X4 scale = Matrix4X4.CreateScale(scaleAmount);
@ -131,10 +131,10 @@ namespace MatterHackers.Plugins.EditorTools
Invalidate(); Invalidate();
InteractionContext.Scene.AddTransformSnapshot(startingTransform); object3DControlContext.Scene.AddTransformSnapshot(startingTransform);
}; };
InteractionContext.GuiSurface.AddChild(zValueDisplayInfo); object3DControlContext.GuiSurface.AddChild(zValueDisplayInfo);
DrawOnTop = true; DrawOnTop = true;
@ -142,16 +142,16 @@ namespace MatterHackers.Plugins.EditorTools
CollisionVolume = topScaleMesh.CreateBVHData(); CollisionVolume = topScaleMesh.CreateBVHData();
InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw; object3DControlContext.GuiSurface.AfterDraw += Object3DControl_AfterDraw;
} }
public override void DrawGlContent(DrawGlContentEventArgs e) public override void Draw(DrawGlContentEventArgs e)
{ {
bool shouldDrawScaleControls = true; bool shouldDrawScaleControls = true;
var selectedItem = RootSelection; var selectedItem = RootSelection;
if (InteractionContext.SelectedInteractionVolume != null if (object3DControlContext.SelectedObject3DControl != null
&& InteractionContext.SelectedInteractionVolume as ScaleTopControl == null) && object3DControlContext.SelectedObject3DControl as ScaleTopControl == null)
{ {
shouldDrawScaleControls = false; shouldDrawScaleControls = false;
} }
@ -161,7 +161,7 @@ namespace MatterHackers.Plugins.EditorTools
if (shouldDrawScaleControls) if (shouldDrawScaleControls)
{ {
// don't draw if any other control is dragging // don't draw if any other control is dragging
if (MouseOver) if (MouseIsOver)
{ {
GLHelper.Render(topScaleMesh, theme.PrimaryAccentColor, TotalTransform, RenderTypes.Shaded); GLHelper.Render(topScaleMesh, theme.PrimaryAccentColor, TotalTransform, RenderTypes.Shaded);
} }
@ -181,28 +181,28 @@ namespace MatterHackers.Plugins.EditorTools
bottomPosition.Z = originalSelectedBounds.MinXYZ.Z; bottomPosition.Z = originalSelectedBounds.MinXYZ.Z;
// render with z-buffer full black // render with z-buffer full black
double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(topPosition); double distBetweenPixelsWorldSpace = object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(topPosition);
Vector3 delta = topPosition - bottomPosition; Vector3 delta = topPosition - bottomPosition;
Vector3 centerPosition = (topPosition + bottomPosition) / 2; Vector3 centerPosition = (topPosition + bottomPosition) / 2;
Matrix4X4 rotateTransform = Matrix4X4.CreateRotation(new Quaternion(delta, Vector3.UnitX)); Matrix4X4 rotateTransform = Matrix4X4.CreateRotation(new Quaternion(delta, Vector3.UnitX));
Matrix4X4 scaleTransform = Matrix4X4.CreateScale((topPosition - bottomPosition).Length, distBetweenPixelsWorldSpace, distBetweenPixelsWorldSpace); Matrix4X4 scaleTransform = Matrix4X4.CreateScale((topPosition - bottomPosition).Length, distBetweenPixelsWorldSpace, distBetweenPixelsWorldSpace);
Matrix4X4 lineTransform = scaleTransform * rotateTransform * Matrix4X4.CreateTranslation(centerPosition); Matrix4X4 lineTransform = scaleTransform * rotateTransform * Matrix4X4.CreateTranslation(centerPosition);
Frustum clippingFrustum = InteractionContext.World.GetClippingFrustum(); Frustum clippingFrustum = object3DControlContext.World.GetClippingFrustum();
if (e.ZBuffered) if (e.ZBuffered)
{ {
InteractionContext.World.Render3DLine(clippingFrustum, bottomPosition, topPosition, theme.TextColor); object3DControlContext.World.Render3DLine(clippingFrustum, bottomPosition, topPosition, theme.TextColor);
} }
else else
{ {
// render on top of everything very lightly // render on top of everything very lightly
InteractionContext.World.Render3DLine(clippingFrustum, bottomPosition, topPosition, new Color(theme.TextColor, 20), false); object3DControlContext.World.Render3DLine(clippingFrustum, bottomPosition, topPosition, new Color(theme.TextColor, 20), false);
} }
} }
} }
base.DrawGlContent(e); base.Draw(e);
} }
public Vector3 GetTopPosition(IObject3D selectedItem) public Vector3 GetTopPosition(IObject3D selectedItem)
@ -213,7 +213,7 @@ namespace MatterHackers.Plugins.EditorTools
public override void OnMouseDown(Mouse3DEventArgs mouseEvent3D) public override void OnMouseDown(Mouse3DEventArgs mouseEvent3D)
{ {
if (mouseEvent3D.info != null && InteractionContext.Scene.SelectedItem != null) if (mouseEvent3D.info != null && object3DControlContext.Scene.SelectedItem != null)
{ {
hadClickOnControl = true; hadClickOnControl = true;
ActiveSelectedItem = RootSelection; ActiveSelectedItem = RootSelection;
@ -239,7 +239,7 @@ namespace MatterHackers.Plugins.EditorTools
var selectedItem = RootSelection; var selectedItem = RootSelection;
ActiveSelectedItem = selectedItem; ActiveSelectedItem = selectedItem;
if (MouseOver) if (MouseIsOver)
{ {
zValueDisplayInfo.Visible = true; zValueDisplayInfo.Visible = true;
} }
@ -261,10 +261,10 @@ namespace MatterHackers.Plugins.EditorTools
Vector3 newPosition = originalPointToMove + delta; Vector3 newPosition = originalPointToMove + delta;
if (InteractionContext.SnapGridDistance > 0) if (object3DControlContext.SnapGridDistance > 0)
{ {
// snap this position to the grid // snap this position to the grid
double snapGridDistance = InteractionContext.SnapGridDistance; double snapGridDistance = object3DControlContext.SnapGridDistance;
// snap this position to the grid // snap this position to the grid
newPosition.Z = ((int)((newPosition.Z / snapGridDistance) + .5)) * snapGridDistance; newPosition.Z = ((int)((newPosition.Z / snapGridDistance) + .5)) * snapGridDistance;
@ -277,7 +277,7 @@ namespace MatterHackers.Plugins.EditorTools
newSize.Z = newPosition.Z - lockedBottom.Z; newSize.Z = newPosition.Z - lockedBottom.Z;
// scale it // scale it
Vector3 scaleAmount = ScaleCornerControl.GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, InteractionContext.GuiSurface.ModifierKeys); Vector3 scaleAmount = ScaleCornerControl.GetScalingConsideringShiftKey(originalSelectedBounds, mouseDownSelectedBounds, newSize, object3DControlContext.GuiSurface.ModifierKeys);
Matrix4X4 scale = Matrix4X4.CreateScale(scaleAmount); Matrix4X4 scale = Matrix4X4.CreateScale(scaleAmount);
@ -298,7 +298,7 @@ namespace MatterHackers.Plugins.EditorTools
public override void OnMouseUp(Mouse3DEventArgs mouseEvent3D) public override void OnMouseUp(Mouse3DEventArgs mouseEvent3D)
{ {
InteractionContext.Scene.AddTransformSnapshot(transformOnMouseDown); object3DControlContext.Scene.AddTransformSnapshot(transformOnMouseDown);
base.OnMouseUp(mouseEvent3D); base.OnMouseUp(mouseEvent3D);
} }
@ -310,10 +310,10 @@ namespace MatterHackers.Plugins.EditorTools
{ {
selectedItem.Matrix = transformOnMouseDown; selectedItem.Matrix = transformOnMouseDown;
MouseDownOnControl = false; MouseDownOnControl = false;
MouseOver = false; MouseIsOver = false;
InteractionContext.Scene.DrawSelection = true; object3DControlContext.Scene.DrawSelection = true;
InteractionContext.Scene.ShowSelectionShadow = true; object3DControlContext.Scene.ShowSelectionShadow = true;
} }
base.CancelOperation(); base.CancelOperation();
@ -325,7 +325,7 @@ namespace MatterHackers.Plugins.EditorTools
Vector3 topPosition = GetTopPosition(selectedItem); Vector3 topPosition = GetTopPosition(selectedItem);
Vector3 bottomPosition = new Vector3(topPosition.X, topPosition.Y, selectedBounds.MinXYZ.Z); Vector3 bottomPosition = new Vector3(topPosition.X, topPosition.Y, selectedBounds.MinXYZ.Z);
double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(topPosition); double distBetweenPixelsWorldSpace = object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(topPosition);
Vector3 arrowCenter = topPosition; Vector3 arrowCenter = topPosition;
arrowCenter.Z += arrowSize / 2 * distBetweenPixelsWorldSpace; arrowCenter.Z += arrowSize / 2 * distBetweenPixelsWorldSpace;
@ -336,14 +336,14 @@ namespace MatterHackers.Plugins.EditorTools
lines.Clear(); lines.Clear();
// left lines // left lines
lines.Add(InteractionContext.World.GetScreenPosition(topPosition + new Vector3(DistToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(topPosition + new Vector3(DistToStart * distBetweenPixelsWorldSpace, 0, 0)));
lines.Add(new Vector2(lines[0].X + LineLength, lines[0].Y)); lines.Add(new Vector2(lines[0].X + LineLength, lines[0].Y));
lines.Add(InteractionContext.World.GetScreenPosition(bottomPosition + new Vector3(DistToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(bottomPosition + new Vector3(DistToStart * distBetweenPixelsWorldSpace, 0, 0)));
lines.Add(new Vector2(lines[2].X + LineLength, lines[2].Y)); lines.Add(new Vector2(lines[2].X + LineLength, lines[2].Y));
} }
private void InteractionLayer_AfterDraw(object sender, DrawEventArgs drawEvent) private void Object3DControl_AfterDraw(object sender, DrawEventArgs drawEvent)
{ {
var selectedItem = RootSelection; var selectedItem = RootSelection;
@ -359,7 +359,10 @@ namespace MatterHackers.Plugins.EditorTools
for (int i = 0; i < lines.Count; i += 4) for (int i = 0; i < lines.Count; i += 4)
{ {
DrawMeasureLine(drawEvent.Graphics2D, (lines[i] + lines[i + 1]) / 2, (lines[i + 2] + lines[i + 3]) / 2, LineArrows.Both, theme); drawEvent.Graphics2D.DrawMeasureLine((lines[i] + lines[i + 1]) / 2,
(lines[i + 2] + lines[i + 3]) / 2,
LineArrows.Both,
theme);
} }
int j = 0; int j = 0;

View file

@ -35,6 +35,6 @@ namespace MatterHackers.MatterControl.DesignTools
{ {
public interface IEditorDraw public interface IEditorDraw
{ {
void DrawEditor(InteractionLayer interactionLayer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw); void DrawEditor(Object3DControlLayer object3DControlLayer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw);
} }
} }

View file

@ -78,7 +78,7 @@ namespace MatterHackers.MatterControl.DesignTools
[Description("Where to start the bend as a percent of the width of the part")] [Description("Where to start the bend as a percent of the width of the part")]
public double StartPercent { get; set; } = 50; public double StartPercent { get; set; } = 50;
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
if (layer.Scene.SelectedItem != null if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any()) && layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())

View file

@ -244,7 +244,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
ScaleItem.Matrix = Object3DExtensions.ApplyAtPosition(ScaleItem.Matrix, aabb.Center, Matrix4X4.CreateScale(scale)); ScaleItem.Matrix = Object3DExtensions.ApplyAtPosition(ScaleItem.Matrix, aabb.Center, Matrix4X4.CreateScale(scale));
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
if (layer.Scene.SelectedItem != null if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any()) && layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())

View file

@ -133,7 +133,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}); });
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
layer.World.RenderDirectionAxis(Axis, this.WorldMatrix(), 30); layer.World.RenderDirectionAxis(Axis, this.WorldMatrix(), 30);
} }

View file

@ -66,7 +66,7 @@ namespace MatterHackers.MatterControl.DesignTools
[Description("Where to start the bend as a percent of the width of the part")] [Description("Where to start the bend as a percent of the width of the part")]
public double StartPercent { get; set; } = 50; public double StartPercent { get; set; } = 50;
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
var sourceAabb = this.SourceContainer.GetAxisAlignedBoundingBox(); var sourceAabb = this.SourceContainer.GetAxisAlignedBoundingBox();
var distance = Diameter / 2 + sourceAabb.YSize / 2; var distance = Diameter / 2 + sourceAabb.YSize / 2;

View file

@ -145,7 +145,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
return fitToBounds; return fitToBounds;
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox(); var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();
var center = aabb.Center; var center = aabb.Center;

View file

@ -105,7 +105,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
return fitToBounds; return fitToBounds;
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
var aabb = this.WorldAxisAlignedBoundingBox(); var aabb = this.WorldAxisAlignedBoundingBox();
layer.World.RenderCylinderOutline(Matrix4X4.Identity, aabb.Center, Diameter, aabb.ZSize, 90, Color.Red); layer.World.RenderCylinderOutline(Matrix4X4.Identity, aabb.Center, Diameter, aabb.ZSize, 90, Color.Red);

View file

@ -252,7 +252,7 @@ namespace MatterHackers.MatterControl.DesignTools
} }
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
ImageToPathObject3D.DrawPath(this); ImageToPathObject3D.DrawPath(this);
} }

View file

@ -125,7 +125,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
return joinType; return joinType;
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
ImageToPathObject3D.DrawPath(this); ImageToPathObject3D.DrawPath(this);
} }

View file

@ -142,7 +142,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
(VertexSource as VertexStorage).Add(0, 0, ShapePath.FlagsAndCommand.Stop); (VertexSource as VertexStorage).Add(0, 0, ShapePath.FlagsAndCommand.Stop);
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
ImageToPathObject3D.DrawPath(this); ImageToPathObject3D.DrawPath(this);
} }

View file

@ -160,7 +160,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
VertexSource = outputPolygons.CreateVertexStorage(); VertexSource = outputPolygons.CreateVertexStorage();
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
ImageToPathObject3D.DrawPath(this); ImageToPathObject3D.DrawPath(this);
} }

View file

@ -100,7 +100,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
} }
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
if (layer.Scene.SelectedItem != null if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any()) && layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())

View file

@ -176,7 +176,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
#endregion // editable properties #endregion // editable properties
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
if (layer.Scene.SelectedItem != null if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any()) && layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())

View file

@ -123,7 +123,7 @@ namespace MatterHackers.MatterControl.DesignTools
} }
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
var sourceAabb = this.SourceContainer.GetAxisAlignedBoundingBox(); var sourceAabb = this.SourceContainer.GetAxisAlignedBoundingBox();
var rotationCenter = SourceContainer.GetSmallestEnclosingCircleAlongZ().Center + RotationOffset; var rotationCenter = SourceContainer.GetSmallestEnclosingCircleAlongZ().Center + RotationOffset;

View file

@ -180,7 +180,7 @@ namespace MatterHackers.MatterControl.DesignTools
return null; return null;
} }
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
ImageToPathObject3D.DrawPath(this); ImageToPathObject3D.DrawPath(this);
} }

View file

@ -0,0 +1,88 @@
/*
Copyright (c) 2018, Lars Brubaker
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using MatterHackers.Agg;
using MatterHackers.Agg.Transform;
using MatterHackers.Agg.VertexSource;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl
{
[Flags]
public enum LineArrows
{
None = 0,
Start = 1,
End = 2,
Both = 3
}
public static class Graphics2DOverrides
{
public static void Ring(this Graphics2D graphics2D, Vector2 center, double radius, double width, Color color)
{
var ring = new Ellipse(center, radius);
var ringStroke = new Stroke(ring, width);
graphics2D.Render(ringStroke, color);
}
public static void DrawMeasureLine(this Graphics2D graphics2D, Vector2 lineStart, Vector2 lineEnd, LineArrows arrows, ThemeConfig theme)
{
graphics2D.Line(lineStart, lineEnd, theme.TextColor);
Vector2 direction = lineEnd - lineStart;
if (direction.LengthSquared > 0
&& (arrows.HasFlag(LineArrows.Start) || arrows.HasFlag(LineArrows.End)))
{
var arrow = new VertexStorage();
arrow.MoveTo(-3, -5);
arrow.LineTo(0, 0);
arrow.LineTo(3, -5);
if (arrows.HasFlag(LineArrows.End))
{
double rotation = Math.Atan2(direction.Y, direction.X);
IVertexSource correctRotation = new VertexSourceApplyTransform(arrow, Affine.NewRotation(rotation - MathHelper.Tau / 4));
IVertexSource inPosition = new VertexSourceApplyTransform(correctRotation, Affine.NewTranslation(lineEnd));
graphics2D.Render(inPosition, theme.TextColor);
}
if (arrows.HasFlag(LineArrows.Start))
{
double rotation = Math.Atan2(direction.Y, direction.X) + MathHelper.Tau / 2;
IVertexSource correctRotation = new VertexSourceApplyTransform(arrow, Affine.NewRotation(rotation - MathHelper.Tau / 4));
IVertexSource inPosition = new VertexSourceApplyTransform(correctRotation, Affine.NewTranslation(lineStart));
graphics2D.Render(inPosition, theme.TextColor);
}
}
}
}
}

View file

@ -317,7 +317,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
{ {
// Mouse and widget positions // Mouse and widget positions
var screenSpaceMousePosition = this.TransformToScreenSpace(mouseEvent.Position); var screenSpaceMousePosition = this.TransformToScreenSpace(mouseEvent.Position);
var meshViewerPosition = view3DWidget.InteractionLayer.TransformToScreenSpace(view3DWidget.InteractionLayer.LocalBounds); var meshViewerPosition = view3DWidget.Object3DControlLayer.TransformToScreenSpace(view3DWidget.Object3DControlLayer.LocalBounds);
// Notify of drag operation complete // Notify of drag operation complete
view3DWidget.FinishDrop(mouseUpInBounds: meshViewerPosition.Contains(screenSpaceMousePosition)); view3DWidget.FinishDrop(mouseUpInBounds: meshViewerPosition.Contains(screenSpaceMousePosition));

View file

@ -94,7 +94,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
viewControls3D, viewControls3D,
theme, theme,
this, this,
editorType: (isPrinterType) ? InteractionLayer.EditorType.Printer : InteractionLayer.EditorType.Part); editorType: (isPrinterType) ? Object3DControlLayer.EditorType.Printer : Object3DControlLayer.EditorType.Part);
viewControls3D.SetView3DWidget(view3DWidget); viewControls3D.SetView3DWidget(view3DWidget);

View file

@ -64,7 +64,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
gcodeOptions = sceneContext.RendererOptions; gcodeOptions = sceneContext.RendererOptions;
view3DWidget.InteractionLayer.EditorMode = InteractionLayer.EditorType.Printer; view3DWidget.Object3DControlLayer.EditorMode = Object3DControlLayer.EditorType.Printer;
viewControls3D.TransformStateChanged += (s, e) => viewControls3D.TransformStateChanged += (s, e) =>
{ {
@ -106,7 +106,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Maximum = sceneContext.LoadedGCode?.LayerCount ?? 1 Maximum = sceneContext.LoadedGCode?.LayerCount ?? 1
}; };
LayerScrollbar.SolidSlider.View.TrackColor = opaqueTrackColor; LayerScrollbar.SolidSlider.View.TrackColor = opaqueTrackColor;
view3DWidget.InteractionLayer.AddChild(LayerScrollbar); view3DWidget.Object3DControlLayer.AddChild(LayerScrollbar);
layerRenderRatioSlider = new DoubleSolidSlider(default(Vector2), SliceLayerSelector.SliderWidth, theme); layerRenderRatioSlider = new DoubleSolidSlider(default(Vector2), SliceLayerSelector.SliderWidth, theme);
layerRenderRatioSlider.FirstValue = 0; layerRenderRatioSlider.FirstValue = 0;
@ -128,14 +128,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.Invalidate(); this.Invalidate();
}; };
view3DWidget.InteractionLayer.AddChild(layerRenderRatioSlider); view3DWidget.Object3DControlLayer.AddChild(layerRenderRatioSlider);
theme.ApplySliderStyle(layerRenderRatioSlider); theme.ApplySliderStyle(layerRenderRatioSlider);
layerRenderRatioSlider.View.TrackColor = opaqueTrackColor; layerRenderRatioSlider.View.TrackColor = opaqueTrackColor;
AddSettingsTabBar(leftToRight, view3DWidget); AddSettingsTabBar(leftToRight, view3DWidget);
view3DWidget.InteractionLayer.BoundsChanged += (s, e) => view3DWidget.Object3DControlLayer.BoundsChanged += (s, e) =>
{ {
SetSliderSizes(); SetSliderSizes();
}; };
@ -147,18 +147,18 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// Must come after we have an instance of View3DWidget an its undo buffer // Must come after we have an instance of View3DWidget an its undo buffer
topToBottom.AddChild(PrinterActionsBar, 0); topToBottom.AddChild(PrinterActionsBar, 0);
var trackball = view3DWidget.InteractionLayer.Children<TrackballTumbleWidget>().FirstOrDefault(); var trackball = view3DWidget.Object3DControlLayer.Children<TrackballTumbleWidget>().FirstOrDefault();
tumbleCubeControl = view3DWidget.InteractionLayer.Children<TumbleCubeControl>().FirstOrDefault(); tumbleCubeControl = view3DWidget.Object3DControlLayer.Children<TumbleCubeControl>().FirstOrDefault();
var position = view3DWidget.InteractionLayer.Children.IndexOf(trackball); var position = view3DWidget.Object3DControlLayer.Children.IndexOf(trackball);
gcodePanel = new GCodePanel(this, printer, sceneContext, theme) gcodePanel = new GCodePanel(this, printer, sceneContext, theme)
{ {
Name = "GCode3DWidget", Name = "GCode3DWidget",
HAnchor = HAnchor.Stretch, HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Stretch, VAnchor = VAnchor.Stretch,
BackgroundColor = theme.InteractionLayerOverlayColor, BackgroundColor = theme.Object3DControlLayerOverlayColor,
}; };
var modelViewSidePanel = view3DWidget.Descendants<VerticalResizeContainer>().FirstOrDefault(); var modelViewSidePanel = view3DWidget.Descendants<VerticalResizeContainer>().FirstOrDefault();
@ -209,7 +209,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
Visible = printer.ViewState.ViewMode == PartViewMode.Layers2D Visible = printer.ViewState.ViewMode == PartViewMode.Layers2D
}; };
view3DWidget.InteractionLayer.AddChild(gcode2DWidget, position + 1); view3DWidget.Object3DControlLayer.AddChild(gcode2DWidget, position + 1);
SetSliderSizes(); SetSliderSizes();
@ -409,7 +409,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
gcode2DWidget.Visible = viewMode == PartViewMode.Layers2D; gcode2DWidget.Visible = viewMode == PartViewMode.Layers2D;
view3DWidget.InteractionLayer.DrawOpenGLContent = printer?.ViewState.ViewMode != PartViewMode.Layers2D; view3DWidget.Object3DControlLayer.DrawOpenGLContent = printer?.ViewState.ViewMode != PartViewMode.Layers2D;
sceneContext.ViewState.ModelView = viewMode == PartViewMode.Model; sceneContext.ViewState.ModelView = viewMode == PartViewMode.Model;
@ -472,7 +472,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
} }
layerRenderRatioSlider.OriginRelativeParent = new Vector2(4, 13); layerRenderRatioSlider.OriginRelativeParent = new Vector2(4, 13);
layerRenderRatioSlider.TotalWidthInPixels = view3DWidget.InteractionLayer.Width - 32; layerRenderRatioSlider.TotalWidthInPixels = view3DWidget.Object3DControlLayer.Width - 32;
} }
private double lastPosition = 0; private double lastPosition = 0;

View file

@ -36,8 +36,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
public class RenderOptionsButton : DropButton public class RenderOptionsButton : DropButton
{ {
public RenderOptionsButton(ThemeConfig theme, InteractionLayer interactionLayer) public RenderOptionsButton(ThemeConfig theme, Object3DControlLayer object3DControlLayer)
: base (theme) : base(theme)
{ {
this.HAnchor = HAnchor.Fit; this.HAnchor = HAnchor.Fit;
this.VAnchor = VAnchor.Fit; this.VAnchor = VAnchor.Fit;
@ -64,7 +64,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Console.WriteLine(); Console.WriteLine();
}; };
foreach (var drawable in ApplicationController.Instance.DragDropData.View3DWidget.InteractionLayer.Drawables) foreach (var drawable in ApplicationController.Instance.DragDropData.View3DWidget.Object3DControlLayer.Drawables)
{ {
var row = new SettingsRow(drawable.Title, drawable.Description, theme); var row = new SettingsRow(drawable.Title, drawable.Description, theme);
subPanel.AddChild(row); subPanel.AddChild(row);
@ -80,7 +80,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
row.AddChild(toggleSwitch); row.AddChild(toggleSwitch);
} }
foreach (var drawable in ApplicationController.Instance.DragDropData.View3DWidget.InteractionLayer.ItemDrawables) foreach (var drawable in ApplicationController.Instance.DragDropData.View3DWidget.Object3DControlLayer.ItemDrawables)
{ {
var row = new SettingsRow(drawable.Title, drawable.Description, theme); var row = new SettingsRow(drawable.Title, drawable.Description, theme);
subPanel.AddChild(row); subPanel.AddChild(row);

View file

@ -59,7 +59,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
pendingTasksList = new FlowLayoutWidget(FlowDirection.TopToBottom) pendingTasksList = new FlowLayoutWidget(FlowDirection.TopToBottom)
{ {
BackgroundColor = theme.InteractionLayerOverlayColor, BackgroundColor = theme.Object3DControlLayerOverlayColor,
HAnchor = HAnchor.Fit | HAnchor.Left, HAnchor = HAnchor.Fit | HAnchor.Left,
VAnchor = VAnchor.Fit, VAnchor = VAnchor.Fit,
MinimumSize = new Vector2(325 * GuiWidget.DeviceScale, 0), MinimumSize = new Vector2(325 * GuiWidget.DeviceScale, 0),

View file

@ -49,7 +49,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public class FloorDrawable : IDrawable, IDisposable public class FloorDrawable : IDrawable, IDisposable
{ {
private ISceneContext sceneContext; private ISceneContext sceneContext;
private InteractionLayer.EditorType editorType; private Object3DControlLayer.EditorType editorType;
private ThemeConfig theme; private ThemeConfig theme;
private PrinterConfig printer; private PrinterConfig printer;
@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private bool loadingTextures = false; private bool loadingTextures = false;
public FloorDrawable(InteractionLayer.EditorType editorType, ISceneContext sceneContext, Color buildVolumeColor, ThemeConfig theme) public FloorDrawable(Object3DControlLayer.EditorType editorType, ISceneContext sceneContext, Color buildVolumeColor, ThemeConfig theme)
{ {
this.buildVolumeColor = buildVolumeColor; this.buildVolumeColor = buildVolumeColor;
this.sceneContext = sceneContext; this.sceneContext = sceneContext;
@ -90,7 +90,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public void Draw(GuiWidget sender, DrawEventArgs e, Matrix4X4 itemMaxtrix, WorldView world) public void Draw(GuiWidget sender, DrawEventArgs e, Matrix4X4 itemMaxtrix, WorldView world)
{ {
if (editorType == InteractionLayer.EditorType.Printer) if (editorType == Object3DControlLayer.EditorType.Printer)
{ {
// only render if we are above the bed // only render if we are above the bed
if (sceneContext.RendererOptions.RenderBed) if (sceneContext.RendererOptions.RenderBed)

View file

@ -78,7 +78,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
int i = 0; int i = 0;
foreach(var p in items) foreach(var p in items)
{ {
InteractionLayer.RenderBounds(e, world, p.Matrix, p.BvhItem, i++); Object3DControlLayer.RenderBounds(e, world, p.Matrix, p.BvhItem, i++);
} }
} }
} }

View file

@ -68,7 +68,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
return false; return false;
}); });
InteractionLayer.RenderBounds(e, world, bvhIterator); Object3DControlLayer.RenderBounds(e, world, bvhIterator);
} }
} }
} }

View file

@ -59,7 +59,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
[DisplayName("Part(s) to Subtract and Replace")] [DisplayName("Part(s) to Subtract and Replace")]
public SelectedChildren SelectedChildren { get; set; } = new SelectedChildren(); public SelectedChildren SelectedChildren { get; set; } = new SelectedChildren();
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
suppressNormalDraw = true; suppressNormalDraw = true;

View file

@ -56,7 +56,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
[DisplayName("Part(s) to Subtract")] [DisplayName("Part(s) to Subtract")]
public SelectedChildren SelectedChildren { get; set; } = new SelectedChildren(); public SelectedChildren SelectedChildren { get; set; } = new SelectedChildren();
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw) public void DrawEditor(Object3DControlLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{ {
if (layer.Scene.SelectedItem != null if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem == this) && layer.Scene.SelectedItem == this)

View file

@ -63,7 +63,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
AxisAlignedBoundingBox bounds = TrackingObject.GetAxisAlignedBoundingBox(offset); AxisAlignedBoundingBox bounds = TrackingObject.GetAxisAlignedBoundingBox(offset);
Vector3 renderPosition = bounds.GetBottomCorner(2); Vector3 renderPosition = bounds.GetBottomCorner(2);
Vector2 cornerScreenSpace = view3DWidget.InteractionLayer.World.GetScreenPosition(renderPosition) - new Vector2(20, 0); Vector2 cornerScreenSpace = view3DWidget.Object3DControlLayer.World.GetScreenPosition(renderPosition) - new Vector2(20, 0);
e.Graphics2D.PushTransform(); e.Graphics2D.PushTransform();
Affine currentGraphics2DTransform = e.Graphics2D.GetTransform(); Affine currentGraphics2DTransform = e.Graphics2D.GetTransform();
@ -84,7 +84,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public void ProgressReporter(double progress0To1, string processingState) public void ProgressReporter(double progress0To1, string processingState)
{ {
progressBar.RatioComplete = progress0To1; progressBar.RatioComplete = progress0To1;
view3DWidget?.InteractionLayer?.Invalidate(); view3DWidget?.Object3DControlLayer?.Invalidate();
this.State = processingState; this.State = processingState;

View file

@ -37,12 +37,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
public class GridOptionsPanel : DropButton public class GridOptionsPanel : DropButton
{ {
InteractionLayer interactionLayer; Object3DControlLayer object3DControlLayer;
public GridOptionsPanel(InteractionLayer interactionLayer, ThemeConfig theme) public GridOptionsPanel(Object3DControlLayer object3DControlLayer, ThemeConfig theme)
: base(theme) : base(theme)
{ {
this.interactionLayer = interactionLayer; this.object3DControlLayer = object3DControlLayer;
this.PopupContent = () => ShowGridOptions(theme); this.PopupContent = () => ShowGridOptions(theme);
this.AddChild(new IconButton(AggContext.StaticData.LoadIcon("1694146.png", 16, 16, theme.InvertIcons), theme) this.AddChild(new IconButton(AggContext.StaticData.LoadIcon("1694146.png", 16, 16, theme.InvertIcons), theme)
@ -61,10 +61,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
popupMenu.CreateBoolMenuItem( popupMenu.CreateBoolMenuItem(
"Off".Localize(), "Off".Localize(),
() => interactionLayer.SnapGridDistance == 0, () => object3DControlLayer.SnapGridDistance == 0,
(isChecked) => (isChecked) =>
{ {
interactionLayer.SnapGridDistance = 0; object3DControlLayer.SnapGridDistance = 0;
}, },
useRadioStyle: true, useRadioStyle: true,
siblingRadioButtonList: siblingList); siblingRadioButtonList: siblingList);
@ -74,14 +74,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
.1, .25, .5, 1, 2, 5 .1, .25, .5, 1, 2, 5
}; };
foreach(var snap in snapSettings) foreach (var snap in snapSettings)
{ {
popupMenu.CreateBoolMenuItem( popupMenu.CreateBoolMenuItem(
snap.ToString(), snap.ToString(),
() => interactionLayer.SnapGridDistance == snap, () => object3DControlLayer.SnapGridDistance == snap,
(isChecked) => (isChecked) =>
{ {
interactionLayer.SnapGridDistance = snap; object3DControlLayer.SnapGridDistance = snap;
}, },
useRadioStyle: true, useRadioStyle: true,
siblingRadioButtonList: siblingList); siblingRadioButtonList: siblingList);

View file

@ -45,23 +45,24 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
public class MoveInZControl : InteractionVolume public class MoveInZControl : Object3DControlBase
{ {
public IObject3D ActiveSelectedItem; public IObject3D ActiveSelectedItem { get; set; }
protected PlaneShape hitPlane;
protected Vector3 initialHitPosition;
protected Mesh upArrowMesh;
protected AxisAlignedBoundingBox mouseDownSelectedBounds;
protected Matrix4X4 transformOnMouseDown = Matrix4X4.Identity;
private double distToStart = 5;
private double lineLength = 55;
private List<Vector2> lines = new List<Vector2>();
private double upArrowSize = 7 * GuiWidget.DeviceScale;
private InlineEditControl zHeightDisplayInfo;
private bool HadClickOnControl;
private ThemeConfig theme;
public MoveInZControl(IInteractionVolumeContext context) private PlaneShape hitPlane;
private Vector3 initialHitPosition;
private readonly Mesh upArrowMesh;
private AxisAlignedBoundingBox mouseDownSelectedBounds;
private Matrix4X4 transformOnMouseDown = Matrix4X4.Identity;
private readonly double distToStart = 5;
private readonly double lineLength = 55;
private readonly List<Vector2> lines = new List<Vector2>();
private readonly double upArrowSize = 7 * GuiWidget.DeviceScale;
private readonly InlineEditControl zHeightDisplayInfo;
private bool hadClickOnControl;
private readonly ThemeConfig theme;
public MoveInZControl(IObject3DControlContext context)
: base(context) : base(context)
{ {
theme = AppContext.Theme; theme = AppContext.Theme;
@ -78,21 +79,20 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
} }
// if another control gets a hover // if another control gets a hover
if (InteractionContext.HoveredInteractionVolume != this if (object3DControlContext.HoveredObject3DControl != this
&& InteractionContext.HoveredInteractionVolume != null) && object3DControlContext.HoveredObject3DControl != null)
{ {
return true; return true;
} }
// if we clicked on the control // if we clicked on the control
if (HadClickOnControl) if (hadClickOnControl)
{ {
return false; return false;
} }
return false; return false;
} },
,
GetDisplayString = (value) => "{0:0.0#}mm".FormatWith(value) GetDisplayString = (value) => "{0:0.0#}mm".FormatWith(value)
}; };
@ -100,7 +100,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
if (!zHeightDisplayInfo.Visible) if (!zHeightDisplayInfo.Visible)
{ {
HadClickOnControl = false; hadClickOnControl = false;
} }
}; };
@ -112,10 +112,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var newZPosition = zHeightDisplayInfo.Value; var newZPosition = zHeightDisplayInfo.Value;
if (InteractionContext.SnapGridDistance > 0) if (object3DControlContext.SnapGridDistance > 0)
{ {
// snap this position to the grid // snap this position to the grid
double snapGridDistance = InteractionContext.SnapGridDistance; double snapGridDistance = object3DControlContext.SnapGridDistance;
// snap this position to the grid // snap this position to the grid
newZPosition = ((int)((newZPosition / snapGridDistance) + .5)) * snapGridDistance; newZPosition = ((int)((newZPosition / snapGridDistance) + .5)) * snapGridDistance;
@ -126,14 +126,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (moveAmount != 0) if (moveAmount != 0)
{ {
selectedItem.Matrix = selectedItem.Matrix * Matrix4X4.CreateTranslation(0, 0, moveAmount); selectedItem.Matrix *= Matrix4X4.CreateTranslation(0, 0, moveAmount);
Invalidate(); Invalidate();
} }
context.Scene.AddTransformSnapshot(startingTransform); context.Scene.AddTransformSnapshot(startingTransform);
}; };
InteractionContext.GuiSurface.AddChild(zHeightDisplayInfo); object3DControlContext.GuiSurface.AddChild(zHeightDisplayInfo);
DrawOnTop = true; DrawOnTop = true;
@ -144,14 +144,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
CollisionVolume = upArrowMesh.CreateBVHData(); CollisionVolume = upArrowMesh.CreateBVHData();
InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw; object3DControlContext.GuiSurface.AfterDraw += Object3DControl_AfterDraw;
} }
public override void DrawGlContent(DrawGlContentEventArgs e) public override void Draw(DrawGlContentEventArgs e)
{ {
bool shouldDrawMoveControls = true; bool shouldDrawMoveControls = true;
if (InteractionContext.SelectedInteractionVolume != null if (object3DControlContext.SelectedObject3DControl != null
&& InteractionContext.SelectedInteractionVolume as MoveInZControl == null) && object3DControlContext.SelectedObject3DControl as MoveInZControl == null)
{ {
shouldDrawMoveControls = false; shouldDrawMoveControls = false;
} }
@ -162,7 +162,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (shouldDrawMoveControls) if (shouldDrawMoveControls)
{ {
// don't draw if any other control is dragging // don't draw if any other control is dragging
if (MouseOver) if (MouseIsOver)
{ {
GLHelper.Render(upArrowMesh, theme.PrimaryAccentColor, TotalTransform, RenderTypes.Shaded); GLHelper.Render(upArrowMesh, theme.PrimaryAccentColor, TotalTransform, RenderTypes.Shaded);
} }
@ -173,7 +173,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
} }
} }
base.DrawGlContent(e); base.Draw(e);
} }
public Vector3 GetTopPosition(IObject3D selectedItem) public Vector3 GetTopPosition(IObject3D selectedItem)
@ -194,7 +194,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (mouseEvent3D.info != null if (mouseEvent3D.info != null
&& selectedItem != null) && selectedItem != null)
{ {
HadClickOnControl = true; hadClickOnControl = true;
ActiveSelectedItem = selectedItem; ActiveSelectedItem = selectedItem;
zHeightDisplayInfo.Visible = true; zHeightDisplayInfo.Visible = true;
@ -214,11 +214,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
var selectedItem = RootSelection; var selectedItem = RootSelection;
ActiveSelectedItem = selectedItem; ActiveSelectedItem = selectedItem;
if (MouseOver) if (MouseIsOver)
{ {
zHeightDisplayInfo.Visible = true; zHeightDisplayInfo.Visible = true;
} }
else if (!HadClickOnControl) else if (!hadClickOnControl)
{ {
zHeightDisplayInfo.Visible = false; zHeightDisplayInfo.Visible = false;
} }
@ -234,10 +234,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
double newZPosition = mouseDownSelectedBounds.MinXYZ.Z + delta; double newZPosition = mouseDownSelectedBounds.MinXYZ.Z + delta;
if (InteractionContext.SnapGridDistance > 0) if (object3DControlContext.SnapGridDistance > 0)
{ {
// snap this position to the grid // snap this position to the grid
double snapGridDistance = InteractionContext.SnapGridDistance; double snapGridDistance = object3DControlContext.SnapGridDistance;
// snap this position to the grid // snap this position to the grid
newZPosition = ((int)((newZPosition / snapGridDistance) + .5)) * snapGridDistance; newZPosition = ((int)((newZPosition / snapGridDistance) + .5)) * snapGridDistance;
@ -248,7 +248,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (moveAmount != 0) if (moveAmount != 0)
{ {
selectedItem.Matrix = selectedItem.Matrix * Matrix4X4.CreateTranslation(0, 0, moveAmount); selectedItem.Matrix *= Matrix4X4.CreateTranslation(0, 0, moveAmount);
Invalidate(); Invalidate();
} }
} }
@ -259,7 +259,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public override void OnMouseUp(Mouse3DEventArgs mouseEvent3D) public override void OnMouseUp(Mouse3DEventArgs mouseEvent3D)
{ {
InteractionContext.Scene.AddTransformSnapshot(transformOnMouseDown); object3DControlContext.Scene.AddTransformSnapshot(transformOnMouseDown);
base.OnMouseUp(mouseEvent3D); base.OnMouseUp(mouseEvent3D);
} }
@ -271,10 +271,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
selectedItem.Matrix = transformOnMouseDown; selectedItem.Matrix = transformOnMouseDown;
MouseDownOnControl = false; MouseDownOnControl = false;
MouseOver = false; MouseIsOver = false;
InteractionContext.Scene.DrawSelection = true; object3DControlContext.Scene.DrawSelection = true;
InteractionContext.Scene.ShowSelectionShadow = true; object3DControlContext.Scene.ShowSelectionShadow = true;
} }
base.CancelOperation(); base.CancelOperation();
@ -285,27 +285,27 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
AxisAlignedBoundingBox selectedBounds = selectedItem.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox selectedBounds = selectedItem.GetAxisAlignedBoundingBox();
Vector3 topPosition = GetTopPosition(selectedItem); Vector3 topPosition = GetTopPosition(selectedItem);
Vector3 bottomPosition = new Vector3(topPosition.X, topPosition.Y, selectedBounds.MinXYZ.Z); var bottomPosition = new Vector3(topPosition.X, topPosition.Y, selectedBounds.MinXYZ.Z);
double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(topPosition); double distBetweenPixelsWorldSpace = object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(topPosition);
Vector3 boxCenter = topPosition; Vector3 boxCenter = topPosition;
boxCenter.Z += (10 * GuiWidget.DeviceScale + upArrowSize / 2) * distBetweenPixelsWorldSpace; boxCenter.Z += (10 * GuiWidget.DeviceScale + upArrowSize / 2) * distBetweenPixelsWorldSpace;
Matrix4X4 centerMatrix = Matrix4X4.CreateTranslation(boxCenter); var centerMatrix = Matrix4X4.CreateTranslation(boxCenter);
TotalTransform = Matrix4X4.CreateScale(distBetweenPixelsWorldSpace * GuiWidget.DeviceScale) * centerMatrix; TotalTransform = Matrix4X4.CreateScale(distBetweenPixelsWorldSpace * GuiWidget.DeviceScale) * centerMatrix;
lines.Clear(); lines.Clear();
// left lines // left lines
// the lines on the bed // the lines on the bed
var bedPosition = new Vector3(topPosition.X, topPosition.Y, 0); var bedPosition = new Vector3(topPosition.X, topPosition.Y, 0);
lines.Add(InteractionContext.World.GetScreenPosition(bedPosition + new Vector3(distToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(bedPosition + new Vector3(distToStart * distBetweenPixelsWorldSpace, 0, 0)));
lines.Add(new Vector2(lines[0].X + lineLength, lines[0].Y)); lines.Add(new Vector2(lines[0].X + lineLength, lines[0].Y));
lines.Add(InteractionContext.World.GetScreenPosition(bottomPosition + new Vector3(distToStart * distBetweenPixelsWorldSpace, 0, 0))); lines.Add(object3DControlContext.World.GetScreenPosition(bottomPosition + new Vector3(distToStart * distBetweenPixelsWorldSpace, 0, 0)));
lines.Add(new Vector2(lines[2].X + lineLength, lines[2].Y)); lines.Add(new Vector2(lines[2].X + lineLength, lines[2].Y));
} }
private void InteractionLayer_AfterDraw(object sender, DrawEventArgs drawEvent) private void Object3DControl_AfterDraw(object sender, DrawEventArgs drawEvent)
{ {
var selectedItem = RootSelection; var selectedItem = RootSelection;
@ -322,13 +322,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
for (int i = 0; i < lines.Count; i += 4) for (int i = 0; i < lines.Count; i += 4)
{ {
DrawMeasureLine(drawEvent.Graphics2D, (lines[i] + lines[i + 1]) / 2, (lines[i + 2] + lines[i + 3]) / 2, LineArrows.Both, theme); drawEvent.Graphics2D.DrawMeasureLine((lines[i] + lines[i + 1]) / 2, (lines[i + 2] + lines[i + 3]) / 2, LineArrows.Both, theme);
} }
AxisAlignedBoundingBox selectedBounds = selectedItem.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox selectedBounds = selectedItem.GetAxisAlignedBoundingBox();
zHeightDisplayInfo.Value = selectedBounds.MinXYZ.Z; zHeightDisplayInfo.Value = selectedBounds.MinXYZ.Z;
zHeightDisplayInfo.OriginRelativeParent = lines[1] + new Vector2(10, - zHeightDisplayInfo.LocalBounds.Center.Y); zHeightDisplayInfo.OriginRelativeParent = lines[1] + new Vector2(10, -zHeightDisplayInfo.LocalBounds.Center.Y);
} }
} }
} }

View file

@ -36,7 +36,7 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
public class SelectionShadow : InteractionVolume public class SelectionShadow : Object3DControlBase
{ {
static Mesh normalShadowMesh; static Mesh normalShadowMesh;
@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private ThemeConfig theme; private ThemeConfig theme;
public SelectionShadow(IInteractionVolumeContext context) public SelectionShadow(IObject3DControlContext context)
: base(context) : base(context)
{ {
theme = AppContext.Theme; theme = AppContext.Theme;
@ -69,11 +69,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
return normalShadowMesh; return normalShadowMesh;
} }
public override void DrawGlContent(DrawGlContentEventArgs e) public override void Draw(DrawGlContentEventArgs e)
{ {
var selectedItem = RootSelection; var selectedItem = RootSelection;
if (selectedItem != null if (selectedItem != null
&& InteractionContext.Scene.ShowSelectionShadow) && object3DControlContext.Scene.ShowSelectionShadow)
{ {
// draw the bounds on the bed // draw the bounds on the bed
AxisAlignedBoundingBox selectedBounds = selectedItem.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox selectedBounds = selectedItem.GetAxisAlignedBoundingBox();
@ -82,7 +82,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
GLHelper.Render(GetNormalShadowMesh(), shadowColor, withScale, RenderTypes.Shaded); GLHelper.Render(GetNormalShadowMesh(), shadowColor, withScale, RenderTypes.Shaded);
} }
base.DrawGlContent(e); base.Draw(e);
} }
} }
} }

View file

@ -35,7 +35,7 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
public class SnappingIndicators : InteractionVolume public class SnappingIndicators : Object3DControlBase
{ {
private double distToStart = 10; private double distToStart = 10;
private double lineLength = 15; private double lineLength = 15;
@ -43,12 +43,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private MeshSelectInfo meshSelectInfo; private MeshSelectInfo meshSelectInfo;
public SnappingIndicators(IInteractionVolumeContext context, MeshSelectInfo currentSelectInfo) public SnappingIndicators(IObject3DControlContext context, MeshSelectInfo currentSelectInfo)
: base(context) : base(context)
{ {
this.DrawOnTop = true; this.DrawOnTop = true;
this.meshSelectInfo = currentSelectInfo; this.meshSelectInfo = currentSelectInfo;
InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw; object3DControlContext.GuiSurface.AfterDraw += Object3DControl_AfterDraw;
} }
public override void SetPosition(IObject3D selectedItem) public override void SetPosition(IObject3D selectedItem)
@ -56,7 +56,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// draw the hight from the bottom to the bed // draw the hight from the bottom to the bed
AxisAlignedBoundingBox selectedBounds = selectedItem.GetAxisAlignedBoundingBox(); AxisAlignedBoundingBox selectedBounds = selectedItem.GetAxisAlignedBoundingBox();
var world = InteractionContext.World; var world = object3DControlContext.World;
switch (meshSelectInfo.HitQuadrant) switch (meshSelectInfo.HitQuadrant)
{ {
@ -114,10 +114,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
} }
} }
private void InteractionLayer_AfterDraw(object drawingWidget, DrawEventArgs drawEvent) private void Object3DControl_AfterDraw(object drawingWidget, DrawEventArgs drawEvent)
{ {
if (InteractionContext.Scene.SelectedItem != null if (object3DControlContext.Scene.SelectedItem != null
&& InteractionContext.SnapGridDistance > 0 && object3DControlContext.SnapGridDistance > 0
&& meshSelectInfo.DownOnPart) && meshSelectInfo.DownOnPart)
{ {
if (drawEvent != null) if (drawEvent != null)

View file

@ -1,43 +0,0 @@
/*
Copyright (c) 2019, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
namespace MatterHackers.MeshVisualizer
{
/// <summary>
/// Interaction control which draws adornments with native OpenGL calls
/// </summary>
public interface IGLInteractionElement : IInteractionElement
{
bool Visible { get; set; }
bool DrawOnTop { get; }
void DrawGlContent(DrawGlContentEventArgs e);
}
}

View file

@ -34,13 +34,27 @@ namespace MatterHackers.MeshVisualizer
/// <summary> /// <summary>
/// Basic Interaction control - notified of position per OpenGL draw /// Basic Interaction control - notified of position per OpenGL draw
/// </summary> /// </summary>
public interface IInteractionElement public interface IObject3DControl
{ {
string Name { get; } string Name { get; }
void SetPosition(IObject3D selectedItem); void SetPosition(IObject3D selectedItem);
/// <summary>
/// The Control has been requested to cancel (usually by the user).
/// The current state of the operation or edit should be returned to the starting state.
/// </summary>
void CancelOperation(); void CancelOperation();
void LostFocus(); void LostFocus();
/// <summary>
/// Gets or sets a value indicating whether the control is currently visible.
/// </summary>
bool Visible { get; set; }
bool DrawOnTop { get; }
void Draw(DrawGlContentEventArgs e);
} }
} }

View file

@ -33,11 +33,11 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MeshVisualizer namespace MatterHackers.MeshVisualizer
{ {
public interface IInteractionVolumeContext public interface IObject3DControlContext
{ {
InteractionVolume HoveredInteractionVolume { get; } Object3DControlBase HoveredObject3DControl { get; }
InteractionVolume SelectedInteractionVolume { get; } Object3DControlBase SelectedObject3DControl { get; }
InteractiveScene Scene { get; } InteractiveScene Scene { get; }

View file

@ -31,8 +31,8 @@ using System.Collections.Generic;
namespace MatterHackers.MeshVisualizer namespace MatterHackers.MeshVisualizer
{ {
public interface IInteractionVolumeProvider public interface IObject3DControlProvider
{ {
IEnumerable<InteractionVolume> Create(IInteractionVolumeContext context); IEnumerable<Object3DControlBase> Create(IObject3DControlContext context);
} }
} }

View file

@ -1,42 +0,0 @@
/*
Copyright (c) 2019, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
namespace MatterHackers.MeshVisualizer
{
[Flags]
public enum LineArrows
{
None = 0,
Start = 1,
End = 2,
Both = 3
}
}

View file

@ -27,28 +27,22 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project. either expressed or implied, of the FreeBSD Project.
*/ */
using System;
using System.Collections.Generic;
using MatterHackers.Agg;
using MatterHackers.Agg.Transform;
using MatterHackers.Agg.UI; using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters3D; using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl;
using MatterHackers.RayTracer; using MatterHackers.RayTracer;
using MatterHackers.VectorMath; using MatterHackers.VectorMath;
namespace MatterHackers.MeshVisualizer namespace MatterHackers.MeshVisualizer
{ {
public class InteractionVolume : IInteractionElement, IGLInteractionElement public abstract class Object3DControlBase : IObject3DControl
{ {
private bool mouseOver = false; private bool _mouseIsOver = false;
public Matrix4X4 TotalTransform = Matrix4X4.Identity; public Matrix4X4 TotalTransform { get; set; } = Matrix4X4.Identity;
public InteractionVolume(IInteractionVolumeContext meshViewerToDrawWith) public Object3DControlBase(IObject3DControlContext meshViewerToDrawWith)
{ {
this.InteractionContext = meshViewerToDrawWith; this.object3DControlContext = meshViewerToDrawWith;
} }
public IPrimitive CollisionVolume { get; set; } public IPrimitive CollisionVolume { get; set; }
@ -61,14 +55,14 @@ namespace MatterHackers.MeshVisualizer
public IntersectInfo MouseMoveInfo { get; set; } public IntersectInfo MouseMoveInfo { get; set; }
public bool MouseOver public bool MouseIsOver
{ {
get => mouseOver; get => _mouseIsOver;
set set
{ {
if (mouseOver != value) if (_mouseIsOver != value)
{ {
mouseOver = value; _mouseIsOver = value;
Invalidate(); Invalidate();
} }
} }
@ -76,49 +70,18 @@ namespace MatterHackers.MeshVisualizer
public string Name { get; set; } public string Name { get; set; }
protected IInteractionVolumeContext InteractionContext { get; } protected IObject3DControlContext object3DControlContext { get; }
public IObject3D RootSelection public IObject3D RootSelection
{ {
get get
{ {
var selectedItemRoot = InteractionContext.Scene.SelectedItemRoot; var selectedItemRoot = object3DControlContext.Scene.SelectedItemRoot;
var selectedItem = InteractionContext.Scene.SelectedItem; var selectedItem = object3DControlContext.Scene.SelectedItem;
return (selectedItemRoot == selectedItem) ? selectedItem : null; return (selectedItemRoot == selectedItem) ? selectedItem : null;
} }
} }
public static void DrawMeasureLine(Graphics2D graphics2D, Vector2 lineStart, Vector2 lineEnd, LineArrows arrows, ThemeConfig theme)
{
graphics2D.Line(lineStart, lineEnd, theme.TextColor);
Vector2 direction = lineEnd - lineStart;
if (direction.LengthSquared > 0
&& (arrows.HasFlag(LineArrows.Start) || arrows.HasFlag(LineArrows.End)))
{
var arrow = new VertexStorage();
arrow.MoveTo(-3, -5);
arrow.LineTo(0, 0);
arrow.LineTo(3, -5);
if (arrows.HasFlag(LineArrows.End))
{
double rotation = Math.Atan2(direction.Y, direction.X);
IVertexSource correctRotation = new VertexSourceApplyTransform(arrow, Affine.NewRotation(rotation - MathHelper.Tau / 4));
IVertexSource inPosition = new VertexSourceApplyTransform(correctRotation, Affine.NewTranslation(lineEnd));
graphics2D.Render(inPosition, theme.TextColor);
}
if (arrows.HasFlag(LineArrows.Start))
{
double rotation = Math.Atan2(direction.Y, direction.X) + MathHelper.Tau / 2;
IVertexSource correctRotation = new VertexSourceApplyTransform(arrow, Affine.NewRotation(rotation - MathHelper.Tau / 4));
IVertexSource inPosition = new VertexSourceApplyTransform(correctRotation, Affine.NewTranslation(lineStart));
graphics2D.Render(inPosition, theme.TextColor);
}
}
}
public static Vector3 SetBottomControlHeight(AxisAlignedBoundingBox originalSelectedBounds, Vector3 cornerPosition) public static Vector3 SetBottomControlHeight(AxisAlignedBoundingBox originalSelectedBounds, Vector3 cornerPosition)
{ {
if (originalSelectedBounds.MinXYZ.Z < 0) if (originalSelectedBounds.MinXYZ.Z < 0)
@ -136,13 +99,13 @@ namespace MatterHackers.MeshVisualizer
return cornerPosition; return cornerPosition;
} }
public virtual void DrawGlContent(DrawGlContentEventArgs e) public virtual void Draw(DrawGlContentEventArgs e)
{ {
} }
public void Invalidate() public void Invalidate()
{ {
InteractionContext.GuiSurface.Invalidate(); object3DControlContext.GuiSurface.Invalidate();
} }
public virtual void CancelOperation() public virtual void CancelOperation()
@ -158,7 +121,7 @@ namespace MatterHackers.MeshVisualizer
if (mouseEvent3D.MouseEvent2D.Button == MouseButtons.Left) if (mouseEvent3D.MouseEvent2D.Button == MouseButtons.Left)
{ {
MouseDownOnControl = true; MouseDownOnControl = true;
InteractionContext.GuiSurface.Invalidate(); object3DControlContext.GuiSurface.Invalidate();
} }
} }

View file

@ -45,19 +45,19 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
public partial class InteractionLayer : GuiWidget, IInteractionVolumeContext public partial class Object3DControlLayer : GuiWidget, IObject3DControlContext
{ {
private InteractionVolume mouseDownIAVolume = null; private Object3DControlBase mouseDownObject3DControl = null;
/// <summary> /// <summary>
/// Contains type to IAVolume mappings /// Gets the mapping for Object3DControls for a given type
/// </summary> /// </summary>
private readonly Dictionary<Type, List<IInteractionElement>> iavMappings = new Dictionary<Type, List<IInteractionElement>>(); private Dictionary<Type, List<IObject3DControl>> Object3DControlMappings { get; } = new Dictionary<Type, List<IObject3DControl>>();
/// <summary> /// <summary>
/// Interaction Volume Overrides for the selected scene item /// Object3DControl Overrides for the selected scene item
/// </summary> /// </summary>
private List<IInteractionElement> iavOverrides = null; private List<IObject3DControl> Object3DControlOverrides = null;
private Type selectedItemType; private Type selectedItemType;
@ -67,19 +67,19 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public bool DrawOpenGLContent { get; set; } = true; public bool DrawOpenGLContent { get; set; } = true;
private readonly List<IInteractionElement> registeredIAVolumes = new List<IInteractionElement>(); private List<IObject3DControl> DefaultObject3DControls { get; } = new List<IObject3DControl>();
public IEnumerable<IInteractionElement> InteractionVolumes public IEnumerable<IObject3DControl> Object3DControls
{ {
get get
{ {
if (selectedItemType == null) if (selectedItemType == null)
{ {
return Enumerable.Empty<IInteractionElement>(); return Enumerable.Empty<IObject3DControl>();
} }
else else
{ {
return iavOverrides ?? registeredIAVolumes; return Object3DControlOverrides ?? DefaultObject3DControls;
} }
} }
} }
@ -87,7 +87,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private LightingData lighting = new LightingData(); private LightingData lighting = new LightingData();
private GuiWidget renderSource; private GuiWidget renderSource;
public InteractionLayer(ISceneContext sceneContext, ThemeConfig theme, EditorType editorType = EditorType.Part) public Object3DControlLayer(ISceneContext sceneContext, ThemeConfig theme, EditorType editorType = EditorType.Part)
{ {
this.sceneContext = sceneContext; this.sceneContext = sceneContext;
this.EditorMode = editorType; this.EditorMode = editorType;
@ -115,8 +115,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}); });
} }
iavMappings.Add(typeof(ImageObject3D), new List<IInteractionElement> { new MoveInZControl(this) }); Object3DControlMappings.Add(typeof(ImageObject3D), new List<IObject3DControl> { new MoveInZControl(this) });
iavMappings.Add(typeof(PathObject3D), new List<IInteractionElement> { new PathControl(this) }); Object3DControlMappings.Add(typeof(PathObject3D), new List<IObject3DControl> { new PathControl(this) });
// Register listeners // Register listeners
sceneContext.Scene.SelectionChanged += this.Scene_SelectionChanged; sceneContext.Scene.SelectionChanged += this.Scene_SelectionChanged;
@ -145,14 +145,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
drawables.Add(drawable); drawables.Add(drawable);
} }
public void RegisterIAVolume(IInteractionElement interactionVolume) public void RegisterObject3DControl(IObject3DControl object3DControl)
{ {
registeredIAVolumes.Add(interactionVolume); DefaultObject3DControls.Add(object3DControl);
} }
public void RegisterIAVolumes(IEnumerable<IInteractionElement> interactionVolumes) public void RegisterObject3DControls(IEnumerable<IObject3DControl> Object3DControls)
{ {
registeredIAVolumes.AddRange(interactionVolumes); DefaultObject3DControls.AddRange(Object3DControls);
} }
public IEnumerable<IDrawable> Drawables => drawables; public IEnumerable<IDrawable> Drawables => drawables;
@ -185,18 +185,18 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private void Scene_SelectionChanged(object sender, EventArgs e) private void Scene_SelectionChanged(object sender, EventArgs e)
{ {
foreach (var item in this.InteractionVolumes) foreach (var item in this.Object3DControls)
{ {
item.LostFocus(); item.LostFocus();
} }
// On selection change, update state for mappings // On selection change, update state for mappings
selectedItemType = scene.SelectedItem?.GetType(); selectedItemType = scene.SelectedItem?.GetType();
iavOverrides = null; Object3DControlOverrides = null;
if (selectedItemType != null) if (selectedItemType != null)
{ {
iavMappings.TryGetValue(selectedItemType, out iavOverrides); Object3DControlMappings.TryGetValue(selectedItemType, out Object3DControlOverrides);
} }
} }
@ -204,7 +204,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
foreach (var bvhIterator in allResults) foreach (var bvhIterator in allResults)
{ {
InteractionLayer.RenderBounds(e, world, bvhIterator.TransformToWorld, bvhIterator.Bvh, bvhIterator.Depth); Object3DControlLayer.RenderBounds(e, world, bvhIterator.TransformToWorld, bvhIterator.Bvh, bvhIterator.Depth);
} }
} }
@ -261,14 +261,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Ray ray = this.World.GetRayForLocalBounds(mouseEvent.Position); Ray ray = this.World.GetRayForLocalBounds(mouseEvent.Position);
if (this.Scene.SelectedItem != null if (this.Scene.SelectedItem != null
&& !SuppressUiVolumes && !SuppressUiVolumes
&& FindInteractionVolumeHit(ray, out mouseDownIAVolume, out IntersectInfo info)) && FindHitObject3DControl(ray, out mouseDownObject3DControl, out IntersectInfo info))
{ {
mouseDownIAVolume.OnMouseDown(new Mouse3DEventArgs(mouseEvent, ray, info)); mouseDownObject3DControl.OnMouseDown(new Mouse3DEventArgs(mouseEvent, ray, info));
SelectedInteractionVolume = mouseDownIAVolume; SelectedObject3DControl = mouseDownObject3DControl;
} }
else else
{ {
SelectedInteractionVolume = null; SelectedObject3DControl = null;
} }
} }
@ -286,32 +286,32 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
IntersectInfo info = null; IntersectInfo info = null;
var mouseEvent3D = new Mouse3DEventArgs(mouseEvent, ray, info); var mouseEvent3D = new Mouse3DEventArgs(mouseEvent, ray, info);
if (MouseDownOnInteractionVolume && mouseDownIAVolume != null) if (MouseDownOnObject3DControlVolume && mouseDownObject3DControl != null)
{ {
mouseDownIAVolume.OnMouseMove(mouseEvent3D); mouseDownObject3DControl.OnMouseMove(mouseEvent3D);
} }
else else
{ {
this.FindInteractionVolumeHit(ray, out InteractionVolume hitIAVolume, out info); this.FindHitObject3DControl(ray, out Object3DControlBase hitObject3DControl, out info);
var iaVolumes = this.InteractionVolumes; var object3DControls = this.Object3DControls;
foreach (var iaVolume in iaVolumes.OfType<InteractionVolume>()) foreach (var object3DControl in object3DControls.OfType<Object3DControlBase>())
{ {
if (hitIAVolume == iaVolume) if (hitObject3DControl == object3DControl)
{ {
iaVolume.MouseOver = true; object3DControl.MouseIsOver = true;
iaVolume.MouseMoveInfo = info; object3DControl.MouseMoveInfo = info;
HoveredInteractionVolume = iaVolume; HoveredObject3DControl = object3DControl;
} }
else else
{ {
iaVolume.MouseOver = false; object3DControl.MouseIsOver = false;
iaVolume.MouseMoveInfo = null; object3DControl.MouseMoveInfo = null;
} }
// TODO: Why do non-hit volumes get mouse move? // TODO: Why do non-hit volumes get mouse move?
iaVolume.OnMouseMove(mouseEvent3D); object3DControl.OnMouseMove(mouseEvent3D);
} }
} }
} }
@ -326,26 +326,26 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
} }
Ray ray = this.World.GetRayForLocalBounds(mouseEvent.Position); Ray ray = this.World.GetRayForLocalBounds(mouseEvent.Position);
bool anyInteractionVolumeHit = FindInteractionVolumeHit(ray, out InteractionVolume iaVolume, out IntersectInfo info); bool anyObject3DControlVolumeHit = FindHitObject3DControl(ray, out Object3DControlBase object3DControlBase, out IntersectInfo info);
var mouseEvent3D = new Mouse3DEventArgs(mouseEvent, ray, info); var mouseEvent3D = new Mouse3DEventArgs(mouseEvent, ray, info);
if (MouseDownOnInteractionVolume && mouseDownIAVolume != null) if (MouseDownOnObject3DControlVolume && mouseDownObject3DControl != null)
{ {
mouseDownIAVolume.OnMouseUp(mouseEvent3D); mouseDownObject3DControl.OnMouseUp(mouseEvent3D);
SelectedInteractionVolume = null; SelectedObject3DControl = null;
mouseDownIAVolume = null; mouseDownObject3DControl = null;
} }
else else
{ {
mouseDownIAVolume = null; mouseDownObject3DControl = null;
if (anyInteractionVolumeHit) if (anyObject3DControlVolumeHit)
{ {
iaVolume.OnMouseUp(mouseEvent3D); object3DControlBase.OnMouseUp(mouseEvent3D);
} }
SelectedInteractionVolume = null; SelectedObject3DControl = null;
} }
base.OnMouseUp(mouseEvent); base.OnMouseUp(mouseEvent);
@ -386,22 +386,22 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
base.OnClosed(e); base.OnClosed(e);
// Clear lists and references // Clear lists and references
iavOverrides?.Clear(); Object3DControlOverrides?.Clear();
iavMappings.Clear(); Object3DControlMappings.Clear();
registeredIAVolumes.Clear(); DefaultObject3DControls.Clear();
drawables.Clear(); drawables.Clear();
itemDrawables.Clear(); itemDrawables.Clear();
SelectedInteractionVolume = null; SelectedObject3DControl = null;
HoveredInteractionVolume = null; HoveredObject3DControl = null;
} }
private bool FindInteractionVolumeHit(Ray ray, out InteractionVolume hitIAVolume, out IntersectInfo info) private bool FindHitObject3DControl(Ray ray, out Object3DControlBase hitObject3DControl, out IntersectInfo info)
{ {
var iaVolumes = this.InteractionVolumes; var object3DControls = this.Object3DControls;
hitIAVolume = null; hitObject3DControl = null;
if (!iaVolumes.Any()) if (!object3DControls.Any())
{ {
info = null; info = null;
return false; return false;
@ -411,12 +411,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// - Looks like the extra list is always required as CreateNewHierachy requires a List and we can only produce an IEnumerable without the list overhead // - Looks like the extra list is always required as CreateNewHierachy requires a List and we can only produce an IEnumerable without the list overhead
// - var uiTraceables = iaVolumes.Where(ia => ia.CollisionVolume != null).Select(ia => new Transform(ia.CollisionVolume, ia.TotalTransform)).ToList<IPrimitive>(); // - var uiTraceables = iaVolumes.Where(ia => ia.CollisionVolume != null).Select(ia => new Transform(ia.CollisionVolume, ia.TotalTransform)).ToList<IPrimitive>();
var uiTraceables = new List<IPrimitive>(); var uiTraceables = new List<IPrimitive>();
foreach (var interactionVolume in iaVolumes.OfType<InteractionVolume>()) foreach (var object3DControl in object3DControls.OfType<Object3DControlBase>())
{ {
if (interactionVolume.CollisionVolume != null) if (object3DControl.CollisionVolume != null)
{ {
IPrimitive traceData = interactionVolume.CollisionVolume; IPrimitive traceData = object3DControl.CollisionVolume;
uiTraceables.Add(new Transform(traceData, interactionVolume.TotalTransform)); uiTraceables.Add(new Transform(traceData, object3DControl.TotalTransform));
} }
} }
@ -431,15 +431,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
info = allUiObjects.GetClosestIntersection(ray); info = allUiObjects.GetClosestIntersection(ray);
if (info != null) if (info != null)
{ {
foreach (var iaVolume in iaVolumes.OfType<InteractionVolume>()) foreach (var object3DControlBase in object3DControls.OfType<Object3DControlBase>())
{ {
var insideBounds = new List<IBvhItem>(); var insideBounds = new List<IBvhItem>();
if (iaVolume.CollisionVolume != null) if (object3DControlBase.CollisionVolume != null)
{ {
iaVolume.CollisionVolume.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox()); object3DControlBase.CollisionVolume.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox());
if (insideBounds.Contains(info.closestHitObject)) if (insideBounds.Contains(info.closestHitObject))
{ {
hitIAVolume = iaVolume; hitObject3DControl = object3DControlBase;
return true; return true;
} }
} }
@ -451,11 +451,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public bool SuppressUiVolumes { get; set; } = false; public bool SuppressUiVolumes { get; set; } = false;
public bool MouseDownOnInteractionVolume => SelectedInteractionVolume != null; public bool MouseDownOnObject3DControlVolume => SelectedObject3DControl != null;
public InteractionVolume SelectedInteractionVolume { get; set; } = null; public Object3DControlBase SelectedObject3DControl { get; set; } = null;
public InteractionVolume HoveredInteractionVolume { get; set; } = null; public Object3DControlBase HoveredObject3DControl { get; set; } = null;
public double SnapGridDistance public double SnapGridDistance
{ {

View file

@ -47,611 +47,6 @@ using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
public partial class InteractionLayer : GuiWidget
{
private static ImageBuffer ViewOnlyTexture;
private Color lightWireframe = new Color("#aaa4");
private Color darkWireframe = new Color("#3334");
private Color gCodeMeshColor;
private readonly InteractiveScene scene;
private readonly ISceneContext sceneContext;
private readonly ThemeConfig theme;
private readonly FloorDrawable floorDrawable;
private ModelRenderStyle modelRenderStyle = ModelRenderStyle.Wireframe;
private readonly List<IDrawable> drawables = new List<IDrawable>();
private readonly List<IDrawableItem> itemDrawables = new List<IDrawableItem>();
private bool emulatorHooked;
private long lastEmulatorDrawMs;
private readonly Mesh emulatorNozzleMesh = PlatonicSolids.CreateCube(1, 1, 10);
public bool AllowBedRenderingWhenEmpty { get; set; }
public Color BuildVolumeColor { get; set; }
public override void OnLoad(EventArgs args)
{
#if DEBUG
drawables.AddRange(new IDrawable[]
{
new AxisIndicatorDrawable(),
new ScreenspaceAxisIndicatorDrawable(),
new SceneTraceDataDrawable(sceneContext),
new AABBDrawable(sceneContext),
new LevelingDataDrawable(sceneContext),
});
#endif
itemDrawables.AddRange(new IDrawableItem[]
{
new SelectedItemDrawable(sceneContext, this),
new ItemTraceDataDrawable(sceneContext)
});
#if DEBUG
itemDrawables.AddRange(new IDrawableItem[]
{
new InspectedItemDrawable(sceneContext),
new NormalsDrawable(sceneContext)
});
#endif
base.OnLoad(args);
}
public override List<WidgetAndPosition> FindDescendants(IEnumerable<string> namesToSearchFor, List<WidgetAndPosition> foundChildren, RectangleDouble touchingBounds, SearchType seachType, bool allowInvalidItems = true)
{
foreach (InteractionVolume child in this.InteractionVolumes)
{
string object3DName = child.Name;
bool nameFound = false;
foreach (var nameToSearchFor in namesToSearchFor)
{
if (seachType == SearchType.Exact)
{
if (object3DName == nameToSearchFor)
{
nameFound = true;
break;
}
}
else
{
if (nameToSearchFor == ""
|| object3DName.Contains(nameToSearchFor))
{
nameFound = true;
break;
}
}
}
if (nameFound
&& child.CollisionVolume != null)
{
AxisAlignedBoundingBox bounds = child.CollisionVolume.GetAxisAlignedBoundingBox();
bounds = bounds.NewTransformed(child.TotalTransform);
RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;
for (int i = 0; i < 4; i++)
{
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i)));
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i)));
}
if (touchingBounds.IsTouching(screenBoundsOfObject3D))
{
Vector3 renderPosition = bounds.Center;
Vector2 objectCenterScreenSpace = this.World.GetScreenPosition(renderPosition);
var screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);
foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child));
}
}
}
foreach (var child in scene.Children)
{
string object3DName = child.Name;
if (object3DName == null && child.MeshPath != null)
{
object3DName = Path.GetFileName(child.MeshPath);
}
bool nameFound = false;
foreach (var nameToSearchFor in namesToSearchFor)
{
if (seachType == SearchType.Exact)
{
if (object3DName == nameToSearchFor)
{
nameFound = true;
break;
}
}
else
{
if (nameToSearchFor == ""
|| object3DName.Contains(nameToSearchFor))
{
nameFound = true;
break;
}
}
}
if (nameFound)
{
AxisAlignedBoundingBox bounds = child.GetBVHData().GetAxisAlignedBoundingBox();
RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;
for (int i = 0; i < 4; i++)
{
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i)));
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i)));
}
if (touchingBounds.IsTouching(screenBoundsOfObject3D))
{
Vector3 renderPosition = bounds.Center;
Vector2 objectCenterScreenSpace = this.World.GetScreenPosition(renderPosition);
var screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);
foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child));
}
}
}
return base.FindDescendants(namesToSearchFor, foundChildren, touchingBounds, seachType, allowInvalidItems);
}
private void DrawObject(IObject3D object3D, List<Object3DView> transparentMeshes, DrawEventArgs e)
{
var selectedItem = scene.SelectedItem;
foreach (var item in object3D.VisibleMeshes())
{
// check for correct protection rendering
ValidateViewOnlyTexturing(item);
Color drawColor = this.GetItemColor(item, selectedItem);
bool hasTransparentTextures = item.Mesh.FaceTextures.Any(ft => ft.Value.image.HasTransparency);
if ((drawColor.alpha == 255
&& !hasTransparentTextures)
|| (item == scene.DebugItem))
{
// Render as solid
GLHelper.Render(item.Mesh,
drawColor,
item.WorldMatrix(),
sceneContext.ViewState.RenderType,
item.WorldMatrix() * World.ModelviewMatrix,
darkWireframe,
() => Invalidate());
}
else if (drawColor != Color.Transparent)
{
// Queue for transparency
transparentMeshes.Add(new Object3DView(item, drawColor));
}
bool isSelected = selectedItem != null
&& (item == selectedItem
|| item.Ancestors().Any(p => p == selectedItem));
// Invoke all item Drawables
foreach (var drawable in itemDrawables.Where(d => d.DrawStage != DrawStage.Last && d.Enabled))
{
drawable.Draw(this, item, isSelected, e, Matrix4X4.Identity, this.World);
}
// turn lighting back on after rendering selection outlines
GL.Enable(EnableCap.Lighting);
}
}
private static void ValidateViewOnlyTexturing(IObject3D item)
{
// if there is no view only texture or the item is locked
if (InteractionLayer.ViewOnlyTexture == null
|| item.Mesh.Faces.Count == 0)
{
return;
}
// if the item is not currently be processed
if (!item.RebuildLocked)
{
item.Mesh.FaceTextures.TryGetValue(0, out FaceTextureData faceTexture);
bool viewOnlyTexture = faceTexture?.image == InteractionLayer.ViewOnlyTexture;
// if not persistable and has view only texture, remove the view only texture if it has it
if (item.WorldPersistable()
&& viewOnlyTexture)
{
// make sure it does not have the view only texture
using (item.RebuildLock())
{
item.Mesh.RemoveTexture(ViewOnlyTexture, 0);
}
}
else if (!item.WorldPersistable()
&& !viewOnlyTexture
&& !item.RebuildLocked)
{
// add a view only texture if it does not have one
// make a copy of the mesh and texture it
Task.Run(() =>
{
// make sure it does have the view only texture
var aabb = item.Mesh.GetAxisAlignedBoundingBox();
var matrix = Matrix4X4.CreateScale(.5, .5, 1);
matrix *= Matrix4X4.CreateRotationZ(MathHelper.Tau / 8);
// make sure it has it's own copy of the mesh
using (item.RebuildLock())
{
item.Mesh = item.Mesh.Copy(CancellationToken.None);
item.Mesh.PlaceTexture(ViewOnlyTexture, matrix);
}
});
}
}
}
private Color GetItemColor(IObject3D item, IObject3D selectedItem)
{
Color drawColor = item.WorldColor();
if (item.WorldOutputType() == PrintOutputTypes.Support)
{
drawColor = new Color(Color.Yellow, 120);
}
else if (item.WorldOutputType() == PrintOutputTypes.WipeTower)
{
drawColor = new Color(Color.Cyan, 120);
}
else if (sceneContext.ViewState.RenderType == RenderTypes.Materials)
{
// check if we should be rendering materials (this overrides the other colors)
drawColor = MaterialRendering.Color(item.WorldMaterialIndex());
}
if (sceneContext.Printer is PrinterConfig printer)
{
if (printer.InsideBuildVolume(item))
{
if (printer.Settings.Helpers.HotendCount() > 1)
{
var materialIndex = item.WorldMaterialIndex();
if (materialIndex == -1)
{
materialIndex = 0;
}
bool isWipeTower = item?.OutputType == PrintOutputTypes.WipeTower;
// Determine if the given item is outside the bounds of the given extruder
if (materialIndex < printer.Settings.ToolBounds.Length
|| isWipeTower)
{
var itemAABB = item.WorldAxisAlignedBoundingBox();
var itemBounds = new RectangleDouble(new Vector2(itemAABB.MinXYZ), new Vector2(itemAABB.MaxXYZ));
var activeHotends = new HashSet<int>(new[] { materialIndex });
if (isWipeTower)
{
activeHotends.Add(0);
activeHotends.Add(1);
}
// Validate against active hotends
foreach (var hotendIndex in activeHotends)
{
if (printer?.Settings?.ToolBounds != null
&& hotendIndex < printer.Settings.ToolBounds.Length)
{
var hotendBounds = printer.Settings.ToolBounds[hotendIndex];
if (!hotendBounds.Contains(itemBounds))
{
// Draw in red outside of the bounds for the hotend
drawColor = Color.Red.WithAlpha(90);
}
}
}
}
}
}
else
{
// Outside of printer build volume
drawColor = new Color(drawColor, 65);
}
}
if (drawColor.alpha != 255
&& item is Object3D item3D)
{
item3D.EnsureTransparentSorting();
}
if (selectedItem is ISelectableChildContainer selectableChildContainer)
{
if (item.AncestorsAndSelf().Any(i => selectableChildContainer.SelectedChildren.Contains(i.ID)))
{
drawColor = new Color(drawColor, 200);
}
}
if (!sceneContext.ViewState.ModelView)
{
if (modelRenderStyle == ModelRenderStyle.WireframeAndSolid)
{
drawColor = gCodeMeshColor;
}
else if (modelRenderStyle == ModelRenderStyle.Wireframe)
{
drawColor = new Color(gCodeMeshColor, 1);
}
else if (modelRenderStyle == ModelRenderStyle.None)
{
drawColor = Color.Transparent;
}
}
return drawColor;
}
public enum EditorType
{
Printer,
Part
}
public EditorType EditorMode { get; set; } = EditorType.Part;
private int BackToFrontXY(Object3DView a, Object3DView b)
{
var meshA = a.Object3D.Mesh;
var meshB = b.Object3D.Mesh;
if (meshA == null)
{
return 1;
}
else if (meshB == null)
{
return -1;
}
var aCenterWorld = Vector3Ex.Transform(meshA.GetAxisAlignedBoundingBox().Center, a.Object3D.Matrix);
aCenterWorld.Z = 0; // we only want to look at the distance on xy in world space
var aCenterInViewSpace = Vector3Ex.Transform(aCenterWorld, World.ModelviewMatrix);
var bCenterWorld = Vector3Ex.Transform(meshB.GetAxisAlignedBoundingBox().Center, b.Object3D.Matrix);
bCenterWorld.Z = 0; // we only want to look at the distance on xy in world space
var bCenterInViewSpace = Vector3Ex.Transform(bCenterWorld, World.ModelviewMatrix);
return bCenterInViewSpace.LengthSquared.CompareTo(aCenterInViewSpace.LengthSquared);
}
private void DrawGlContent(DrawEventArgs e)
{
var gcodeOptions = sceneContext.RendererOptions;
if (gcodeOptions.GCodeModelView)
{
modelRenderStyle = ModelRenderStyle.WireframeAndSolid;
}
else
{
modelRenderStyle = ModelRenderStyle.None;
}
foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.First))
{
if (drawable.Enabled)
{
drawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
}
GLHelper.SetGlContext(this.World, renderSource.TransformToScreenSpace(renderSource.LocalBounds), lighting);
foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.OpaqueContent))
{
if (drawable.Enabled)
{
drawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
}
// Draw solid objects, extract transparent
var transparentMeshes = new List<Object3DView>();
var selectedItem = scene.SelectedItem;
bool suppressNormalDraw = false;
if (selectedItem != null)
{
// Invoke existing IEditorDraw when iterating items
if (selectedItem is IEditorDraw editorDraw)
{
// TODO: Putting the drawing code in the IObject3D means almost certain bindings to MatterControl in IObject3D. If instead
// we had a UI layer object that used binding to register scene drawing hooks for specific types, we could avoid the bindings
editorDraw.DrawEditor(this, transparentMeshes, e, ref suppressNormalDraw);
}
}
foreach (var item in scene.Children)
{
if (item.Visible
&& (item != selectedItem || suppressNormalDraw == false))
{
DrawObject(item, transparentMeshes, e);
}
}
if (sceneContext.Printer?.Connection?.serialPort is PrinterEmulator.Emulator emulator)
{
void NozzlePositionChanged(object s, EventArgs e2)
{
// limit max number of updates per second to 10
if (UiThread.CurrentTimerMs > lastEmulatorDrawMs + 100)
{
UiThread.RunOnIdle(Invalidate);
// set it to now
lastEmulatorDrawMs = UiThread.CurrentTimerMs;
}
}
var matrix = Matrix4X4.CreateTranslation(emulator.CurrentPosition + new Vector3(.5, .5, 5));
GLHelper.Render(emulatorNozzleMesh,
MaterialRendering.Color(emulator.ExtruderIndex),
matrix,
RenderTypes.Shaded,
matrix * World.ModelviewMatrix);
if (!emulatorHooked)
{
emulator.DestinationChanged += NozzlePositionChanged;
emulatorHooked = true;
}
Closed += (s, e3) => emulator.DestinationChanged -= NozzlePositionChanged;
}
transparentMeshes.Sort(BackToFrontXY);
var bedNormalInViewSpace = Vector3Ex.TransformNormal(Vector3.UnitZ, World.ModelviewMatrix).GetNormal();
var pointOnBedInViewSpace = Vector3Ex.Transform(new Vector3(10, 10, 0), World.ModelviewMatrix);
var lookingDownOnBed = Vector3Ex.Dot(bedNormalInViewSpace, pointOnBedInViewSpace) < 0;
floorDrawable.LookingDownOnBed = lookingDownOnBed;
if (lookingDownOnBed)
{
floorDrawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
var wireColor = Color.Transparent;
switch (modelRenderStyle)
{
case ModelRenderStyle.Wireframe:
wireColor = darkWireframe;
break;
case ModelRenderStyle.WireframeAndSolid:
wireColor = lightWireframe;
break;
}
// Draw transparent objects
foreach (var item in transparentMeshes)
{
GL.Enable(EnableCap.Lighting);
var object3D = item.Object3D;
GLHelper.Render(
object3D.Mesh,
item.Color,
object3D.WorldMatrix(),
RenderTypes.Outlines,
object3D.WorldMatrix() * World.ModelviewMatrix,
wireColor,
allowBspRendering: transparentMeshes.Count < 1000);
}
if (!lookingDownOnBed)
{
floorDrawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
DrawInteractionVolumes(e);
foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.TransparentContent))
{
if (drawable.Enabled)
{
drawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
}
GLHelper.UnsetGlContext();
// Invoke DrawStage.Last item drawables
foreach (var item in scene.Children)
{
// HACK: Consider how shared code in DrawObject can be reused to prevent duplicate execution
bool isSelected = selectedItem != null
&& selectedItem.DescendantsAndSelf().Any((i) => i == item);
foreach (var itemDrawable in itemDrawables.Where(d => d.DrawStage == DrawStage.Last && d.Enabled))
{
itemDrawable.Draw(this, item, isSelected, e, Matrix4X4.Identity, this.World);
}
}
// Invoke DrawStage.Last scene drawables
foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.Last))
{
if (drawable.Enabled)
{
drawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
}
}
private void DrawInteractionVolumes(DrawEventArgs e)
{
foreach (var item in this.InteractionVolumes.OfType<IGLInteractionElement>())
{
item.Visible = !SuppressUiVolumes;
}
if (SuppressUiVolumes)
{
return;
}
// draw on top of anything that is already drawn
GL.Disable(EnableCap.DepthTest);
foreach (var interactionVolume in this.InteractionVolumes.OfType<IGLInteractionElement>())
{
if (interactionVolume.DrawOnTop)
{
interactionVolume.DrawGlContent(new DrawGlContentEventArgs(false, e));
}
}
// Restore DepthTest
GL.Enable(EnableCap.DepthTest);
// Draw again setting the depth buffer and ensuring that all the interaction objects are sorted as well as we can
foreach (var interactionVolume in this.InteractionVolumes.OfType<IGLInteractionElement>())
{
interactionVolume.DrawGlContent(new DrawGlContentEventArgs(true, e));
}
}
public enum ModelRenderStyle
{
Solid,
Wireframe,
WireframeAndSolid,
None
}
}
public class Object3DView public class Object3DView
{ {
public Color Color { get; set; } public Color Color { get; set; }

View file

@ -0,0 +1,654 @@
/*
Copyright (c) 2019, Lars Brubaker
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl.DesignTools;
using MatterHackers.MatterControl.PartPreviewWindow.View3D;
using MatterHackers.MeshVisualizer;
using MatterHackers.PolygonMesh;
using MatterHackers.RenderOpenGl;
using MatterHackers.RenderOpenGl.OpenGl;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
public partial class Object3DControlLayer : GuiWidget, IObject3DControlContext
{
private static ImageBuffer ViewOnlyTexture;
private Color lightWireframe = new Color("#aaa4");
private Color darkWireframe = new Color("#3334");
private Color gCodeMeshColor;
private readonly InteractiveScene scene;
private readonly ISceneContext sceneContext;
private readonly ThemeConfig theme;
private readonly FloorDrawable floorDrawable;
private ModelRenderStyle modelRenderStyle = ModelRenderStyle.Wireframe;
private readonly List<IDrawable> drawables = new List<IDrawable>();
private readonly List<IDrawableItem> itemDrawables = new List<IDrawableItem>();
private bool emulatorHooked;
private long lastEmulatorDrawMs;
private readonly Mesh emulatorNozzleMesh = PlatonicSolids.CreateCube(1, 1, 10);
public bool AllowBedRenderingWhenEmpty { get; set; }
public Color BuildVolumeColor { get; set; }
public override void OnLoad(EventArgs args)
{
#if DEBUG
drawables.AddRange(new IDrawable[]
{
new AxisIndicatorDrawable(),
new ScreenspaceAxisIndicatorDrawable(),
new SceneTraceDataDrawable(sceneContext),
new AABBDrawable(sceneContext),
new LevelingDataDrawable(sceneContext),
});
#endif
itemDrawables.AddRange(new IDrawableItem[]
{
new SelectedItemDrawable(sceneContext, this),
new ItemTraceDataDrawable(sceneContext)
});
#if DEBUG
itemDrawables.AddRange(new IDrawableItem[]
{
new InspectedItemDrawable(sceneContext),
new NormalsDrawable(sceneContext)
});
#endif
base.OnLoad(args);
}
public override List<WidgetAndPosition> FindDescendants(IEnumerable<string> namesToSearchFor, List<WidgetAndPosition> foundChildren, RectangleDouble touchingBounds, SearchType seachType, bool allowInvalidItems = true)
{
foreach (Object3DControlBase child in this.Object3DControls)
{
string object3DName = child.Name;
bool nameFound = false;
foreach (var nameToSearchFor in namesToSearchFor)
{
if (seachType == SearchType.Exact)
{
if (object3DName == nameToSearchFor)
{
nameFound = true;
break;
}
}
else
{
if (nameToSearchFor == ""
|| object3DName.Contains(nameToSearchFor))
{
nameFound = true;
break;
}
}
}
if (nameFound
&& child.CollisionVolume != null)
{
AxisAlignedBoundingBox bounds = child.CollisionVolume.GetAxisAlignedBoundingBox();
bounds = bounds.NewTransformed(child.TotalTransform);
RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;
for (int i = 0; i < 4; i++)
{
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i)));
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i)));
}
if (touchingBounds.IsTouching(screenBoundsOfObject3D))
{
Vector3 renderPosition = bounds.Center;
Vector2 objectCenterScreenSpace = this.World.GetScreenPosition(renderPosition);
var screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);
foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child));
}
}
}
foreach (var child in scene.Children)
{
string object3DName = child.Name;
if (object3DName == null && child.MeshPath != null)
{
object3DName = Path.GetFileName(child.MeshPath);
}
bool nameFound = false;
foreach (var nameToSearchFor in namesToSearchFor)
{
if (seachType == SearchType.Exact)
{
if (object3DName == nameToSearchFor)
{
nameFound = true;
break;
}
}
else
{
if (nameToSearchFor == ""
|| object3DName.Contains(nameToSearchFor))
{
nameFound = true;
break;
}
}
}
if (nameFound)
{
AxisAlignedBoundingBox bounds = child.GetBVHData().GetAxisAlignedBoundingBox();
RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;
for (int i = 0; i < 4; i++)
{
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetTopCorner(i)));
screenBoundsOfObject3D.ExpandToInclude(this.World.GetScreenPosition(bounds.GetBottomCorner(i)));
}
if (touchingBounds.IsTouching(screenBoundsOfObject3D))
{
Vector3 renderPosition = bounds.Center;
Vector2 objectCenterScreenSpace = this.World.GetScreenPosition(renderPosition);
var screenPositionOfObject3D = new Point2D((int)objectCenterScreenSpace.X, (int)objectCenterScreenSpace.Y);
foundChildren.Add(new WidgetAndPosition(this, screenPositionOfObject3D, object3DName, child));
}
}
}
return base.FindDescendants(namesToSearchFor, foundChildren, touchingBounds, seachType, allowInvalidItems);
}
private void DrawObject(IObject3D object3D, List<Object3DView> transparentMeshes, DrawEventArgs e)
{
var selectedItem = scene.SelectedItem;
foreach (var item in object3D.VisibleMeshes())
{
// check for correct protection rendering
ValidateViewOnlyTexturing(item);
Color drawColor = this.GetItemColor(item, selectedItem);
bool hasTransparentTextures = item.Mesh.FaceTextures.Any(ft => ft.Value.image.HasTransparency);
if ((drawColor.alpha == 255
&& !hasTransparentTextures)
|| (item == scene.DebugItem))
{
// Render as solid
GLHelper.Render(item.Mesh,
drawColor,
item.WorldMatrix(),
sceneContext.ViewState.RenderType,
item.WorldMatrix() * World.ModelviewMatrix,
darkWireframe,
() => Invalidate());
}
else if (drawColor != Color.Transparent)
{
// Queue for transparency
transparentMeshes.Add(new Object3DView(item, drawColor));
}
bool isSelected = selectedItem != null
&& (item == selectedItem
|| item.Ancestors().Any(p => p == selectedItem));
// Invoke all item Drawables
foreach (var drawable in itemDrawables.Where(d => d.DrawStage != DrawStage.Last && d.Enabled))
{
drawable.Draw(this, item, isSelected, e, Matrix4X4.Identity, this.World);
}
// turn lighting back on after rendering selection outlines
GL.Enable(EnableCap.Lighting);
}
}
private static void ValidateViewOnlyTexturing(IObject3D item)
{
// if there is no view only texture or the item is locked
if (Object3DControlLayer.ViewOnlyTexture == null
|| item.Mesh.Faces.Count == 0)
{
return;
}
// if the item is not currently be processed
if (!item.RebuildLocked)
{
item.Mesh.FaceTextures.TryGetValue(0, out FaceTextureData faceTexture);
bool viewOnlyTexture = faceTexture?.image == Object3DControlLayer.ViewOnlyTexture;
// if not persistable and has view only texture, remove the view only texture if it has it
if (item.WorldPersistable()
&& viewOnlyTexture)
{
// make sure it does not have the view only texture
using (item.RebuildLock())
{
item.Mesh.RemoveTexture(ViewOnlyTexture, 0);
}
}
else if (!item.WorldPersistable()
&& !viewOnlyTexture
&& !item.RebuildLocked)
{
// add a view only texture if it does not have one
// make a copy of the mesh and texture it
Task.Run(() =>
{
// make sure it does have the view only texture
var aabb = item.Mesh.GetAxisAlignedBoundingBox();
var matrix = Matrix4X4.CreateScale(.5, .5, 1);
matrix *= Matrix4X4.CreateRotationZ(MathHelper.Tau / 8);
// make sure it has it's own copy of the mesh
using (item.RebuildLock())
{
item.Mesh = item.Mesh.Copy(CancellationToken.None);
item.Mesh.PlaceTexture(ViewOnlyTexture, matrix);
}
});
}
}
}
private Color GetItemColor(IObject3D item, IObject3D selectedItem)
{
Color drawColor = item.WorldColor();
if (item.WorldOutputType() == PrintOutputTypes.Support)
{
drawColor = new Color(Color.Yellow, 120);
}
else if (item.WorldOutputType() == PrintOutputTypes.WipeTower)
{
drawColor = new Color(Color.Cyan, 120);
}
else if (sceneContext.ViewState.RenderType == RenderTypes.Materials)
{
// check if we should be rendering materials (this overrides the other colors)
drawColor = MaterialRendering.Color(item.WorldMaterialIndex());
}
if (sceneContext.Printer is PrinterConfig printer)
{
if (printer.InsideBuildVolume(item))
{
if (printer.Settings.Helpers.HotendCount() > 1)
{
var materialIndex = item.WorldMaterialIndex();
if (materialIndex == -1)
{
materialIndex = 0;
}
bool isWipeTower = item?.OutputType == PrintOutputTypes.WipeTower;
// Determine if the given item is outside the bounds of the given extruder
if (materialIndex < printer.Settings.ToolBounds.Length
|| isWipeTower)
{
var itemAABB = item.WorldAxisAlignedBoundingBox();
var itemBounds = new RectangleDouble(new Vector2(itemAABB.MinXYZ), new Vector2(itemAABB.MaxXYZ));
var activeHotends = new HashSet<int>(new[] { materialIndex });
if (isWipeTower)
{
activeHotends.Add(0);
activeHotends.Add(1);
}
// Validate against active hotends
foreach (var hotendIndex in activeHotends)
{
if (printer?.Settings?.ToolBounds != null
&& hotendIndex < printer.Settings.ToolBounds.Length)
{
var hotendBounds = printer.Settings.ToolBounds[hotendIndex];
if (!hotendBounds.Contains(itemBounds))
{
// Draw in red outside of the bounds for the hotend
drawColor = Color.Red.WithAlpha(90);
}
}
}
}
}
}
else
{
// Outside of printer build volume
drawColor = new Color(drawColor, 65);
}
}
if (drawColor.alpha != 255
&& item is Object3D item3D)
{
item3D.EnsureTransparentSorting();
}
if (selectedItem is ISelectableChildContainer selectableChildContainer)
{
if (item.AncestorsAndSelf().Any(i => selectableChildContainer.SelectedChildren.Contains(i.ID)))
{
drawColor = new Color(drawColor, 200);
}
}
if (!sceneContext.ViewState.ModelView)
{
if (modelRenderStyle == ModelRenderStyle.WireframeAndSolid)
{
drawColor = gCodeMeshColor;
}
else if (modelRenderStyle == ModelRenderStyle.Wireframe)
{
drawColor = new Color(gCodeMeshColor, 1);
}
else if (modelRenderStyle == ModelRenderStyle.None)
{
drawColor = Color.Transparent;
}
}
return drawColor;
}
public enum EditorType
{
Printer,
Part
}
public EditorType EditorMode { get; set; } = EditorType.Part;
private int BackToFrontXY(Object3DView a, Object3DView b)
{
var meshA = a.Object3D.Mesh;
var meshB = b.Object3D.Mesh;
if (meshA == null)
{
return 1;
}
else if (meshB == null)
{
return -1;
}
var aCenterWorld = Vector3Ex.Transform(meshA.GetAxisAlignedBoundingBox().Center, a.Object3D.Matrix);
aCenterWorld.Z = 0; // we only want to look at the distance on xy in world space
var aCenterInViewSpace = Vector3Ex.Transform(aCenterWorld, World.ModelviewMatrix);
var bCenterWorld = Vector3Ex.Transform(meshB.GetAxisAlignedBoundingBox().Center, b.Object3D.Matrix);
bCenterWorld.Z = 0; // we only want to look at the distance on xy in world space
var bCenterInViewSpace = Vector3Ex.Transform(bCenterWorld, World.ModelviewMatrix);
return bCenterInViewSpace.LengthSquared.CompareTo(aCenterInViewSpace.LengthSquared);
}
private void DrawGlContent(DrawEventArgs e)
{
var gcodeOptions = sceneContext.RendererOptions;
if (gcodeOptions.GCodeModelView)
{
modelRenderStyle = ModelRenderStyle.WireframeAndSolid;
}
else
{
modelRenderStyle = ModelRenderStyle.None;
}
foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.First))
{
if (drawable.Enabled)
{
drawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
}
GLHelper.SetGlContext(this.World, renderSource.TransformToScreenSpace(renderSource.LocalBounds), lighting);
foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.OpaqueContent))
{
if (drawable.Enabled)
{
drawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
}
// Draw solid objects, extract transparent
var transparentMeshes = new List<Object3DView>();
var selectedItem = scene.SelectedItem;
bool suppressNormalDraw = false;
if (selectedItem != null)
{
// Invoke existing IEditorDraw when iterating items
if (selectedItem is IEditorDraw editorDraw)
{
// TODO: Putting the drawing code in the IObject3D means almost certain bindings to MatterControl in IObject3D. If instead
// we had a UI layer object that used binding to register scene drawing hooks for specific types, we could avoid the bindings
editorDraw.DrawEditor(this, transparentMeshes, e, ref suppressNormalDraw);
}
}
foreach (var item in scene.Children)
{
if (item.Visible
&& (item != selectedItem || suppressNormalDraw == false))
{
DrawObject(item, transparentMeshes, e);
}
}
if (sceneContext.Printer?.Connection?.serialPort is PrinterEmulator.Emulator emulator)
{
void NozzlePositionChanged(object s, EventArgs e2)
{
// limit max number of updates per second to 10
if (UiThread.CurrentTimerMs > lastEmulatorDrawMs + 100)
{
UiThread.RunOnIdle(Invalidate);
// set it to now
lastEmulatorDrawMs = UiThread.CurrentTimerMs;
}
}
var matrix = Matrix4X4.CreateTranslation(emulator.CurrentPosition + new Vector3(.5, .5, 5));
GLHelper.Render(emulatorNozzleMesh,
MaterialRendering.Color(emulator.ExtruderIndex),
matrix,
RenderTypes.Shaded,
matrix * World.ModelviewMatrix);
if (!emulatorHooked)
{
emulator.DestinationChanged += NozzlePositionChanged;
emulatorHooked = true;
}
Closed += (s, e3) => emulator.DestinationChanged -= NozzlePositionChanged;
}
transparentMeshes.Sort(BackToFrontXY);
var bedNormalInViewSpace = Vector3Ex.TransformNormal(Vector3.UnitZ, World.ModelviewMatrix).GetNormal();
var pointOnBedInViewSpace = Vector3Ex.Transform(new Vector3(10, 10, 0), World.ModelviewMatrix);
var lookingDownOnBed = Vector3Ex.Dot(bedNormalInViewSpace, pointOnBedInViewSpace) < 0;
floorDrawable.LookingDownOnBed = lookingDownOnBed;
if (lookingDownOnBed)
{
floorDrawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
var wireColor = Color.Transparent;
switch (modelRenderStyle)
{
case ModelRenderStyle.Wireframe:
wireColor = darkWireframe;
break;
case ModelRenderStyle.WireframeAndSolid:
wireColor = lightWireframe;
break;
}
// Draw transparent objects
foreach (var item in transparentMeshes)
{
GL.Enable(EnableCap.Lighting);
var object3D = item.Object3D;
GLHelper.Render(
object3D.Mesh,
item.Color,
object3D.WorldMatrix(),
RenderTypes.Outlines,
object3D.WorldMatrix() * World.ModelviewMatrix,
wireColor,
allowBspRendering: transparentMeshes.Count < 1000);
}
if (!lookingDownOnBed)
{
floorDrawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
DrawObject3DControlVolumes(e);
foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.TransparentContent))
{
if (drawable.Enabled)
{
drawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
}
GLHelper.UnsetGlContext();
// Invoke DrawStage.Last item drawables
foreach (var item in scene.Children)
{
// HACK: Consider how shared code in DrawObject can be reused to prevent duplicate execution
bool isSelected = selectedItem != null
&& selectedItem.DescendantsAndSelf().Any((i) => i == item);
foreach (var itemDrawable in itemDrawables.Where(d => d.DrawStage == DrawStage.Last && d.Enabled))
{
itemDrawable.Draw(this, item, isSelected, e, Matrix4X4.Identity, this.World);
}
}
// Invoke DrawStage.Last scene drawables
foreach (var drawable in drawables.Where(d => d.DrawStage == DrawStage.Last))
{
if (drawable.Enabled)
{
drawable.Draw(this, e, Matrix4X4.Identity, this.World);
}
}
}
private void DrawObject3DControlVolumes(DrawEventArgs e)
{
foreach (var item in this.Object3DControls.OfType<IObject3DControl>())
{
item.Visible = !SuppressUiVolumes;
}
if (SuppressUiVolumes)
{
return;
}
// draw on top of anything that is already drawn
GL.Disable(EnableCap.DepthTest);
foreach (var object3DControl in this.Object3DControls.OfType<IObject3DControl>())
{
if (object3DControl.DrawOnTop)
{
object3DControl.Draw(new DrawGlContentEventArgs(false, e));
}
}
// Restore DepthTest
GL.Enable(EnableCap.DepthTest);
// Draw again setting the depth buffer and ensuring that all the interaction objects are sorted as well as we can
foreach (var object3DVolume in this.Object3DControls.OfType<IObject3DControl>())
{
object3DVolume.Draw(new DrawGlContentEventArgs(true, e));
}
}
public enum ModelRenderStyle
{
Solid,
Wireframe,
WireframeAndSolid,
None
}
}
}

View file

@ -153,7 +153,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
private Mesh cube = PlatonicSolids.CreateCube(4, 4, 4); private Mesh cube = PlatonicSolids.CreateCube(4, 4, 4);
private IPrimitive cubeTraceData; private IPrimitive cubeTraceData;
private InteractionLayer interactionLayer; private Object3DControlLayer object3DControlLayer;
private Vector2 lastMovePosition; private Vector2 lastMovePosition;
private LightingData lighting = new LightingData(); private LightingData lighting = new LightingData();
private Vector2 mouseDownPosition; private Vector2 mouseDownPosition;
@ -164,11 +164,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private List<ConnectedFaces> connections = new List<ConnectedFaces>(); private List<ConnectedFaces> connections = new List<ConnectedFaces>();
private HitData lastHitData = new HitData(); private HitData lastHitData = new HitData();
public TumbleCubeControl(InteractionLayer interactionLayer, ThemeConfig theme) public TumbleCubeControl(Object3DControlLayer object3DControlLayer, ThemeConfig theme)
: base(100 * GuiWidget.DeviceScale, 100 * GuiWidget.DeviceScale) : base(100 * GuiWidget.DeviceScale, 100 * GuiWidget.DeviceScale)
{ {
this.theme = theme; this.theme = theme;
this.interactionLayer = interactionLayer; this.object3DControlLayer = object3DControlLayer;
// this data needs to be made on the ui thread // this data needs to be made on the ui thread
UiThread.RunOnIdle(() => UiThread.RunOnIdle(() =>
@ -208,10 +208,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
world = new WorldView(screenSpaceBounds.Width, screenSpaceBounds.Height); world = new WorldView(screenSpaceBounds.Width, screenSpaceBounds.Height);
var forward = -Vector3.UnitZ; var forward = -Vector3.UnitZ;
var directionForward = Vector3Ex.TransformNormal(forward, interactionLayer.World.InverseModelviewMatrix); var directionForward = Vector3Ex.TransformNormal(forward, object3DControlLayer.World.InverseModelviewMatrix);
var up = Vector3.UnitY; var up = Vector3.UnitY;
var directionUp = Vector3Ex.TransformNormal(up, interactionLayer.World.InverseModelviewMatrix); var directionUp = Vector3Ex.TransformNormal(up, object3DControlLayer.World.InverseModelviewMatrix);
world.RotationMatrix = Matrix4X4.LookAt(Vector3.Zero, directionForward, directionUp) * Matrix4X4.CreateScale(.8); world.RotationMatrix = Matrix4X4.LookAt(Vector3.Zero, directionForward, directionUp) * Matrix4X4.CreateScale(.8);
GLHelper.SetGlContext(world, screenSpaceBounds, lighting); GLHelper.SetGlContext(world, screenSpaceBounds, lighting);
@ -246,8 +246,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (activeRotationQuaternion != Quaternion.Identity) if (activeRotationQuaternion != Quaternion.Identity)
{ {
lastMovePosition = movePosition; lastMovePosition = movePosition;
interactionLayer.World.RotationMatrix = interactionLayer.World.RotationMatrix * Matrix4X4.CreateRotation(activeRotationQuaternion); object3DControlLayer.World.RotationMatrix = object3DControlLayer.World.RotationMatrix * Matrix4X4.CreateRotation(activeRotationQuaternion);
interactionLayer.Invalidate(); object3DControlLayer.Invalidate();
} }
} }
else if (world != null else if (world != null
@ -392,7 +392,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var look = Matrix4X4.LookAt(Vector3.Zero, normalAndUp.normal, normalAndUp.up); var look = Matrix4X4.LookAt(Vector3.Zero, normalAndUp.normal, normalAndUp.up);
var start = new Quaternion(interactionLayer.World.RotationMatrix); var start = new Quaternion(object3DControlLayer.World.RotationMatrix);
var end = new Quaternion(look); var end = new Quaternion(look);
Task.Run(() => Task.Run(() =>
@ -407,20 +407,20 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var current = Quaternion.Slerp(start, end, time / duration); var current = Quaternion.Slerp(start, end, time / duration);
UiThread.RunOnIdle(() => UiThread.RunOnIdle(() =>
{ {
interactionLayer.World.RotationMatrix = Matrix4X4.CreateRotation(current); object3DControlLayer.World.RotationMatrix = Matrix4X4.CreateRotation(current);
Invalidate(); Invalidate();
}); });
time = timer.Elapsed.TotalSeconds; time = timer.Elapsed.TotalSeconds;
Thread.Sleep(10); Thread.Sleep(10);
} }
interactionLayer.World.RotationMatrix = Matrix4X4.CreateRotation(end); object3DControlLayer.World.RotationMatrix = Matrix4X4.CreateRotation(end);
Invalidate(); Invalidate();
}); });
} }
} }
interactionLayer.Focus(); object3DControlLayer.Focus();
} }
private (Vector3 normal, Vector3 up) GetDirectionForFace(HitData hitData) private (Vector3 normal, Vector3 up) GetDirectionForFace(HitData hitData)

View file

@ -84,7 +84,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public TrackballTumbleWidget TrackballTumbleWidget { get; private set; } public TrackballTumbleWidget TrackballTumbleWidget { get; private set; }
public InteractionLayer InteractionLayer { get; } public Object3DControlLayer Object3DControlLayer { get; }
public ISceneContext sceneContext; public ISceneContext sceneContext;
@ -92,20 +92,20 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private PrinterTabPage printerTabPage; private PrinterTabPage printerTabPage;
public View3DWidget(PrinterConfig printer, ISceneContext sceneContext, ViewControls3D viewControls3D, ThemeConfig theme, PartTabPage printerTabBase, InteractionLayer.EditorType editorType = InteractionLayer.EditorType.Part) public View3DWidget(PrinterConfig printer, ISceneContext sceneContext, ViewControls3D viewControls3D, ThemeConfig theme, PartTabPage printerTabBase, Object3DControlLayer.EditorType editorType = Object3DControlLayer.EditorType.Part)
{ {
this.sceneContext = sceneContext; this.sceneContext = sceneContext;
this.printerTabPage = printerTabBase as PrinterTabPage; this.printerTabPage = printerTabBase as PrinterTabPage;
this.Printer = printer; this.Printer = printer;
this.InteractionLayer = new InteractionLayer(sceneContext, theme, editorType) this.Object3DControlLayer = new Object3DControlLayer(sceneContext, theme, editorType)
{ {
Name = "InteractionLayer", Name = "Object3DControlLayer",
}; };
this.InteractionLayer.AnchorAll(); this.Object3DControlLayer.AnchorAll();
// Register ourself as an IDrawable // Register ourself as an IDrawable
this.InteractionLayer.RegisterDrawable(this); this.Object3DControlLayer.RegisterDrawable(this);
this.viewControls3D = viewControls3D; this.viewControls3D = viewControls3D;
this.printer = printer; this.printer = printer;
@ -130,9 +130,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.BoundsChanged += UpdateRenderView; this.BoundsChanged += UpdateRenderView;
// TumbleWidget // TumbleWidget
this.InteractionLayer.AddChild(TrackballTumbleWidget); this.Object3DControlLayer.AddChild(TrackballTumbleWidget);
this.InteractionLayer.SetRenderTarget(this); this.Object3DControlLayer.SetRenderTarget(this);
// Add splitter support with the InteractionLayer on the left and resize containers on the right // Add splitter support with the InteractionLayer on the left and resize containers on the right
var splitContainer = new FlowLayoutWidget() var splitContainer = new FlowLayoutWidget()
@ -141,7 +141,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
HAnchor = HAnchor.Stretch, HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Stretch, VAnchor = VAnchor.Stretch,
}; };
splitContainer.AddChild(this.InteractionLayer); splitContainer.AddChild(this.Object3DControlLayer);
this.AddChild(splitContainer); this.AddChild(splitContainer);
Scene.SelectionChanged += Scene_SelectionChanged; Scene.SelectionChanged += Scene_SelectionChanged;
@ -162,7 +162,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Width = UserSettings.Instance.SelectedObjectPanelWidth, Width = UserSettings.Instance.SelectedObjectPanelWidth,
VAnchor = VAnchor.Stretch, VAnchor = VAnchor.Stretch,
HAnchor = HAnchor.Absolute, HAnchor = HAnchor.Absolute,
BackgroundColor = theme.InteractionLayerOverlayColor, BackgroundColor = theme.Object3DControlLayerOverlayColor,
SplitterBarColor = theme.SplitterBackground, SplitterBarColor = theme.SplitterBackground,
SplitterWidth = theme.SplitterWidth, SplitterWidth = theme.SplitterWidth,
MinimumSize = new Vector2(theme.SplitterWidth, 0) MinimumSize = new Vector2(theme.SplitterWidth, 0)
@ -267,7 +267,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
historyAndProperties.Panel2.AddChild(selectedObjectPanel); historyAndProperties.Panel2.AddChild(selectedObjectPanel);
splitContainer.AddChild(modelViewSidePanel); splitContainer.AddChild(modelViewSidePanel);
var tumbleCubeControl = new TumbleCubeControl(this.InteractionLayer, theme) var tumbleCubeControl = new TumbleCubeControl(this.Object3DControlLayer, theme)
{ {
Margin = new BorderDouble(0, 0, 10, 35), Margin = new BorderDouble(0, 0, 10, 35),
VAnchor = VAnchor.Top, VAnchor = VAnchor.Top,
@ -275,7 +275,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Name = "Tumble Cube Control" Name = "Tumble Cube Control"
}; };
this.InteractionLayer.AddChild(tumbleCubeControl); this.Object3DControlLayer.AddChild(tumbleCubeControl);
var viewOptionsBar = new FlowLayoutWidget() var viewOptionsBar = new FlowLayoutWidget()
{ {
@ -285,7 +285,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
BackgroundColor = theme.MinimalShade, BackgroundColor = theme.MinimalShade,
Name = "View Options Bar" Name = "View Options Bar"
}; };
this.InteractionLayer.AddChild(viewOptionsBar); this.Object3DControlLayer.AddChild(viewOptionsBar);
var homeButton = new IconButton(AggContext.StaticData.LoadIcon("fa-home_16.png", 16, 16, theme.InvertIcons), theme) var homeButton = new IconButton(AggContext.StaticData.LoadIcon("fa-home_16.png", 16, 16, theme.InvertIcons), theme)
{ {
@ -297,7 +297,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
viewOptionsBar.AddChild(homeButton); viewOptionsBar.AddChild(homeButton);
#if DEBUG #if DEBUG
var renderOptionsButton = new RenderOptionsButton(theme, this.InteractionLayer) var renderOptionsButton = new RenderOptionsButton(theme, this.Object3DControlLayer)
{ {
ToolTipText = "Model View Style".Localize(), ToolTipText = "Model View Style".Localize(),
PopupMate = new MatePoint() PopupMate = new MatePoint()
@ -333,7 +333,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
ApplicationController.Instance.GetViewOptionButtons(viewOptionsBar, sceneContext, printer, theme); ApplicationController.Instance.GetViewOptionButtons(viewOptionsBar, sceneContext, printer, theme);
// now add the grid snap button // now add the grid snap button
var gridSnapButton = new GridOptionsPanel(InteractionLayer, theme) var gridSnapButton = new GridOptionsPanel(Object3DControlLayer, theme)
{ {
ToolTipText = "Snap Grid".Localize(), ToolTipText = "Snap Grid".Localize(),
PopupMate = new MatePoint() PopupMate = new MatePoint()
@ -346,17 +346,17 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
viewOptionsBar.AddChild(gridSnapButton); viewOptionsBar.AddChild(gridSnapButton);
this.InteractionLayer.RegisterIAVolume(new MoveInZControl(this.InteractionLayer)); this.Object3DControlLayer.RegisterObject3DControl(new MoveInZControl(this.Object3DControlLayer));
this.InteractionLayer.RegisterIAVolume(new SelectionShadow(this.InteractionLayer)); this.Object3DControlLayer.RegisterObject3DControl(new SelectionShadow(this.Object3DControlLayer));
this.InteractionLayer.RegisterIAVolume(new SnappingIndicators(this.InteractionLayer, this.CurrentSelectInfo)); this.Object3DControlLayer.RegisterObject3DControl(new SnappingIndicators(this.Object3DControlLayer, this.CurrentSelectInfo));
// Add IAVolumeProviderPlugins // Add IAVolumeProviderPlugins
foreach (var ivProvider in ApplicationController.Instance.Extensions.IAVolumeProviders) foreach (var ivProvider in ApplicationController.Instance.Extensions.IAVolumeProviders)
{ {
this.InteractionLayer.RegisterIAVolumes(ivProvider.Create(this.InteractionLayer)); this.Object3DControlLayer.RegisterObject3DControls(ivProvider.Create(this.Object3DControlLayer));
} }
this.InteractionLayer.AfterDraw += AfterDraw3DContent; this.Object3DControlLayer.AfterDraw += AfterDraw3DContent;
Scene.SelectFirstChild(); Scene.SelectFirstChild();
@ -670,9 +670,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
printer.ViewState.ViewModeChanged -= this.ViewState_ViewModeChanged; printer.ViewState.ViewModeChanged -= this.ViewState_ViewModeChanged;
} }
if (this.InteractionLayer != null) if (this.Object3DControlLayer != null)
{ {
this.InteractionLayer.AfterDraw -= AfterDraw3DContent; this.Object3DControlLayer.AfterDraw -= AfterDraw3DContent;
} }
base.OnClosed(e); base.OnClosed(e);
@ -700,7 +700,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
} }
// If the mouse is within the MeshViewer process the Drag move // If the mouse is within the MeshViewer process the Drag move
var meshViewerScreenBounds = this.InteractionLayer.TransformToScreenSpace(this.InteractionLayer.LocalBounds); var meshViewerScreenBounds = this.Object3DControlLayer.TransformToScreenSpace(this.Object3DControlLayer.LocalBounds);
if (meshViewerScreenBounds.Contains(screenSpaceMousePosition)) if (meshViewerScreenBounds.Contains(screenSpaceMousePosition))
{ {
// If already started, process drag move // If already started, process drag move
@ -743,7 +743,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
&& selectedItem != null) && selectedItem != null)
{ {
// Move the DropDropObject the target item // Move the DropDropObject the target item
DragSelectedObject(selectedItem, localMousePosition: this.InteractionLayer.TransformFromScreenSpace(screenSpaceMousePosition)); DragSelectedObject(selectedItem, localMousePosition: this.Object3DControlLayer.TransformFromScreenSpace(screenSpaceMousePosition));
} }
} }
@ -767,7 +767,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.SceneReplacement = firstItem as ILibraryAssetStream; this.SceneReplacement = firstItem as ILibraryAssetStream;
// TODO: Figure out a mechanism to disable View3DWidget with dark overlay, displaying something like "Switch to xxx.gcode", make disappear on mouseLeaveBounds and dragfinish // TODO: Figure out a mechanism to disable View3DWidget with dark overlay, displaying something like "Switch to xxx.gcode", make disappear on mouseLeaveBounds and dragfinish
this.InteractionLayer.BackgroundColor = new Color(Color.Black, 200); this.Object3DControlLayer.BackgroundColor = new Color(Color.Black, 200);
return; return;
} }
@ -813,7 +813,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
if (this.DragOperationActive) if (this.DragOperationActive)
{ {
this.InteractionLayer.BackgroundColor = Color.Transparent; this.Object3DControlLayer.BackgroundColor = Color.Transparent;
this.DragOperationActive = false; this.DragOperationActive = false;
if (mouseUpInBounds) if (mouseUpInBounds)
@ -869,7 +869,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (selectedItem != null) if (selectedItem != null)
{ {
foreach (var volume in this.InteractionLayer.InteractionVolumes) foreach (var volume in this.Object3DControlLayer.Object3DControls)
{ {
volume.SetPosition(selectedItem); volume.SetPosition(selectedItem);
} }
@ -917,7 +917,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
} }
else else
{ {
InteractionLayer.RenderBounds(e, sceneContext.World, allResults); Object3DControlLayer.RenderBounds(e, sceneContext.World, allResults);
} }
} }
} }
@ -1032,7 +1032,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (mouseEvent.Button == MouseButtons.Right || if (mouseEvent.Button == MouseButtons.Right ||
mouseEvent.Button == MouseButtons.Middle) mouseEvent.Button == MouseButtons.Middle)
{ {
this.InteractionLayer.SuppressUiVolumes = true; this.Object3DControlLayer.SuppressUiVolumes = true;
} }
base.OnMouseDown(mouseEvent); base.OnMouseDown(mouseEvent);
@ -1048,9 +1048,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
&& ModifierKeys != Keys.Control && ModifierKeys != Keys.Control
&& ModifierKeys != Keys.Alt)) && ModifierKeys != Keys.Alt))
{ {
if (!this.InteractionLayer.MouseDownOnInteractionVolume) if (!this.Object3DControlLayer.MouseDownOnObject3DControlVolume)
{ {
this.InteractionLayer.SuppressUiVolumes = true; this.Object3DControlLayer.SuppressUiVolumes = true;
var info = new IntersectInfo(); var info = new IntersectInfo();
@ -1250,8 +1250,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{ {
DragSelectionEndPosition = mouseEvent.Position - OffsetToMeshViewerWidget(); DragSelectionEndPosition = mouseEvent.Position - OffsetToMeshViewerWidget();
DragSelectionEndPosition = new Vector2( DragSelectionEndPosition = new Vector2(
Math.Max(Math.Min((double)DragSelectionEndPosition.X, this.InteractionLayer.LocalBounds.Right), this.InteractionLayer.LocalBounds.Left), Math.Max(Math.Min((double)DragSelectionEndPosition.X, this.Object3DControlLayer.LocalBounds.Right), this.Object3DControlLayer.LocalBounds.Left),
Math.Max(Math.Min((double)DragSelectionEndPosition.Y, this.InteractionLayer.LocalBounds.Top), this.InteractionLayer.LocalBounds.Bottom)); Math.Max(Math.Min((double)DragSelectionEndPosition.Y, this.Object3DControlLayer.LocalBounds.Top), this.Object3DControlLayer.LocalBounds.Bottom));
Invalidate(); Invalidate();
} }
@ -1261,7 +1261,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public IntersectInfo GetIntersectPosition(Vector2 screenSpacePosition) public IntersectInfo GetIntersectPosition(Vector2 screenSpacePosition)
{ {
// Translate to local // Translate to local
Vector2 localPosition = this.InteractionLayer.TransformFromScreenSpace(screenSpacePosition); Vector2 localPosition = this.Object3DControlLayer.TransformFromScreenSpace(screenSpacePosition);
Ray ray = sceneContext.World.GetRayForLocalBounds(localPosition); Ray ray = sceneContext.World.GetRayForLocalBounds(localPosition);
@ -1279,7 +1279,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
return; return;
} }
Vector2 meshViewerWidgetScreenPosition = this.InteractionLayer.TransformFromParentSpace(this, localMousePosition); Vector2 meshViewerWidgetScreenPosition = this.Object3DControlLayer.TransformFromParentSpace(this, localMousePosition);
Ray ray = sceneContext.World.GetRayForLocalBounds(meshViewerWidgetScreenPosition); Ray ray = sceneContext.World.GetRayForLocalBounds(meshViewerWidgetScreenPosition);
IntersectInfo info = CurrentSelectInfo.HitPlane.GetClosestIntersection(ray); IntersectInfo info = CurrentSelectInfo.HitPlane.GetClosestIntersection(ray);
@ -1298,7 +1298,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Vector3 delta = info.HitPosition - CurrentSelectInfo.PlaneDownHitPos; Vector3 delta = info.HitPosition - CurrentSelectInfo.PlaneDownHitPos;
double snapGridDistance = this.InteractionLayer.SnapGridDistance; double snapGridDistance = this.Object3DControlLayer.SnapGridDistance;
if (snapGridDistance > 0) if (snapGridDistance > 0)
{ {
// snap this position to the grid // snap this position to the grid
@ -1360,7 +1360,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Vector2 OffsetToMeshViewerWidget() Vector2 OffsetToMeshViewerWidget()
{ {
List<GuiWidget> parents = new List<GuiWidget>(); List<GuiWidget> parents = new List<GuiWidget>();
GuiWidget parent = this.InteractionLayer.Parent; GuiWidget parent = this.Object3DControlLayer.Parent;
while (parent != this) while (parent != this)
{ {
parents.Add(parent); parents.Add(parent);
@ -1412,7 +1412,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
} }
} }
this.InteractionLayer.SuppressUiVolumes = false; this.Object3DControlLayer.SuppressUiVolumes = false;
CurrentSelectInfo.DownOnPart = false; CurrentSelectInfo.DownOnPart = false;
@ -1685,7 +1685,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
protected IObject3D FindHitObject3D(Vector2 screenPosition, ref IntersectInfo intersectionInfo) protected IObject3D FindHitObject3D(Vector2 screenPosition, ref IntersectInfo intersectionInfo)
{ {
Vector2 meshViewerWidgetScreenPosition = this.InteractionLayer.TransformFromParentSpace(this, screenPosition); Vector2 meshViewerWidgetScreenPosition = this.Object3DControlLayer.TransformFromParentSpace(this, screenPosition);
Ray ray = sceneContext.World.GetRayForLocalBounds(meshViewerWidgetScreenPosition); Ray ray = sceneContext.World.GetRayForLocalBounds(meshViewerWidgetScreenPosition);
intersectionInfo = Scene.GetBVHData().GetClosestIntersection(ray); intersectionInfo = Scene.GetBVHData().GetClosestIntersection(ray);

View file

@ -107,7 +107,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.undoBuffer = undoBuffer; this.undoBuffer = undoBuffer;
this.ActionArea.Click += (s, e) => this.ActionArea.Click += (s, e) =>
{ {
view3DWidget.InteractionLayer.Focus(); view3DWidget.Object3DControlLayer.Focus();
}; };
this.OverflowButton.DynamicPopupContent = () => this.OverflowButton.DynamicPopupContent = () =>
@ -189,7 +189,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
undoButton.Click += (sender, e) => undoButton.Click += (sender, e) =>
{ {
sceneContext.Scene.Undo(); sceneContext.Scene.Undo();
view3DWidget.InteractionLayer.Focus(); view3DWidget.Object3DControlLayer.Focus();
}; };
this.AddChild(undoButton); this.AddChild(undoButton);
@ -204,7 +204,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
redoButton.Click += (sender, e) => redoButton.Click += (sender, e) =>
{ {
sceneContext.Scene.Redo(); sceneContext.Scene.Redo();
view3DWidget.InteractionLayer.Focus(); view3DWidget.Object3DControlLayer.Focus();
}; };
this.AddChild(redoButton); this.AddChild(redoButton);
@ -418,7 +418,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
namedAction.Action.Invoke(sceneContext); namedAction.Action.Invoke(sceneContext);
var partTab = button.Parents<PartTabPage>().FirstOrDefault(); var partTab = button.Parents<PartTabPage>().FirstOrDefault();
var view3D = partTab.Descendants<View3DWidget>().FirstOrDefault(); var view3D = partTab.Descendants<View3DWidget>().FirstOrDefault();
view3D.InteractionLayer.Focus(); view3D.Object3DControlLayer.Focus();
}); });
} }

View file

@ -44,7 +44,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
TextColor = canChangeComPort ? theme.TextColor : new Color(theme.TextColor, 150), TextColor = canChangeComPort ? theme.TextColor : new Color(theme.TextColor, 150),
}; };
//Create default option // Create default option
MenuItem defaultOption = dropdownList.AddItem("Manual", "127.0.0.1:23"); MenuItem defaultOption = dropdownList.AddItem("Manual", "127.0.0.1:23");
defaultOption.Selected += (sender, e) => defaultOption.Selected += (sender, e) =>
{ {
@ -59,6 +59,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
dropdownList.TextColor = theme.TextColor; dropdownList.TextColor = theme.TextColor;
dropdownList.Enabled = canChangeComPort; dropdownList.Enabled = canChangeComPort;
} }
printer.Connection.CommunicationStateChanged += CommunicationStateChanged; printer.Connection.CommunicationStateChanged += CommunicationStateChanged;
dropdownList.Closed += (s, e) => printer.Connection.CommunicationStateChanged -= CommunicationStateChanged; dropdownList.Closed += (s, e) => printer.Connection.CommunicationStateChanged -= CommunicationStateChanged;
@ -90,24 +91,24 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
MenuItem defaultOption = dropdownList.AddItem("Manual", "127.0.0.1:23"); MenuItem defaultOption = dropdownList.AddItem("Manual", "127.0.0.1:23");
defaultOption.Selected += (sender, e) => defaultOption.Selected += (sender, e) =>
{ {
printer.Settings.SetValue(SettingsKey.selector_ip_address,defaultOption.Text); printer.Settings.SetValue(SettingsKey.selector_ip_address, defaultOption.Text);
}; };
foreach (Zeroconf.IZeroconfHost host in possibleHosts) foreach (Zeroconf.IZeroconfHost host in possibleHosts)
{ {
// Add each found telnet host to the dropdown list // Add each found telnet host to the dropdown list
IService service; IService service;
bool exists = host.Services.TryGetValue("_telnet._tcp.local.", out service); bool exists = host.Services.TryGetValue("_telnet._tcp.local.", out service);
int port = exists ? service.Port:23; int port = exists ? service.Port : 23;
MenuItem newItem = dropdownList.AddItem(host.DisplayName, $"{host.IPAddress}:{port}"); //The port may be unnecessary MenuItem newItem = dropdownList.AddItem(host.DisplayName, $"{host.IPAddress}:{port}"); // The port may be unnecessary
// When the given menu item is selected, save its value back into settings // When the given menu item is selected, save its value back into settings
newItem.Selected += (sender, e) => newItem.Selected += (sender, e) =>
{ {
if (sender is MenuItem menuItem) if (sender is MenuItem menuItem)
{ {
//this.SetValue( // this.SetValue(
// menuItem.Text, // menuItem.Text,
// userInitiated: true); // userInitiated: true);
string[] ipAndPort = menuItem.Value.Split(':'); string[] ipAndPort = menuItem.Value.Split(':');
printer.Settings.SetValue(SettingsKey.ip_address, ipAndPort[0]); printer.Settings.SetValue(SettingsKey.ip_address, ipAndPort[0]);
printer.Settings.SetValue(SettingsKey.ip_port, ipAndPort[1]); printer.Settings.SetValue(SettingsKey.ip_port, ipAndPort[1]);
@ -115,6 +116,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
} }
}; };
} }
refreshButton.Enabled = true; refreshButton.Enabled = true;
} }

View file

@ -20,7 +20,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
// Get View3DWidget // Get View3DWidget
View3DWidget view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget; View3DWidget view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget;
var scene = view3D.InteractionLayer.Scene; var scene = view3D.Object3DControlLayer.Scene;
testRunner.WaitForName("Calibration - Box.stl"); testRunner.WaitForName("Calibration - Box.stl");
Assert.AreEqual(1, scene.Children.Count, "Should have 1 part before copy"); Assert.AreEqual(1, scene.Children.Count, "Should have 1 part before copy");
@ -53,7 +53,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
// Get View3DWidget and count Scene.Children before Copy button is clicked // Get View3DWidget and count Scene.Children before Copy button is clicked
View3DWidget view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget; View3DWidget view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget;
var scene = view3D.InteractionLayer.Scene; var scene = view3D.Object3DControlLayer.Scene;
// Assert expected start count // Assert expected start count
Assert.AreEqual(1, scene.Children.Count, "Should have one part before copy"); Assert.AreEqual(1, scene.Children.Count, "Should have one part before copy");
@ -99,7 +99,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
testRunner.AddItemToBedplate(); testRunner.AddItemToBedplate();
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget; var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
var scene = view3D.InteractionLayer.Scene; var scene = view3D.Object3DControlLayer.Scene;
testRunner.Select3DPart("Calibration - Box.stl"); testRunner.Select3DPart("Calibration - Box.stl");

View file

@ -170,16 +170,16 @@ namespace MatterHackers.MatterControl.Tests.Automation
testRunner.AddTestAssetsToLibrary(new[] { "Batman.stl" }); testRunner.AddTestAssetsToLibrary(new[] { "Batman.stl" });
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget; var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
var scene = view3D.InteractionLayer.Scene; var scene = view3D.Object3DControlLayer.Scene;
Assert.AreEqual(0, scene.Children.Count, "The scene should have zero items before drag/drop"); Assert.AreEqual(0, scene.Children.Count, "The scene should have zero items before drag/drop");
testRunner.DragDropByName("Row Item Batman", "InteractionLayer"); testRunner.DragDropByName("Row Item Batman", "Object3DControlLayer");
Assert.AreEqual(1, scene.Children.Count, "The scene should have one item after drag/drop"); Assert.AreEqual(1, scene.Children.Count, "The scene should have one item after drag/drop");
testRunner.Delay(.2); testRunner.Delay(.2);
testRunner.DragDropByName("Row Item Batman", "InteractionLayer"); testRunner.DragDropByName("Row Item Batman", "Object3DControlLayer");
Assert.AreEqual(2, scene.Children.Count, "The scene should have two items after drag/drop"); Assert.AreEqual(2, scene.Children.Count, "The scene should have two items after drag/drop");
return Task.CompletedTask; return Task.CompletedTask;

View file

@ -60,7 +60,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
printer.Settings.SetValue(SettingsKey.enable_line_splitting, "0"); printer.Settings.SetValue(SettingsKey.enable_line_splitting, "0");
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget; var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
var scene = view3D.InteractionLayer.Scene; var scene = view3D.Object3DControlLayer.Scene;
// Add a callback to check that every line has an extruder // Add a callback to check that every line has an extruder
// distance greater than the largest distance minus the max retraction // distance greater than the largest distance minus the max retraction

View file

@ -18,7 +18,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
testRunner.AddItemToBedplate(); testRunner.AddItemToBedplate();
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget; var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
var scene = view3D.InteractionLayer.Scene; var scene = view3D.Object3DControlLayer.Scene;
testRunner.WaitFor(() => scene.SelectedItem != null); testRunner.WaitFor(() => scene.SelectedItem != null);
Assert.IsNotNull(scene.SelectedItem, "Expect part selection after Add to Bed action"); Assert.IsNotNull(scene.SelectedItem, "Expect part selection after Add to Bed action");

View file

@ -224,7 +224,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
testRunner.ClickByName("3D View Edit"); testRunner.ClickByName("3D View Edit");
} }
testRunner.DragDropByName("InteractionLayer", "InteractionLayer", offsetDrop: new Agg.Point2D(10, 15), mouseButtons: MouseButtons.Right); testRunner.DragDropByName("Object3DControlLayer", "Object3DControlLayer", offsetDrop: new Agg.Point2D(10, 15), mouseButtons: MouseButtons.Right);
testRunner.Delay(1); testRunner.Delay(1);
testRunner.ClickByName(partNameToSelect); testRunner.ClickByName(partNameToSelect);
@ -701,7 +701,7 @@ namespace MatterHackers.MatterControl.Tests.Automation
testRunner.ClickByName("Print Library Overflow Menu"); testRunner.ClickByName("Print Library Overflow Menu");
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget; var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
var scene = view3D.InteractionLayer.Scene; var scene = view3D.Object3DControlLayer.Scene;
var preAddCount = scene.Children.Count(); var preAddCount = scene.Children.Count();
testRunner.ClickByName("Add to Bed Menu Item"); testRunner.ClickByName("Add to Bed Menu Item");