More tests and better support generation

issue: MatterHackers/MCCentral#5004
Generate support from bed

issue: MatterHackers/MatterControl#4265
Support needed on flat surface

issue: MatterHackers/MCCentral#5047
Unusable support generated for item

issue: MatterHackers/MatterControl#4377
Bed Support
This commit is contained in:
Lars Brubaker 2019-03-29 15:23:53 -07:00
parent a9252a1ab8
commit 21f92bf4eb
3 changed files with 135 additions and 43 deletions

View file

@ -171,24 +171,29 @@ namespace MatterHackers.MatterControl.DesignTools
progress?.Report(status);
// Get visible meshes for each of them
var supportCandidates = scene.Children.SelectMany(i => i.VisibleMeshes());
var allBedItems = scene.Children.SelectMany(i => i.VisibleMeshes());
AxisAlignedBoundingBox suppoortBounds = AxisAlignedBoundingBox.Empty();
if (selectedItem != null)
{
supportCandidates = selectedItem.VisibleMeshes();
foreach (var candidate in selectedItem.VisibleMeshes())
{
suppoortBounds += candidate.GetAxisAlignedBoundingBox(candidate.Matrix.Inverted * candidate.WorldMatrix());
}
}
AxisAlignedBoundingBox allBounds = AxisAlignedBoundingBox.Empty();
foreach (var candidate in supportCandidates)
else
{
allBounds += candidate.GetAxisAlignedBoundingBox(candidate.Matrix.Inverted * candidate.WorldMatrix());
foreach (var candidate in allBedItems)
{
suppoortBounds += candidate.GetAxisAlignedBoundingBox(candidate.Matrix.Inverted * candidate.WorldMatrix());
}
}
// create the gird of possible support
var gridBounds = new RectangleDouble(Math.Floor((double)(allBounds.MinXYZ.X / PillarSize)),
Math.Floor((double)(allBounds.MinXYZ.Y / PillarSize)),
Math.Ceiling(allBounds.MaxXYZ.X / PillarSize),
Math.Ceiling(allBounds.MaxXYZ.Y / PillarSize));
var gridBounds = new RectangleDouble(Math.Floor((double)(suppoortBounds.MinXYZ.X / PillarSize)),
Math.Floor((double)(suppoortBounds.MinXYZ.Y / PillarSize)),
Math.Ceiling(suppoortBounds.MaxXYZ.X / PillarSize),
Math.Ceiling(suppoortBounds.MaxXYZ.Y / PillarSize));
var partBounds = new RectangleDouble(gridBounds.Left * PillarSize,
gridBounds.Bottom * PillarSize,
gridBounds.Right * PillarSize,
@ -209,7 +214,7 @@ namespace MatterHackers.MatterControl.DesignTools
// get all the support plane intersections
status.Status = "Trace";
progress?.Report(status);
var detectedPlanes = DetectRequiredSupportByTracing(gridBounds, supportCandidates);
var detectedPlanes = DetectRequiredSupportByTracing(gridBounds, allBedItems);
status.Status = "Columns";
progress?.Report(status);
@ -374,7 +379,7 @@ namespace MatterHackers.MatterControl.DesignTools
do
{
lastBottom = i;
// find all open arreas in the list and add support
// find all open areas in the list and add support
i = GetNextBottom(i, planes);
if (i >= 0)
{
@ -400,6 +405,9 @@ namespace MatterHackers.MatterControl.DesignTools
private Dictionary<(int x, int y), List<(double z, bool bottom)>> DetectRequiredSupportByTracing(RectangleDouble gridBounds, IEnumerable<IObject3D> supportCandidates)
{
var allBounds = supportCandidates.GetAxisAlignedBoundingBox();
var rayStartZ = allBounds.MinXYZ.Z - 1;
var traceData = GetTraceData(supportCandidates);
// keep a list of all the detected planes in each support column
@ -428,7 +436,7 @@ namespace MatterHackers.MatterControl.DesignTools
var xPos = (gridBounds.Left + x) * PillarSize + halfPillar + (xOffset * halfPillar);
// detect all the bottom plans (surfaces that might need support
var upRay = new Ray(new Vector3(xPos + .000013, yPos - .00027, -.001), Vector3.UnitZ, intersectionType: IntersectionType.FrontFace);
var upRay = new Ray(new Vector3(xPos + .000013, yPos - .00027, rayStartZ), Vector3.UnitZ, intersectionType: IntersectionType.FrontFace);
do
{
upHit = traceData.GetClosestIntersection(upRay);
@ -442,7 +450,7 @@ namespace MatterHackers.MatterControl.DesignTools
} while (upHit != null);
// detect all the up plans (surfaces that will have support on top of them)
upRay = new Ray(new Vector3(xPos + .000013, yPos - .00027, 0), Vector3.UnitZ, intersectionType: IntersectionType.BackFace);
upRay = new Ray(new Vector3(xPos + .000013, yPos - .00027, rayStartZ), Vector3.UnitZ, intersectionType: IntersectionType.BackFace);
do
{
upHit = traceData.GetClosestIntersection(upRay);
@ -557,7 +565,7 @@ namespace MatterHackers.MatterControl.DesignTools
supportVerts = new List<Vector3Float>();
supportFaces = new FaceList();
// find all the down faces from the support cindidates
// find all the down faces from the support candidates
AddSupportFaces(supportCandidates,
supportVerts,
supportFaces,

@ -1 +1 @@
Subproject commit cb96dfcfa70f2b89a05a055a593ccf73cbd98635
Subproject commit 913fd3720ab662e4e439ecd7672afde0580b4e1e

View file

@ -80,6 +80,27 @@ namespace MatterControl.Tests.MatterControl
}
}
// make a single cube in the bed and ensure that no support is generated
// _________
// | |
// __| |__
// |_______|
//
{
InteractiveScene scene = new InteractiveScene();
var cube = await CubeObject3D.Create(20, 20, 20);
var aabb = cube.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cube.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabb.MinXYZ.Z - 5);
scene.Children.Add(cube);
var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
await supportGenerator.Create(null, CancellationToken.None);
Assert.AreEqual(1, scene.Children.Count, "We should not have added any support");
}
// make a cube on the bed and single cube in the air and ensure that support is not generated
// _________
// | |
@ -95,14 +116,14 @@ namespace MatterControl.Tests.MatterControl
var cubeOnBed = await CubeObject3D.Create(20, 20, 20);
var aabbBed = cubeOnBed.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z - 5);
scene.Children.Add(cubeOnBed);
var cubeInAair = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAair.GetAxisAlignedBoundingBox();
var cubeInAir = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeInAair.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 25);
scene.Children.Add(cubeInAair);
cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 25);
scene.Children.Add(cubeInAir);
var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
@ -110,7 +131,38 @@ namespace MatterControl.Tests.MatterControl
Assert.AreEqual(2, scene.Children.Count, "We should not have added support");
}
// make a cube on the bed and another cube exactily on top of it and ensure that support is not generated
// make a single cube in the bed and another cube on top, ensure that no support is generated
// _________
// | |
// | |
// |_______|
// _________
// | |
// __| |__
// |_______|
//
{
InteractiveScene scene = new InteractiveScene();
var cubeOnBed = await CubeObject3D.Create(20, 20, 20);
var aabbBed = cubeOnBed.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
scene.Children.Add(cubeOnBed);
var cubeInAir = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 25);
scene.Children.Add(cubeInAir);
var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
await supportGenerator.Create(null, CancellationToken.None);
Assert.AreEqual(2, scene.Children.Count, "We should not have added support");
}
// make a cube on the bed and another cube exactly on top of it and ensure that support is not generated
// _________
// | |
// | |
@ -127,11 +179,11 @@ namespace MatterControl.Tests.MatterControl
cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
scene.Children.Add(cubeOnBed);
var cubeInAair = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAair.GetAxisAlignedBoundingBox();
var cubeInAir = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeInAair.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 20);
scene.Children.Add(cubeInAair);
cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 20);
scene.Children.Add(cubeInAir);
var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
@ -155,11 +207,43 @@ namespace MatterControl.Tests.MatterControl
cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
scene.Children.Add(cubeOnBed);
var cubeInAair = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAair.GetAxisAlignedBoundingBox();
var cubeInAir = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeInAair.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 15);
scene.Children.Add(cubeInAair);
cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 15);
scene.Children.Add(cubeInAir);
var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
await supportGenerator.Create(null, CancellationToken.None);
Assert.AreEqual(2, scene.Children.Count, "We should not have added support");
}
// Make a cube on the bed and single cube in the air that intersects it.
// SELECT the cube on top
// Ensure that support is not generated.
// _________
// | |
// |______ | // top cube actually exactly on top of bottom cube
// ||______||
// | |
//___|_______|___
{
InteractiveScene scene = new InteractiveScene();
var cubeOnBed = await CubeObject3D.Create(20, 20, 20);
var aabbBed = cubeOnBed.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
scene.Children.Add(cubeOnBed);
var cubeInAir = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 15);
scene.Children.Add(cubeInAir);
scene.SelectedItem = cubeInAir;
var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;
@ -259,11 +343,11 @@ namespace MatterControl.Tests.MatterControl
cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
scene.Children.Add(cubeOnBed);
var cubeInAair = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAair.GetAxisAlignedBoundingBox();
var cubeInAir = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeInAair.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 25);
scene.Children.Add(cubeInAair);
cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 25);
scene.Children.Add(cubeInAir);
var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
supportGenerator.SupportType = SupportGenerator.SupportGenerationType.Normal;
@ -292,11 +376,11 @@ namespace MatterControl.Tests.MatterControl
cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
scene.Children.Add(cubeOnBed);
var cubeInAair = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAair.GetAxisAlignedBoundingBox();
var cubeInAir = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeInAair.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 15);
scene.Children.Add(cubeInAair);
cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 15);
scene.Children.Add(cubeInAir);
var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
supportGenerator.SupportType = SupportGenerator.SupportGenerationType.Normal;
@ -304,7 +388,7 @@ namespace MatterControl.Tests.MatterControl
Assert.AreEqual(2, scene.Children.Count, "We should not have added support");
}
// make a cube on the bed and another cube exactily on top of it and ensure that support is not generated
// make a cube on the bed and another cube exactly on top of it and ensure that support is not generated
// _________
// | |
// | |
@ -321,11 +405,11 @@ namespace MatterControl.Tests.MatterControl
cubeOnBed.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbBed.MinXYZ.Z);
scene.Children.Add(cubeOnBed);
var cubeInAair = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAair.GetAxisAlignedBoundingBox();
var cubeInAir = await CubeObject3D.Create(20, 20, 20);
var aabbAir = cubeInAir.GetAxisAlignedBoundingBox();
// move it so the bottom is 15 above the bed
cubeInAair.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 20);
scene.Children.Add(cubeInAair);
cubeInAir.Matrix = Matrix4X4.CreateTranslation(0, 0, -aabbAir.MinXYZ.Z + 20);
scene.Children.Add(cubeInAir);
var supportGenerator = new SupportGenerator(scene, minimumSupportHeight);
supportGenerator.SupportType = SupportGenerator.SupportGenerationType.From_Bed;