refactoring
This commit is contained in:
parent
cf6b02c8eb
commit
aec26a2292
12 changed files with 356 additions and 226 deletions
|
|
@ -1,41 +1,21 @@
|
|||
/*
|
||||
Copyright (c) 2018, Lars Brubaker, John Lewin
|
||||
Copyright (c) Ryan Schmidt (rms@gradientspace.com) - All Rights Reserved
|
||||
Distributed under the Boost Software License, Version 1.0. http://www.boost.org/LICENSE_1_0.txt
|
||||
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 System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using g3;
|
||||
using gs;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.DesignTools.Operations;
|
||||
using MatterHackers.PolygonMesh;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static gs.MeshAutoRepair;
|
||||
|
||||
namespace MatterHackers.MatterControl.DesignTools
|
||||
{
|
||||
|
|
@ -46,9 +26,19 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
Name = "Repair".Localize();
|
||||
}
|
||||
|
||||
[Description("Ensure that each reduced point is on the surface of the original mesh. This is not normally required and slows the computation significantly.")]
|
||||
[Description("Make all the faces have a consistent orientation.")]
|
||||
public bool FaceOrientation { get; set; } = true;
|
||||
|
||||
[Description("Repair any small cracks or bad seams in the model.")]
|
||||
public bool WeldEdges { get; set; } = true;
|
||||
|
||||
[Description("Try to fill in any holes that are in the model.")]
|
||||
public bool FillHoles { get; set; } = true;
|
||||
|
||||
|
||||
[Description("Remove interior faces and bodies.")]
|
||||
public RemoveModes RemoveMode { get; set; } = RemoveModes.None;
|
||||
|
||||
public override Task Rebuild()
|
||||
{
|
||||
this.DebugDepth("Rebuild");
|
||||
|
|
@ -94,103 +84,93 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
}
|
||||
|
||||
public Mesh Repair(Mesh inMesh, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var mesh = inMesh.ToDMesh3();
|
||||
if (FaceOrientation)
|
||||
{
|
||||
var repaired = new MeshRepairOrientation(mesh);
|
||||
repaired.OrientComponents();
|
||||
mesh = repaired.Mesh;
|
||||
}
|
||||
|
||||
{
|
||||
int repeat_count = 0;
|
||||
int repeatCount = 0;
|
||||
int erosionIterations = 5;
|
||||
double repairTolerance = MathUtil.ZeroTolerancef;
|
||||
double minEdgeLengthTol = 0.0001;
|
||||
|
||||
repeat_all:
|
||||
// Remove parts of the mesh we don't want before we bother with anything else
|
||||
// TODO: maybe we need to repair orientation first? if we want to use MWN...
|
||||
do_remove_inside(mesh);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
}
|
||||
|
||||
if (FaceOrientation)
|
||||
{
|
||||
// make sure orientation of connected components is consistent
|
||||
// TODO: what about mobius strip problems?
|
||||
repair_orientation(mesh, cancellationToken, false);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
RepairOrientation(mesh, cancellationToken, true);
|
||||
}
|
||||
|
||||
if (RemoveMode != RemoveModes.None)
|
||||
{
|
||||
// Remove parts of the mesh we don't want before we bother with anything else
|
||||
// TODO: maybe we need to repair orientation first? if we want to use MWN (MeshWindingNumber)...
|
||||
RremoveInside(mesh);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
if (WeldEdges || FillHoles)
|
||||
{
|
||||
// Do safe close-cracks to handle easy cases
|
||||
repair_cracks(true, RepairTolerance);
|
||||
RepairCracks(mesh, true, repairTolerance);
|
||||
|
||||
if (Mesh.IsClosed()) goto all_done;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
if (mesh.IsClosed())
|
||||
{
|
||||
return inMesh;
|
||||
goto all_done;
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Collapse tiny edges and then try easy cases again, and
|
||||
// then allow for handling of ambiguous cases
|
||||
collapse_all_degenerate_edges(RepairTolerance * 0.5, true);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
}
|
||||
CollapseAllDegenerateEdges(mesh, cancellationToken, repairTolerance * 0.5, true);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
repair_cracks(true, 2 * RepairTolerance);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
}
|
||||
RepairCracks(mesh, true, 2 * repairTolerance);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
repair_cracks(false, 2 * RepairTolerance);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
}
|
||||
RepairCracks(mesh, false, 2 * repairTolerance);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (Mesh.IsClosed()) goto all_done;
|
||||
if (mesh.IsClosed())
|
||||
{
|
||||
goto all_done;
|
||||
}
|
||||
|
||||
// Possibly we have joined regions with different orientation (is it?), fix that
|
||||
// TODO: mobius strips again
|
||||
repair_orientation(false);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
}
|
||||
|
||||
RepairOrientation(mesh, cancellationToken, true);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// get rid of any remaining single-triangles before we start filling holes
|
||||
remove_loners();
|
||||
|
||||
// Ok, fill simple holes.
|
||||
int nRemainingBowties = 0;
|
||||
int nHoles; bool bSawSpans;
|
||||
fill_trivial_holes(out nHoles, out bSawSpans);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
MeshEditor.RemoveIsolatedTriangles(mesh);
|
||||
}
|
||||
|
||||
if (Mesh.IsClosed()) goto all_done;
|
||||
if (FillHoles)
|
||||
{
|
||||
// Ok, fill simple holes.
|
||||
int nRemainingBowties = 0;
|
||||
FillTrivialHoles(mesh, cancellationToken, out int nHoles, out bool bSawSpans);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (mesh.IsClosed())
|
||||
{
|
||||
goto all_done;
|
||||
}
|
||||
|
||||
// Now fill harder holes. If we saw spans, that means boundary loops could
|
||||
// not be resolved in some cases, do we disconnect bowties and try again.
|
||||
fill_any_holes(out nHoles, out bSawSpans);
|
||||
if (Cancelled()) return false;
|
||||
FillAnyHoles(mesh, cancellationToken, out nHoles, out bSawSpans);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (bSawSpans)
|
||||
{
|
||||
disconnect_bowties(out nRemainingBowties);
|
||||
fill_any_holes(out nHoles, out bSawSpans);
|
||||
DisconnectBowties(mesh, out nRemainingBowties);
|
||||
FillAnyHoles(mesh, cancellationToken, out nHoles, out bSawSpans);
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
}
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (mesh.IsClosed())
|
||||
{
|
||||
|
|
@ -199,106 +179,57 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
|
||||
// We may have a closed mesh now but it might still have bowties (eg
|
||||
// tetrahedra sharing vtx case). So disconnect those.
|
||||
disconnect_bowties(out nRemainingBowties);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
}
|
||||
DisconnectBowties(mesh, out nRemainingBowties);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// If the mesh is not closed, we will do one more round to try again.
|
||||
if (repeat_count == 0 && mesh.IsClosed() == false)
|
||||
if (repeatCount == 0 && mesh.IsClosed() == false)
|
||||
{
|
||||
repeat_count++;
|
||||
repeatCount++;
|
||||
goto repeat_all;
|
||||
}
|
||||
|
||||
// Ok, we didn't get anywhere on our first repeat. If we are still not
|
||||
// closed, we will try deleting boundary triangles and repeating.
|
||||
//* Repeat this N times.
|
||||
if (repeat_count <= ErosionIterations && Mesh.IsClosed() == false)
|
||||
// Repeat this N times.
|
||||
if (repeatCount <= erosionIterations && mesh.IsClosed() == false)
|
||||
{
|
||||
repeat_count++;
|
||||
MeshFaceSelection bdry_faces = new MeshFaceSelection(Mesh);
|
||||
foreach (int eid in MeshIterators.BoundaryEdges(Mesh))
|
||||
repeatCount++;
|
||||
var bdry_faces = new MeshFaceSelection(mesh);
|
||||
foreach (int eid in MeshIterators.BoundaryEdges(mesh))
|
||||
{
|
||||
bdry_faces.SelectEdgeTris(eid);
|
||||
}
|
||||
|
||||
MeshEditor.RemoveTriangles(Mesh, bdry_faces, true);
|
||||
MeshEditor.RemoveTriangles(mesh, bdry_faces, true);
|
||||
goto repeat_all;
|
||||
}
|
||||
}
|
||||
|
||||
all_done:
|
||||
// Remove tiny edges
|
||||
if (MinEdgeLengthTol > 0)
|
||||
|
||||
// and do a final clean up of the model
|
||||
if (FillHoles)
|
||||
{
|
||||
collapse_all_degenerate_edges(MinEdgeLengthTol, false);
|
||||
// Remove tiny edges
|
||||
if (minEdgeLengthTol > 0)
|
||||
{
|
||||
CollapseAllDegenerateEdges(mesh, cancellationToken, minEdgeLengthTol, false);
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
}
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// finally do global orientation
|
||||
repair_orientation(mesh, cancellationToken, true);
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return inMesh;
|
||||
}
|
||||
RepairOrientation(mesh, cancellationToken, true);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
return mesh.ToMesh();
|
||||
}
|
||||
|
||||
void repair_orientation(DMesh3 Mesh, CancellationToken cancellationToken, bool bGlobal)
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
MeshRepairOrientation orient = new MeshRepairOrientation(Mesh);
|
||||
orient.OrientComponents();
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
return inMesh;
|
||||
}
|
||||
|
||||
if (bGlobal)
|
||||
{
|
||||
orient.SolveGlobalOrientation();
|
||||
}
|
||||
}
|
||||
|
||||
bool remove_interior(DMesh3 Mesh, out int nRemoved)
|
||||
{
|
||||
RemoveOccludedTriangles remove = new RemoveOccludedTriangles(Mesh);
|
||||
remove.PerVertex = true;
|
||||
remove.InsideMode = RemoveOccludedTriangles.CalculationMode.FastWindingNumber;
|
||||
remove.Apply();
|
||||
nRemoved = remove.RemovedT.Count();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool remove_occluded(DMesh3 Mesh, out int nRemoved)
|
||||
{
|
||||
RemoveOccludedTriangles remove = new RemoveOccludedTriangles(Mesh);
|
||||
remove.PerVertex = true;
|
||||
remove.InsideMode = RemoveOccludedTriangles.CalculationMode.SimpleOcclusionTest;
|
||||
remove.Apply();
|
||||
nRemoved = remove.RemovedT.Count();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool do_remove_inside(DMesh3 Mesh)
|
||||
{
|
||||
int nRemoved = 0;
|
||||
if (RemoveMode == RemoveModes.Interior)
|
||||
{
|
||||
return remove_interior(Mesh, out nRemoved);
|
||||
}
|
||||
else if (RemoveMode == RemoveModes.Occluded)
|
||||
{
|
||||
return remove_occluded(Mesh, out nRemoved);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateControls(PublicPropertyChange change)
|
||||
|
|
@ -308,5 +239,204 @@ namespace MatterHackers.MatterControl.DesignTools
|
|||
// percentWidget.Visible = Mode == ReductionMode.Polygon_Percent;
|
||||
// }
|
||||
}
|
||||
|
||||
private bool CollapseAllDegenerateEdges(DMesh3 mesh,
|
||||
CancellationToken cancellationToken,
|
||||
double minLength,
|
||||
bool bBoundaryOnly)
|
||||
{
|
||||
bool repeat = true;
|
||||
while (repeat)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
CollapseDegenerateEdges(mesh, cancellationToken, minLength, bBoundaryOnly, out int collapseCount);
|
||||
if (collapseCount == 0)
|
||||
{
|
||||
repeat = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CollapseDegenerateEdges(DMesh3 mesh,
|
||||
CancellationToken cancellationToken,
|
||||
double minLength,
|
||||
bool bBoundaryOnly,
|
||||
out int collapseCount)
|
||||
{
|
||||
collapseCount = 0;
|
||||
// don't iterate sequentially because there may be pathological cases
|
||||
foreach (int eid in MathUtil.ModuloIteration(mesh.MaxEdgeID))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
if (mesh.IsEdge(eid) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isBoundaryEdge = mesh.IsBoundaryEdge(eid);
|
||||
if (bBoundaryOnly && isBoundaryEdge == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Index2i ev = mesh.GetEdgeV(eid);
|
||||
Vector3d a = mesh.GetVertex(ev.a), b = mesh.GetVertex(ev.b);
|
||||
if (a.Distance(b) < minLength)
|
||||
{
|
||||
int keep = mesh.IsBoundaryVertex(ev.a) ? ev.a : ev.b;
|
||||
int discard = (keep == ev.a) ? ev.b : ev.a;
|
||||
MeshResult result = mesh.CollapseEdge(keep, discard, out DMesh3.EdgeCollapseInfo collapseInfo);
|
||||
if (result == MeshResult.Ok)
|
||||
{
|
||||
++collapseCount;
|
||||
if (mesh.IsBoundaryVertex(keep) == false || isBoundaryEdge)
|
||||
{
|
||||
mesh.SetVertex(keep, (a + b) * 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DisconnectBowties(DMesh3 mesh, out int nRemaining)
|
||||
{
|
||||
var editor = new MeshEditor(mesh);
|
||||
nRemaining = editor.DisconnectAllBowties();
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool RremoveInside(DMesh3 mesh)
|
||||
{
|
||||
if (RemoveMode == RemoveModes.Interior)
|
||||
{
|
||||
return RemoveInterior(mesh, out _);
|
||||
}
|
||||
else if (RemoveMode == RemoveModes.Occluded)
|
||||
{
|
||||
return RemoveOccluded(mesh, out _);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void FillAnyHoles(DMesh3 mesh,
|
||||
CancellationToken cancellationToken,
|
||||
out int nRemaining,
|
||||
out bool sawSpans)
|
||||
{
|
||||
var loops = new MeshBoundaryLoops(mesh);
|
||||
nRemaining = 0;
|
||||
sawSpans = loops.SawOpenSpans;
|
||||
|
||||
foreach (var loop in loops)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var filler = new MinimalHoleFill(mesh, loop);
|
||||
bool filled = filler.Apply();
|
||||
if (filled == false)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var fallback = new SimpleHoleFiller(mesh, loop);
|
||||
fallback.Fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FillTrivialHoles(DMesh3 mesh,
|
||||
CancellationToken cancellationToken,
|
||||
out int nRemaining,
|
||||
out bool sawSpans)
|
||||
{
|
||||
var loops = new MeshBoundaryLoops(mesh);
|
||||
nRemaining = 0;
|
||||
sawSpans = loops.SawOpenSpans;
|
||||
|
||||
foreach (var loop in loops)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
bool filled = false;
|
||||
if (loop.VertexCount == 3)
|
||||
{
|
||||
var filler = new SimpleHoleFiller(mesh, loop);
|
||||
filled = filler.Fill();
|
||||
}
|
||||
else if (loop.VertexCount == 4)
|
||||
{
|
||||
var filler = new MinimalHoleFill(mesh, loop);
|
||||
filled = filler.Apply();
|
||||
if (filled == false)
|
||||
{
|
||||
var fallback = new SimpleHoleFiller(mesh, loop);
|
||||
filled = fallback.Fill();
|
||||
}
|
||||
}
|
||||
|
||||
if (filled == false)
|
||||
{
|
||||
++nRemaining;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool RemoveInterior(DMesh3 mesh, out int nRemoved)
|
||||
{
|
||||
var remove = new RemoveOccludedTriangles(mesh)
|
||||
{
|
||||
PerVertex = true,
|
||||
InsideMode = RemoveOccludedTriangles.CalculationMode.FastWindingNumber
|
||||
};
|
||||
remove.Apply();
|
||||
nRemoved = remove.RemovedT.Count;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool RemoveOccluded(DMesh3 mesh, out int nRemoved)
|
||||
{
|
||||
var remove = new RemoveOccludedTriangles(mesh)
|
||||
{
|
||||
PerVertex = true,
|
||||
InsideMode = RemoveOccludedTriangles.CalculationMode.SimpleOcclusionTest
|
||||
};
|
||||
remove.Apply();
|
||||
nRemoved = remove.RemovedT.Count;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool RepairCracks(DMesh3 mesh, bool bUniqueOnly, double mergeDist)
|
||||
{
|
||||
try
|
||||
{
|
||||
var merge = new MergeCoincidentEdges(mesh)
|
||||
{
|
||||
OnlyUniquePairs = bUniqueOnly,
|
||||
MergeDistance = mergeDist
|
||||
};
|
||||
return merge.Apply();
|
||||
}
|
||||
catch (Exception /*e*/)
|
||||
{
|
||||
// ??
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RepairOrientation(DMesh3 mesh,
|
||||
CancellationToken cancellationToken,
|
||||
bool bGlobal)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var orient = new MeshRepairOrientation(mesh);
|
||||
orient.OrientComponents();
|
||||
|
||||
if (bGlobal)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
orient.SolveGlobalOrientation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ namespace MatterHackers.Plugins.EditorTools
|
|||
}
|
||||
}
|
||||
|
||||
CollisionVolume = rotationHandle.CreateTraceData();
|
||||
CollisionVolume = rotationHandle.CreateBVHData();
|
||||
|
||||
InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ namespace MatterHackers.Plugins.EditorTools
|
|||
|
||||
minXminYMesh = PlatonicSolids.CreateCube(selectCubeSize, selectCubeSize, selectCubeSize);
|
||||
|
||||
CollisionVolume = minXminYMesh.CreateTraceData();
|
||||
CollisionVolume = minXminYMesh.CreateBVHData();
|
||||
|
||||
InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ namespace MatterHackers.Plugins.EditorTools
|
|||
|
||||
topScaleMesh = PlatonicSolids.CreateCube(selectCubeSize, selectCubeSize, selectCubeSize);
|
||||
|
||||
CollisionVolume = topScaleMesh.CreateTraceData();
|
||||
CollisionVolume = topScaleMesh.CreateBVHData();
|
||||
|
||||
InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
foreach (var child in sceneContext.Scene.Children)
|
||||
{
|
||||
world.RenderDebugAABB(e.Graphics2D, child.TraceData().GetAxisAlignedBoundingBox());
|
||||
world.RenderDebugAABB(e.Graphics2D, child.GetBVHData().GetAxisAlignedBoundingBox());
|
||||
world.RenderDebugAABB(e.Graphics2D, child.GetAxisAlignedBoundingBox());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
var center = item.GetAxisAlignedBoundingBox().Center;
|
||||
|
||||
var traceData = item.TraceData();
|
||||
var traceData = item.GetBVHData();
|
||||
|
||||
var xy = traceData.Contains(center);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
public void Draw(GuiWidget sender, DrawEventArgs e, Matrix4X4 itemMaxtrix, WorldView world)
|
||||
{
|
||||
// RenderSceneTraceData
|
||||
var bvhIterator = new BvhIterator(scene?.TraceData(), decentFilter: (x) =>
|
||||
var bvhIterator = new BvhIterator(scene?.GetBVHData(), decentFilter: (x) =>
|
||||
{
|
||||
var center = x.Bvh.GetCenter();
|
||||
var worldCenter = Vector3Ex.Transform(center, x.TransformToWorld);
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
upArrowMesh = StlProcessing.Load(arrowStream, CancellationToken.None);
|
||||
}
|
||||
|
||||
CollisionVolume = upArrowMesh.CreateTraceData();
|
||||
CollisionVolume = upArrowMesh.CreateBVHData();
|
||||
|
||||
InteractionContext.GuiSurface.AfterDraw += InteractionLayer_AfterDraw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
if (nameFound)
|
||||
{
|
||||
AxisAlignedBoundingBox bounds = child.TraceData().GetAxisAlignedBoundingBox();
|
||||
AxisAlignedBoundingBox bounds = child.GetBVHData().GetAxisAlignedBoundingBox();
|
||||
|
||||
RectangleDouble screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;
|
||||
for (int i = 0; i < 4; i++)
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
connections.Add(new ConnectedFaces(1, 1, 2, 3, 1, 0));
|
||||
connections.Add(new ConnectedFaces(1, -1, 1, 3, 2, 0));
|
||||
|
||||
cubeTraceData = cube.CreateTraceData();
|
||||
cubeTraceData = cube.CreateBVHData();
|
||||
});
|
||||
|
||||
MouseLeave += (s, e) =>
|
||||
|
|
|
|||
|
|
@ -913,7 +913,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
foundTriangleInSelectionBounds = false;
|
||||
|
||||
// Filter the IPrimitive trace data finding matches as defined in InSelectionBounds
|
||||
var filteredResults = item.TraceData().Filter(InSelectionBounds);
|
||||
var filteredResults = item.GetBVHData().Filter(InSelectionBounds);
|
||||
|
||||
// Accumulate all matching BvhIterator results for debug rendering
|
||||
allResults.AddRange(filteredResults);
|
||||
|
|
@ -1461,7 +1461,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
{
|
||||
foreach (Object3D object3D in selectedItem.Children)
|
||||
{
|
||||
if (object3D.TraceData().Contains(info.HitPosition))
|
||||
if (object3D.GetBVHData().Contains(info.HitPosition))
|
||||
{
|
||||
CurrentSelectInfo.PlaneDownHitPos = info.HitPosition;
|
||||
CurrentSelectInfo.LastMoveDelta = default(Vector3);
|
||||
|
|
@ -1711,12 +1711,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
Vector2 meshViewerWidgetScreenPosition = this.InteractionLayer.TransformFromParentSpace(this, screenPosition);
|
||||
Ray ray = sceneContext.World.GetRayForLocalBounds(meshViewerWidgetScreenPosition);
|
||||
|
||||
intersectionInfo = Scene.TraceData().GetClosestIntersection(ray);
|
||||
intersectionInfo = Scene.GetBVHData().GetClosestIntersection(ray);
|
||||
if (intersectionInfo != null)
|
||||
{
|
||||
foreach (Object3D object3D in Scene.Children)
|
||||
{
|
||||
if (object3D.TraceData().Contains(intersectionInfo.HitPosition))
|
||||
if (object3D.GetBVHData().Contains(intersectionInfo.HitPosition))
|
||||
{
|
||||
CurrentSelectInfo.PlaneDownHitPos = intersectionInfo.HitPosition;
|
||||
CurrentSelectInfo.LastMoveDelta = default(Vector3);
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b3588348683eeca5d1308dc9a0c7179c2488835f
|
||||
Subproject commit 5d3c5e0290472cddbe0abc95ad8ef99559ea82b4
|
||||
Loading…
Add table
Add a link
Reference in a new issue