Working on adding hole support to Source Objects
This commit is contained in:
parent
16af8dcdb2
commit
ce9019884f
11 changed files with 599 additions and 125 deletions
|
|
@ -79,7 +79,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
|
||||
var rebuildLocks = this.RebuilLockAll();
|
||||
|
||||
return ApplicationController.Instance.Tasks.Execute(
|
||||
return ApplicationController.Instance.Tasks.Execute(
|
||||
"Combine".Localize(),
|
||||
null,
|
||||
(reporter, cancellationTokenSource) =>
|
||||
|
|
@ -105,10 +105,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
this.cancellationToken = null;
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
rebuildLocks.Dispose();
|
||||
this.CancelAllParentBuilding();
|
||||
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
|
||||
rebuildLocks.Dispose();
|
||||
this.CancelAllParentBuilding();
|
||||
Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children));
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
if (layer.Scene.SelectedItem != null
|
||||
&& layer.Scene.SelectedItem == this)
|
||||
{
|
||||
var parentOfSubtractTargets = this.SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf();
|
||||
var parentOfSubtractTargets = this.SourceContainer.FirstWithMultipleChildrenDescendantsAndSelf();
|
||||
|
||||
var removeObjects = parentOfSubtractTargets.Children
|
||||
.Where(i => SelectedChildren.Contains(i.ID))
|
||||
|
|
@ -195,7 +195,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
SourceContainer.Visible = true;
|
||||
RemoveAllButSource();
|
||||
|
||||
var parentOfPaintTargets = SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf();
|
||||
var parentOfPaintTargets = SourceContainer.FirstWithMultipleChildrenDescendantsAndSelf();
|
||||
|
||||
if (parentOfPaintTargets.Children.Count() < 2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
if (layer.Scene.SelectedItem != null
|
||||
&& layer.Scene.SelectedItem == this)
|
||||
{
|
||||
var parentOfSubtractTargets = this.SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf();
|
||||
var parentOfSubtractTargets = this.SourceContainer.FirstWithMultipleChildrenDescendantsAndSelf();
|
||||
|
||||
var removeObjects = parentOfSubtractTargets.Children
|
||||
.Where(i => SelectedChildren.Contains(i.ID))
|
||||
|
|
@ -109,7 +109,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
|
||||
if (SelectedChildren.Count == 0)
|
||||
{
|
||||
SelectedChildren.Add(SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf().Children.Last().ID);
|
||||
SelectedChildren.Add(SourceContainer.FirstWithMultipleChildrenDescendantsAndSelf().Children.Last().ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,28 +212,29 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
Subtract(CancellationToken.None, null);
|
||||
}
|
||||
|
||||
private (IEnumerable<IObject3D>, IEnumerable<IObject3D>) GetSubtractItems()
|
||||
private static (IEnumerable<IObject3D>, IEnumerable<IObject3D>) GetSubtractItems(IObject3D source, SelectedChildren selectedChildren)
|
||||
{
|
||||
var parentOfSubtractTargets = SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf();
|
||||
|
||||
if (parentOfSubtractTargets.Children.Count() < 2)
|
||||
{
|
||||
if (parentOfSubtractTargets.Children.Count() == 1)
|
||||
{
|
||||
this.Children.Add(SourceContainer.Clone());
|
||||
SourceContainer.Visible = false;
|
||||
}
|
||||
var parentOfSubtractTargets = source.FirstWithMultipleChildrenDescendantsAndSelf();
|
||||
|
||||
// if there are 0 results
|
||||
if (parentOfSubtractTargets.Children.Count() == 0)
|
||||
{
|
||||
return (null, null);
|
||||
}
|
||||
|
||||
// if there is only 1 result (regardless of it being a keep or remove) return it as a keep
|
||||
if (parentOfSubtractTargets.Children.Count() == 1)
|
||||
{
|
||||
return (new IObject3D[] { source }, null);
|
||||
}
|
||||
|
||||
var removeItems = parentOfSubtractTargets.Children
|
||||
.Where((i) => SelectedChildren
|
||||
.Where((i) => selectedChildren
|
||||
.Contains(i.ID))
|
||||
.SelectMany(c => c.VisibleMeshes());
|
||||
|
||||
var keepItems = parentOfSubtractTargets.Children
|
||||
.Where((i) => !SelectedChildren
|
||||
.Where((i) => !selectedChildren
|
||||
.Contains(i.ID))
|
||||
.SelectMany(c => c.VisibleMeshes());
|
||||
|
||||
|
|
@ -247,98 +248,45 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
|
||||
CleanUpSelectedChildrenIDs(this);
|
||||
|
||||
var (keepItems, removeItems) = GetSubtractItems();
|
||||
var removeItemsCount = removeItems == null ? 0 : removeItems.Count();
|
||||
var keepItemsCount = keepItems == null ? 0 : keepItems.Count();
|
||||
var (keepItems, removeItems) = GetSubtractItems(SourceContainer, SelectedChildren);
|
||||
|
||||
if (removeItems?.Any() == true
|
||||
&& keepItems?.Any() == true)
|
||||
{
|
||||
foreach (var keep in keepItems)
|
||||
var resultItems = DoSubtract(SourceContainer,
|
||||
keepItems,
|
||||
removeItems,
|
||||
reporter,
|
||||
cancellationToken,
|
||||
Processing,
|
||||
InputResolution,
|
||||
OutputResolution);
|
||||
|
||||
foreach(var resultsItem in resultItems)
|
||||
{
|
||||
this.Children.Add(resultsItem);
|
||||
|
||||
if (!RemoveSubtractObjects)
|
||||
{
|
||||
#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,
|
||||
Processing,
|
||||
InputResolution,
|
||||
OutputResolution,
|
||||
reporter,
|
||||
cancellationToken);
|
||||
#else
|
||||
var totalOperations = removeItemsCount * keepItemsCount;
|
||||
double amountPerOperation = 1.0 / totalOperations;
|
||||
double ratioCompleted = 0;
|
||||
|
||||
var progressStatus = new ProgressStatus
|
||||
this.Children.Modify((list) =>
|
||||
{
|
||||
Status = "Do CSG"
|
||||
};
|
||||
|
||||
var resultsMesh = keep.Mesh;
|
||||
var keepWorldMatrix = keep.WorldMatrix(SourceContainer);
|
||||
|
||||
foreach (var remove in removeItems)
|
||||
{
|
||||
resultsMesh = BooleanProcessing.Do(resultsMesh,
|
||||
keepWorldMatrix,
|
||||
// other mesh
|
||||
remove.Mesh,
|
||||
remove.WorldMatrix(SourceContainer),
|
||||
// operation type
|
||||
CsgModes.Subtract,
|
||||
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
|
||||
// store our results mesh
|
||||
var resultsItem = new Object3D()
|
||||
{
|
||||
Mesh = resultsMesh,
|
||||
Visible = false,
|
||||
OwnerID = keep.ID
|
||||
};
|
||||
|
||||
// copy all the properties but the matrix
|
||||
resultsItem.CopyWorldProperties(keep, SourceContainer, Object3DPropertyFlags.All & (~(Object3DPropertyFlags.Matrix | Object3DPropertyFlags.Visible)));
|
||||
// and add it to this
|
||||
this.Children.Add(resultsItem);
|
||||
|
||||
if (!RemoveSubtractObjects)
|
||||
{
|
||||
this.Children.Modify((list) =>
|
||||
foreach (var item in removeItems)
|
||||
{
|
||||
foreach (var item in removeItems)
|
||||
var newObject = new Object3D()
|
||||
{
|
||||
var newObject = new Object3D()
|
||||
{
|
||||
Mesh = item.Mesh
|
||||
};
|
||||
Mesh = item.Mesh
|
||||
};
|
||||
|
||||
newObject.CopyWorldProperties(item, SourceContainer, Object3DPropertyFlags.All & (~Object3DPropertyFlags.Visible));
|
||||
list.Add(newObject);
|
||||
}
|
||||
});
|
||||
}
|
||||
newObject.CopyWorldProperties(item, SourceContainer, Object3DPropertyFlags.All & (~Object3DPropertyFlags.Visible));
|
||||
list.Add(newObject);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (Children.Count == 1)
|
||||
{
|
||||
// we only have the source item, leave it visible
|
||||
}
|
||||
else // hide the source and show the children
|
||||
{
|
||||
bool first = true;
|
||||
foreach (var child in Children)
|
||||
{
|
||||
|
|
@ -356,11 +304,98 @@ 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.WorldMatrix(sourceContainer);
|
||||
|
||||
foreach (var remove in removeItems)
|
||||
{
|
||||
resultsMesh = BooleanProcessing.Do(resultsMesh,
|
||||
keepWorldMatrix,
|
||||
// other mesh
|
||||
remove.Mesh,
|
||||
remove.WorldMatrix(sourceContainer),
|
||||
// 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
|
||||
resultsItem.CopyWorldProperties(keep, sourceContainer, 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)
|
||||
{
|
||||
var parentOfSubtractTargets = item.SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf();
|
||||
var parentOfSubtractTargets = item.SourceContainer.FirstWithMultipleChildrenDescendantsAndSelf();
|
||||
|
||||
var allVisibleIDs = parentOfSubtractTargets.Children.Select(i => i.ID);
|
||||
// remove any names from SelectedChildren that are not a child we can select
|
||||
|
|
@ -384,7 +419,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
|
||||
public override string NameFromChildren()
|
||||
{
|
||||
var (keepItems, removeItems) = GetSubtractItems();
|
||||
var (keepItems, removeItems) = GetSubtractItems(SourceContainer, SelectedChildren);
|
||||
return CalculateName(keepItems, ", ", " - ", removeItems, ", ");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
SourceContainer.Visible = true;
|
||||
RemoveAllButSource();
|
||||
|
||||
var parentOfSubtractTargets = SourceContainer.DescendantsAndSelfMultipleChildrenFirstOrSelf();
|
||||
var parentOfSubtractTargets = SourceContainer.FirstWithMultipleChildrenDescendantsAndSelf();
|
||||
|
||||
if (parentOfSubtractTargets.Children.Count() < 2)
|
||||
{
|
||||
|
|
@ -243,7 +243,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
{
|
||||
if (item is ISelectableChildContainer selectableChildContainer)
|
||||
{
|
||||
var parentOfSubtractTargets = item.DescendantsAndSelfMultipleChildrenFirstOrSelf();
|
||||
var parentOfSubtractTargets = item.FirstWithMultipleChildrenDescendantsAndSelf();
|
||||
|
||||
var allVisibleNames = parentOfSubtractTargets.Children.Select(i => i.ID);
|
||||
// remove any names from SelectedChildren that are not a child we can select
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue