diff --git a/PartPreviewWindow/View3D/Actions/SubtractAndReplace.cs b/PartPreviewWindow/View3D/Actions/SubtractAndReplace.cs
index a53b76ecf..ca14d8f27 100644
--- a/PartPreviewWindow/View3D/Actions/SubtractAndReplace.cs
+++ b/PartPreviewWindow/View3D/Actions/SubtractAndReplace.cs
@@ -209,6 +209,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
if (paintObjects.Any()
&& keepObjects.Any())
{
+ var totalOperations = paintObjects.Count * keepObjects.Count;
+ double amountPerOperation = 1.0 / totalOperations;
+ double percentCompleted = 0;
+
foreach (var paint in paintObjects)
{
var transformedPaint = Mesh.Copy(paint.Mesh, cancellationToken);
@@ -223,7 +227,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
transformedKeep.Transform(keep.WorldMatrix());
// remove the paint from the original
- var intersectAndSubtract = PolygonMesh.Csg.CsgOperations.IntersectAndSubtract(transformedKeep, transformedPaint);
+ var intersectAndSubtract = PolygonMesh.Csg.CsgOperations.IntersectAndSubtract(transformedKeep, transformedPaint, (status, progress0To1) =>
+ {
+ // Abort if flagged
+ cancellationToken.ThrowIfCancellationRequested();
+
+ progressStatus.Status = status;
+ progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1;
+ reporter?.Report(progressStatus);
+ }, cancellationToken);
var inverseKeep = keep.WorldMatrix();
inverseKeep.Invert();
intersectAndSubtract.subtract.Transform(inverseKeep);
diff --git a/PartPreviewWindow/View3D/Actions/SubtractEditor.cs b/PartPreviewWindow/View3D/Actions/SubtractEditor.cs
index 1a7a15e2e..3186760ce 100644
--- a/PartPreviewWindow/View3D/Actions/SubtractEditor.cs
+++ b/PartPreviewWindow/View3D/Actions/SubtractEditor.cs
@@ -216,12 +216,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
{
progressStatus.Status = "Copy Remove";
reporter?.Report(progressStatus);
- var transformedRemove = Mesh.Copy(remove.Mesh, CancellationToken.None);
+ var transformedRemove = Mesh.Copy(remove.Mesh, cancellationToken);
transformedRemove.Transform(remove.WorldMatrix());
progressStatus.Status = "Copy Keep";
reporter?.Report(progressStatus);
- var transformedKeep = Mesh.Copy(keep.Mesh, CancellationToken.None);
+ var transformedKeep = Mesh.Copy(keep.Mesh, cancellationToken);
transformedKeep.Transform(keep.WorldMatrix());
progressStatus.Status = "Do CSG";
diff --git a/PrinterCommunication/PrinterConnection.cs b/PrinterCommunication/PrinterConnection.cs
index feb5300f6..74c8b4e58 100644
--- a/PrinterCommunication/PrinterConnection.cs
+++ b/PrinterCommunication/PrinterConnection.cs
@@ -2466,7 +2466,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication
}
// times up turn off heaters
- if (ContinuWaitingToTurnOffHeaters)
+ if (ContinuWaitingToTurnOffHeaters
+ && !PrinterIsPrinting
+ && !PrinterIsPaused)
{
UiThread.RunOnIdle(() =>
{
diff --git a/Submodules/MatterSlice b/Submodules/MatterSlice
index 6cb7f7949..3ca863d64 160000
--- a/Submodules/MatterSlice
+++ b/Submodules/MatterSlice
@@ -1 +1 @@
-Subproject commit 6cb7f7949ccfc62096bf5a3cbedc39fe8fe56ece
+Subproject commit 3ca863d643ff47053e74424efd13db13048c7892
diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp
index ed0cd4a86..39695a622 160000
--- a/Submodules/agg-sharp
+++ b/Submodules/agg-sharp
@@ -1 +1 @@
-Subproject commit ed0cd4a8625acf26eb41cb45f430a03049ea577e
+Subproject commit 39695a622650ffd4abdbe5de2921675104e94b78
diff --git a/Tests/MatterControl.Tests/MatterControl.Tests.csproj b/Tests/MatterControl.Tests/MatterControl.Tests.csproj
index eae17513c..379af7542 100644
--- a/Tests/MatterControl.Tests/MatterControl.Tests.csproj
+++ b/Tests/MatterControl.Tests/MatterControl.Tests.csproj
@@ -127,6 +127,10 @@
{670BDDFF-927B-425D-9DD1-22ACB14356EB}
PlatformWin32
+
+ {7ee4636d-8a92-4015-9562-7fcd6add0645}
+ Net3dBool
+
{86F6AAF2-9B50-40B8-A427-1897D76471C5}
PolygonMesh
diff --git a/Tests/MatterControl.Tests/MatterControl/MeshCsgTests.cs b/Tests/MatterControl.Tests/MatterControl/MeshCsgTests.cs
index 44d98885b..47bdf5a9e 100644
--- a/Tests/MatterControl.Tests/MatterControl/MeshCsgTests.cs
+++ b/Tests/MatterControl.Tests/MatterControl/MeshCsgTests.cs
@@ -43,6 +43,7 @@ using MatterHackers.MatterControl.Tests.Automation;
using MatterHackers.PolygonMesh.Csg;
using MatterHackers.PolygonMesh.Processors;
using MatterHackers.VectorMath;
+using Net3dBool;
using NUnit.Framework;
namespace MatterHackers.PolygonMesh.UnitTests
@@ -51,7 +52,7 @@ namespace MatterHackers.PolygonMesh.UnitTests
public class MeshCsgTests
{
[Test]
- public void CylinderMinusCylinder()
+ public void CsgCylinderMinusCylinder()
{
AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));
@@ -61,66 +62,102 @@ namespace MatterHackers.PolygonMesh.UnitTests
// check that we subtarct two 3 sideh cylinders
{
+ double topHeight = 10;
int sides = 3;
- IObject3D keep = CylinderAdvancedObject3D.Create(20, 20, sides);
- IObject3D subtract = CylinderAdvancedObject3D.Create(10, 20, sides);
+ IObject3D keep = CylinderAdvancedObject3D.Create(20, topHeight * 2, sides);
+ IObject3D subtract = CylinderAdvancedObject3D.Create(10, topHeight * 2, sides);
var keepMesh = keep.Mesh;
var subtractMesh = subtract.Mesh;
- var split1 = new DebugFace()
+ if (false)
{
- EvaluateHeight = 10,
- FileName = "Split1"
- };
+ var split1 = new DebugFace()
+ {
+ EvaluateHeight = topHeight,
+ FileName = "Split1"
+ };
- var resultMesh = keepMesh.Subtract(subtractMesh, null, CancellationToken.None);//,
- //split1.Split, split1.Result);
+ BooleanModeller.Object1SplitFace = split1.Split;
+ BooleanModeller.Object1SplitResults = split1.Result;
+
+ BooleanModeller.Object1ClassifyFace = split1.Classify1;
+ BooleanModeller.Object2ClassifyFace = split1.Classify2;
+ }
+
+ var resultMesh = keepMesh.Subtract(subtractMesh, null, CancellationToken.None);
// this is for debuging the opperation
//split1.FinishOutput();
//resultMesh.Save("c:/temp/mesh1.stl", CancellationToken.None);
- Assert.AreEqual(12, CountFacesAtHeight(keepMesh, 10));
+ var topZero = new Vector3(0, 0, topHeight);
+ foreach (var topVertex in keepMesh.Vertices
+ .Where((v) => v.Position.Z == topHeight && v.Position != topZero)
+ .Select((gv) => gv.Position))
+ {
+ Assert.IsTrue(resultMesh.Vertices.Where((v) => v.Position == topVertex).Any(), "Have all top vertexes");
+ }
+ foreach (var topVertex in subtractMesh.Vertices
+ .Where((v) => v.Position.Z == topHeight && v.Position != topZero)
+ .Select((gv) => gv.Position))
+ {
+ Assert.IsTrue(resultMesh.Vertices.Where((v) => v.Position == topVertex).Any(), "Have all top vertexes");
+ }
}
// check that we subtarct two 3 sideh cylinders
{
int sides = 3;
IObject3D keep = CylinderAdvancedObject3D.Create(20, 20, sides);
- IObject3D subtract = CylinderAdvancedObject3D.Create(10, 21, sides);
+ IObject3D subtract = CylinderAdvancedObject3D.Create(10, 22, sides);
var keepMesh = keep.Mesh;
var subtractMesh = subtract.Mesh;
- var split1 = new DebugFace()
+ if (false)
{
- EvaluateHeight = 10,
- FileName = "Split2"
- };
+ var split1 = new DebugFace()
+ {
+ EvaluateHeight = 10,
+ FileName = "Split2"
+ };
- var resultMesh = keepMesh.Subtract(subtractMesh, null, CancellationToken.None);//,
- //split1.Split, split1.Result);
+ BooleanModeller.Object1SplitFace = split1.Split;
+ BooleanModeller.Object1SplitResults = split1.Result;
+ }
+
+ var resultMesh = keepMesh.Subtract(subtractMesh, null, CancellationToken.None);
// this is for debuging the opperation
//split1.FinishOutput();
- //esultMesh.Save("c:/temp/mesh2.stl", CancellationToken.None);
+ //resultMesh.Save("c:/temp/mesh2.stl", CancellationToken.None);
- Assert.AreEqual(12, CountFacesAtHeight(keepMesh, 10));
+ foreach (var topVertex in keepMesh.Vertices
+ .Where((v) => v.Position.Z == 10 && v.Position != new Vector3(0, 0, 10))
+ .Select((gv) => gv.Position))
+ {
+ Assert.IsTrue(resultMesh.Vertices.Where((v) => v.Position == topVertex).Any(), "Have all top vertexes");
+ }
+ foreach (var topVertex in subtractMesh.Vertices
+ .Where((v) => v.Position.Z == 11 && v.Position != new Vector3(0, 0, 11))
+ .Select((gv) => gv.Position))
+ {
+ Assert.IsTrue(resultMesh.Vertices
+ .Where((v) => v.Position.Equals(new Vector3(topVertex.X, topVertex.Y, 10), .0001))
+ .Any(), "Have all top vertexes");
+ }
}
}
-
- private double CountFacesAtHeight(Mesh keepMesh, double zHeightToFind)
- {
- // TODO: make this work
- return 12;
- }
}
public class DebugFace
{
private int currentIndex;
- private StringBuilder allPolygonDebug = new StringBuilder();
+ private StringBuilder allSplitPolygonDebug = new StringBuilder();
+ private StringBuilder allResultsPolygonDebug = new StringBuilder();
+ private StringBuilder classifiedFaces1 = new StringBuilder();
+ private StringBuilder classifiedFaces2 = new StringBuilder();
private StringBuilder htmlContent = new StringBuilder();
private StringBuilder individualPolygonDebug = new StringBuilder();
@@ -131,7 +168,7 @@ namespace MatterHackers.PolygonMesh.UnitTests
Vector2 offset = new Vector2(10, 18);
double scale = 13;
- public void Result(List splitResults)
+ public void Result(List splitResults)
{
if (splitResults.Count > 0
&& FaceAtHeight(splitResults[0], EvaluateHeight))
@@ -141,19 +178,17 @@ namespace MatterHackers.PolygonMesh.UnitTests
foreach (var face in splitResults)
{
individualPolygonDebug.AppendLine(GetCoords(face));
+ allResultsPolygonDebug.AppendLine(GetCoords(face));
}
individualPolygonDebug.AppendLine("");
}
}
- public void Split(Vector3[] faceToSplit, Vector3[] splitAtFace)
+ public void Split(CsgFace faceToSplit, CsgFace splitAtFace)
{
if (FaceAtHeight(faceToSplit, EvaluateHeight))
{
- string faceToSplitCoords = GetCoords(faceToSplit);
- string splitAtFaceCoords = GetCoords(splitAtFace);
-
- allPolygonDebug.AppendLine(faceToSplitCoords);
+ allSplitPolygonDebug.AppendLine(GetCoords(faceToSplit));
if (currentIndex == 0)
{
@@ -166,22 +201,32 @@ namespace MatterHackers.PolygonMesh.UnitTests
currentIndex++;
individualPolygonDebug.AppendLine($"
{currentIndex}");
individualPolygonDebug.AppendLine($"");
}
}
public void FinishOutput()
{
- htmlContent.AppendLine($"