public void SetCenteringForMeshGroup(MeshGroup meshGroup) { AxisAlignedBoundingBox bounds = meshGroup.GetAxisAlignedBoundingBox(); Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2; centering = Matrix4X4.CreateTranslation(-boundsCenter); // and move the translation back so the part does not move translation *= Matrix4X4.CreateTranslation(boundsCenter); }
public static void MoveMeshGroupToOpenPosition(int meshGroupToMoveIndex, List <PlatingMeshGroupData> perMeshInfo, List <MeshGroup> allMeshGroups, List <ScaleRotateTranslate> meshTransforms) { MeshGroup meshGroupToMove = allMeshGroups[meshGroupToMoveIndex]; // find a place to put it that doesn't hit anything AxisAlignedBoundingBox meshToMoveBounds = meshGroupToMove.GetAxisAlignedBoundingBox(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) { 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; } } ScaleRotateTranslate moved = meshTransforms[meshGroupToMoveIndex]; moved.translation *= transform; meshTransforms[meshGroupToMoveIndex] = moved; }
static AxisAlignedBoundingBox GetAxisAlignedBoundingBox(MeshGroup meshGroup, Matrix4X4 transform) { return(meshGroup.GetAxisAlignedBoundingBox(transform)); }
private void AlignSelected() { if (SelectedMeshGroupIndex == -1) { SelectedMeshGroupIndex = 0; } // make sure our thread traslates numbmers correctly (always do this in a thread) Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; // save our data so we don't mess up the display while doing work PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DO_COPY); // try to move all the not selected meshes relative to the selected mesh AxisAlignedBoundingBox selectedOriginalBounds = asyncMeshGroups[SelectedMeshGroupIndex].GetAxisAlignedBoundingBox(); Vector3 selectedOriginalCenter = selectedOriginalBounds.Center; AxisAlignedBoundingBox selectedCurrentBounds = asyncMeshGroups[SelectedMeshGroupIndex].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[SelectedMeshGroupIndex].TotalTransform); Vector3 selctedCurrentCenter = selectedCurrentBounds.Center; for (int meshGroupToMoveIndex = 0; meshGroupToMoveIndex < asyncMeshGroups.Count; meshGroupToMoveIndex++) { MeshGroup meshGroupToMove = asyncMeshGroups[meshGroupToMoveIndex]; if (meshGroupToMove != asyncMeshGroups[SelectedMeshGroupIndex]) { AxisAlignedBoundingBox groupToMoveOriginalBounds = meshGroupToMove.GetAxisAlignedBoundingBox(); Vector3 groupToMoveOriginalCenter = groupToMoveOriginalBounds.Center; AxisAlignedBoundingBox groupToMoveBounds = meshGroupToMove.GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[meshGroupToMoveIndex].TotalTransform); Vector3 groupToMoveCenter = groupToMoveBounds.Center; Vector3 originalCoordinatesDelta = groupToMoveOriginalCenter - selectedOriginalCenter; Vector3 currentCoordinatesDelta = groupToMoveCenter - selctedCurrentCenter; Vector3 deltaRequired = originalCoordinatesDelta - currentCoordinatesDelta; if (deltaRequired.Length > .0001) { ScaleRotateTranslate translated = asyncMeshGroupTransforms[meshGroupToMoveIndex]; translated.translation *= Matrix4X4.CreateTranslation(deltaRequired); asyncMeshGroupTransforms[meshGroupToMoveIndex] = translated; PartHasBeenChanged(); } } } // now put all the meshes into just one group MeshGroup meshGroupWeAreKeeping = asyncMeshGroups[SelectedMeshGroupIndex]; for (int meshGroupToMoveIndex = asyncMeshGroups.Count - 1; meshGroupToMoveIndex >= 0; meshGroupToMoveIndex--) { MeshGroup meshGroupToMove = asyncMeshGroups[meshGroupToMoveIndex]; if (meshGroupToMove != meshGroupWeAreKeeping) { // move all the meshes into the new aligned mesh group for (int moveIndex = 0; moveIndex < meshGroupToMove.Meshes.Count; moveIndex++) { Mesh mesh = meshGroupToMove.Meshes[moveIndex]; meshGroupWeAreKeeping.Meshes.Add(mesh); } asyncMeshGroups.RemoveAt(meshGroupToMoveIndex); asyncMeshGroupTransforms.RemoveAt(meshGroupToMoveIndex); } } asyncPlatingDatas.Clear(); double ratioPerMeshGroup = 1.0 / asyncMeshGroups.Count; double currentRatioDone = 0; for (int i = 0; i < asyncMeshGroups.Count; i++) { PlatingMeshGroupData newInfo = new PlatingMeshGroupData(); asyncPlatingDatas.Add(newInfo); MeshGroup meshGroup = asyncMeshGroups[i]; // create the selection info PlatingHelper.CreateITraceableForMeshGroup(asyncPlatingDatas, asyncMeshGroups, i, (double progress0To1, string processingState, out bool continueProcessing) => { ReportProgressChanged(progress0To1, processingState, out continueProcessing); }); currentRatioDone += ratioPerMeshGroup; } }
public static void ArrangeMeshGroups(List <MeshGroup> asyncMeshGroups, List <ScaleRotateTranslate> asyncMeshGroupTransforms, List <PlatingMeshGroupData> asyncPlatingDatas, Action <double, string> reportProgressChanged) { // move them all out of the way for (int i = 0; i < asyncMeshGroups.Count; i++) { ScaleRotateTranslate translate = asyncMeshGroupTransforms[i]; translate.translation *= Matrix4X4.CreateTranslation(10000, 10000, 0); asyncMeshGroupTransforms[i] = translate; } // sort them by size for (int i = 0; i < asyncMeshGroups.Count; i++) { AxisAlignedBoundingBox iAABB = asyncMeshGroups[i].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[i].TotalTransform); for (int j = i + 1; j < asyncMeshGroups.Count; j++) { AxisAlignedBoundingBox jAABB = asyncMeshGroups[j].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[j].TotalTransform); if (Math.Max(iAABB.XSize, iAABB.YSize) < Math.Max(jAABB.XSize, jAABB.YSize)) { PlatingMeshGroupData tempData = asyncPlatingDatas[i]; asyncPlatingDatas[i] = asyncPlatingDatas[j]; asyncPlatingDatas[j] = tempData; MeshGroup tempMeshGroup = asyncMeshGroups[i]; asyncMeshGroups[i] = asyncMeshGroups[j]; asyncMeshGroups[j] = tempMeshGroup; ScaleRotateTranslate iTransform = asyncMeshGroupTransforms[i]; ScaleRotateTranslate jTransform = asyncMeshGroupTransforms[j]; Matrix4X4 tempTransform = iTransform.translation; iTransform.translation = jTransform.translation; jTransform.translation = tempTransform; asyncMeshGroupTransforms[i] = jTransform; asyncMeshGroupTransforms[j] = iTransform; iAABB = jAABB; } } } double ratioPerMeshGroup = 1.0 / asyncMeshGroups.Count; double currentRatioDone = 0; // put them onto the plate (try the center) starting with the biggest and moving down for (int meshGroupIndex = 0; meshGroupIndex < asyncMeshGroups.Count; meshGroupIndex++) { reportProgressChanged(currentRatioDone, "Calculating Positions...".Localize()); MeshGroup meshGroup = asyncMeshGroups[meshGroupIndex]; Vector3 meshLowerLeft = meshGroup.GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[meshGroupIndex].TotalTransform).minXYZ; ScaleRotateTranslate atZero = asyncMeshGroupTransforms[meshGroupIndex]; atZero.translation *= Matrix4X4.CreateTranslation(-meshLowerLeft); asyncMeshGroupTransforms[meshGroupIndex] = atZero; PlatingHelper.MoveMeshGroupToOpenPosition(meshGroupIndex, asyncPlatingDatas, asyncMeshGroups, asyncMeshGroupTransforms); // and create the trace info so we can select it if (asyncPlatingDatas[meshGroupIndex].meshTraceableData.Count == 0) { PlatingHelper.CreateITraceableForMeshGroup(asyncPlatingDatas, asyncMeshGroups, meshGroupIndex, null); } currentRatioDone += ratioPerMeshGroup; // and put it on the bed PlatingHelper.PlaceMeshGroupOnBed(asyncMeshGroups, asyncMeshGroupTransforms, meshGroupIndex); } // and finally center whatever we have as a group { AxisAlignedBoundingBox bounds = asyncMeshGroups[0].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[0].TotalTransform); for (int i = 1; i < asyncMeshGroups.Count; i++) { bounds = AxisAlignedBoundingBox.Union(bounds, asyncMeshGroups[i].GetAxisAlignedBoundingBox(asyncMeshGroupTransforms[i].TotalTransform)); } Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2; for (int i = 0; i < asyncMeshGroups.Count; i++) { ScaleRotateTranslate translate = asyncMeshGroupTransforms[i]; translate.translation *= Matrix4X4.CreateTranslation(-boundsCenter + new Vector3(0, 0, bounds.ZSize / 2)); asyncMeshGroupTransforms[i] = translate; } } }
private void arrangeMeshGroupsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DONT_COPY); BackgroundWorker backgroundWorker = (BackgroundWorker)sender; // move them all out of the way for (int i = 0; i < asynchMeshGroups.Count; i++) { ScaleRotateTranslate translate = asynchMeshGroupTransforms[i]; translate.translation *= Matrix4X4.CreateTranslation(10000, 10000, 0); asynchMeshGroupTransforms[i] = translate; } // sort them by size for (int i = 0; i < asynchMeshGroups.Count; i++) { AxisAlignedBoundingBox iAABB = asynchMeshGroups[i].GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[i].TotalTransform); for (int j = i + 1; j < asynchMeshGroups.Count; j++) { AxisAlignedBoundingBox jAABB = asynchMeshGroups[j].GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[j].TotalTransform); if (Math.Max(iAABB.XSize, iAABB.YSize) < Math.Max(jAABB.XSize, jAABB.YSize)) { PlatingMeshGroupData tempData = asynchPlatingDatas[i]; asynchPlatingDatas[i] = asynchPlatingDatas[j]; asynchPlatingDatas[j] = tempData; MeshGroup tempMeshGroup = asynchMeshGroups[i]; asynchMeshGroups[i] = asynchMeshGroups[j]; asynchMeshGroups[j] = tempMeshGroup; ScaleRotateTranslate iTransform = asynchMeshGroupTransforms[i]; ScaleRotateTranslate jTransform = asynchMeshGroupTransforms[j]; Matrix4X4 tempTransform = iTransform.translation; iTransform.translation = jTransform.translation; jTransform.translation = tempTransform; asynchMeshGroupTransforms[i] = jTransform; asynchMeshGroupTransforms[j] = iTransform; iAABB = jAABB; } } } double ratioPerMeshGroup = 1.0 / asynchMeshGroups.Count; double currentRatioDone = 0; // 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; ReportProgressChanged(currentRatioDone, "Calculating Positions...".Localize(), out continueProcessing2); MeshGroup meshGroup = asynchMeshGroups[meshGroupIndex]; Vector3 meshLowerLeft = meshGroup.GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[meshGroupIndex].TotalTransform).minXYZ; ScaleRotateTranslate atZero = asynchMeshGroupTransforms[meshGroupIndex]; atZero.translation *= Matrix4X4.CreateTranslation(-meshLowerLeft); asynchMeshGroupTransforms[meshGroupIndex] = atZero; PlatingHelper.MoveMeshGroupToOpenPosition(meshGroupIndex, asynchPlatingDatas, asynchMeshGroups, asynchMeshGroupTransforms); // and create the trace info so we can select it if (asynchPlatingDatas[meshGroupIndex].meshTraceableData.Count == 0) { PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, meshGroupIndex, null); } currentRatioDone += ratioPerMeshGroup; // and put it on the bed PlatingHelper.PlaceMeshGroupOnBed(asynchMeshGroups, asynchMeshGroupTransforms, meshGroupIndex); } // and finally center whatever we have as a group { AxisAlignedBoundingBox bounds = asynchMeshGroups[0].GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[0].TotalTransform); for (int i = 1; i < asynchMeshGroups.Count; i++) { bounds = AxisAlignedBoundingBox.Union(bounds, asynchMeshGroups[i].GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[i].TotalTransform)); } Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2; for (int i = 0; i < asynchMeshGroups.Count; i++) { ScaleRotateTranslate translate = asynchMeshGroupTransforms[i]; translate.translation *= Matrix4X4.CreateTranslation(-boundsCenter + new Vector3(0, 0, bounds.ZSize / 2)); asynchMeshGroupTransforms[i] = translate; } } }