Improving STL export

Getting more MatterCad scripting working
This commit is contained in:
Lars Brubaker 2018-02-23 18:05:13 -08:00
parent 7ca194b8a7
commit d6a50e3956
7 changed files with 104 additions and 148 deletions

View file

@ -64,6 +64,31 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
return resultsA;
}
public static IObject3D Plus(this IObject3D a, IObject3D b)
{
var results = new Object3D();
results.Children.Add(a.Clone());
results.Children.Add(b.Clone());
return results;
}
public static double XSize(this IObject3D item)
{
return item.GetAxisAlignedBoundingBox().XSize;
}
public static double YSize(this IObject3D item)
{
return item.GetAxisAlignedBoundingBox().YSize;
}
public static double ZSize(this IObject3D item)
{
return item.GetAxisAlignedBoundingBox().ZSize;
}
public static void AddSelectionAsChildren(this InteractiveScene scene, IObject3D newParent)
{
if (scene.HasSelection)

View file

@ -32,110 +32,20 @@ using MatterHackers.PolygonMesh;
namespace MatterHackers.MatterControl.DesignTools
{
/*
public class ChairFoot2 : MatterCadObject3D
{
public ChairFoot()
{
Rebuild();
}
[DisplayName("Angle")]
public double AngleDegrees { get; set; } = 3;
// these are the public variables that would be edited
[DisplayName("Final")]
public bool FinalPart { get; set; } = true;
[DisplayName("Height")]
public double HeightFromFloorToBottomOfLeg { get; set; } = 10;
[DisplayName("Inner Size")]
public double InnerSize { get; set; } = 20;
[DisplayName("Reach")]
public double InsideReach { get; set; } = 10;
[DisplayName("Outer Size")]
public double OuterSize { get; set; } = 22;
public void Rebuild()
{
// This would be better expressed as the desired offset height (height from ground to bottom of chair leg).
double angleRadians = MathHelper.DegreesToRadians(AngleDegrees);
double extraHeightForRotation = Math.Sinh(angleRadians) * OuterSize; // get the distance to clip off the extra bottom
double unclippedFootHeight = HeightFromFloorToBottomOfLeg + extraHeightForRotation;
if (FinalPart)
{
Box chairFootBox = new Box(OuterSize, OuterSize, unclippedFootHeight);
//chairFootBox.BevelEdge(Edge.LeftBack, 2);
//chairFootBox.BevelEdge(Edge.LeftFront, 2);
//chairFootBox.BevelEdge(Edge.RightBack, 2);
//chairFootBox.BevelEdge(Edge.RightFront, 2);
IObject3D chairFoot = chairFootBox;
IObject3D ring = new Cylinder(InnerSize / 2 - 1, InsideReach, 30);
ring -= new Cylinder(ring.XSize / 2 - 2, ring.ZSize + 1, 30);
IObject3D fins = new Box(3, 1, ring.ZSize);
fins = new Translate(fins, 0, 1) + new Translate(fins, 0, -1);
fins -= new Align(new Rotate(new Box(5, 5, 5), 0, MathHelper.DegreesToRadians(45)), Face.Bottom | Face.Left, fins, Face.Top | Face.Left, 0, 0, -fins.XSize);
fins = new Translate(fins, InnerSize / 2 - .1);
ring += new Rotate(fins, 0, 0, MathHelper.DegreesToRadians(45));
ring += new Rotate(fins, 0, 0, MathHelper.DegreesToRadians(45 + 90));
ring += new Rotate(fins, 0, 0, MathHelper.DegreesToRadians(45 + 180));
ring += new Rotate(fins, 0, 0, MathHelper.DegreesToRadians(45 - 90));
chairFoot += new Align(ring, Face.Bottom, chairFoot, Face.Top, 0, 0, -.1);
chairFoot = new Rotate(chairFoot, 0, angleRadians, 0);
IObject3D clipBox = new Align(new Box(OuterSize * 2, OuterSize * 2, unclippedFootHeight), Face.Top, chairFoot, Face.Bottom, 0, 0, extraHeightForRotation);
chairFoot -= clipBox;
chairFoot = new Translate(chairFoot, 0, 0, clipBox.GetAxisAlignedBoundingBox().maxXYZ.Z);
this.Mesh = CsgToMesh.Convert(chairFoot);
}
else // fit part
{
double baseHeight = 3;
double insideHeight = 4;
Box chairFootBox = new Box(OuterSize, OuterSize, baseHeight);
chairFootBox.BevelEdge(Edge.LeftBack, 2);
chairFootBox.BevelEdge(Edge.LeftFront, 2);
chairFootBox.BevelEdge(Edge.RightBack, 2);
chairFootBox.BevelEdge(Edge.RightFront, 2);
IObject3D chairFoot = chairFootBox;
IObject3D ring = new Cylinder(InnerSize / 2 - 1, insideHeight, 30);
ring -= new Cylinder(ring.XSize / 2 - 2, ring.ZSize + 1, 30);
IObject3D fins = new Box(3, 1, ring.ZSize);
fins = new Translate(fins, 0, 1) + new Translate(fins, 0, -1);
fins -= new Align(new Rotate(new Box(5, 5, 5), 0, MathHelper.DegreesToRadians(45)), Face.Bottom | Face.Left, fins, Face.Top | Face.Left, 0, 0, -fins.XSize);
fins = new Translate(fins, InnerSize / 2 - .1);
ring += new Rotate(fins, 0, 0, MathHelper.DegreesToRadians(45));
ring += new Rotate(fins, 0, 0, MathHelper.DegreesToRadians(45 + 90));
ring += new Rotate(fins, 0, 0, MathHelper.DegreesToRadians(45 + 180));
ring += new Rotate(fins, 0, 0, MathHelper.DegreesToRadians(45 - 90));
chairFoot += new Align(ring, Face.Bottom, chairFoot, Face.Top, 0, 0, -.1);
this.Mesh = CsgToMesh.Convert(chairFoot);
}
}
}
*/
public class CubeObject3D : Object3D, IRebuildable
{
public CubeObject3D()
{
}
public CubeObject3D(double width, double depth, double height)
{
Width = width;
Depth = depth;
Height = height;
Rebuild();
}
public override string ActiveEditor => "PublicPropertyEditor";
public double Width { get; set; } = 20;

View file

@ -43,6 +43,15 @@ namespace MatterHackers.MatterControl.DesignTools
{
}
public CylinderObject3D(double diameter, double height, int sides)
{
Diameter = diameter;
Height = height;
Sides = sides;
Rebuild();
}
public static CylinderObject3D Create()
{
var item = new CylinderObject3D();
@ -60,10 +69,10 @@ namespace MatterHackers.MatterControl.DesignTools
var aabb = this.GetAxisAlignedBoundingBox();
var path = new VertexStorage();
path.MoveTo(0, 0);
path.LineTo(Diameter / 2, 0);
path.LineTo(Diameter / 2, Height);
path.LineTo(0, Height);
path.MoveTo(0, -Height / 2);
path.LineTo(Diameter / 2, -Height / 2);
path.LineTo(Diameter / 2, Height / 2);
path.LineTo(0, Height / 2);
Mesh = VertexSourceToMesh.Revolve(path, Sides);

View file

@ -58,7 +58,7 @@ namespace MatterHackers.MatterControl.Library.Export
public Task<bool> Generate(IEnumerable<ILibraryItem> libraryItems, string outputPath)
{
if (libraryItems.OfType<ILibraryAssetStream>().FirstOrDefault() is ILibraryAssetStream libraryItem)
if (libraryItems.OfType<ILibraryAsset>().FirstOrDefault() is ILibraryAsset libraryItem)
{
return MeshExport.ExportMesh(libraryItem, outputPath);
}

View file

@ -129,6 +129,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
BackgroundColor = theme.MinimalShade,
Margin = theme.ButtonSpacing
};
scene.SelectionChanged += (s, e) => editButton.Enabled = scene.SelectedItem?.CanEdit == true;
editButton.Click += async (s, e) =>
{
var bed = new BedConfig();

View file

@ -76,57 +76,68 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
private void ProcessBooleans(IObject3D group)
{
// spin up a task to remove holes from the objects in the group
ApplicationController.Instance.Tasks.Execute(
"Processing Booleans".Localize(),
(reporter, cancellationToken) =>
{
var progressStatus = new ProgressStatus();
reporter.Report(progressStatus);
var participants = group.DescendantsAndSelf().Where((obj) => obj.OwnerID == group.ID);
if (participants.Count() > 1)
"Combine".Localize(),
(reporter, cancellationToken) =>
{
var first = participants.First();
var progressStatus = new ProgressStatus();
reporter.Report(progressStatus);
var totalOperations = participants.Count()-1;
double amountPerOperation = 1.0 / totalOperations;
double percentCompleted = 0;
var participants = group.Descendants().Where(o => o.OwnerID == group.ID).ToList();
foreach (var remove in participants)
if (participants.Count() > 1)
{
if (remove != first)
{
var transformedRemove = Mesh.Copy(remove.Mesh, CancellationToken.None);
transformedRemove.Transform(remove.WorldMatrix());
var transformedKeep = Mesh.Copy(first.Mesh, CancellationToken.None);
transformedKeep.Transform(first.WorldMatrix());
transformedKeep = PolygonMesh.Csg.CsgOperations.Union(transformedKeep, transformedRemove, (status, progress0To1) =>
{
// Abort if flagged
cancellationToken.ThrowIfCancellationRequested();
progressStatus.Status = status;
progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1;
reporter.Report(progressStatus);
}, cancellationToken);
var inverse = first.WorldMatrix();
inverse.Invert();
transformedKeep.Transform(inverse);
first.Mesh = transformedKeep;
remove.Visible = false;
percentCompleted += amountPerOperation;
progressStatus.Progress0To1 = percentCompleted;
reporter.Report(progressStatus);
}
Combine(participants, cancellationToken, reporter);
}
}
return Task.CompletedTask;
});
}
return Task.CompletedTask;
});
public static void Combine(List<IObject3D> participants)
{
Combine(participants, CancellationToken.None, null);
}
public static void Combine(List<IObject3D> participants, CancellationToken cancellationToken, IProgress<ProgressStatus> reporter)
{
var first = participants.First();
var totalOperations = participants.Count() - 1;
double amountPerOperation = 1.0 / totalOperations;
double percentCompleted = 0;
ProgressStatus progressStatus = new ProgressStatus();
foreach (var remove in participants)
{
if (remove != first)
{
var transformedRemove = Mesh.Copy(remove.Mesh, CancellationToken.None);
transformedRemove.Transform(remove.WorldMatrix());
var transformedKeep = Mesh.Copy(first.Mesh, CancellationToken.None);
transformedKeep.Transform(first.WorldMatrix());
transformedKeep = PolygonMesh.Csg.CsgOperations.Union(transformedKeep, transformedRemove, (status, progress0To1) =>
{
// Abort if flagged
cancellationToken.ThrowIfCancellationRequested();
progressStatus.Status = status;
progressStatus.Progress0To1 = percentCompleted + amountPerOperation * progress0To1;
reporter.Report(progressStatus);
}, cancellationToken);
var inverse = first.WorldMatrix();
inverse.Invert();
transformedKeep.Transform(inverse);
first.Mesh = transformedKeep;
remove.Visible = false;
percentCompleted += amountPerOperation;
progressStatus.Progress0To1 = percentCompleted;
reporter.Report(progressStatus);
}
}
}
}
}

@ -1 +1 @@
Subproject commit bea8649f3e1545c106b93e7bb9c2d18dec7c0332
Subproject commit c82ba50c84e6e8f24f2d4fffcd4a9404fc0bd889