Improving subtract object rendering

This commit is contained in:
Lars Brubaker 2019-02-13 10:26:02 -08:00
parent 76c4985111
commit ac03a4fcfd
16 changed files with 116 additions and 105 deletions

View file

@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project.
*/
using System.Collections.Generic;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl.PartPreviewWindow;
@ -35,6 +36,6 @@ namespace MatterHackers.MatterControl.DesignTools
{
public interface IEditorDraw
{
void DrawEditor(object sender, DrawEventArgs e);
void DrawEditor(InteractionLayer interactionLayer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw);
}
}

View file

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

View file

@ -33,6 +33,7 @@ either expressed or implied, of the FreeBSD Project.
/*********************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
@ -241,10 +242,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
ScaleItem.Matrix = Object3DExtensions.ApplyAtPosition(ScaleItem.Matrix, aabb.Center, Matrix4X4.CreateScale(scale));
}
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
if (sender is InteractionLayer layer
&& layer.Scene.SelectedItem != null
if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
{
var aabb = ItemToScale.GetAxisAlignedBoundingBox();

View file

@ -35,6 +35,7 @@ using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.MeshVisualizer;
using MatterHackers.VectorMath;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
@ -132,10 +133,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
});
}
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
if (sender is InteractionLayer layer
&& layer.Scene.SelectedItem != null
if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
{
layer.World.RenderDirectionAxis(Axis, this.WorldMatrix(), 30);

View file

@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
@ -69,10 +70,9 @@ namespace MatterHackers.MatterControl.DesignTools
[Description("Where to start the bend as a percent of the width of the part")]
public double StartPercent { get; set; } = 50;
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
if (sender is InteractionLayer layer
&& layer.Scene.SelectedItem != null
if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
{
// we want to measure the

View file

@ -36,6 +36,7 @@ using MatterHackers.MeshVisualizer;
using MatterHackers.PolygonMesh;
using MatterHackers.VectorMath;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
@ -145,10 +146,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
return fitToBounds;
}
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
if (sender is InteractionLayer layer
&& layer.Scene.SelectedItem != null
if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
{
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();

View file

@ -113,10 +113,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
return fitToBounds;
}
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
if (sender is InteractionLayer layer
&& layer.Scene.SelectedItem != null
if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
{
var aabb = UntransformedChildren.GetAxisAlignedBoundingBox();

View file

@ -45,6 +45,7 @@ namespace MatterHackers.MatterControl.DesignTools
{
using MatterHackers.Agg.Image.ThresholdFunctions;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.RenderOpenGl.OpenGl;
using MatterHackers.VectorMath;
using System.ComponentModel.DataAnnotations;
@ -240,7 +241,7 @@ namespace MatterHackers.MatterControl.DesignTools
}
}
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
ImageToPathObject3D.DrawPath(this);
}

View file

@ -38,6 +38,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
{
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters2D;
using MatterHackers.MatterControl.PartPreviewWindow;
using Newtonsoft.Json;
using System;
using System.ComponentModel;
@ -103,7 +104,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
VertexSource = path.VertexSource.Offset(Inflate);
}
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
ImageToPathObject3D.DrawPath(this);
}

View file

@ -38,6 +38,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
{
using MatterHackers.Agg.VertexSource;
using MatterHackers.DataConverters2D;
using MatterHackers.MatterControl.PartPreviewWindow;
using Newtonsoft.Json;
using System;
using System.Linq;
@ -160,7 +161,7 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
VertexSource = outputPolygons.CreateVertexStorage();
}
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
ImageToPathObject3D.DrawPath(this);
}

View file

@ -101,10 +101,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
}
}
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
if (sender is InteractionLayer layer
&& layer.Scene.SelectedItem != null
if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
{
layer.World.RenderDirectionAxis(RotateAbout, this.WorldMatrix(), 30);

View file

@ -175,10 +175,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
#endregion // editable properties
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
if (sender is InteractionLayer layer
&& layer.Scene.SelectedItem != null
if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
{
layer.World.RenderAxis(ScaleAbout, this.WorldMatrix(), 30, 1);

View file

@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using MatterHackers.Agg.Font;
@ -38,6 +39,7 @@ using MatterHackers.DataConverters3D;
using MatterHackers.DataConverters3D.UndoCommands;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.PolygonMesh;
using MatterHackers.VectorMath;
using Newtonsoft.Json;
@ -177,7 +179,7 @@ namespace MatterHackers.MatterControl.DesignTools
return null;
}
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
ImageToPathObject3D.DrawPath(this);
}

View file

@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -52,10 +53,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
public SelectedChildren SelectedChildren { get; set; } = new SelectedChildren();
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
if (sender is InteractionLayer layer
&& layer.Scene.SelectedItem != null
if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
{
// draw the component objects
@ -143,47 +143,34 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
ProgressStatus progressStatus = new ProgressStatus();
progressStatus.Status = "Do CSG";
foreach (var paint in paintObjects)
foreach (var keep in keepObjects)
{
Mesh paintMesh = null;
var paintWorldMatrix = paint.WorldMatrix(SourceContainer);
var keepResultsMesh = keep.Mesh;
var keepWorldMatrix = keep.WorldMatrix(SourceContainer);
foreach (var keep in keepObjects)
foreach (var paint in paintObjects)
{
var keepResultsMesh = keep.Mesh;
var intersect = BooleanProcessing.Do(keepResultsMesh, keep.WorldMatrix(SourceContainer),
paint.Mesh, paintWorldMatrix,
Mesh paintMesh = BooleanProcessing.Do(keepResultsMesh, keepWorldMatrix,
paint.Mesh, paint.WorldMatrix(SourceContainer),
2, reporter, amountPerOperation, percentCompleted, progressStatus, cancellationToken);
keepResultsMesh = BooleanProcessing.Do(keepResultsMesh, keep.WorldMatrix(SourceContainer),
paint.Mesh, paintWorldMatrix,
keepResultsMesh = BooleanProcessing.Do(keepResultsMesh, keepWorldMatrix,
paint.Mesh, paint.WorldMatrix(SourceContainer),
1, reporter, amountPerOperation, percentCompleted, progressStatus, cancellationToken);
// after the first time we get a result the results mesh is in the right coordinate space
paintWorldMatrix = Matrix4X4.Identity;
keepWorldMatrix = Matrix4X4.Identity;
// keep all the intersections together
if (paintMesh == null)
// store our intersection (paint) results mesh
var paintResultsItem = new Object3D()
{
paintMesh = intersect;
}
else // union into the current paint
{
paintMesh = BooleanProcessing.Do(paintMesh, Matrix4X4.Identity,
intersect, Matrix4X4.Identity, 0, reporter, amountPerOperation, percentCompleted, progressStatus, cancellationToken);
}
// store our results mesh
var keepResultsItem = new Object3D()
{
Mesh = keepResultsMesh,
Mesh = paintMesh,
Visible = false
};
// copy all the properties but the matrix
keepResultsItem.CopyProperties(keep, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible)));
paintResultsItem.CopyProperties(paint, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible)));
// and add it to this
this.Children.Add(keepResultsItem);
this.Children.Add(paintResultsItem);
// report our progress
percentCompleted += amountPerOperation;
@ -192,15 +179,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
}
// store our results mesh
var paintResultsItem = new Object3D()
var keepResultsItem = new Object3D()
{
Mesh = paintMesh,
Mesh = keepResultsMesh,
Visible = false
};
// copy all the properties but the matrix
paintResultsItem.CopyProperties(paint, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible)));
keepResultsItem.CopyProperties(keep, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible)));
// and add it to this
this.Children.Add(paintResultsItem);
this.Children.Add(keepResultsItem);
}
foreach (var child in Children)

View file

@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -52,12 +53,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
public SelectedChildren SelectedChildren { get; set; } = new SelectedChildren();
public void DrawEditor(object sender, DrawEventArgs e)
public void DrawEditor(InteractionLayer layer, List<Object3DView> transparentMeshes, DrawEventArgs e, ref bool suppressNormalDraw)
{
if (sender is InteractionLayer layer
&& layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem.DescendantsAndSelf().Where((i) => i == this).Any())
if (layer.Scene.SelectedItem != null
&& layer.Scene.SelectedItem == this)
{
suppressNormalDraw = true;
var removeObjects = this.SourceContainer.VisibleMeshes()
.Where((i) => SelectedChildren.Contains(i.Name)).ToList();
var keepObjects = this.SourceContainer.VisibleMeshes()
@ -65,22 +67,28 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
foreach (var item in removeObjects)
{
GLHelper.Render(item.Mesh,
Color.Transparent,
item.WorldMatrix(),
RenderTypes.Outlines,
item.WorldMatrix() * layer.World.ModelviewMatrix,
Color.Red);
transparentMeshes.Add(new Object3DView(item, new Color(item.WorldColor(SourceContainer), 128)));
}
foreach (var item in keepObjects)
{
GLHelper.Render(item.Mesh,
Color.Transparent,
item.WorldMatrix(),
RenderTypes.Outlines,
item.WorldMatrix() * layer.World.ModelviewMatrix,
Color.Green);
var subtractChild = this.Children.Where(i => i.Name == item.Name).FirstOrDefault();
if (subtractChild != null)
{
GLHelper.Render(subtractChild.Mesh,
subtractChild.Color,
subtractChild.WorldMatrix(),
RenderTypes.Outlines,
subtractChild.WorldMatrix() * layer.World.ModelviewMatrix);
}
else
{
GLHelper.Render(item.Mesh,
item.WorldColor(SourceContainer),
item.WorldMatrix(),
RenderTypes.Outlines,
item.WorldMatrix() * layer.World.ModelviewMatrix);
}
}
}
}
@ -204,11 +212,20 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
this.Children.Add(resultsItem);
}
bool first = true;
foreach (var child in Children)
{
child.Visible = true;
if (first)
{
// hid the source item
child.Visible = false;
first = false;
}
else
{
child.Visible = true;
}
}
SourceContainer.Visible = false;
}
}
}

View file

@ -391,19 +391,26 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// Draw solid objects, extract transparent
var transparentMeshes = new List<Object3DView>();
foreach (var object3D in scene.Children)
{
if (object3D.Visible)
{
DrawObject(object3D, transparentMeshes, e);
}
var selectedItem = scene.SelectedItem;
bool suppressNormalDraw = false;
if (selectedItem != null)
{
// Invoke existing IEditorDraw when iterating items
if (object3D is IEditorDraw editorDraw)
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, e);
editorDraw.DrawEditor(this, transparentMeshes, e, ref suppressNormalDraw);
}
}
foreach (var item in scene.Children)
{
if (item.Visible
&& (item != selectedItem || suppressNormalDraw == false))
{
DrawObject(item, transparentMeshes, e);
}
}
@ -462,8 +469,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
GLHelper.UnsetGlContext();
var selectedItem = scene.SelectedItem;
// Invoke DrawStage.Last item drawables
foreach (var item in scene.Children)
{
@ -520,24 +525,24 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
WireframeAndSolid,
None
}
}
private class Object3DView
public class Object3DView
{
public Color Color { get; set; }
public IObject3D Object3D { get; }
public Object3DView(IObject3D source, Color color)
{
public Color Color { get; set; }
this.Object3D = source;
this.Color = color;
public IObject3D Object3D { get; }
public Object3DView(IObject3D source, Color color)
if (source is Object3D object3D
&& color != source.Color
&& color.alpha != 255)
{
this.Object3D = source;
this.Color = color;
if (source is Object3D object3D
&& color != source.Color
&& color.alpha != 255)
{
object3D.EnsureTransparentSorting();
}
object3D.EnsureTransparentSorting();
}
}
}