Making export to STL process the scene
This commit is contained in:
parent
55454a8615
commit
20a100dc70
3 changed files with 4 additions and 252 deletions
|
|
@ -84,7 +84,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
null,
|
||||
(reporter, cancellationTokenSource) =>
|
||||
{
|
||||
this.cancellationToken = cancellationTokenSource as CancellationTokenSource;
|
||||
this.cancellationToken = cancellationTokenSource;
|
||||
var progressStatus = new ProgressStatus();
|
||||
reporter.Report(progressStatus);
|
||||
|
||||
|
|
@ -142,7 +142,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
}
|
||||
else
|
||||
{
|
||||
resultsMesh = CombineParticipanets(reporter, participants, cancellationToken);
|
||||
resultsMesh = Object3D.CombineParticipanets(SourceContainer, participants, cancellationToken, reporter);
|
||||
}
|
||||
|
||||
var resultsItem = new Object3D()
|
||||
|
|
@ -152,7 +152,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
|
||||
if (holes != null)
|
||||
{
|
||||
var holesMesh = CombineParticipanets(null, holes, cancellationToken);
|
||||
var holesMesh = CombineParticipanets(SourceContainer, holes, cancellationToken, null);
|
||||
if (holesMesh != null)
|
||||
{
|
||||
var holesItem = new Object3D()
|
||||
|
|
@ -185,149 +185,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
SourceContainer.Visible = false;
|
||||
}
|
||||
|
||||
private Mesh CombineParticipanets(IProgress<ProgressStatus> reporter, IEnumerable<IObject3D> participants, CancellationToken cancellationToken)
|
||||
{
|
||||
List<List<(Mesh mesh, Matrix4X4 matrix, AxisAlignedBoundingBox aabb)>> touchingSets = GetTouchingMeshes(participants);
|
||||
|
||||
var totalOperations = touchingSets.Sum(t => t.Count);
|
||||
|
||||
double amountPerOperation = 1.0 / totalOperations;
|
||||
double ratioCompleted = 0;
|
||||
|
||||
var progressStatus = new ProgressStatus();
|
||||
|
||||
var setMeshes = new List<Mesh>();
|
||||
foreach (var set in touchingSets)
|
||||
{
|
||||
var setMesh = set.First().Item1;
|
||||
var keepWorldMatrix = set.First().matrix;
|
||||
|
||||
if (set.Count > 1)
|
||||
{
|
||||
#if true
|
||||
setMesh = BooleanProcessing.DoArray(set.Select(i => (i.mesh, i.matrix)),
|
||||
CsgModes.Union,
|
||||
Processing,
|
||||
InputResolution,
|
||||
OutputResolution,
|
||||
reporter,
|
||||
cancellationToken);
|
||||
#else
|
||||
|
||||
bool first = true;
|
||||
foreach (var next in set)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
setMesh = BooleanProcessing.Do(setMesh,
|
||||
keepWorldMatrix,
|
||||
// other mesh
|
||||
next.mesh,
|
||||
next.matrix,
|
||||
// operation type
|
||||
CsgModes.Union,
|
||||
Processing,
|
||||
InputResolution,
|
||||
OutputResolution,
|
||||
// reporting
|
||||
reporter,
|
||||
amountPerOperation,
|
||||
ratioCompleted,
|
||||
progressStatus,
|
||||
cancellationToken);
|
||||
|
||||
// after the first time we get a result the results mesh is in the right coordinate space
|
||||
keepWorldMatrix = Matrix4X4.Identity;
|
||||
|
||||
// report our progress
|
||||
ratioCompleted += amountPerOperation;
|
||||
progressStatus.Progress0To1 = ratioCompleted;
|
||||
reporter?.Report(progressStatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
setMeshes.Add(setMesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
setMesh.Transform(keepWorldMatrix);
|
||||
// report our progress
|
||||
ratioCompleted += amountPerOperation;
|
||||
progressStatus.Progress0To1 = ratioCompleted;
|
||||
reporter?.Report(progressStatus);
|
||||
setMeshes.Add(setMesh);
|
||||
}
|
||||
}
|
||||
|
||||
Mesh resultsMesh = null;
|
||||
foreach (var setMesh in setMeshes)
|
||||
{
|
||||
if (resultsMesh == null)
|
||||
{
|
||||
resultsMesh = setMesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultsMesh.CopyAllFaces(setMesh, Matrix4X4.Identity);
|
||||
}
|
||||
}
|
||||
|
||||
return resultsMesh;
|
||||
}
|
||||
|
||||
private List<List<(Mesh mesh, Matrix4X4 matrix, AxisAlignedBoundingBox aabb)>> GetTouchingMeshes(IEnumerable<IObject3D> participants)
|
||||
{
|
||||
void AddAllTouching(List<(Mesh mesh, Matrix4X4 matrix, AxisAlignedBoundingBox aabb)> touching,
|
||||
List<(Mesh mesh, Matrix4X4 matrix, AxisAlignedBoundingBox aabb)> available)
|
||||
{
|
||||
// add the frirst item
|
||||
touching.Add(available[available.Count - 1]);
|
||||
available.RemoveAt(available.Count - 1);
|
||||
|
||||
var indexBeingChecked = 0;
|
||||
|
||||
// keep adding items until we have checked evry item in the the touching list
|
||||
while (indexBeingChecked < touching.Count
|
||||
&& available.Count > 0)
|
||||
{
|
||||
// look for a aabb that intersects any aabb in the set
|
||||
for (int i = available.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (touching[indexBeingChecked].aabb.Intersects(available[i].aabb))
|
||||
{
|
||||
touching.Add(available[i]);
|
||||
available.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
indexBeingChecked++;
|
||||
}
|
||||
}
|
||||
|
||||
var allItems = participants.Select(i =>
|
||||
{
|
||||
var mesh = i.Mesh.Copy(CancellationToken.None);
|
||||
var matrix = i.WorldMatrix(SourceContainer);
|
||||
var aabb = mesh.GetAxisAlignedBoundingBox(matrix);
|
||||
return (mesh, matrix, aabb);
|
||||
}).ToList();
|
||||
|
||||
var touchingSets = new List<List<(Mesh mesh, Matrix4X4 matrix, AxisAlignedBoundingBox aabb)>>();
|
||||
|
||||
while (allItems.Count > 0)
|
||||
{
|
||||
var touchingSet = new List<(Mesh mesh, Matrix4X4 matrix, AxisAlignedBoundingBox aabb)>();
|
||||
touchingSets.Add(touchingSet);
|
||||
AddAllTouching(touchingSet, allItems);
|
||||
}
|
||||
|
||||
return touchingSets;
|
||||
}
|
||||
|
||||
public void UpdateControls(PublicPropertyChange change)
|
||||
{
|
||||
change.SetRowVisible(nameof(InputResolution), () => Processing != ProcessingModes.Polygons);
|
||||
|
|
|
|||
|
|
@ -304,111 +304,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<IObject3D> DoSubtract(IObject3D sourceContainer,
|
||||
IEnumerable<IObject3D> keepItems,
|
||||
IEnumerable<IObject3D> removeItems,
|
||||
IProgress<ProgressStatus> reporter,
|
||||
CancellationToken cancellationToken,
|
||||
ProcessingModes processingMode = ProcessingModes.Polygons,
|
||||
ProcessingResolution inputResolution = ProcessingResolution._64,
|
||||
ProcessingResolution outputResolution = ProcessingResolution._64)
|
||||
{
|
||||
var results = new List<IObject3D>();
|
||||
if (keepItems?.Any() == true)
|
||||
{
|
||||
if (removeItems?.Any() == true)
|
||||
{
|
||||
foreach (var keep in keepItems)
|
||||
{
|
||||
#if false
|
||||
var items = removeItems.Select(i => (i.Mesh, i.WorldMatrix(sourceContainer))).ToList();
|
||||
items.Insert(0, (keep.Mesh, keep.Matrix));
|
||||
var resultsMesh = BooleanProcessing.DoArray(items,
|
||||
CsgModes.Subtract,
|
||||
processingMode,
|
||||
inputResolution,
|
||||
outputResolution,
|
||||
reporter,
|
||||
cancellationToken);
|
||||
#else
|
||||
var totalOperations = removeItems.Count() * keepItems.Count();
|
||||
double amountPerOperation = 1.0 / totalOperations;
|
||||
double ratioCompleted = 0;
|
||||
|
||||
var progressStatus = new ProgressStatus
|
||||
{
|
||||
Status = "Do CSG"
|
||||
};
|
||||
|
||||
var resultsMesh = keep.Mesh;
|
||||
var keepWorldMatrix = keep.Matrix;
|
||||
if (sourceContainer != null)
|
||||
{
|
||||
keepWorldMatrix = keep.WorldMatrix(sourceContainer);
|
||||
}
|
||||
|
||||
foreach (var remove in removeItems)
|
||||
{
|
||||
var removeWorldMatrix = remove.Matrix;
|
||||
if (sourceContainer != null)
|
||||
{
|
||||
removeWorldMatrix = remove.WorldMatrix(sourceContainer);
|
||||
}
|
||||
|
||||
resultsMesh = BooleanProcessing.Do(resultsMesh,
|
||||
keepWorldMatrix,
|
||||
// other mesh
|
||||
remove.Mesh,
|
||||
removeWorldMatrix,
|
||||
// operation type
|
||||
CsgModes.Subtract,
|
||||
processingMode,
|
||||
inputResolution,
|
||||
outputResolution,
|
||||
// reporting
|
||||
reporter,
|
||||
amountPerOperation,
|
||||
ratioCompleted,
|
||||
progressStatus,
|
||||
cancellationToken);
|
||||
|
||||
// after the first time we get a result the results mesh is in the right coordinate space
|
||||
keepWorldMatrix = Matrix4X4.Identity;
|
||||
|
||||
// report our progress
|
||||
ratioCompleted += amountPerOperation;
|
||||
progressStatus.Progress0To1 = ratioCompleted;
|
||||
reporter?.Report(progressStatus);
|
||||
}
|
||||
|
||||
#endif
|
||||
// store our results mesh
|
||||
var resultsItem = new Object3D()
|
||||
{
|
||||
Mesh = resultsMesh,
|
||||
Visible = false,
|
||||
OwnerID = keep.ID
|
||||
};
|
||||
|
||||
// copy all the properties but the matrix
|
||||
if (sourceContainer != null)
|
||||
{
|
||||
resultsItem.CopyWorldProperties(keep, sourceContainer, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible)));
|
||||
}
|
||||
else
|
||||
{
|
||||
resultsItem.CopyProperties(keep, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible)));
|
||||
}
|
||||
|
||||
// and add it to this
|
||||
results.Add(resultsItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static void CleanUpSelectedChildrenIDs(OperationSourceContainerObject3D item)
|
||||
{
|
||||
if (item is ISelectableChildContainer selectableChildContainer)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b426c1d2361ca4ef15bd6a77333a44d610ad127e
|
||||
Subproject commit 6750bc4daa8c0188b61ebf61bbdeb3ae57b8a998
|
||||
Loading…
Add table
Add a link
Reference in a new issue