private void CreateBase(List <MeshGroup> meshesList, List <ScaleRotateTranslate> meshTransforms, List <PlatingMeshGroupData> platingDataList) { if (meshesList.Count > 0) { AxisAlignedBoundingBox bounds = meshesList[0].GetAxisAlignedBoundingBox(meshTransforms[0].TotalTransform); for (int i = 1; i < meshesList.Count; i++) { bounds = AxisAlignedBoundingBox.Union(bounds, meshesList[i].GetAxisAlignedBoundingBox(meshTransforms[i].TotalTransform)); } double roundingScale = 20; RectangleDouble baseRect = new RectangleDouble(bounds.minXYZ.x, bounds.minXYZ.y, bounds.maxXYZ.x, bounds.maxXYZ.y); baseRect.Inflate(2); baseRect *= roundingScale; RoundedRect baseRoundedRect = new RoundedRect(baseRect, 1 * roundingScale); Mesh baseMeshResult = VertexSourceToMesh.Extrude(baseRoundedRect, unscaledBaseHeight / 2 * roundingScale * sizeScrollBar.Value * heightScrollBar.Value); baseMeshResult.Transform(Matrix4X4.CreateScale(1 / roundingScale)); meshesList.Add(new MeshGroup(baseMeshResult)); platingDataList.Add(new PlatingMeshGroupData()); meshTransforms.Add(ScaleRotateTranslate.CreateTranslation(0, 0, 0)); PlatingHelper.CreateITraceableForMeshGroup(platingDataList, meshesList, meshesList.Count - 1, null); } }
private void SetWordSize(List <MeshGroup> meshesList, List <ScaleRotateTranslate> meshTransforms) { if (meshesList.Count > 0) { for (int meshIndex = 0; meshIndex < meshesList.Count; meshIndex++) { Vector3 startPositionRelCenter = Vector3.Transform(Vector3.Zero, meshTransforms[meshIndex].translation); // take out the last scale double oldSize = 1.0 / lastSizeValue; Vector3 unscaledStartPositionRelCenter = startPositionRelCenter * oldSize; double newSize = sizeScrollBar.Value; Vector3 endPositionRelCenter = unscaledStartPositionRelCenter * newSize; Vector3 deltaPosition = endPositionRelCenter - startPositionRelCenter; // move the part to keep it in the same relative position ScaleRotateTranslate scale = meshTransforms[meshIndex]; scale.scale *= Matrix4X4.CreateScale(new Vector3(oldSize, oldSize, oldSize)); scale.scale *= Matrix4X4.CreateScale(new Vector3(newSize, newSize, newSize)); scale.translation *= Matrix4X4.CreateTranslation(deltaPosition); meshTransforms[meshIndex] = scale; } lastSizeValue = sizeScrollBar.Value; } CenterTextOnScreen(meshesList, meshTransforms); }
public static void CenterMeshesXY(List <Mesh> meshesList, List <ScaleRotateTranslate> meshTransforms) { bool first = true; AxisAlignedBoundingBox totalBounds = new AxisAlignedBoundingBox(new Vector3(), new Vector3()); for (int index = 0; index < meshesList.Count; index++) { if (first) { totalBounds = meshesList[index].GetAxisAlignedBoundingBox(meshTransforms[index].TotalTransform); first = false; } else { AxisAlignedBoundingBox bounds = meshesList[index].GetAxisAlignedBoundingBox(meshTransforms[index].TotalTransform); totalBounds = AxisAlignedBoundingBox.Union(totalBounds, bounds); } } Vector3 boundsCenter = (totalBounds.maxXYZ + totalBounds.minXYZ) / 2; boundsCenter.z = 0; for (int index = 0; index < meshesList.Count; index++) { ScaleRotateTranslate moved = meshTransforms[index]; moved.translation *= Matrix4X4.CreateTranslation(-boundsCenter); meshTransforms[index] = moved; } }
public override void OnMouseMove(MouseEventArgs mouseEvent) { if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None && meshSelectInfo.downOnPart) { Vector2 meshViewerWidgetScreenPosition = meshViewerWidget.TransformFromParentSpace(this, new Vector2(mouseEvent.X, mouseEvent.Y)); Ray ray = meshViewerWidget.TrackballTumbleWidget.GetRayFromScreen(meshViewerWidgetScreenPosition); IntersectInfo info = meshSelectInfo.hitPlane.GetClosestIntersection(ray); if (info != null) { Vector3 delta = info.hitPosition - meshSelectInfo.planeDownHitPos; Matrix4X4 totalTransform = Matrix4X4.CreateTranslation(new Vector3(-meshSelectInfo.lastMoveDelta)); totalTransform *= Matrix4X4.CreateTranslation(new Vector3(delta)); meshSelectInfo.lastMoveDelta = delta; ScaleRotateTranslate translated = SelectedMeshTransform; translated.translation *= totalTransform; SelectedMeshTransform = translated; Invalidate(); } } base.OnMouseMove(mouseEvent); }
private void insertTextBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; BackgroundWorker backgroundWorker = (BackgroundWorker)sender; asynchMeshGroups.Clear(); asynchMeshGroupTransforms.Clear(); asynchPlatingDatas.Clear(); string currentText = (string)e.Argument; TypeFacePrinter printer = new TypeFacePrinter(currentText, new StyledTypeFace(boldTypeFace, 12)); Vector2 size = printer.GetSize(currentText); double centerOffset = -size.x / 2; double ratioPerMeshGroup = 1.0 / currentText.Length; double currentRatioDone = 0; for (int i = 0; i < currentText.Length; i++) { int newIndex = asynchMeshGroups.Count; TypeFacePrinter letterPrinter = new TypeFacePrinter(currentText[i].ToString(), new StyledTypeFace(boldTypeFace, 12)); Mesh textMesh = VertexSourceToMesh.Extrude(letterPrinter, 10 + (i % 2)); if (textMesh.Faces.Count > 0) { asynchMeshGroups.Add(new MeshGroup(textMesh)); PlatingMeshGroupData newMeshInfo = new PlatingMeshGroupData(); newMeshInfo.xSpacing = printer.GetOffsetLeftOfCharacterIndex(i).x + centerOffset; asynchPlatingDatas.Add(newMeshInfo); asynchMeshGroupTransforms.Add(ScaleRotateTranslate.Identity()); PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, newIndex, (double progress0To1, string processingState, out bool continueProcessing) => { continueProcessing = true; int nextPercent = (int)((currentRatioDone + ratioPerMeshGroup * progress0To1) * 100); backgroundWorker.ReportProgress(nextPercent); }); currentRatioDone += ratioPerMeshGroup; PlatingHelper.PlaceMeshGroupOnBed(asynchMeshGroups, asynchMeshGroupTransforms, newIndex); } backgroundWorker.ReportProgress((i + 1) * 95 / currentText.Length); } SetWordSpacing(asynchMeshGroups, asynchMeshGroupTransforms, asynchPlatingDatas); SetWordSize(asynchMeshGroups, asynchMeshGroupTransforms); SetWordHeight(asynchMeshGroups, asynchMeshGroupTransforms); if (createUnderline.Checked) { CreateUnderline(asynchMeshGroups, asynchMeshGroupTransforms, asynchPlatingDatas); } backgroundWorker.ReportProgress(95); }
private async void AutoArrangePartsInBackground() { if (MeshGroups.Count > 0) { string progressArrangeParts = LocalizedString.Get("Arranging Parts"); string progressArrangePartsFull = string.Format("{0}:", progressArrangeParts); processingProgressControl.ProcessType = progressArrangePartsFull; processingProgressControl.Visible = true; processingProgressControl.PercentComplete = 0; LockEditControls(); await Task.Run((System.Action) ArrangeMeshGroups); if (WidgetHasBeenClosed) { return; } // offset them to the centor of the bed for (int i = 0; i < asynchMeshGroups.Count; i++) { ScaleRotateTranslate translate = asynchMeshGroupTransforms[i]; translate.translation *= Matrix4X4.CreateTranslation(new Vector3(ActiveSliceSettings.Instance.BedCenter, 0)); asynchMeshGroupTransforms[i] = translate; } UnlockEditControls(); PartHasBeenChanged(); PullMeshGroupDataFromAsynchLists(); } }
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; }
public static void PlaceMeshGroupOnBed(List <MeshGroup> meshesGroupList, List <ScaleRotateTranslate> meshTransforms, int index) { AxisAlignedBoundingBox bounds = meshesGroupList[index].GetAxisAlignedBoundingBox(meshTransforms[index].TotalTransform); Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2; ScaleRotateTranslate moved = meshTransforms[index]; moved.translation *= Matrix4X4.CreateTranslation(new Vector3(0, 0, -boundsCenter.z + bounds.ZSize / 2)); meshTransforms[index] = moved; }
public static void CenterMeshGroupXY(List <MeshGroup> meshesGroupList, List <ScaleRotateTranslate> meshTransforms, int index) { AxisAlignedBoundingBox bounds = GetAxisAlignedBoundingBox(meshesGroupList[index], meshTransforms[index].TotalTransform); Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2; ScaleRotateTranslate moved = meshTransforms[index]; moved.translation *= Matrix4X4.CreateTranslation(new Vector3(-boundsCenter.x + bounds.XSize / 2, -boundsCenter.y + bounds.YSize / 2, 0)); meshTransforms[index] = moved; }
private void AddCharacterMeshes(string currentText, TypeFacePrinter printer) { int newIndex = asyncMeshGroups.Count; StyledTypeFace typeFace = printer.TypeFaceStyle; for (int i = 0; i < currentText.Length; i++) { string letter = currentText[i].ToString(); TypeFacePrinter letterPrinter = new TypeFacePrinter(letter, typeFace); if (CharacterHasMesh(letterPrinter, letter)) { #if true Mesh textMesh = VertexSourceToMesh.Extrude(letterPrinter, unscaledLetterHeight / 2); #else Mesh textMesh = VertexSourceToMesh.Extrude(letterPrinter, unscaledLetterHeight / 2); // this is the code to make rounded tops // convert the letterPrinter to clipper polygons List <List <IntPoint> > insetPoly = VertexSourceToPolygon.CreatePolygons(letterPrinter); // inset them ClipperOffset clipper = new ClipperOffset(); clipper.AddPaths(insetPoly, JoinType.jtMiter, EndType.etClosedPolygon); List <List <IntPoint> > solution = new List <List <IntPoint> >(); clipper.Execute(solution, 5.0); // convert them back into a vertex source // merge both the inset and original vertex sources together // convert the new vertex source into a mesh (trianglulate them) // offset the inner loop in z // create the polygons from the inner loop to a center point so that there is the rest of an approximation of the bubble // make the mesh for the bottom // add the top and bottom together // done #endif asyncMeshGroups.Add(new MeshGroup(textMesh)); PlatingMeshGroupData newMeshInfo = new PlatingMeshGroupData(); newMeshInfo.spacing = printer.GetOffsetLeftOfCharacterIndex(i); asyncPlatingDatas.Add(newMeshInfo); asyncMeshGroupTransforms.Add(ScaleRotateTranslate.Identity()); PlatingHelper.CreateITraceableForMeshGroup(asyncPlatingDatas, asyncMeshGroups, newIndex, null); ScaleRotateTranslate moved = asyncMeshGroupTransforms[newIndex]; moved.translation *= Matrix4X4.CreateTranslation(new Vector3(0, 0, unscaledLetterHeight / 2)); asyncMeshGroupTransforms[newIndex] = moved; newIndex++; } processingProgressControl.PercentComplete = ((i + 1) * 95 / currentText.Length); } }
private void DoGroup(BackgroundWorker backgroundWorker) { if (SelectedMeshGroupIndex == -1) { SelectedMeshGroupIndex = 0; } MeshGroup meshGroupWeAreKeeping = asynchMeshGroups[SelectedMeshGroupIndex]; for (int meshGroupToMoveIndex = asynchMeshGroups.Count - 1; meshGroupToMoveIndex >= 0; meshGroupToMoveIndex--) { MeshGroup meshGroupToMove = asynchMeshGroups[meshGroupToMoveIndex]; if (meshGroupToMove != meshGroupWeAreKeeping) { for (int moveIndex = 0; moveIndex < meshGroupToMove.Meshes.Count; moveIndex++) { Mesh mesh = meshGroupToMove.Meshes[moveIndex]; meshGroupWeAreKeeping.Meshes.Add(mesh); } asynchMeshGroups.RemoveAt(meshGroupToMoveIndex); asynchMeshGroupTransforms.RemoveAt(meshGroupToMoveIndex); } else { asynchMeshGroupTransforms[meshGroupToMoveIndex] = ScaleRotateTranslate.Identity(); } } asynchPlatingDatas.Clear(); double ratioPerMeshGroup = 1.0 / asynchMeshGroups.Count; double currentRatioDone = 0; for (int i = 0; i < asynchMeshGroups.Count; i++) { PlatingMeshGroupData newInfo = new PlatingMeshGroupData(); asynchPlatingDatas.Add(newInfo); MeshGroup meshGroup = asynchMeshGroups[i]; // create the selection info PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, i, (double progress0To1, string processingState, out bool continueProcessing) => { ReportProgressChanged(progress0To1, processingState, out continueProcessing); }); currentRatioDone += ratioPerMeshGroup; } }
void ungroupSelectedBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { string makingCopyLabel = LocalizedString.Get("Ungrouping"); string makingCopyLabelFull = string.Format("{0}:", makingCopyLabel); processingProgressControl.ProcessType = makingCopyLabelFull; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; BackgroundWorker backgroundWorker = (BackgroundWorker)sender; PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DO_COPY); int indexBeingReplaced = SelectedMeshGroupIndex; asynchMeshGroups[indexBeingReplaced].Transform(asynchMeshGroupTransforms[indexBeingReplaced].TotalTransform); List <Mesh> discreetMeshes = CreateDiscreteMeshes.SplitConnectedIntoMeshes(asynchMeshGroups[indexBeingReplaced], (double progress0To1, string processingState, out bool continueProcessing) => { BackgroundWorker_ProgressChanged(progress0To1 * .5, processingState, out continueProcessing); }); asynchMeshGroups.RemoveAt(indexBeingReplaced); asynchPlatingDatas.RemoveAt(indexBeingReplaced); asynchMeshGroupTransforms.RemoveAt(indexBeingReplaced); double ratioPerDiscreetMesh = 1.0 / discreetMeshes.Count; double currentRatioDone = 0; for (int discreetMeshIndex = 0; discreetMeshIndex < discreetMeshes.Count; discreetMeshIndex++) { PlatingMeshGroupData newInfo = new PlatingMeshGroupData(); asynchPlatingDatas.Add(newInfo); asynchMeshGroups.Add(new MeshGroup(discreetMeshes[discreetMeshIndex])); int addedMeshIndex = asynchMeshGroups.Count - 1; MeshGroup addedMeshGroup = asynchMeshGroups[addedMeshIndex]; ScaleRotateTranslate transform = ScaleRotateTranslate.Identity(); transform.SetCenteringForMeshGroup(addedMeshGroup); asynchMeshGroupTransforms.Add(transform); //PlatingHelper.PlaceMeshGroupOnBed(asynchMeshGroups, asynchMeshGroupTransforms, addedMeshIndex, false); // and create selection info PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, addedMeshIndex, (double progress0To1, string processingState, out bool continueProcessing) => { BackgroundWorker_ProgressChanged(progress0To1 * .5 + .5, processingState, out continueProcessing); }); currentRatioDone += ratioPerDiscreetMesh; } }
private void SetWordSpacing(List <MeshGroup> meshesList, List <ScaleRotateTranslate> meshTransforms, List <PlatingMeshGroupData> platingDataList) { if (meshesList.Count > 0) { for (int meshIndex = 0; meshIndex < meshesList.Count; meshIndex++) { Vector3 startPosition = Vector3.Transform(Vector3.Zero, meshTransforms[meshIndex].translation); ScaleRotateTranslate translation = meshTransforms[meshIndex]; translation.translation *= Matrix4X4.CreateTranslation(-startPosition); double newX = platingDataList[meshIndex].spacing.x * spacingScrollBar.Value * lastSizeValue; translation.translation *= Matrix4X4.CreateTranslation(new Vector3(newX, 0, 0) + new Vector3(MeshViewerWidget.BedCenter)); meshTransforms[meshIndex] = translation; } } }
private void SetWordSize(List <MeshGroup> meshesList, List <ScaleRotateTranslate> meshTransforms) { if (meshesList.Count > 0) { for (int meshIndex = 0; meshIndex < meshesList.Count; meshIndex++) { // take out the last scale double oldSize = 1.0 / lastSizeValue; ScaleRotateTranslate scale = meshTransforms[meshIndex]; scale.scale *= Matrix4X4.CreateScale(new Vector3(oldSize, oldSize, oldSize)); double newSize = sizeScrollBar.Value; scale.scale *= Matrix4X4.CreateScale(new Vector3(newSize, newSize, newSize)); meshTransforms[meshIndex] = scale; } lastSizeValue = sizeScrollBar.Value; } }
private void SetWordHeight(List <MeshGroup> meshesList, List <ScaleRotateTranslate> meshTransforms) { if (meshesList.Count > 0) { for (int meshIndex = 0; meshIndex < meshesList.Count; meshIndex++) { // take out the last scale double oldHeight = lastHeightValue; ScaleRotateTranslate scale = meshTransforms[meshIndex]; scale.scale *= Matrix4X4.CreateScale(new Vector3(1, 1, 1 / oldHeight)); double newHeight = heightScrollBar.Value; scale.scale *= Matrix4X4.CreateScale(new Vector3(1, 1, newHeight)); meshTransforms[meshIndex] = scale; } lastHeightValue = heightScrollBar.Value; } }
private void CreateUnderline(List <MeshGroup> meshesList, List <ScaleRotateTranslate> meshTransforms, List <PlatingMeshGroupData> platingDataList) { if (meshesList.Count > 0) { AxisAlignedBoundingBox bounds = meshesList[0].GetAxisAlignedBoundingBox(meshTransforms[0].TotalTransform); for (int i = 1; i < meshesList.Count; i++) { bounds = AxisAlignedBoundingBox.Union(bounds, meshesList[i].GetAxisAlignedBoundingBox(meshTransforms[i].TotalTransform)); } double xSize = bounds.XSize; double ySize = sizeScrollBar.Value * 3; double zSize = bounds.ZSize / 3; Mesh connectionLine = PlatonicSolids.CreateCube(xSize, ySize, zSize); meshesList.Add(new MeshGroup(connectionLine)); platingDataList.Add(new PlatingMeshGroupData()); meshTransforms.Add(ScaleRotateTranslate.CreateTranslation((bounds.maxXYZ.x + bounds.minXYZ.x) / 2, bounds.minXYZ.y + ySize / 2 - ySize * 1 / 3, zSize / 2)); PlatingHelper.CreateITraceableForMeshGroup(platingDataList, meshesList, meshesList.Count - 1, null); } }
private void CenterTextOnScreen(List <MeshGroup> meshesList, List <ScaleRotateTranslate> meshTransforms) { // center in y if (meshesList.Count > 0) { AxisAlignedBoundingBox bounds = meshesList[0].GetAxisAlignedBoundingBox(meshTransforms[0].TotalTransform); for (int i = 1; i < meshesList.Count; i++) { bounds = AxisAlignedBoundingBox.Union(bounds, meshesList[i].GetAxisAlignedBoundingBox(meshTransforms[i].TotalTransform)); } Vector3 bedCenter = new Vector3(MeshViewerWidget.BedCenter); Vector3 centerOffset = bounds.Center - bedCenter; for (int meshIndex = 0; meshIndex < meshesList.Count; meshIndex++) { ScaleRotateTranslate centering = meshTransforms[meshIndex]; centering.centering *= Matrix4X4.CreateTranslation(new Vector3(-centerOffset.x, -centerOffset.y, 0)); meshTransforms[meshIndex] = centering; } } }
public static void FindPositionForGroupAndAddToPlate(MeshGroup meshGroupToAdd, ScaleRotateTranslate meshTransform, List <PlatingMeshGroupData> perMeshInfo, List <MeshGroup> meshesGroupsToAvoid, List <ScaleRotateTranslate> meshTransforms) { if (meshGroupToAdd == null || meshGroupToAdd.Meshes.Count < 1) { return; } // first find the bounds of what is already here. AxisAlignedBoundingBox allPlacedMeshBounds = GetAxisAlignedBoundingBox(meshesGroupsToAvoid[0], meshTransforms[0].TotalTransform); for (int i = 1; i < meshesGroupsToAvoid.Count; i++) { AxisAlignedBoundingBox nextMeshBounds = GetAxisAlignedBoundingBox(meshesGroupsToAvoid[i], meshTransforms[i].TotalTransform); allPlacedMeshBounds = AxisAlignedBoundingBox.Union(allPlacedMeshBounds, nextMeshBounds); } meshesGroupsToAvoid.Add(meshGroupToAdd); PlatingMeshGroupData newMeshInfo = new PlatingMeshGroupData(); perMeshInfo.Add(newMeshInfo); meshTransform.SetCenteringForMeshGroup(meshGroupToAdd); meshTransforms.Add(meshTransform); int meshGroupIndex = meshesGroupsToAvoid.Count - 1; // move the part to the total bounds lower left side MeshGroup meshGroup = meshesGroupsToAvoid[meshGroupIndex]; Vector3 meshLowerLeft = GetAxisAlignedBoundingBox(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); }
public override void OnMouseMove(MouseEvent3DArgs mouseEvent3D) { IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay); if (info != null && MeshViewerToDrawWith.SelectedMeshGroupIndex != -1) { Vector3 delta = new Vector3(0, 0, info.hitPosition.z - zHitHeight); // move it back to where it started ScaleRotateTranslate translated = MeshViewerToDrawWith.SelectedMeshGroupTransform; translated.translation *= Matrix4X4.CreateTranslation(new Vector3(-lastMoveDelta)); MeshViewerToDrawWith.SelectedMeshGroupTransform = translated; if (MeshViewerToDrawWith.SnapGridDistance > 0) { // snap this position to the grid double snapGridDistance = MeshViewerToDrawWith.SnapGridDistance; AxisAlignedBoundingBox selectedBounds = MeshViewerToDrawWith.GetBoundsForSelection(); // snap the z position double bottom = selectedBounds.minXYZ.z + delta.z; double snappedBottom = ((int)((bottom / snapGridDistance) + .5)) * snapGridDistance; delta.z = snappedBottom - selectedBounds.minXYZ.z; } // and move it from there to where we are now translated.translation *= Matrix4X4.CreateTranslation(new Vector3(delta)); MeshViewerToDrawWith.SelectedMeshGroupTransform = translated; lastMoveDelta = delta; view3DWidget.PartHasBeenChanged(); Invalidate(); } base.OnMouseMove(mouseEvent3D); }
private async void AutoArrangePartsInBackground() { if (MeshGroups.Count > 0) { string progressArrangeParts = LocalizedString.Get("Arranging Parts"); string progressArrangePartsFull = string.Format("{0}:", progressArrangeParts); processingProgressControl.ProcessType = progressArrangePartsFull; processingProgressControl.Visible = true; processingProgressControl.PercentComplete = 0; LockEditControls(); await Task.Run(() => { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DONT_COPY); PlatingHelper.ArrangeMeshGroups(asyncMeshGroups, asyncMeshGroupTransforms, asyncPlatingDatas, ReportProgressChanged); }); if (WidgetHasBeenClosed) { return; } // offset them to the centor of the bed for (int i = 0; i < asyncMeshGroups.Count; i++) { ScaleRotateTranslate translate = asyncMeshGroupTransforms[i]; translate.translation *= Matrix4X4.CreateTranslation(new Vector3(ActiveSliceSettings.Instance.BedCenter, 0)); asyncMeshGroupTransforms[i] = translate; } UnlockEditControls(); PartHasBeenChanged(); PullMeshGroupDataFromAsynchLists(); } }
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; } } }
private void UngroupSelected() { if (SelectedMeshGroupIndex == -1) { SelectedMeshGroupIndex = 0; } string makingCopyLabel = LocalizedString.Get("Ungrouping"); string makingCopyLabelFull = string.Format("{0}:", makingCopyLabel); processingProgressControl.ProcessType = makingCopyLabelFull; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DO_COPY); int indexBeingReplaced = SelectedMeshGroupIndex; List <Mesh> discreetMeshes = new List <Mesh>(); asynchMeshGroups[indexBeingReplaced].Transform(asynchMeshGroupTransforms[indexBeingReplaced].TotalTransform); // if there are multiple meshes than just make them separate groups if (asynchMeshGroups[indexBeingReplaced].Meshes.Count > 1) { foreach (Mesh mesh in asynchMeshGroups[indexBeingReplaced].Meshes) { discreetMeshes.Add(mesh); } } else // actually try and cut up the mesh into separate parts { discreetMeshes = CreateDiscreteMeshes.SplitConnectedIntoMeshes(asynchMeshGroups[indexBeingReplaced], (double progress0To1, string processingState, out bool continueProcessing) => { ReportProgressChanged(progress0To1 * .5, processingState, out continueProcessing); }); } asynchMeshGroups.RemoveAt(indexBeingReplaced); asynchPlatingDatas.RemoveAt(indexBeingReplaced); asynchMeshGroupTransforms.RemoveAt(indexBeingReplaced); double ratioPerDiscreetMesh = 1.0 / discreetMeshes.Count; double currentRatioDone = 0; for (int discreetMeshIndex = 0; discreetMeshIndex < discreetMeshes.Count; discreetMeshIndex++) { PlatingMeshGroupData newInfo = new PlatingMeshGroupData(); asynchPlatingDatas.Add(newInfo); asynchMeshGroups.Add(new MeshGroup(discreetMeshes[discreetMeshIndex])); int addedMeshIndex = asynchMeshGroups.Count - 1; MeshGroup addedMeshGroup = asynchMeshGroups[addedMeshIndex]; ScaleRotateTranslate transform = ScaleRotateTranslate.Identity(); transform.SetCenteringForMeshGroup(addedMeshGroup); asynchMeshGroupTransforms.Add(transform); //PlatingHelper.PlaceMeshGroupOnBed(asynchMeshGroups, asynchMeshGroupTransforms, addedMeshIndex, false); // and create selection info PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, addedMeshIndex, (double progress0To1, string processingState, out bool continueProcessing) => { ReportProgressChanged(.5 + progress0To1 * .5 * currentRatioDone, processingState, out continueProcessing); }); currentRatioDone += ratioPerDiscreetMesh; } }
public static void FindPositionForGroupAndAddToPlate(MeshGroup meshGroupToAdd, ScaleRotateTranslate meshTransform, List <PlatingMeshGroupData> perMeshInfo, List <MeshGroup> meshesGroupsToAvoid, List <ScaleRotateTranslate> meshTransforms) { if (meshGroupToAdd == null || meshGroupToAdd.Meshes.Count < 1) { return; } meshesGroupsToAvoid.Add(meshGroupToAdd); PlatingMeshGroupData newMeshInfo = new PlatingMeshGroupData(); perMeshInfo.Add(newMeshInfo); meshTransform.SetCenteringForMeshGroup(meshGroupToAdd); meshTransforms.Add(meshTransform); int meshGroupIndex = meshesGroupsToAvoid.Count - 1; // now actually center the part we are going to finde a position for CenterMeshGroupXY(meshesGroupsToAvoid, meshTransforms, meshGroupIndex); MoveMeshGroupToOpenPosition(meshGroupIndex, perMeshInfo, meshesGroupsToAvoid, meshTransforms); PlaceMeshGroupOnBed(meshesGroupsToAvoid, meshTransforms, meshGroupIndex); }
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; } } }
public View3DTextCreator(Vector3 viewerVolume, Vector2 bedCenter, MeshViewerWidget.BedShape bedShape) { boldTypeFace = TypeFace.LoadFrom(StaticData.Instance.ReadAllText(Path.Combine("Fonts", "LiberationSans-Bold.svg"))); MeshGroupExtraData = new List <PlatingMeshGroupData>(); FlowLayoutWidget mainContainerTopToBottom = new FlowLayoutWidget(FlowDirection.TopToBottom); mainContainerTopToBottom.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth; mainContainerTopToBottom.VAnchor = Agg.UI.VAnchor.Max_FitToChildren_ParentHeight; FlowLayoutWidget centerPartPreviewAndControls = new FlowLayoutWidget(FlowDirection.LeftToRight); centerPartPreviewAndControls.AnchorAll(); GuiWidget viewArea = new GuiWidget(); viewArea.AnchorAll(); { meshViewerWidget = new MeshViewerWidget(viewerVolume, bedCenter, bedShape); meshViewerWidget.AllowBedRenderingWhenEmpty = true; meshViewerWidget.AnchorAll(); } viewArea.AddChild(meshViewerWidget); centerPartPreviewAndControls.AddChild(viewArea); mainContainerTopToBottom.AddChild(centerPartPreviewAndControls); FlowLayoutWidget buttonBottomPanel = new FlowLayoutWidget(FlowDirection.LeftToRight); buttonBottomPanel.HAnchor = HAnchor.ParentLeftRight; buttonBottomPanel.Padding = new BorderDouble(3, 3); buttonBottomPanel.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor; buttonRightPanel = CreateRightButtonPanel(viewerVolume.y); // add in the plater tools { FlowLayoutWidget editToolBar = new FlowLayoutWidget(); processingProgressControl = new ProgressControl("Finding Parts:".Localize(), ActiveTheme.Instance.PrimaryTextColor, ActiveTheme.Instance.PrimaryAccentColor); processingProgressControl.VAnchor = Agg.UI.VAnchor.ParentCenter; editToolBar.AddChild(processingProgressControl); editToolBar.VAnchor |= Agg.UI.VAnchor.ParentCenter; editPlateButtonsContainer = new FlowLayoutWidget(); textToAddWidget = new MHTextEditWidget("", pixelWidth: 300, messageWhenEmptyAndNotSelected: "Enter Text Here".Localize()); textToAddWidget.VAnchor = VAnchor.ParentCenter; textToAddWidget.Margin = new BorderDouble(5); editPlateButtonsContainer.AddChild(textToAddWidget); textToAddWidget.ActualTextEditWidget.EnterPressed += (object sender, KeyEventArgs keyEvent) => { InsertTextNow(textToAddWidget.Text); }; Button insertTextButton = textImageButtonFactory.Generate("Insert".Localize()); editPlateButtonsContainer.AddChild(insertTextButton); insertTextButton.Click += (sender, e) => { InsertTextNow(textToAddWidget.Text); }; KeyDown += (sender, e) => { KeyEventArgs keyEvent = e as KeyEventArgs; if (keyEvent != null && !keyEvent.Handled) { if (keyEvent.KeyCode == Keys.Escape) { if (meshSelectInfo.downOnPart) { meshSelectInfo.downOnPart = false; ScaleRotateTranslate translated = SelectedMeshTransform; translated.translation *= transformOnMouseDown; SelectedMeshTransform = translated; Invalidate(); } } } }; editToolBar.AddChild(editPlateButtonsContainer); buttonBottomPanel.AddChild(editToolBar); } GuiWidget buttonRightPanelHolder = new GuiWidget(HAnchor.FitToChildren, VAnchor.ParentBottomTop); centerPartPreviewAndControls.AddChild(buttonRightPanelHolder); buttonRightPanelHolder.AddChild(buttonRightPanel); viewControls3D = new ViewControls3D(meshViewerWidget); viewControls3D.ResetView += (sender, e) => { SetDefaultView(); }; buttonRightPanelDisabledCover = new Cover(HAnchor.ParentLeftRight, VAnchor.ParentBottomTop); buttonRightPanelDisabledCover.BackgroundColor = new RGBA_Bytes(ActiveTheme.Instance.PrimaryBackgroundColor, 150); buttonRightPanelHolder.AddChild(buttonRightPanelDisabledCover); LockEditControls(); GuiWidget leftRightSpacer = new GuiWidget(); leftRightSpacer.HAnchor = HAnchor.ParentLeftRight; buttonBottomPanel.AddChild(leftRightSpacer); closeButton = textImageButtonFactory.Generate("Close".Localize()); buttonBottomPanel.AddChild(closeButton); mainContainerTopToBottom.AddChild(buttonBottomPanel); this.AddChild(mainContainerTopToBottom); this.AnchorAll(); meshViewerWidget.TrackballTumbleWidget.TransformState = TrackBallController.MouseDownType.Rotation; AddChild(viewControls3D); SetDefaultView(); AddHandlers(); UnlockEditControls(); // but make sure we can't use the right panel yet buttonRightPanelDisabledCover.Visible = true; }
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 MoveMeshGroupToOpenPosition(int meshGroupToMoveIndex, List <PlatingMeshGroupData> perMeshInfo, List <MeshGroup> allMeshGroups, List <ScaleRotateTranslate> meshTransforms) { AxisAlignedBoundingBox allPlacedMeshBounds = GetAxisAlignedBoundingBox(allMeshGroups[0], meshTransforms[0].TotalTransform); for (int i = 1; i < meshGroupToMoveIndex; i++) { AxisAlignedBoundingBox nextMeshBounds = GetAxisAlignedBoundingBox(allMeshGroups[i], meshTransforms[i].TotalTransform); allPlacedMeshBounds = AxisAlignedBoundingBox.Union(allPlacedMeshBounds, nextMeshBounds); } 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 = GetAxisAlignedBoundingBox(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); Matrix4X4 transform = Matrix4X4.Identity; int currentSize = 1; bool partPlaced = false; while (!partPlaced && meshGroupToMoveIndex > 0) { int yStep = 0; int xStep = currentSize; // check far right edge for (yStep = 0; yStep < currentSize; yStep++) { partPlaced = CheckPosition(meshGroupToMoveIndex, allMeshGroups, meshTransforms, meshGroupToMove, meshToMoveBounds, yStep, xStep, ref transform); if (partPlaced) { break; } } if (!partPlaced) { yStep = currentSize; // check top edeg for (xStep = 0; xStep < currentSize; xStep++) { partPlaced = CheckPosition(meshGroupToMoveIndex, allMeshGroups, meshTransforms, meshGroupToMove, meshToMoveBounds, yStep, xStep, ref transform); if (partPlaced) { break; } } if (!partPlaced) { xStep = currentSize; // check top right point partPlaced = CheckPosition(meshGroupToMoveIndex, allMeshGroups, meshTransforms, meshGroupToMove, meshToMoveBounds, yStep, xStep, ref transform); } } currentSize++; } ScaleRotateTranslate moved = meshTransforms[meshGroupToMoveIndex]; moved.translation *= transform; meshTransforms[meshGroupToMoveIndex] = moved; }
private void GroupSelected() { string makingCopyLabel = LocalizedString.Get("Grouping"); string makingCopyLabelFull = string.Format("{0}:", makingCopyLabel); processingProgressControl.ProcessType = makingCopyLabelFull; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; PushMeshGroupDataToAsynchLists(TraceInfoOpperation.DO_COPY); for (int i = 0; i < asyncMeshGroups.Count; i++) { asyncMeshGroups[i].Transform(asyncMeshGroupTransforms[i].TotalTransform); bool continueProcessing; ReportProgressChanged((i + 1) * .4 / asyncMeshGroups.Count, "", out continueProcessing); } if (SelectedMeshGroupIndex == -1) { SelectedMeshGroupIndex = 0; } MeshGroup meshGroupWeAreKeeping = asyncMeshGroups[SelectedMeshGroupIndex]; for (int meshGroupToMoveIndex = asyncMeshGroups.Count - 1; meshGroupToMoveIndex >= 0; meshGroupToMoveIndex--) { MeshGroup meshGroupToMove = asyncMeshGroups[meshGroupToMoveIndex]; if (meshGroupToMove != meshGroupWeAreKeeping) { for (int moveIndex = 0; moveIndex < meshGroupToMove.Meshes.Count; moveIndex++) { Mesh mesh = meshGroupToMove.Meshes[moveIndex]; meshGroupWeAreKeeping.Meshes.Add(mesh); } asyncMeshGroups.RemoveAt(meshGroupToMoveIndex); asyncMeshGroupTransforms.RemoveAt(meshGroupToMoveIndex); } else { asyncMeshGroupTransforms[meshGroupToMoveIndex] = ScaleRotateTranslate.Identity(); } } 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; } }