Improving STL export
Getting more MatterCad scripting working
This commit is contained in:
parent
7ca194b8a7
commit
d6a50e3956
7 changed files with 104 additions and 148 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue