diff --git a/CustomWidgets/ExportPrintItemWindow.cs b/CustomWidgets/ExportPrintItemWindow.cs index 714df5d2d..5ca126504 100644 --- a/CustomWidgets/ExportPrintItemWindow.cs +++ b/CustomWidgets/ExportPrintItemWindow.cs @@ -15,6 +15,7 @@ using MatterHackers.MatterControl.PrintQueue; using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.MatterControl.PrinterCommunication; using MatterHackers.MatterControl.DataStorage; +using MatterHackers.PolygonMesh.Processors; namespace MatterHackers.MatterControl { @@ -320,7 +321,8 @@ namespace MatterHackers.MatterControl gcodePathAndFilenameToSave += ".gcode"; } - if (Path.GetExtension(printItemWrapper.FileLocation).ToUpper() == ".STL") + string sourceExtension = Path.GetExtension(printItemWrapper.FileLocation).ToUpper(); + if (MeshFileIo.ValidFileExtensions().Contains(sourceExtension)) { Close(); SlicingQueue.Instance.QueuePartForSlicing(printItemWrapper); diff --git a/MatterControl.csproj b/MatterControl.csproj index b7e54375b..0a0275a3e 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -119,6 +119,10 @@ + + + + @@ -156,7 +160,7 @@ - + Code diff --git a/PartPreviewWindow/BaseClasses/PartPreview3DWidget.cs b/PartPreviewWindow/BaseClasses/PartPreview3DWidget.cs index 80b4c3fc5..9bcf1eb7d 100644 --- a/PartPreviewWindow/BaseClasses/PartPreview3DWidget.cs +++ b/PartPreviewWindow/BaseClasses/PartPreview3DWidget.cs @@ -40,6 +40,14 @@ using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.PartPreviewWindow { + public class Cover : GuiWidget + { + public Cover(HAnchor hAnchor = HAnchor.None, VAnchor vAnchor = VAnchor.None) + : base(hAnchor, vAnchor) + { + } + } + public class PartPreview3DWidget : PartPreviewWidget { protected bool autoRotateEnabled = false; diff --git a/PartPreviewWindow/View3D/View3DAlign.cs b/PartPreviewWindow/View3D/View3DAlign.cs new file mode 100644 index 000000000..f23d4e236 --- /dev/null +++ b/PartPreviewWindow/View3D/View3DAlign.cs @@ -0,0 +1,53 @@ +/* +Copyright (c) 2014, Lars Brubaker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Threading; +using MatterHackers.Localizations; +using MatterHackers.MeshVisualizer; +using MatterHackers.VectorMath; +using MatterHackers.PolygonMesh; +using MatterHackers.MeshVisualizer; + +namespace MatterHackers.MatterControl.PartPreviewWindow +{ + public partial class View3DTransformPart + { + void AlignSelectedMeshGroup() + { + AxisAlignedBoundingBox selectedOriginalBounds = SelectedMeshGroup.GetAxisAlignedBoundingBox(); + AxisAlignedBoundingBox selectedCurrentBounds = SelectedMeshGroup.GetAxisAlignedBoundingBox(SelectedMeshGroupTransform.TotalTransform); + foreach (MeshGroup meshGroup in MeshGroups) + { + } + } + } +} diff --git a/PartPreviewWindow/View3D/View3DAutoArange.cs b/PartPreviewWindow/View3D/View3DAutoArange.cs new file mode 100644 index 000000000..fee1ef4f8 --- /dev/null +++ b/PartPreviewWindow/View3D/View3DAutoArange.cs @@ -0,0 +1,167 @@ +/* +Copyright (c) 2014, Lars Brubaker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System; +using System.ComponentModel; +using System.Globalization; +using System.Threading; +using MatterHackers.Localizations; +using MatterHackers.MeshVisualizer; +using MatterHackers.PolygonMesh; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl.PartPreviewWindow +{ + public partial class View3DTransformPart + { + private void AutoArangePartsInBackground() + { + if (MeshGroups.Count > 0) + { + string progressArrangeParts = LocalizedString.Get("Arranging Parts"); + string progressArrangePartsFull = string.Format("{0}:", progressArrangeParts); + processingProgressControl.textWidget.Text = progressArrangePartsFull; + processingProgressControl.Visible = true; + processingProgressControl.PercentComplete = 0; + LockEditControls(); + + BackgroundWorker arrangeMeshGroupsBackgroundWorker = new BackgroundWorker(); + arrangeMeshGroupsBackgroundWorker.WorkerReportsProgress = true; + + arrangeMeshGroupsBackgroundWorker.DoWork += new DoWorkEventHandler(arrangeMeshGroupsBackgroundWorker_DoWork); + arrangeMeshGroupsBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged); + arrangeMeshGroupsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(arrangeMeshGroupsBackgroundWorker_RunWorkerCompleted); + + arrangeMeshGroupsBackgroundWorker.RunWorkerAsync(); + } + } + + void arrangeMeshGroupsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) + { + Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; + PushMeshGroupDataToAsynchLists(TranceInfoOpperation.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(1000, 1000, 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++) + { + MeshGroup meshGroup = asynchMeshGroups[meshGroupIndex]; + Vector3 meshCenter = meshGroup.GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[meshGroupIndex].translation).Center; + ScaleRotateTranslate atZero = asynchMeshGroupTransforms[meshGroupIndex]; + atZero.translation = Matrix4X4.Identity; + 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) => + { + int nextPercent = (int)((currentRatioDone + ratioPerMeshGroup * progress0To1) * 100); + backgroundWorker.ReportProgress(nextPercent); + return true; + }); + + currentRatioDone += ratioPerMeshGroup; + + // and put it on the bed + PlatingHelper.PlaceMeshGroupOnBed(asynchMeshGroups, asynchMeshGroupTransforms, meshGroupIndex, false); + } + + // 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; + } + } + } + + void arrangeMeshGroupsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + if (WidgetHasBeenClosed) + { + return; + } + UnlockEditControls(); + saveButtons.Visible = true; + + PullMeshGroupDataFromAsynchLists(); + } + } +} diff --git a/PartPreviewWindow/View3D/View3DCopyGroup.cs b/PartPreviewWindow/View3D/View3DCopyGroup.cs new file mode 100644 index 000000000..dbb83713c --- /dev/null +++ b/PartPreviewWindow/View3D/View3DCopyGroup.cs @@ -0,0 +1,106 @@ +/* +Copyright (c) 2014, Lars Brubaker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System.ComponentModel; +using System.Globalization; +using System.Threading; +using MatterHackers.Localizations; +using MatterHackers.PolygonMesh; + +namespace MatterHackers.MatterControl.PartPreviewWindow +{ + public partial class View3DTransformPart + { + private void MakeCopyOfGroup() + { + if (MeshGroups.Count > 0) + { + string makingCopyLabel = LocalizedString.Get("Making Copy"); + string makingCopyLabelFull = string.Format("{0}:", makingCopyLabel); + processingProgressControl.textWidget.Text = makingCopyLabelFull; + processingProgressControl.Visible = true; + processingProgressControl.PercentComplete = 0; + LockEditControls(); + + BackgroundWorker copyGroupBackgroundWorker = null; + copyGroupBackgroundWorker = new BackgroundWorker(); + copyGroupBackgroundWorker.WorkerReportsProgress = true; + + copyGroupBackgroundWorker.DoWork += new DoWorkEventHandler(copyGroupBackgroundWorker_DoWork); + copyGroupBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged); + copyGroupBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(copyGroupBackgroundWorker_RunWorkerCompleted); + + copyGroupBackgroundWorker.RunWorkerAsync(); + } + } + + void copyGroupBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) + { + Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; + BackgroundWorker backgroundWorker = (BackgroundWorker)sender; + + PushMeshGroupDataToAsynchLists(TranceInfoOpperation.DO_COPY); + + MeshGroup meshGroupToCopy = asynchMeshGroups[SelectedMeshGroupIndex]; + MeshGroup copyMeshGroup = new MeshGroup(); + double meshCount = meshGroupToCopy.Meshes.Count; + for (int i = 0; i < meshCount; i++) + { + Mesh mesh = asynchMeshGroups[SelectedMeshGroupIndex].Meshes[i]; + copyMeshGroup.Meshes.Add(Mesh.Copy(mesh, (progress0To1, processingState) => + { + int nextPercent = (int)(100 * (progress0To1 * .8 * i / meshCount)); + backgroundWorker.ReportProgress(nextPercent); + return true; + })); + } + + PlatingHelper.FindPositionForGroupAndAddToPlate(copyMeshGroup, SelectedMeshGroupTransform, asynchPlatingDatas, asynchMeshGroups, asynchMeshGroupTransforms); + PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, asynchMeshGroups.Count - 1, null); + + backgroundWorker.ReportProgress(95); + } + + void copyGroupBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + if (WidgetHasBeenClosed) + { + return; + } + + UnlockEditControls(); + PullMeshGroupDataFromAsynchLists(); + saveButtons.Visible = true; + + // now set the selection to the new copy + MeshGroupExtraData[MeshGroups.Count - 1].currentScale = MeshGroupExtraData[SelectedMeshGroupIndex].currentScale; + SelectedMeshGroupIndex = MeshGroups.Count - 1; + } + } +} diff --git a/PartPreviewWindow/View3DTransfromPart.cs b/PartPreviewWindow/View3D/View3DTransfromPart.cs similarity index 83% rename from PartPreviewWindow/View3DTransfromPart.cs rename to PartPreviewWindow/View3D/View3DTransfromPart.cs index cda394c5a..83de74865 100644 --- a/PartPreviewWindow/View3DTransfromPart.cs +++ b/PartPreviewWindow/View3D/View3DTransfromPart.cs @@ -36,7 +36,7 @@ using System.IO; using System.Threading; using MatterHackers.Agg; using MatterHackers.Agg.UI; -using MatterHackers.Localizations; //Added Namespace +using MatterHackers.Localizations; using MatterHackers.MatterControl.PrinterCommunication; using MatterHackers.MatterControl.PrintQueue; using MatterHackers.MatterControl.SlicerConfiguration; @@ -50,15 +50,7 @@ using MatterHackers.VectorMath; namespace MatterHackers.MatterControl.PartPreviewWindow { - public class Cover : GuiWidget - { - public Cover(HAnchor hAnchor = HAnchor.None, VAnchor vAnchor = VAnchor.None) - : base(hAnchor, vAnchor) - { - } - } - - public class View3DTransformPart : PartPreview3DWidget + public partial class View3DTransformPart : PartPreview3DWidget { public WindowType windowType { get; set; } public PrintItemWrapper PrintItemWrapper { @@ -99,9 +91,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow ExportPrintItemWindow exportingWindow; bool exportingWindowIsOpen = false; - List asynchMeshGroupsList = new List(); + List asynchMeshGroups = new List(); List asynchMeshGroupTransforms = new List(); - List asynchPlatingDataList = new List(); + List asynchPlatingDatas = new List(); List MeshGroupExtraData; @@ -395,6 +387,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow UngroupSelectedMeshGroup(); }; + Button alignButton = textImageButtonFactory.Generate(LocalizedString.Get("Align")); + doEdittingButtonsContainer.AddChild(alignButton); + alignButton.Click += (sender, e) => + { + AlignSelectedMeshGroup(); + }; + Button copyButton = textImageButtonFactory.Generate(LocalizedString.Get("Copy")); doEdittingButtonsContainer.AddChild(copyButton); copyButton.Click += (sender, e) => @@ -602,196 +601,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } } - private void MakeCopyOfGroup() - { - if (MeshGroups.Count > 0) - { - string makingCopyLabel = LocalizedString.Get("Making Copy"); - string makingCopyLabelFull = string.Format("{0}:", makingCopyLabel); - processingProgressControl.textWidget.Text = makingCopyLabelFull; - processingProgressControl.Visible = true; - processingProgressControl.PercentComplete = 0; - LockEditControls(); - - BackgroundWorker copyGroupBackgroundWorker = null; - copyGroupBackgroundWorker = new BackgroundWorker(); - copyGroupBackgroundWorker.WorkerReportsProgress = true; - - copyGroupBackgroundWorker.DoWork += new DoWorkEventHandler(copyGroupBackgroundWorker_DoWork); - copyGroupBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged); - copyGroupBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(copyGroupBackgroundWorker_RunWorkerCompleted); - - copyGroupBackgroundWorker.RunWorkerAsync(); - } - } - - void copyGroupBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) - { - Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; - BackgroundWorker backgroundWorker = (BackgroundWorker)sender; - - PushMeshGroupDataToAsynchLists(TranceInfoOpperation.DO_COPY); - - MeshGroup meshGroupToCopy = asynchMeshGroupsList[SelectedMeshGroupIndex]; - MeshGroup copyMeshGroup = new MeshGroup(); - double meshCount = meshGroupToCopy.Meshes.Count; - for (int i = 0; i < meshCount; i++) - { - Mesh mesh = asynchMeshGroupsList[SelectedMeshGroupIndex].Meshes[i]; - copyMeshGroup.Meshes.Add(Mesh.Copy(mesh, (progress0To1, processingState) => - { - int nextPercent = (int)(100 * (progress0To1 * .8 * i / meshCount)); - backgroundWorker.ReportProgress(nextPercent); - return true; - })); - } - - PlatingHelper.FindPositionForGroupAndAddToPlate(copyMeshGroup, SelectedMeshGroupTransform, asynchPlatingDataList, asynchMeshGroupsList, asynchMeshGroupTransforms); - PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDataList, asynchMeshGroupsList, asynchMeshGroupsList.Count - 1, null); - - backgroundWorker.ReportProgress(95); - } - - void copyGroupBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { - if (WidgetHasBeenClosed) - { - return; - } - - UnlockEditControls(); - PullMeshGroupDataFromAsynchLists(); - saveButtons.Visible = true; - - // now set the selection to the new copy - MeshGroupExtraData[MeshGroups.Count - 1].currentScale = MeshGroupExtraData[SelectedMeshGroupIndex].currentScale; - SelectedMeshGroupIndex = MeshGroups.Count - 1; - } - - private void AutoArangePartsInBackground() - { - if (MeshGroups.Count > 0) - { - string progressArrangeParts = LocalizedString.Get("Arranging Parts"); - string progressArrangePartsFull = string.Format("{0}:", progressArrangeParts); - processingProgressControl.textWidget.Text = progressArrangePartsFull; - processingProgressControl.Visible = true; - processingProgressControl.PercentComplete = 0; - LockEditControls(); - - BackgroundWorker arrangeMeshGroupsBackgroundWorker = new BackgroundWorker(); - arrangeMeshGroupsBackgroundWorker.WorkerReportsProgress = true; - - arrangeMeshGroupsBackgroundWorker.DoWork += new DoWorkEventHandler(arrangeMeshGroupsBackgroundWorker_DoWork); - arrangeMeshGroupsBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged); - arrangeMeshGroupsBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(arrangeMeshGroupsBackgroundWorker_RunWorkerCompleted); - - arrangeMeshGroupsBackgroundWorker.RunWorkerAsync(); - } - } - - void arrangeMeshGroupsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) - { - Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; - PushMeshGroupDataToAsynchLists(TranceInfoOpperation.DONT_COPY); - - BackgroundWorker backgroundWorker = (BackgroundWorker)sender; - - // move them all out of the way - for (int i = 0; i < asynchMeshGroupsList.Count; i++) - { - ScaleRotateTranslate translate = asynchMeshGroupTransforms[i]; - translate.translation *= Matrix4X4.CreateTranslation(1000, 1000, 0); - asynchMeshGroupTransforms[i] = translate; - } - - // sort them by size - for (int i = 0; i < asynchMeshGroupsList.Count; i++) - { - AxisAlignedBoundingBox iAABB = asynchMeshGroupsList[i].GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[i].TotalTransform); - for (int j = i + 1; j < asynchMeshGroupsList.Count; j++) - { - AxisAlignedBoundingBox jAABB = asynchMeshGroupsList[j].GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[j].TotalTransform); - if (Math.Max(iAABB.XSize, iAABB.YSize) < Math.Max(jAABB.XSize, jAABB.YSize)) - { - PlatingMeshGroupData tempData = asynchPlatingDataList[i]; - asynchPlatingDataList[i] = asynchPlatingDataList[j]; - asynchPlatingDataList[j] = tempData; - - MeshGroup tempMeshGroup = asynchMeshGroupsList[i]; - asynchMeshGroupsList[i] = asynchMeshGroupsList[j]; - asynchMeshGroupsList[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 / asynchMeshGroupsList.Count; - double currentRatioDone = 0; - // put them onto the plate (try the center) starting with the biggest and moving down - for (int meshGroupIndex = 0; meshGroupIndex < asynchMeshGroupsList.Count; meshGroupIndex++) - { - MeshGroup meshGroup = asynchMeshGroupsList[meshGroupIndex]; - Vector3 meshCenter = meshGroup.GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[meshGroupIndex].translation).Center; - ScaleRotateTranslate atZero = asynchMeshGroupTransforms[meshGroupIndex]; - atZero.translation = Matrix4X4.Identity; - asynchMeshGroupTransforms[meshGroupIndex] = atZero; - PlatingHelper.MoveMeshGroupToOpenPosition(meshGroupIndex, asynchPlatingDataList, asynchMeshGroupsList, asynchMeshGroupTransforms); - - // and create the trace info so we can select it - PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDataList, asynchMeshGroupsList, meshGroupIndex, (double progress0To1, string processingState) => - { - int nextPercent = (int)((currentRatioDone + ratioPerMeshGroup * progress0To1) * 100); - backgroundWorker.ReportProgress(nextPercent); - return true; - }); - - currentRatioDone += ratioPerMeshGroup; - - // and put it on the bed - PlatingHelper.PlaceMeshGroupOnBed(asynchMeshGroupsList, asynchMeshGroupTransforms, meshGroupIndex, false); - } - - // and finally center whatever we have as a group - { - AxisAlignedBoundingBox bounds = asynchMeshGroupsList[0].GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[0].TotalTransform); - for (int i = 1; i < asynchMeshGroupsList.Count; i++) - { - bounds = AxisAlignedBoundingBox.Union(bounds, asynchMeshGroupsList[i].GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[i].TotalTransform)); - } - - Vector3 boundsCenter = (bounds.maxXYZ + bounds.minXYZ) / 2; - for (int i = 0; i < asynchMeshGroupsList.Count; i++) - { - ScaleRotateTranslate translate = asynchMeshGroupTransforms[i]; - translate.translation *= Matrix4X4.CreateTranslation(-boundsCenter + new Vector3(0, 0, bounds.ZSize / 2)); - asynchMeshGroupTransforms[i] = translate; - } - } - } - - void arrangeMeshGroupsBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { - if (WidgetHasBeenClosed) - { - return; - } - UnlockEditControls(); - saveButtons.Visible = true; - - PullMeshGroupDataFromAsynchLists(); - } - private void LoadAndAddPartsToPlate(string[] filesToLoad) { if (MeshGroups.Count > 0 && filesToLoad != null && filesToLoad.Length > 0) @@ -820,7 +629,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow enum TranceInfoOpperation { DONT_COPY, DO_COPY }; private void PushMeshGroupDataToAsynchLists(TranceInfoOpperation tranceInfoOpperation) { - asynchMeshGroupsList.Clear(); + asynchMeshGroups.Clear(); asynchMeshGroupTransforms.Clear(); for (int meshGroupIndex = 0; meshGroupIndex < MeshGroups.Count; meshGroupIndex++) { @@ -832,9 +641,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow newMeshGroup.Meshes.Add(Mesh.Copy(mesh)); asynchMeshGroupTransforms.Add(MeshGroupTransforms[meshGroupIndex]); } - asynchMeshGroupsList.Add(newMeshGroup); + asynchMeshGroups.Add(newMeshGroup); } - asynchPlatingDataList.Clear(); + asynchPlatingDatas.Clear(); for (int meshGroupIndex = 0; meshGroupIndex < MeshGroupExtraData.Count; meshGroupIndex++) { @@ -848,7 +657,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow meshData.meshTraceableData.AddRange(MeshGroupExtraData[meshGroupIndex].meshTraceableData); } } - asynchPlatingDataList.Add(meshData); + asynchPlatingDatas.Add(meshData); } } @@ -861,10 +670,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow UnlockEditControls(); saveButtons.Visible = true; - if (asynchMeshGroupsList.Count == MeshGroups.Count + 1) + if (asynchMeshGroups.Count == MeshGroups.Count + 1) { // if we are only adding one part to the plate set the selection to it - SelectedMeshGroupIndex = asynchMeshGroupsList.Count - 1; + SelectedMeshGroupIndex = asynchMeshGroups.Count - 1; } if (MeshGroups.Count > 0) @@ -875,8 +684,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow private void PullMeshGroupDataFromAsynchLists() { + if (MeshGroups.Count != asynchMeshGroups.Count) + { + saveButtons.Visible = true; + } + MeshGroups.Clear(); - foreach (MeshGroup meshGroup in asynchMeshGroupsList) + foreach (MeshGroup meshGroup in asynchMeshGroups) { MeshGroups.Add(meshGroup); } @@ -886,7 +700,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow MeshGroupTransforms.Add(transform); } MeshGroupExtraData.Clear(); - foreach (PlatingMeshGroupData meshData in asynchPlatingDataList) + foreach (PlatingMeshGroupData meshData in asynchPlatingDatas) { MeshGroupExtraData.Add(meshData); } @@ -922,12 +736,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { MeshGroup meshGroup = loadedMeshGroups[subMeshIndex]; - PlatingHelper.FindPositionForGroupAndAddToPlate(meshGroup, ScaleRotateTranslate.Identity(), asynchPlatingDataList, asynchMeshGroupsList, asynchMeshGroupTransforms); + PlatingHelper.FindPositionForGroupAndAddToPlate(meshGroup, ScaleRotateTranslate.Identity(), asynchPlatingDatas, asynchMeshGroups, asynchMeshGroupTransforms); if (WidgetHasBeenClosed) { return; } - PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDataList, asynchMeshGroupsList, asynchMeshGroupsList.Count - 1, null); + PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, asynchMeshGroups.Count - 1, null); backgroundWorker.ReportProgress(lastPercent + subMeshIndex + 1 * subLength / loadedMeshGroups.Count); } @@ -1005,27 +819,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } } - void UngroupSelectedMeshGroup() - { - if (MeshGroups.Count > 0) - { - processingProgressControl.PercentComplete = 0; - processingProgressControl.Visible = true; - LockEditControls(); - viewIsInEditModePreLock = true; - - BackgroundWorker createDiscreteMeshesBackgroundWorker = null; - createDiscreteMeshesBackgroundWorker = new BackgroundWorker(); - createDiscreteMeshesBackgroundWorker.WorkerReportsProgress = true; - - createDiscreteMeshesBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged); - createDiscreteMeshesBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(createDiscreteMeshesBackgroundWorker_RunWorkerCompleted); - createDiscreteMeshesBackgroundWorker.DoWork += new DoWorkEventHandler(createDiscreteMeshesBackgroundWorker_DoWork); - - createDiscreteMeshesBackgroundWorker.RunWorkerAsync(); - } - } - void EnterEditAndCreateSelectionData() { if (enterEditButtonsContainer.Visible == true) @@ -1064,18 +857,18 @@ namespace MatterHackers.MatterControl.PartPreviewWindow PushMeshGroupDataToAsynchLists(TranceInfoOpperation.DONT_COPY); - asynchPlatingDataList.Clear(); - double ratioPerMeshGroup = 1.0 / asynchMeshGroupsList.Count; + asynchPlatingDatas.Clear(); + double ratioPerMeshGroup = 1.0 / asynchMeshGroups.Count; double currentRatioDone = 0; - for (int i = 0; i < asynchMeshGroupsList.Count; i++) + for (int i = 0; i < asynchMeshGroups.Count; i++) { PlatingMeshGroupData newInfo = new PlatingMeshGroupData(); - asynchPlatingDataList.Add(newInfo); + asynchPlatingDatas.Add(newInfo); - MeshGroup meshGroup = asynchMeshGroupsList[i]; + MeshGroup meshGroup = asynchMeshGroups[i]; // create the selection info - PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDataList, asynchMeshGroupsList, i, (double progress0To1, string processingState) => + PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, i, (double progress0To1, string processingState) => { int nextPercent = (int)((currentRatioDone + ratioPerMeshGroup * progress0To1) * 100); backgroundWorker.ReportProgress(nextPercent); @@ -1105,84 +898,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow Invalidate(); } - void createDiscreteMeshesBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) - { - string makingCopyLabel = LocalizedString.Get("Finding Meshes"); - string makingCopyLabelFull = string.Format("{0}:", makingCopyLabel); - processingProgressControl.textWidget.Text = makingCopyLabelFull; - - Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; - BackgroundWorker backgroundWorker = (BackgroundWorker)sender; - - PushMeshGroupDataToAsynchLists(TranceInfoOpperation.DO_COPY); - - int indexBeingReplaced = MeshGroups.IndexOf(SelectedMeshGroup); - asynchMeshGroupsList[indexBeingReplaced].Transform(asynchMeshGroupTransforms[indexBeingReplaced].TotalTransform); - List discreetMeshes = CreateDiscreteMeshes.SplitConnectedIntoMeshes(asynchMeshGroupsList[indexBeingReplaced], (double progress0To1, string processingState) => - { - int nextPercent = (int)(progress0To1 * 50); - backgroundWorker.ReportProgress(nextPercent); - return true; - }); - - asynchMeshGroupsList.RemoveAt(indexBeingReplaced); - asynchPlatingDataList.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(); - asynchPlatingDataList.Add(newInfo); - asynchMeshGroupsList.Add(new MeshGroup(discreetMeshes[discreetMeshIndex])); - asynchMeshGroupTransforms.Add(new ScaleRotateTranslate(SelectedMeshGroupTransform.scale, SelectedMeshGroupTransform.rotation, Matrix4X4.Identity)); - - int addedMeshIndex = asynchMeshGroupsList.Count - 1; - - MeshGroup meshGroup = asynchMeshGroupsList[addedMeshIndex]; - - // remember where it is now - AxisAlignedBoundingBox startingBounds = meshGroup.GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[addedMeshIndex].TotalTransform); - Vector3 startingCenter = (startingBounds.maxXYZ + startingBounds.minXYZ) / 2; - - // move the mesh to be centered on the origin - AxisAlignedBoundingBox meshBounds = meshGroup.GetAxisAlignedBoundingBox(); - Vector3 meshCenter = (meshBounds.maxXYZ + meshBounds.minXYZ) / 2; - meshGroup.Translate(-meshCenter); - - // set the transform to position it where it was - ScaleRotateTranslate meshTransform = asynchMeshGroupTransforms[addedMeshIndex]; - meshTransform.translation = Matrix4X4.CreateTranslation(startingCenter); - asynchMeshGroupTransforms[addedMeshIndex] = meshTransform; - PlatingHelper.PlaceMeshGroupOnBed(asynchMeshGroupsList, asynchMeshGroupTransforms, addedMeshIndex, false); - - // and create selection info - PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDataList, asynchMeshGroupsList, addedMeshIndex, (double progress0To1, string processingState) => - { - int nextPercent = (int)((currentRatioDone + ratioPerDiscreetMesh * progress0To1) * 50) + 50; - backgroundWorker.ReportProgress(nextPercent); - return true; - }); - currentRatioDone += ratioPerDiscreetMesh; - } - } - - void createDiscreteMeshesBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) - { - if (WidgetHasBeenClosed) - { - return; - } - // remove the original mesh and replace it with these new meshes - PullMeshGroupDataFromAsynchLists(); - - SelectedMeshGroupIndex = MeshGroups.Count - 1; - - UnlockEditControls(); - - Invalidate(); - } - void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { processingProgressControl.PercentComplete = e.ProgressPercentage; @@ -2018,16 +1733,16 @@ namespace MatterHackers.MatterControl.PartPreviewWindow try { // push all the transforms into the meshes - for (int i = 0; i < asynchMeshGroupsList.Count; i++) + for (int i = 0; i < asynchMeshGroups.Count; i++) { - asynchMeshGroupsList[i].Transform(asynchMeshGroupTransforms[i].TotalTransform); + asynchMeshGroups[i].Transform(asynchMeshGroupTransforms[i].TotalTransform); - int nextPercent = (i + 1) * 40 / asynchMeshGroupsList.Count; + int nextPercent = (i + 1) * 40 / asynchMeshGroups.Count; backgroundWorker.ReportProgress(nextPercent); } MeshOutputSettings outputInfo = new MeshOutputSettings(MeshOutputSettings.OutputType.Binary, new string[] { "Created By", "MatterControl" }); - MeshFileIo.Save(asynchMeshGroupsList, printItemWrapper.FileLocation, outputInfo); + MeshFileIo.Save(asynchMeshGroups, printItemWrapper.FileLocation, outputInfo); printItemWrapper.OnFileHasChanged(); } catch (System.UnauthorizedAccessException) diff --git a/PartPreviewWindow/View3D/View3DUngroup.cs b/PartPreviewWindow/View3D/View3DUngroup.cs new file mode 100644 index 000000000..336312eca --- /dev/null +++ b/PartPreviewWindow/View3D/View3DUngroup.cs @@ -0,0 +1,131 @@ +/* +Copyright (c) 2014, Lars Brubaker +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Threading; +using MatterHackers.Localizations; +using MatterHackers.MeshVisualizer; +using MatterHackers.PolygonMesh; + +namespace MatterHackers.MatterControl.PartPreviewWindow +{ + public partial class View3DTransformPart + { + void UngroupSelectedMeshGroup() + { + if (MeshGroups.Count > 0) + { + processingProgressControl.PercentComplete = 0; + processingProgressControl.Visible = true; + LockEditControls(); + viewIsInEditModePreLock = true; + + BackgroundWorker createDiscreteMeshesBackgroundWorker = null; + createDiscreteMeshesBackgroundWorker = new BackgroundWorker(); + createDiscreteMeshesBackgroundWorker.WorkerReportsProgress = true; + + createDiscreteMeshesBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged); + createDiscreteMeshesBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ungroupSelectedBackgroundWorker_RunWorkerCompleted); + createDiscreteMeshesBackgroundWorker.DoWork += new DoWorkEventHandler(ungroupSelectedBackgroundWorker_DoWork); + + createDiscreteMeshesBackgroundWorker.RunWorkerAsync(); + } + } + + void ungroupSelectedBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) + { + string makingCopyLabel = LocalizedString.Get("Finding Meshes"); + string makingCopyLabelFull = string.Format("{0}:", makingCopyLabel); + processingProgressControl.textWidget.Text = makingCopyLabelFull; + + Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; + BackgroundWorker backgroundWorker = (BackgroundWorker)sender; + + PushMeshGroupDataToAsynchLists(TranceInfoOpperation.DO_COPY); + + int indexBeingReplaced = MeshGroups.IndexOf(SelectedMeshGroup); + asynchMeshGroups[indexBeingReplaced].Transform(asynchMeshGroupTransforms[indexBeingReplaced].TotalTransform); + List discreetMeshes = CreateDiscreteMeshes.SplitConnectedIntoMeshes(asynchMeshGroups[indexBeingReplaced], (double progress0To1, string processingState) => + { + int nextPercent = (int)(progress0To1 * 50); + backgroundWorker.ReportProgress(nextPercent); + return true; + }); + + 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) => + { + int nextPercent = (int)((currentRatioDone + ratioPerDiscreetMesh * progress0To1) * 50) + 50; + backgroundWorker.ReportProgress(nextPercent); + return true; + }); + currentRatioDone += ratioPerDiscreetMesh; + } + } + + void ungroupSelectedBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + if (WidgetHasBeenClosed) + { + return; + } + + // remove the original mesh and replace it with these new meshes + PullMeshGroupDataFromAsynchLists(); + + // our selection changed to the mesh we just added which is at the end + SelectedMeshGroupIndex = MeshGroups.Count - 1; + + UnlockEditControls(); + + Invalidate(); + } + } +} diff --git a/SlicerConfiguration/SlicingQueue.cs b/SlicerConfiguration/SlicingQueue.cs index b53793f05..674fbbc6d 100644 --- a/SlicerConfiguration/SlicingQueue.cs +++ b/SlicerConfiguration/SlicingQueue.cs @@ -185,6 +185,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration case 2: extruder2Group[0].Meshes.Add(mesh); break; + + default: + extruder1Group[0].Meshes.Add(mesh); + break; } } } diff --git a/StaticData/Translations/Master.txt b/StaticData/Translations/Master.txt index 065a10698..7fafb130f 100644 --- a/StaticData/Translations/Master.txt +++ b/StaticData/Translations/Master.txt @@ -2729,3 +2729,6 @@ Translated:Export... English:Temperature Translated:Temperature +English:Align +Translated:Align +