diff --git a/PartPreviewWindow/PlatingHelper.cs b/PartPreviewWindow/PlatingHelper.cs index d8d42b23f..e0bdf714f 100644 --- a/PartPreviewWindow/PlatingHelper.cs +++ b/PartPreviewWindow/PlatingHelper.cs @@ -106,7 +106,7 @@ namespace MatterHackers.MatterControl public static void PlaceMeshGroupOnBed(List meshesGroupList, List meshTransforms, int index) { - AxisAlignedBoundingBox bounds = meshesGroupList[index].GetAxisAlignedBoundingBox(meshTransforms[index].TotalTransform); + AxisAlignedBoundingBox bounds = GetAxisAlignedBoundingBoxQuick(meshesGroupList[index], meshTransforms[index].TotalTransform); Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2; ScaleRotateTranslate moved = meshTransforms[index]; @@ -116,7 +116,7 @@ namespace MatterHackers.MatterControl public static void CenterMeshGroupXY(List meshesGroupList, List meshTransforms, int index) { - AxisAlignedBoundingBox bounds = meshesGroupList[index].GetAxisAlignedBoundingBox(meshTransforms[index].TotalTransform); + AxisAlignedBoundingBox bounds = GetAxisAlignedBoundingBoxQuick(meshesGroupList[index], meshTransforms[index].TotalTransform); Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2; ScaleRotateTranslate moved = meshTransforms[index]; @@ -131,6 +131,14 @@ namespace MatterHackers.MatterControl return; } + // first find the bounds of what is already here. + AxisAlignedBoundingBox allPlacedMeshBounds = GetAxisAlignedBoundingBoxQuick(meshesGroupsToAvoid[0], meshTransforms[0].TotalTransform); + for (int i = 1; i < meshesGroupsToAvoid.Count; i++) + { + AxisAlignedBoundingBox nextMeshBounds = GetAxisAlignedBoundingBoxQuick(meshesGroupsToAvoid[i], meshTransforms[i].TotalTransform); + allPlacedMeshBounds = AxisAlignedBoundingBox.Union(allPlacedMeshBounds, nextMeshBounds); + } + meshesGroupsToAvoid.Add(meshGroupToAdd); PlatingMeshGroupData newMeshInfo = new PlatingMeshGroupData(); @@ -140,63 +148,128 @@ namespace MatterHackers.MatterControl int meshGroupIndex = meshesGroupsToAvoid.Count - 1; - // now actually center the part we are going to finde a position for - CenterMeshGroupXY(meshesGroupsToAvoid, meshTransforms, meshGroupIndex); + // move the part to the total bounds lower left side + MeshGroup meshGroup = meshesGroupsToAvoid[meshGroupIndex]; + Vector3 meshLowerLeft = GetAxisAlignedBoundingBoxQuick(meshGroup, meshTransforms[meshGroupIndex].TotalTransform).minXYZ; + ScaleRotateTranslate atLowerLeft = meshTransforms[meshGroupIndex]; + atLowerLeft.translation *= Matrix4X4.CreateTranslation(-meshLowerLeft + allPlacedMeshBounds.minXYZ); + meshTransforms[meshGroupIndex] = atLowerLeft; MoveMeshGroupToOpenPosition(meshGroupIndex, perMeshInfo, meshesGroupsToAvoid, meshTransforms); PlaceMeshGroupOnBed(meshesGroupsToAvoid, meshTransforms, meshGroupIndex); } + internal class TransformCacheData + { + internal Matrix4X4 transform; + internal AxisAlignedBoundingBox boundingBox; + } + static Dictionary transformCache = new Dictionary(); + static AxisAlignedBoundingBox GetAxisAlignedBoundingBoxQuick(MeshGroup meshGroup, Matrix4X4 transform) + { + AxisAlignedBoundingBox boundingBox; + if (transformCache.ContainsKey(meshGroup)) + { + if (transformCache[meshGroup].transform == transform) + { + boundingBox = transformCache[meshGroup].boundingBox; + } + else + { + boundingBox = meshGroup.GetAxisAlignedBoundingBox(transform); + TransformCacheData data = new TransformCacheData(); + data.transform = transform; + data.boundingBox = boundingBox; + transformCache[meshGroup] = data; + } + } + else + { + boundingBox = meshGroup.GetAxisAlignedBoundingBox(transform); + TransformCacheData data = new TransformCacheData(); + data.transform = transform; + data.boundingBox = boundingBox; + transformCache.Add(meshGroup, data); + } + + return boundingBox; + } + public static void MoveMeshGroupToOpenPosition(int meshGroupToMoveIndex, List perMeshInfo, List allMeshGroups, List meshTransforms) { + AxisAlignedBoundingBox allPlacedMeshBounds = GetAxisAlignedBoundingBoxQuick(allMeshGroups[0], meshTransforms[0].TotalTransform); + for (int i = 1; i < meshGroupToMoveIndex; i++) + { + AxisAlignedBoundingBox nextMeshBounds = GetAxisAlignedBoundingBoxQuick(allMeshGroups[i], meshTransforms[i].TotalTransform); + allPlacedMeshBounds = AxisAlignedBoundingBox.Union(allPlacedMeshBounds, nextMeshBounds); + } + + double xStepAmount = 5; + double yStepAmount = 5; + double xStart = allPlacedMeshBounds.minXYZ.x; + double yStart = allPlacedMeshBounds.minXYZ.y; + MeshGroup meshGroupToMove = allMeshGroups[meshGroupToMoveIndex]; // find a place to put it that doesn't hit anything - AxisAlignedBoundingBox meshToMoveBounds = meshGroupToMove.GetAxisAlignedBoundingBox(meshTransforms[meshGroupToMoveIndex].TotalTransform); + AxisAlignedBoundingBox meshToMoveBounds = GetAxisAlignedBoundingBoxQuick(meshGroupToMove, meshTransforms[meshGroupToMoveIndex].TotalTransform); // add in a few mm so that it will not be touching meshToMoveBounds.minXYZ -= new Vector3(2, 2, 0); meshToMoveBounds.maxXYZ += new Vector3(2, 2, 0); - double ringDist = Math.Min(meshToMoveBounds.XSize, meshToMoveBounds.YSize); - double currentDist = 0; - double angle = 0; - double angleIncrement = MathHelper.Tau / 64; - Matrix4X4 transform; - while (true) + + int xSteps = (int)(allPlacedMeshBounds.XSize / xStepAmount) + 2; + int ySteps = (int)(allPlacedMeshBounds.YSize / yStepAmount) + 2; + + // If we have to expand the size of the total box should we do it in x or y? + if (allPlacedMeshBounds.XSize + meshToMoveBounds.XSize < allPlacedMeshBounds.YSize + meshToMoveBounds.YSize) { - Matrix4X4 positionTransform = Matrix4X4.CreateTranslation(currentDist, 0, 0); - positionTransform *= Matrix4X4.CreateRotationZ(angle); - Vector3 newPosition = Vector3.Transform(Vector3.Zero, positionTransform); - transform = Matrix4X4.CreateTranslation(newPosition); - AxisAlignedBoundingBox testBounds = meshToMoveBounds.NewTransformed(transform); - bool foundHit = false; - for (int i = 0; i < allMeshGroups.Count; i++) - { - MeshGroup meshToTest = allMeshGroups[i]; - if (meshToTest != meshGroupToMove) - { - AxisAlignedBoundingBox existingMeshBounds = meshToTest.GetAxisAlignedBoundingBox(meshTransforms[i].TotalTransform); - AxisAlignedBoundingBox intersection = AxisAlignedBoundingBox.Intersection(testBounds, existingMeshBounds); - if (intersection.XSize > 0 && intersection.YSize > 0) - { - foundHit = true; - break; - } - } - } - - if (!foundHit) - { - break; - } - - angle += angleIncrement; - if (angle >= MathHelper.Tau) - { - angle = 0; - currentDist += ringDist; - } + xSteps++; + } + else + { + xSteps-=3; + ySteps++; } + Matrix4X4 transform = Matrix4X4.Identity; + + for (int yStep = 0; yStep < ySteps; yStep++) + { + for (int xStep = 0; xStep < xSteps; xStep++) + { + Matrix4X4 positionTransform = Matrix4X4.CreateTranslation(xStep * xStepAmount, yStep * yStepAmount, 0); + Vector3 newPosition = Vector3.Transform(Vector3.Zero, positionTransform); + transform = Matrix4X4.CreateTranslation(newPosition); + AxisAlignedBoundingBox testBounds = meshToMoveBounds.NewTransformed(transform); + bool foundHit = false; + for (int i = 0; i < meshGroupToMoveIndex; i++) + { + MeshGroup meshToTest = allMeshGroups[i]; + if (meshToTest != meshGroupToMove) + { + AxisAlignedBoundingBox existingMeshBounds = GetAxisAlignedBoundingBoxQuick(meshToTest, meshTransforms[i].TotalTransform); + AxisAlignedBoundingBox intersection = AxisAlignedBoundingBox.Intersection(testBounds, existingMeshBounds); + if (intersection.XSize > 0 && intersection.YSize > 0) + { + foundHit = true; + // and move our x-step up past the thing we hit + while (xStep * xStepAmount < existingMeshBounds.maxXYZ.x) + { + xStep++; + } + break; + } + } + } + + if (!foundHit) + { + xStep = xSteps; + yStep = ySteps; + } + } + } + ScaleRotateTranslate moved = meshTransforms[meshGroupToMoveIndex]; moved.translation *= transform; meshTransforms[meshGroupToMoveIndex] = moved; diff --git a/PartPreviewWindow/View3D/View3DAutoArange.cs b/PartPreviewWindow/View3D/View3DAutoArange.cs index efd2319d0..a4023d042 100644 --- a/PartPreviewWindow/View3D/View3DAutoArange.cs +++ b/PartPreviewWindow/View3D/View3DAutoArange.cs @@ -71,7 +71,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow for (int i = 0; i < asynchMeshGroups.Count; i++) { ScaleRotateTranslate translate = asynchMeshGroupTransforms[i]; - translate.translation *= Matrix4X4.CreateTranslation(1000, 1000, 0); + translate.translation *= Matrix4X4.CreateTranslation(10000, 10000, 0); asynchMeshGroupTransforms[i] = translate; } @@ -111,18 +111,22 @@ namespace MatterHackers.MatterControl.PartPreviewWindow // put them onto the plate (try the center) starting with the biggest and moving down for (int meshGroupIndex = 0; meshGroupIndex < asynchMeshGroups.Count; meshGroupIndex++) { + bool continueProcessing2 = true; + BackgroundWorker_ProgressChanged(currentRatioDone, "Calculating Positions...".Localize(), out continueProcessing2); + MeshGroup meshGroup = asynchMeshGroups[meshGroupIndex]; - Vector3 meshCenter = meshGroup.GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[meshGroupIndex].translation).Center; + Vector3 meshLowerLeft = meshGroup.GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[meshGroupIndex].TotalTransform).minXYZ; ScaleRotateTranslate atZero = asynchMeshGroupTransforms[meshGroupIndex]; - atZero.translation = Matrix4X4.Identity; + atZero.translation *= Matrix4X4.CreateTranslation(-meshLowerLeft); asynchMeshGroupTransforms[meshGroupIndex] = atZero; + PlatingHelper.MoveMeshGroupToOpenPosition(meshGroupIndex, asynchPlatingDatas, asynchMeshGroups, asynchMeshGroupTransforms); // and create the trace info so we can select it - PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, meshGroupIndex, (double progress0To1, string processingState, out bool continueProcessing) => + if (asynchPlatingDatas[meshGroupIndex].meshTraceableData.Count == 0) { - BackgroundWorker_ProgressChanged(progress0To1, processingState, out continueProcessing); - }); + PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, meshGroupIndex, null); + } currentRatioDone += ratioPerMeshGroup; diff --git a/PartPreviewWindow/View3D/View3DWidget.cs b/PartPreviewWindow/View3D/View3DWidget.cs index 78c1f5e7d..1d5356a78 100644 --- a/PartPreviewWindow/View3D/View3DWidget.cs +++ b/PartPreviewWindow/View3D/View3DWidget.cs @@ -317,12 +317,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { Vector3 delta = info.hitPosition - meshSelectInfo.planeDownHitPos; - Matrix4X4 totalTransfrom = Matrix4X4.CreateTranslation(new Vector3(-meshSelectInfo.lastMoveDelta)); - totalTransfrom *= Matrix4X4.CreateTranslation(new Vector3(delta)); + Matrix4X4 totalTransform = Matrix4X4.CreateTranslation(new Vector3(-meshSelectInfo.lastMoveDelta)); + totalTransform *= Matrix4X4.CreateTranslation(new Vector3(delta)); meshSelectInfo.lastMoveDelta = delta; ScaleRotateTranslate translated = SelectedMeshGroupTransform; - translated.translation *= totalTransfrom; + translated.translation *= totalTransform; SelectedMeshGroupTransform = translated; Invalidate(); diff --git a/StaticData/Translations/Master.txt b/StaticData/Translations/Master.txt index 02f63bef5..c9ec42342 100644 --- a/StaticData/Translations/Master.txt +++ b/StaticData/Translations/Master.txt @@ -3194,3 +3194,6 @@ Translated:Bottom Solid Layers: English:This will cause the extruder to try to wipe itself after retracting to minimize strings. Translated:This will cause the extruder to try to wipe itself after retracting to minimize strings. +English:Calculating Positions... +Translated:Calculating Positions... + diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index e8005d107..a70958022 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit e8005d107dcb0640990d0934d5a68405c8dad0bf +Subproject commit a70958022dc4428ca67aedb4c77909e2222a8544 diff --git a/TextCreator/View3DTextCreator.cs b/TextCreator/View3DTextCreator.cs index b13910b96..52b003df7 100644 --- a/TextCreator/View3DTextCreator.cs +++ b/TextCreator/View3DTextCreator.cs @@ -365,12 +365,12 @@ namespace MatterHackers.MatterControl.Plugins.TextCreator { Vector3 delta = info.hitPosition - meshSelectInfo.planeDownHitPos; - Matrix4X4 totalTransfrom = Matrix4X4.CreateTranslation(new Vector3(-meshSelectInfo.lastMoveDelta)); - totalTransfrom *= Matrix4X4.CreateTranslation(new Vector3(delta)); + Matrix4X4 totalTransform = Matrix4X4.CreateTranslation(new Vector3(-meshSelectInfo.lastMoveDelta)); + totalTransform *= Matrix4X4.CreateTranslation(new Vector3(delta)); meshSelectInfo.lastMoveDelta = delta; ScaleRotateTranslate translated = SelectedMeshTransform; - translated.translation *= totalTransfrom; + translated.translation *= totalTransform; SelectedMeshTransform = translated; Invalidate();