2014-01-29 19:09:30 -08:00
/ *
2014-02-15 18:06:03 -08:00
Copyright ( c ) 2014 , Lars Brubaker
2014-01-29 19:09:30 -08:00
All rights reserved .
Redistribution and use in source and binary forms , with or without
2015-04-08 15:20:10 -07:00
modification , are permitted provided that the following conditions are met :
2014-01-29 19:09:30 -08:00
1. Redistributions of source code must retain the above copyright notice , this
2015-04-08 15:20:10 -07:00
list of conditions and the following disclaimer .
2014-01-29 19:09:30 -08:00
2. Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
2015-04-08 15:20:10 -07:00
and / or other materials provided with the distribution .
2014-01-29 19:09:30 -08:00
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
2015-04-08 15:20:10 -07:00
of the authors and should not be interpreted as representing official policies ,
2014-01-29 19:09:30 -08:00
either expressed or implied , of the FreeBSD Project .
* /
2016-03-08 12:13:58 -08:00
//#define DoBooleanTest
2014-01-29 19:09:30 -08:00
using MatterHackers.Agg ;
2016-05-06 17:56:27 -07:00
using MatterHackers.Agg.Image ;
using MatterHackers.Agg.ImageProcessing ;
using MatterHackers.Agg.PlatformAbstract ;
2015-04-08 15:20:10 -07:00
using MatterHackers.Agg.Transform ;
2014-01-29 19:09:30 -08:00
using MatterHackers.Agg.UI ;
2014-11-22 20:35:40 -08:00
using MatterHackers.Agg.VertexSource ;
2014-10-15 14:11:14 -07:00
using MatterHackers.Localizations ;
2014-10-23 14:40:12 -07:00
using MatterHackers.MatterControl.CustomWidgets ;
using MatterHackers.MatterControl.DataStorage ;
2014-06-11 14:52:58 -07:00
using MatterHackers.MatterControl.PrinterCommunication ;
2015-06-17 15:43:37 -07:00
using MatterHackers.MatterControl.PrintLibrary.Provider ;
2014-04-15 18:13:27 -07:00
using MatterHackers.MatterControl.PrintQueue ;
2014-10-13 18:20:01 -07:00
using MatterHackers.MatterControl.SlicerConfiguration ;
2014-01-29 19:09:30 -08:00
using MatterHackers.MeshVisualizer ;
2014-04-15 18:13:27 -07:00
using MatterHackers.PolygonMesh ;
2014-01-29 19:09:30 -08:00
using MatterHackers.PolygonMesh.Processors ;
using MatterHackers.RayTracer ;
using MatterHackers.RayTracer.Traceable ;
2014-04-15 18:13:27 -07:00
using MatterHackers.RenderOpenGl ;
using MatterHackers.VectorMath ;
2015-04-08 15:20:10 -07:00
using System ;
using System.Collections.Generic ;
using System.Collections.ObjectModel ;
using System.Diagnostics ;
using System.Globalization ;
using System.IO ;
2016-01-10 10:18:53 -08:00
using System.Linq ;
using System.Text.RegularExpressions ;
2015-04-08 15:20:10 -07:00
using System.Threading ;
2015-07-02 11:23:44 -07:00
using System.Threading.Tasks ;
2014-01-29 19:09:30 -08:00
namespace MatterHackers.MatterControl.PartPreviewWindow
{
2016-02-21 13:18:29 -08:00
public interface IInteractionVolumeCreator
{
2016-03-04 10:11:05 -08:00
InteractionVolume CreateInteractionVolume ( View3DWidget widget ) ;
2016-02-21 13:18:29 -08:00
}
public class InteractionVolumePlugin : IInteractionVolumeCreator
{
2016-03-04 10:11:05 -08:00
public virtual InteractionVolume CreateInteractionVolume ( View3DWidget widget )
{
return null ;
}
}
public interface ISideBarToolCreator
{
GuiWidget CreateSideBarTool ( View3DWidget widget ) ;
}
public class SideBarPlugin : ISideBarToolCreator
{
public virtual GuiWidget CreateSideBarTool ( View3DWidget widget )
2016-02-21 13:18:29 -08:00
{
return null ;
}
}
2015-04-08 15:20:10 -07:00
public partial class View3DWidget : PartPreview3DWidget
{
2016-08-08 14:44:21 -07:00
public UndoBuffer UndoBuffer { get ; private set ; } = new UndoBuffer ( ) ;
2016-02-26 21:54:15 -08:00
public readonly int EditButtonHeight = 44 ;
2015-06-24 16:59:10 -07:00
private Action afterSaveCallback = null ;
2016-02-19 11:27:55 -08:00
private List < MeshGroup > asyncMeshGroups = new List < MeshGroup > ( ) ;
2016-02-26 14:19:52 -08:00
private List < Matrix4X4 > asyncMeshGroupTransforms = new List < Matrix4X4 > ( ) ;
2016-02-19 11:27:55 -08:00
private List < PlatingMeshGroupData > asyncPlatingDatas = new List < PlatingMeshGroupData > ( ) ;
2015-05-30 12:48:16 -07:00
private FlowLayoutWidget doEdittingButtonsContainer ;
private bool editorThatRequestedSave = false ;
private FlowLayoutWidget enterEditButtonsContainer ;
private CheckBox expandMaterialOptions ;
private CheckBox expandRotateOptions ;
private CheckBox expandViewOptions ;
private ExportPrintItemWindow exportingWindow = null ;
private ObservableCollection < GuiWidget > extruderButtons = new ObservableCollection < GuiWidget > ( ) ;
private bool hasDrawn = false ;
private FlowLayoutWidget materialOptionContainer ;
2016-02-27 15:01:28 -08:00
public List < PlatingMeshGroupData > MeshGroupExtraData { get ; private set ; }
2016-02-19 08:29:49 -08:00
public MeshSelectInfo CurrentSelectInfo { get ; private set ; } = new MeshSelectInfo ( ) ;
2015-05-30 12:48:16 -07:00
private OpenMode openMode ;
private bool partHasBeenEdited = false ;
2015-04-08 15:20:10 -07:00
private List < string > pendingPartsToLoad = new List < string > ( ) ;
2015-05-30 12:48:16 -07:00
private PrintItemWrapper printItemWrapper ;
2015-04-08 15:20:10 -07:00
private ProgressControl processingProgressControl ;
2015-05-30 12:48:16 -07:00
private FlowLayoutWidget rotateOptionContainer ;
private SaveAsWindow saveAsWindow = null ;
private SplitButton saveButtons ;
private bool saveSucceded = true ;
private EventHandler SelectionChanged ;
private RGBA_Bytes [ ] SelectionColors = new RGBA_Bytes [ ] { new RGBA_Bytes ( 131 , 4 , 66 ) , new RGBA_Bytes ( 227 , 31 , 61 ) , new RGBA_Bytes ( 255 , 148 , 1 ) , new RGBA_Bytes ( 247 , 224 , 23 ) , new RGBA_Bytes ( 143 , 212 , 1 ) } ;
private Stopwatch timeSinceLastSpin = new Stopwatch ( ) ;
private Stopwatch timeSinceReported = new Stopwatch ( ) ;
private Matrix4X4 transformOnMouseDown = Matrix4X4 . Identity ;
private EventHandler unregisterEvents ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
private bool viewIsInEditModePreLock = false ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
private FlowLayoutWidget viewOptionContainer ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
private bool wasInSelectMode = false ;
2015-04-08 15:20:10 -07:00
2016-02-28 11:54:42 -08:00
public event EventHandler SelectedTransformChanged ;
2016-10-06 10:59:51 -07:00
public static ImageBuffer ArrowRight
{
get
{
2016-10-10 15:16:26 -07:00
if ( ActiveTheme . Instance . IsDarkTheme )
{
return StaticData . Instance . LoadIcon ( "icon_arrow_right_no_border_32x32.png" , 32 , 32 ) . InvertLightness ( ) ;
}
else
{
return StaticData . Instance . LoadIcon ( "icon_arrow_right_no_border_32x32.png" , 32 , 32 ) ;
}
2016-10-06 10:59:51 -07:00
}
}
public static ImageBuffer ArrowDown
{
get
{
2016-10-10 15:16:26 -07:00
if ( ActiveTheme . Instance . IsDarkTheme )
{
return StaticData . Instance . LoadIcon ( "icon_arrow_down_no_border_32x32.png" , 32 , 32 ) . InvertLightness ( ) ;
}
else
{
return StaticData . Instance . LoadIcon ( "icon_arrow_down_no_border_32x32.png" , 32 , 32 ) ;
}
2016-10-06 10:59:51 -07:00
}
}
2016-06-16 10:22:38 -07:00
public View3DWidget ( PrintItemWrapper printItemWrapper , Vector3 viewerVolume , Vector2 bedCenter , BedShape bedShape , WindowMode windowType , AutoRotate autoRotate , OpenMode openMode = OpenMode . Viewing )
2015-05-30 12:48:16 -07:00
{
this . openMode = openMode ;
this . windowType = windowType ;
allowAutoRotate = ( autoRotate = = AutoRotate . Enabled ) ;
autoRotating = allowAutoRotate ;
MeshGroupExtraData = new List < PlatingMeshGroupData > ( ) ;
MeshGroupExtraData . Add ( new PlatingMeshGroupData ( ) ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
this . printItemWrapper = printItemWrapper ;
2016-03-01 11:25:15 -08:00
this . Name = "View3DWidget" ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
FlowLayoutWidget mainContainerTopToBottom = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
mainContainerTopToBottom . HAnchor = Agg . UI . HAnchor . Max_FitToChildren_ParentWidth ;
mainContainerTopToBottom . VAnchor = Agg . UI . VAnchor . Max_FitToChildren_ParentHeight ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
FlowLayoutWidget centerPartPreviewAndControls = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
centerPartPreviewAndControls . Name = "centerPartPreviewAndControls" ;
centerPartPreviewAndControls . AnchorAll ( ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
GuiWidget viewArea = new GuiWidget ( ) ;
viewArea . AnchorAll ( ) ;
{
meshViewerWidget = new MeshViewerWidget ( viewerVolume , bedCenter , bedShape , "Press 'Add' to select an item." . Localize ( ) ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
PutOemImageOnBed ( ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
meshViewerWidget . AnchorAll ( ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
viewArea . AddChild ( meshViewerWidget ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
centerPartPreviewAndControls . AddChild ( viewArea ) ;
mainContainerTopToBottom . AddChild ( centerPartPreviewAndControls ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
FlowLayoutWidget buttonBottomPanel = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
buttonBottomPanel . HAnchor = HAnchor . ParentLeftRight ;
buttonBottomPanel . Padding = new BorderDouble ( 3 , 3 ) ;
buttonBottomPanel . BackgroundColor = ActiveTheme . Instance . PrimaryBackgroundColor ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
buttonRightPanel = CreateRightButtonPanel ( viewerVolume . y ) ;
buttonRightPanel . Name = "buttonRightPanel" ;
buttonRightPanel . Visible = false ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
CreateOptionsContent ( ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
// add in the plater tools
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
FlowLayoutWidget editToolBar = new FlowLayoutWidget ( ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
string progressFindPartsLabel = "Entering Editor" . Localize ( ) ;
string progressFindPartsLabelFull = "{0}:" . FormatWith ( progressFindPartsLabel ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
processingProgressControl = new ProgressControl ( progressFindPartsLabelFull , ActiveTheme . Instance . PrimaryTextColor , ActiveTheme . Instance . PrimaryAccentColor ) ;
processingProgressControl . VAnchor = Agg . UI . VAnchor . ParentCenter ;
editToolBar . AddChild ( processingProgressControl ) ;
editToolBar . VAnchor | = Agg . UI . VAnchor . ParentCenter ;
processingProgressControl . Visible = false ;
2015-04-08 15:20:10 -07:00
2016-02-16 17:41:51 -08:00
// If the window is embedded (in the center panel) and there is no item loaded then don't show the add button
2015-05-30 12:48:16 -07:00
enterEditButtonsContainer = new FlowLayoutWidget ( ) ;
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
Button addButton = textImageButtonFactory . Generate ( "Insert" . Localize ( ) , "icon_insert_32x32.png" ) ;
2015-08-10 13:36:31 -07:00
addButton . ToolTipText = "Insert an .stl, .amf or .zip file" . Localize ( ) ;
2015-05-30 12:48:16 -07:00
addButton . Margin = new BorderDouble ( right : 0 ) ;
enterEditButtonsContainer . AddChild ( addButton ) ;
addButton . Click + = ( sender , e ) = >
2015-04-08 15:20:10 -07:00
{
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
DoAddFileAfterCreatingEditData = true ;
EnterEditAndCreateSelectionData ( ) ;
} ) ;
} ;
2015-12-22 15:26:51 -08:00
if ( printItemWrapper ! = null
2015-07-14 16:44:05 -07:00
& & printItemWrapper . PrintItem . ReadOnly )
2015-07-13 10:08:08 -07:00
{
addButton . Enabled = false ;
}
2015-04-08 15:20:10 -07:00
2016-05-13 11:37:22 -07:00
ImageBuffer normalImage = StaticData . Instance . LoadIcon ( "icon_edit.png" , 14 , 14 ) ;
2016-05-06 17:56:27 -07:00
2016-05-07 17:18:05 -07:00
Button enterEdittingButton = textImageButtonFactory . Generate ( "Edit" . Localize ( ) , normalImage ) ;
2015-09-01 16:03:29 -07:00
enterEdittingButton . Name = "3D View Edit" ;
2015-05-30 12:48:16 -07:00
enterEdittingButton . Margin = new BorderDouble ( right : 4 ) ;
enterEdittingButton . Click + = ( sender , e ) = >
{
EnterEditAndCreateSelectionData ( ) ;
} ;
2015-12-22 15:26:51 -08:00
if ( printItemWrapper ! = null
2015-07-14 16:44:05 -07:00
& & printItemWrapper . PrintItem . ReadOnly )
2015-07-13 10:08:08 -07:00
{
enterEdittingButton . Enabled = false ;
}
2014-03-07 09:50:41 -08:00
2014-11-06 11:57:32 -08:00
Button exportButton = textImageButtonFactory . Generate ( "Export..." . Localize ( ) ) ;
2015-12-22 15:26:51 -08:00
if ( printItemWrapper ! = null & &
2015-07-14 16:44:05 -07:00
( printItemWrapper . PrintItem . Protected | | printItemWrapper . PrintItem . ReadOnly ) )
2015-07-13 10:08:08 -07:00
{
exportButton . Enabled = false ;
}
2014-10-10 14:52:50 -07:00
exportButton . Margin = new BorderDouble ( right : 10 ) ;
2015-04-08 15:20:10 -07:00
exportButton . Click + = ( sender , e ) = >
2014-10-10 14:52:50 -07:00
{
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2014-10-10 14:52:50 -07:00
{
OpenExportWindow ( ) ;
} ) ;
} ;
2015-04-08 15:20:10 -07:00
enterEditButtonsContainer . AddChild ( enterEdittingButton ) ;
2014-10-10 14:52:50 -07:00
enterEditButtonsContainer . AddChild ( exportButton ) ;
2015-04-08 15:20:10 -07:00
}
editToolBar . AddChild ( enterEditButtonsContainer ) ;
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
doEdittingButtonsContainer = new FlowLayoutWidget ( ) ;
doEdittingButtonsContainer . Visible = false ;
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
{
2014-12-20 09:07:13 -08:00
Button addButton = textImageButtonFactory . Generate ( "Insert" . Localize ( ) , "icon_insert_32x32.png" ) ;
2015-04-08 15:20:10 -07:00
addButton . Margin = new BorderDouble ( right : 10 ) ;
doEdittingButtonsContainer . AddChild ( addButton ) ;
addButton . Click + = ( sender , e ) = >
{
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2015-04-08 15:20:10 -07:00
{
FileDialog . OpenFileDialog (
new OpenFileDialogParams ( ApplicationSettings . OpenDesignFileParams , multiSelect : true ) ,
( openParams ) = >
{
LoadAndAddPartsToPlate ( openParams . FileNames ) ;
} ) ;
} ) ;
} ;
2014-01-29 19:09:30 -08:00
2014-12-20 09:07:13 -08:00
GuiWidget separator = new GuiWidget ( 1 , 2 ) ;
separator . BackgroundColor = ActiveTheme . Instance . PrimaryTextColor ;
separator . Margin = new BorderDouble ( 4 , 2 ) ;
separator . VAnchor = VAnchor . ParentBottomTop ;
doEdittingButtonsContainer . AddChild ( separator ) ;
2014-12-19 09:39:29 -08:00
2015-04-08 15:20:10 -07:00
Button ungroupButton = textImageButtonFactory . Generate ( "Ungroup" . Localize ( ) ) ;
2016-03-01 13:00:18 -08:00
ungroupButton . Name = "3D View Ungroup" ;
2015-04-08 15:20:10 -07:00
doEdittingButtonsContainer . AddChild ( ungroupButton ) ;
ungroupButton . Click + = ( sender , e ) = >
{
UngroupSelectedMeshGroup ( ) ;
2016-08-08 14:44:21 -07:00
UndoBuffer . ClearHistory ( ) ;
2015-04-08 15:20:10 -07:00
} ;
2014-10-13 18:20:01 -07:00
2015-04-08 15:20:10 -07:00
Button groupButton = textImageButtonFactory . Generate ( "Group" . Localize ( ) ) ;
2016-03-01 13:00:18 -08:00
groupButton . Name = "3D View Group" ;
2015-04-08 15:20:10 -07:00
doEdittingButtonsContainer . AddChild ( groupButton ) ;
groupButton . Click + = ( sender , e ) = >
{
GroupSelectedMeshs ( ) ;
2016-08-08 14:44:21 -07:00
UndoBuffer . ClearHistory ( ) ;
2015-04-08 15:20:10 -07:00
} ;
2014-10-29 13:15:53 -07:00
2015-04-08 15:20:10 -07:00
Button alignButton = textImageButtonFactory . Generate ( "Align" . Localize ( ) ) ;
doEdittingButtonsContainer . AddChild ( alignButton ) ;
alignButton . Click + = ( sender , e ) = >
{
AlignToSelectedMeshGroup ( ) ;
2016-08-08 14:44:21 -07:00
UndoBuffer . ClearHistory ( ) ;
2015-04-08 15:20:10 -07:00
} ;
2014-10-15 14:11:14 -07:00
2015-05-01 09:45:50 -07:00
Button arrangeButton = textImageButtonFactory . Generate ( "Arrange" . Localize ( ) ) ;
doEdittingButtonsContainer . AddChild ( arrangeButton ) ;
arrangeButton . Click + = ( sender , e ) = >
{
AutoArrangePartsInBackground ( ) ;
} ;
2014-12-20 09:07:13 -08:00
GuiWidget separatorTwo = new GuiWidget ( 1 , 2 ) ;
separatorTwo . BackgroundColor = ActiveTheme . Instance . PrimaryTextColor ;
separatorTwo . Margin = new BorderDouble ( 4 , 2 ) ;
separatorTwo . VAnchor = VAnchor . ParentBottomTop ;
doEdittingButtonsContainer . AddChild ( separatorTwo ) ;
2015-04-08 15:20:10 -07:00
Button copyButton = textImageButtonFactory . Generate ( "Copy" . Localize ( ) ) ;
2015-09-01 16:03:29 -07:00
copyButton . Name = "3D View Copy" ;
2015-04-08 15:20:10 -07:00
doEdittingButtonsContainer . AddChild ( copyButton ) ;
copyButton . Click + = ( sender , e ) = >
{
MakeCopyOfGroup ( ) ;
} ;
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
Button deleteButton = textImageButtonFactory . Generate ( "Remove" . Localize ( ) ) ;
2016-03-01 15:15:48 -08:00
deleteButton . Name = "3D View Remove" ;
2015-04-08 15:20:10 -07:00
doEdittingButtonsContainer . AddChild ( deleteButton ) ;
deleteButton . Click + = ( sender , e ) = >
{
DeleteSelectedMesh ( ) ;
} ;
2014-10-13 18:20:01 -07:00
2014-12-20 09:07:13 -08:00
GuiWidget separatorThree = new GuiWidget ( 1 , 2 ) ;
separatorThree . BackgroundColor = ActiveTheme . Instance . PrimaryTextColor ;
separatorThree . Margin = new BorderDouble ( 4 , 1 ) ;
separatorThree . VAnchor = VAnchor . ParentBottomTop ;
doEdittingButtonsContainer . AddChild ( separatorThree ) ;
2016-02-14 17:53:44 -08:00
Button cancelEditModeButton = textImageButtonFactory . Generate ( "Cancel" . Localize ( ) , centerText : true ) ;
2016-03-01 18:19:28 -08:00
cancelEditModeButton . Name = "3D View Cancel" ;
2016-02-14 17:53:44 -08:00
cancelEditModeButton . Click + = ( sender , e ) = >
2015-04-15 16:39:37 -07:00
{
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2014-12-20 09:07:13 -08:00
{
2015-04-15 16:39:37 -07:00
if ( saveButtons . Visible )
{
2016-01-20 10:12:01 -08:00
StyledMessageBox . ShowMessageBox ( ExitEditingAndSaveIfRequired , "Would you like to save your changes before exiting the editor?" . Localize ( ) , "Save Changes" . Localize ( ) , StyledMessageBox . MessageType . YES_NO ) ;
2015-04-15 16:39:37 -07:00
}
else
{
if ( partHasBeenEdited )
2014-12-20 09:07:13 -08:00
{
2015-04-15 16:39:37 -07:00
ExitEditingAndSaveIfRequired ( false ) ;
}
else
{
SwitchStateToNotEditing ( ) ;
}
}
} ) ;
} ;
2016-02-14 17:53:44 -08:00
doEdittingButtonsContainer . AddChild ( cancelEditModeButton ) ;
2014-12-20 09:07:13 -08:00
// put in the save button
AddSaveAndSaveAs ( doEdittingButtonsContainer ) ;
2015-04-08 15:20:10 -07:00
}
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
editToolBar . AddChild ( doEdittingButtonsContainer ) ;
buttonBottomPanel . AddChild ( editToolBar ) ;
}
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
GuiWidget buttonRightPanelHolder = new GuiWidget ( HAnchor . FitToChildren , VAnchor . ParentBottomTop ) ;
2015-04-15 16:39:37 -07:00
buttonRightPanelHolder . Name = "buttonRightPanelHolder" ;
2015-04-08 15:20:10 -07:00
centerPartPreviewAndControls . AddChild ( buttonRightPanelHolder ) ;
buttonRightPanelHolder . AddChild ( buttonRightPanel ) ;
2015-09-04 09:55:40 -07:00
buttonRightPanel . VisibleChanged + = ( sender , e ) = >
{
buttonRightPanelHolder . Visible = buttonRightPanel . Visible ;
} ;
2014-05-25 11:11:11 -07:00
2015-04-08 15:20:10 -07:00
viewControls3D = new ViewControls3D ( meshViewerWidget ) ;
2014-10-24 13:53:00 -07:00
2015-11-09 12:36:47 -08:00
viewControls3D . ResetView + = ( sender , e ) = >
{
2016-02-29 14:04:52 -08:00
meshViewerWidget . ResetView ( ) ;
2015-12-22 15:26:51 -08:00
} ;
2015-11-09 12:36:47 -08:00
2015-04-08 15:20:10 -07:00
buttonRightPanelDisabledCover = new Cover ( HAnchor . ParentLeftRight , VAnchor . ParentBottomTop ) ;
buttonRightPanelDisabledCover . BackgroundColor = new RGBA_Bytes ( ActiveTheme . Instance . PrimaryBackgroundColor , 150 ) ;
buttonRightPanelHolder . AddChild ( buttonRightPanelDisabledCover ) ;
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
viewControls3D . PartSelectVisible = false ;
LockEditControls ( ) ;
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
GuiWidget leftRightSpacer = new GuiWidget ( ) ;
leftRightSpacer . HAnchor = HAnchor . ParentLeftRight ;
buttonBottomPanel . AddChild ( leftRightSpacer ) ;
2014-04-09 21:47:00 -07:00
2015-04-08 15:20:10 -07:00
if ( windowType = = WindowMode . StandAlone )
{
Button closeButton = textImageButtonFactory . Generate ( "Close" . Localize ( ) ) ;
buttonBottomPanel . AddChild ( closeButton ) ;
closeButton . Click + = ( sender , e ) = >
{
CloseOnIdle ( ) ;
} ;
}
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
mainContainerTopToBottom . AddChild ( buttonBottomPanel ) ;
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
this . AddChild ( mainContainerTopToBottom ) ;
this . AnchorAll ( ) ;
2014-01-29 19:09:30 -08:00
2015-04-08 15:20:10 -07:00
meshViewerWidget . TrackballTumbleWidget . TransformState = TrackBallController . MouseDownType . Rotation ;
AddChild ( viewControls3D ) ;
2014-03-01 23:27:34 -08:00
2015-04-08 15:20:10 -07:00
UiThread . RunOnIdle ( AutoSpin ) ;
2014-05-27 09:16:35 -07:00
2015-04-08 15:20:10 -07:00
if ( printItemWrapper = = null & & windowType = = WindowMode . Embeded )
{
enterEditButtonsContainer . Visible = false ;
}
if ( windowType = = WindowMode . Embeded )
{
PrinterConnectionAndCommunication . Instance . CommunicationStateChanged . RegisterEvent ( SetEditControlsBasedOnPrinterState , ref unregisterEvents ) ;
if ( windowType = = WindowMode . Embeded )
{
// make sure we lock the controls if we are printing or paused
switch ( PrinterConnectionAndCommunication . Instance . CommunicationState )
{
case PrinterConnectionAndCommunication . CommunicationStates . Printing :
case PrinterConnectionAndCommunication . CommunicationStates . Paused :
LockEditControls ( ) ;
break ;
}
}
}
2016-04-29 07:45:15 -07:00
ActiveTheme . ThemeChanged . RegisterEvent ( ThemeChanged , ref unregisterEvents ) ;
2015-04-08 15:20:10 -07:00
2016-02-16 08:30:13 -08:00
meshViewerWidget . interactionVolumes . Add ( new UpArrow3D ( this ) ) ;
meshViewerWidget . interactionVolumes . Add ( new SelectionShadow ( this ) ) ;
2016-02-20 15:39:54 -08:00
meshViewerWidget . interactionVolumes . Add ( new SnappingIndicators ( this ) ) ;
2015-04-08 15:20:10 -07:00
2016-02-21 13:18:29 -08:00
PluginFinder < InteractionVolumePlugin > InteractionVolumePlugins = new PluginFinder < InteractionVolumePlugin > ( ) ;
2016-02-27 13:56:57 -08:00
foreach ( InteractionVolumePlugin plugin in InteractionVolumePlugins . Plugins )
2016-02-21 13:18:29 -08:00
{
2016-03-18 12:02:46 -07:00
meshViewerWidget . interactionVolumes . Add ( plugin . CreateInteractionVolume ( this ) ) ;
2016-02-21 13:18:29 -08:00
}
2016-02-17 18:06:32 -08:00
// make sure the colors are set correct
2015-04-08 15:20:10 -07:00
ThemeChanged ( this , null ) ;
saveButtons . VisibleChanged + = ( sender , e ) = >
{
partHasBeenEdited = true ;
} ;
2015-11-09 12:36:47 -08:00
2016-02-29 14:04:52 -08:00
meshViewerWidget . ResetView ( ) ;
2015-12-22 15:26:51 -08:00
#if DoBooleanTest
DrawBefore + = CreateBooleanTestGeometry ;
DrawAfter + = RemoveBooleanTestGeometry ;
#endif
2016-03-25 17:32:05 -07:00
meshViewerWidget . TrackballTumbleWidget . DrawGlContent + = trackballTumbleWidget_DrawGlContent ;
}
private void trackballTumbleWidget_DrawGlContent ( object sender , EventArgs e )
{
if ( allObjects ! = null )
{
//DebugBvh.Render(allObjects, Matrix4X4.Identity);
}
2015-12-22 15:26:51 -08:00
}
2016-02-27 13:56:57 -08:00
public override void OnKeyDown ( KeyEventArgs keyEvent )
{
if ( activeButtonBeforeKeyOverride = = null )
{
activeButtonBeforeKeyOverride = viewControls3D . ActiveButton ;
if ( keyEvent . Alt )
{
viewControls3D . ActiveButton = ViewControls3DButtons . Rotate ;
}
else if ( keyEvent . Shift )
{
viewControls3D . ActiveButton = ViewControls3DButtons . Translate ;
}
else if ( keyEvent . Control )
{
viewControls3D . ActiveButton = ViewControls3DButtons . Scale ;
}
}
switch ( keyEvent . KeyCode )
{
case Keys . Z :
if ( keyEvent . Control )
{
2016-08-08 14:44:21 -07:00
UndoBuffer . Undo ( ) ;
2016-02-27 13:56:57 -08:00
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
}
break ;
case Keys . Y :
if ( keyEvent . Control )
{
2016-08-08 14:44:21 -07:00
UndoBuffer . Redo ( ) ;
2016-02-27 13:56:57 -08:00
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
}
break ;
case Keys . Delete :
case Keys . Back :
DeleteSelectedMesh ( ) ;
break ;
case Keys . Escape :
if ( CurrentSelectInfo . DownOnPart )
{
CurrentSelectInfo . DownOnPart = false ;
SelectedMeshGroupTransform = transformOnMouseDown ;
Invalidate ( ) ;
}
break ;
}
2016-02-29 07:57:30 -08:00
base . OnKeyDown ( keyEvent ) ;
2016-02-27 13:56:57 -08:00
}
2016-02-17 18:06:32 -08:00
public bool DragingPart
{
2016-02-19 08:29:49 -08:00
get { return CurrentSelectInfo . DownOnPart ; }
2016-02-17 18:06:32 -08:00
}
2016-02-14 17:53:44 -08:00
private void AddGridSnapSettings ( GuiWidget widgetToAddTo )
{
FlowLayoutWidget container = new FlowLayoutWidget ( )
{
2016-05-06 17:56:27 -07:00
Margin = new BorderDouble ( 5 , 0 ) ,
2016-02-14 17:53:44 -08:00
} ;
TextWidget snapGridLabel = new TextWidget ( "Snap Grid" . Localize ( ) )
{
TextColor = ActiveTheme . Instance . PrimaryTextColor ,
VAnchor = VAnchor . ParentCenter ,
2016-05-06 17:56:27 -07:00
Margin = new BorderDouble ( 3 , 0 , 0 , 0 ) ,
2016-02-14 17:53:44 -08:00
} ;
container . AddChild ( snapGridLabel ) ;
2016-06-03 18:11:51 -07:00
DropDownList selectableOptions = new DropDownList ( "Custom" , Direction . Up )
2016-02-14 17:53:44 -08:00
{
VAnchor = VAnchor . ParentCenter | VAnchor . FitToChildren ,
} ;
Dictionary < double , string > snapSettings = new Dictionary < double , string > ( )
{
{ 0 , "Off" } ,
2016-02-16 11:07:34 -08:00
{ . 1 , "0.1" } ,
{ . 25 , "0.25" } ,
{ . 5 , "0.5" } ,
2016-02-14 17:53:44 -08:00
{ 1 , "1" } ,
{ 2 , "2" } ,
{ 5 , "5" } ,
} ;
foreach ( KeyValuePair < double , string > snapSetting in snapSettings )
{
double valueLocal = snapSetting . Key ;
MenuItem newItem = selectableOptions . AddItem ( snapSetting . Value ) ;
if ( meshViewerWidget . SnapGridDistance = = valueLocal )
{
selectableOptions . SelectedLabel = snapSetting . Value ;
}
newItem . Selected + = ( sender , e ) = >
{
meshViewerWidget . SnapGridDistance = snapSetting . Key ;
} ;
}
container . AddChild ( selectableOptions ) ;
widgetToAddTo . AddChild ( container ) ;
}
2015-12-22 15:26:51 -08:00
#if DoBooleanTest
MeshGroup booleanGroup ;
2016-02-26 14:19:52 -08:00
Matrix4X4 groupTransform ;
2016-03-12 14:16:34 -08:00
Vector3 offset = new Vector3 ( ) ;
Vector3 direction = new Vector3 ( . 11 , . 12 , . 13 ) ;
Vector3 rotCurrent = new Vector3 ( ) ;
Vector3 rotChange = new Vector3 ( . 011 , . 012 , . 013 ) ;
Vector3 scaleChange = new Vector3 ( . 0011 , . 0012 , . 0013 ) ;
Vector3 scaleCurrent = new Vector3 ( 1 , 1 , 1 ) ;
2016-03-07 14:23:22 -08:00
private void CreateBooleanTestGeometry ( GuiWidget drawingWidget , DrawEventArgs e )
{
try
{
booleanGroup = new MeshGroup ( ) ;
2016-03-13 10:29:45 -07:00
booleanGroup . Meshes . Add ( ApplyBoolean ( PolygonMesh . Csg . CsgOperations . Union , AxisAlignedBoundingBox . Union , new Vector3 ( 100 , 0 , 20 ) , "U" ) ) ;
booleanGroup . Meshes . Add ( ApplyBoolean ( PolygonMesh . Csg . CsgOperations . Subtract , null , new Vector3 ( 100 , 100 , 20 ) , "S" ) ) ;
booleanGroup . Meshes . Add ( ApplyBoolean ( PolygonMesh . Csg . CsgOperations . Intersect , AxisAlignedBoundingBox . Intersection , new Vector3 ( 100 , 200 , 20 ) , "I" ) ) ;
2016-03-07 14:23:22 -08:00
offset + = direction ;
2016-03-12 14:16:34 -08:00
rotCurrent + = rotChange ;
scaleCurrent + = scaleChange ;
2016-03-07 14:23:22 -08:00
meshViewerWidget . MeshGroups . Add ( booleanGroup ) ;
groupTransform = Matrix4X4 . Identity ;
meshViewerWidget . MeshGroupTransforms . Add ( groupTransform ) ;
}
catch ( Exception e2 )
{
string text = e2 . Message ;
int a = 0 ;
}
}
2016-03-13 10:29:45 -07:00
private Mesh ApplyBoolean ( Func < Mesh , Mesh , Mesh > meshOpperation , Func < AxisAlignedBoundingBox , AxisAlignedBoundingBox , AxisAlignedBoundingBox > aabbOpperation , Vector3 centering , string opp )
2016-03-07 14:23:22 -08:00
{
Mesh boxA = PlatonicSolids . CreateCube ( 40 , 40 , 40 ) ;
2016-03-13 10:29:45 -07:00
boxA = PlatonicSolids . CreateIcosahedron ( 35 ) ;
2016-03-07 14:23:22 -08:00
boxA . Translate ( centering ) ;
2016-03-05 15:54:38 -08:00
Mesh boxB = PlatonicSolids . CreateCube ( 40 , 40 , 40 ) ;
2016-03-13 10:29:45 -07:00
boxB = PlatonicSolids . CreateIcosahedron ( 35 ) ;
2015-12-22 15:26:51 -08:00
2016-03-07 14:23:22 -08:00
for ( int i = 0 ; i < 3 ; i + + )
{
if ( Math . Abs ( direction [ i ] + offset [ i ] ) > 10 )
{
2016-03-12 14:16:34 -08:00
direction [ i ] = direction [ i ] * - 1.00073112 ;
2016-03-07 14:23:22 -08:00
}
}
2016-03-12 14:16:34 -08:00
for ( int i = 0 ; i < 3 ; i + + )
{
if ( Math . Abs ( rotChange [ i ] + rotCurrent [ i ] ) > 6 )
{
rotChange [ i ] = rotChange [ i ] * - 1.000073112 ;
}
}
for ( int i = 0 ; i < 3 ; i + + )
{
if ( scaleChange [ i ] + scaleCurrent [ i ] > 1.1 | | scaleChange [ i ] + scaleCurrent [ i ] < . 9 )
{
scaleChange [ i ] = scaleChange [ i ] * - 1.000073112 ;
}
}
2016-03-08 12:13:58 -08:00
Vector3 offsetB = offset + centering ;
// switch to the failing offset
2016-03-13 10:29:45 -07:00
//offsetB = new Vector3(105.240172225344, 92.9716306394062, 18.4619570261172);
//rotCurrent = new Vector3(4.56890223673623, -2.67874102322035, 1.02768848238523);
//scaleCurrent = new Vector3(1.07853517569753, 0.964980885267323, 1.09290934544604);
2016-03-12 14:16:34 -08:00
Debug . WriteLine ( "t" + offsetB . ToString ( ) + " r" + rotCurrent . ToString ( ) + " s" + scaleCurrent . ToString ( ) + " " + opp ) ;
Matrix4X4 transformB = Matrix4X4 . CreateScale ( scaleCurrent ) * Matrix4X4 . CreateRotation ( rotCurrent ) * Matrix4X4 . CreateTranslation ( offsetB ) ;
boxB . Transform ( transformB ) ;
2015-12-22 15:26:51 -08:00
2016-03-13 10:29:45 -07:00
Mesh meshToAdd = meshOpperation ( boxA , boxB ) ;
2016-03-07 14:23:22 -08:00
meshToAdd . CleanAndMergMesh ( ) ;
2016-03-13 10:29:45 -07:00
if ( aabbOpperation ! = null )
{
AxisAlignedBoundingBox boundsA = boxA . GetAxisAlignedBoundingBox ( ) ;
AxisAlignedBoundingBox boundsB = boxB . GetAxisAlignedBoundingBox ( ) ;
AxisAlignedBoundingBox boundsAdd = meshToAdd . GetAxisAlignedBoundingBox ( ) ;
AxisAlignedBoundingBox boundsResult = aabbOpperation ( boundsA , boundsB ) ;
if ( ! boundsAdd . Equals ( boundsResult , . 0001 ) )
{
int a = 0 ;
}
}
int nonManifoldEdges = meshToAdd . GetNonManifoldEdges ( ) . Count ;
if ( nonManifoldEdges > 0 )
{
// shoud be manifold
int a = 0 ;
}
2016-03-07 14:23:22 -08:00
return meshToAdd ;
}
private void RemoveBooleanTestGeometry ( GuiWidget drawingWidget , DrawEventArgs e )
2015-12-22 15:26:51 -08:00
{
2016-03-07 14:23:22 -08:00
if ( meshViewerWidget . MeshGroups . Contains ( booleanGroup ) )
{
meshViewerWidget . MeshGroups . Remove ( booleanGroup ) ;
meshViewerWidget . MeshGroupTransforms . Remove ( groupTransform ) ;
UiThread . RunOnIdle ( ( ) = > Invalidate ( ) , 1.0 / 30.0 ) ;
}
2015-12-22 15:26:51 -08:00
}
#endif
2015-04-08 15:20:10 -07:00
2015-12-22 15:26:51 -08:00
public enum AutoRotate { Enabled , Disabled } ;
2015-04-15 16:39:37 -07:00
2015-05-30 12:48:16 -07:00
public enum OpenMode { Viewing , Editing }
2015-04-15 16:59:12 -07:00
2015-05-30 12:48:16 -07:00
public enum WindowMode { Embeded , StandAlone } ;
2015-12-22 15:26:51 -08:00
2015-05-30 12:48:16 -07:00
private enum TraceInfoOpperation { DONT_COPY , DO_COPY } ;
2015-04-16 10:38:53 -07:00
2015-05-30 12:48:16 -07:00
public bool DisplayAllValueData { get ; set ; }
2014-12-20 11:12:02 -08:00
2015-05-30 12:48:16 -07:00
public bool HaveSelection
{
get { return MeshGroups . Count > 0 & & SelectedMeshGroupIndex > - 1 ; }
}
2014-12-20 23:45:13 -08:00
2015-05-30 12:48:16 -07:00
public List < MeshGroup > MeshGroups
{
get { return meshViewerWidget . MeshGroups ; }
2015-04-08 15:20:10 -07:00
}
2014-12-20 11:12:02 -08:00
2016-02-26 14:19:52 -08:00
public List < Matrix4X4 > MeshGroupTransforms
2015-01-25 17:54:26 -08:00
{
2015-05-30 12:48:16 -07:00
get { return meshViewerWidget . MeshGroupTransforms ; }
}
public MeshGroup SelectedMeshGroup
{
get { return meshViewerWidget . SelectedMeshGroup ; }
}
public int SelectedMeshGroupIndex
{
get
2015-05-22 11:11:32 -07:00
{
2015-05-30 12:48:16 -07:00
return meshViewerWidget . SelectedMeshGroupIndex ;
2015-05-22 11:11:32 -07:00
}
2015-05-30 12:48:16 -07:00
set
2015-01-25 17:54:26 -08:00
{
2015-05-30 12:48:16 -07:00
if ( value ! = SelectedMeshGroupIndex )
2015-01-25 17:54:26 -08:00
{
2015-05-30 12:48:16 -07:00
meshViewerWidget . SelectedMeshGroupIndex = value ;
if ( SelectionChanged ! = null )
2015-01-25 17:54:26 -08:00
{
2015-05-30 12:48:16 -07:00
SelectionChanged ( this , null ) ;
2015-02-10 14:36:02 -08:00
}
2015-05-30 12:48:16 -07:00
Invalidate ( ) ;
2015-01-25 17:54:26 -08:00
}
}
2015-05-30 12:48:16 -07:00
}
2015-01-25 17:54:26 -08:00
2016-02-26 14:19:52 -08:00
public Matrix4X4 SelectedMeshGroupTransform
2015-05-30 12:48:16 -07:00
{
get { return meshViewerWidget . SelectedMeshGroupTransform ; }
set { meshViewerWidget . SelectedMeshGroupTransform = value ; }
2015-01-25 17:54:26 -08:00
}
2015-05-30 12:48:16 -07:00
public WindowMode windowType { get ; set ; }
private bool DoAddFileAfterCreatingEditData { get ; set ; }
2015-12-22 15:26:51 -08:00
2015-05-30 12:48:16 -07:00
public override void OnClosed ( EventArgs e )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( unregisterEvents ! = null )
2014-10-10 14:52:50 -07:00
{
2015-05-30 12:48:16 -07:00
unregisterEvents ( this , null ) ;
2014-10-10 14:52:50 -07:00
}
2015-05-30 12:48:16 -07:00
base . OnClosed ( e ) ;
2014-10-10 14:52:50 -07:00
}
2015-05-30 12:48:16 -07:00
public override void OnDragDrop ( FileDropEventArgs fileDropEventArgs )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( AllowDragDrop ( ) )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
pendingPartsToLoad . Clear ( ) ;
foreach ( string droppedFileName in fileDropEventArgs . DroppedFiles )
2015-04-15 16:59:12 -07:00
{
2015-05-30 12:48:16 -07:00
string extension = Path . GetExtension ( droppedFileName ) . ToLower ( ) ;
2015-08-03 16:46:57 -07:00
if ( extension ! = "" & & ApplicationSettings . OpenDesignFileParams . Contains ( extension ) )
2015-05-30 12:48:16 -07:00
{
pendingPartsToLoad . Add ( droppedFileName ) ;
}
}
if ( pendingPartsToLoad . Count > 0 )
{
bool enterEditModeBeforeAddingParts = enterEditButtonsContainer . Visible = = true ;
if ( enterEditModeBeforeAddingParts )
{
EnterEditAndCreateSelectionData ( ) ;
}
else
{
LoadAndAddPartsToPlate ( pendingPartsToLoad . ToArray ( ) ) ;
2016-01-07 12:41:36 -08:00
pendingPartsToLoad . Clear ( ) ;
2015-05-30 12:48:16 -07:00
}
2015-04-15 16:59:12 -07:00
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
base . OnDragDrop ( fileDropEventArgs ) ;
2015-04-08 15:20:10 -07:00
}
2014-10-12 20:40:38 -07:00
2015-05-30 12:48:16 -07:00
public override void OnDragEnter ( FileDropEventArgs fileDropEventArgs )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( AllowDragDrop ( ) )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
foreach ( string file in fileDropEventArgs . DroppedFiles )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
string extension = Path . GetExtension ( file ) . ToLower ( ) ;
2015-08-03 16:46:57 -07:00
if ( extension ! = "" & & ApplicationSettings . OpenDesignFileParams . Contains ( extension ) )
2015-05-30 12:48:16 -07:00
{
fileDropEventArgs . AcceptDrop = true ;
}
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
base . OnDragEnter ( fileDropEventArgs ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
public override void OnDragOver ( FileDropEventArgs fileDropEventArgs )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( AllowDragDrop ( ) )
{
foreach ( string file in fileDropEventArgs . DroppedFiles )
{
string extension = Path . GetExtension ( file ) . ToLower ( ) ;
2015-08-03 16:46:57 -07:00
if ( extension ! = "" & & ApplicationSettings . OpenDesignFileParams . Contains ( extension ) )
2015-05-30 12:48:16 -07:00
{
fileDropEventArgs . AcceptDrop = true ;
}
}
}
base . OnDragOver ( fileDropEventArgs ) ;
2015-04-08 15:20:10 -07:00
}
2016-07-24 17:26:24 -07:00
public override void OnLoad ( EventArgs args )
2015-04-08 15:20:10 -07:00
{
2016-07-24 17:26:24 -07:00
ClearBedAndLoadPrintItemWrapper ( printItemWrapper ) ;
base . OnLoad ( args ) ;
}
2015-04-08 15:20:10 -07:00
2016-07-24 17:26:24 -07:00
public override void OnDraw ( Graphics2D graphics2D )
{
2015-05-30 12:48:16 -07:00
if ( HaveSelection )
{
2016-02-16 08:30:13 -08:00
foreach ( InteractionVolume volume in meshViewerWidget . interactionVolumes )
{
volume . SetPosition ( ) ;
}
2015-04-08 15:20:10 -07:00
}
2014-03-20 18:20:52 -07:00
2015-05-30 12:48:16 -07:00
hasDrawn = true ;
base . OnDraw ( graphics2D ) ;
}
2015-04-08 15:20:10 -07:00
2015-12-22 15:26:51 -08:00
private ViewControls3DButtons ? activeButtonBeforeMouseOverride = null ;
private ViewControls3DButtons ? activeButtonBeforeKeyOverride = null ;
2015-05-29 15:13:56 -07:00
public override void OnKeyUp ( KeyEventArgs keyEvent )
{
if ( activeButtonBeforeKeyOverride ! = null )
{
viewControls3D . ActiveButton = ( ViewControls3DButtons ) activeButtonBeforeKeyOverride ;
activeButtonBeforeKeyOverride = null ;
}
base . OnKeyUp ( keyEvent ) ;
}
2015-05-30 12:48:16 -07:00
public override void OnMouseDown ( MouseEventArgs mouseEvent )
2015-04-08 15:20:10 -07:00
{
2015-05-29 15:13:56 -07:00
// Show transform override
if ( activeButtonBeforeMouseOverride = = null & & mouseEvent . Button = = MouseButtons . Right )
{
activeButtonBeforeMouseOverride = viewControls3D . ActiveButton ;
viewControls3D . ActiveButton = ViewControls3DButtons . Rotate ;
}
else if ( activeButtonBeforeMouseOverride = = null & & mouseEvent . Button = = MouseButtons . Middle )
{
activeButtonBeforeMouseOverride = viewControls3D . ActiveButton ;
viewControls3D . ActiveButton = ViewControls3DButtons . Translate ;
}
2015-05-30 12:48:16 -07:00
autoRotating = false ;
base . OnMouseDown ( mouseEvent ) ;
if ( meshViewerWidget . TrackballTumbleWidget . UnderMouseState = = Agg . UI . UnderMouseState . FirstUnderMouse )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( meshViewerWidget . TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . None
& & mouseEvent . Button = = MouseButtons . Left
& & ModifierKeys ! = Keys . Shift
& & ModifierKeys ! = Keys . Control
& & ModifierKeys ! = Keys . Alt )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( ! meshViewerWidget . MouseDownOnInteractionVolume )
{
int meshGroupHitIndex ;
2016-02-19 08:29:49 -08:00
IntersectInfo info = new IntersectInfo ( ) ;
if ( FindMeshGroupHitPosition ( mouseEvent . Position , out meshGroupHitIndex , ref info ) )
2015-05-30 12:48:16 -07:00
{
2016-02-19 08:29:49 -08:00
CurrentSelectInfo . HitPlane = new PlaneShape ( Vector3 . UnitZ , CurrentSelectInfo . PlaneDownHitPos . z , null ) ;
2015-05-30 12:48:16 -07:00
SelectedMeshGroupIndex = meshGroupHitIndex ;
2014-03-20 18:20:52 -07:00
2016-02-26 14:19:52 -08:00
transformOnMouseDown = SelectedMeshGroupTransform ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
Invalidate ( ) ;
2016-02-19 08:29:49 -08:00
CurrentSelectInfo . DownOnPart = true ;
AxisAlignedBoundingBox selectedBounds = meshViewerWidget . GetBoundsForSelection ( ) ;
if ( info . hitPosition . x < selectedBounds . Center . x )
{
if ( info . hitPosition . y < selectedBounds . Center . y )
{
CurrentSelectInfo . HitQuadrant = HitQuadrant . LB ;
}
else
{
CurrentSelectInfo . HitQuadrant = HitQuadrant . LT ;
}
}
else
{
if ( info . hitPosition . y < selectedBounds . Center . y )
{
CurrentSelectInfo . HitQuadrant = HitQuadrant . RB ;
}
else
{
CurrentSelectInfo . HitQuadrant = HitQuadrant . RT ;
}
}
2015-05-30 12:48:16 -07:00
}
else
{
SelectedMeshGroupIndex = - 1 ;
}
2016-02-28 11:54:42 -08:00
SelectedTransformChanged ? . Invoke ( this , null ) ;
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
}
}
2015-02-27 11:09:37 -08:00
2016-02-17 08:23:09 -08:00
public Vector3 LastHitPosition { get ; private set ; }
2015-05-30 12:48:16 -07:00
public override void OnMouseMove ( MouseEventArgs mouseEvent )
{
2016-02-19 08:29:49 -08:00
if ( meshViewerWidget . TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . None & & CurrentSelectInfo . DownOnPart )
2015-05-30 12:48:16 -07:00
{
Vector2 meshViewerWidgetScreenPosition = meshViewerWidget . TransformFromParentSpace ( this , new Vector2 ( mouseEvent . X , mouseEvent . Y ) ) ;
Ray ray = meshViewerWidget . TrackballTumbleWidget . GetRayFromScreen ( meshViewerWidgetScreenPosition ) ;
2016-02-19 08:29:49 -08:00
IntersectInfo info = CurrentSelectInfo . HitPlane . GetClosestIntersection ( ray ) ;
2015-05-30 12:48:16 -07:00
if ( info ! = null )
2015-02-27 11:09:37 -08:00
{
2016-02-18 09:36:01 -08:00
// move the mesh back to the start position
{
2016-02-19 08:29:49 -08:00
Matrix4X4 totalTransform = Matrix4X4 . CreateTranslation ( new Vector3 ( - CurrentSelectInfo . LastMoveDelta ) ) ;
2016-02-26 14:19:52 -08:00
SelectedMeshGroupTransform * = totalTransform ;
2016-02-18 09:36:01 -08:00
}
2016-02-19 08:29:49 -08:00
Vector3 delta = info . hitPosition - CurrentSelectInfo . PlaneDownHitPos ;
2015-02-27 11:09:37 -08:00
2016-02-20 09:17:25 -08:00
double snapGridDistance = meshViewerWidget . SnapGridDistance ;
if ( snapGridDistance > 0 )
2016-02-17 08:23:09 -08:00
{
// snap this position to the grid
AxisAlignedBoundingBox selectedBounds = meshViewerWidget . GetBoundsForSelection ( ) ;
2016-02-20 15:39:54 -08:00
double xSnapOffset = selectedBounds . minXYZ . x ;
2016-02-17 08:23:09 -08:00
// snap the x position
2016-02-20 09:17:25 -08:00
if ( CurrentSelectInfo . HitQuadrant = = HitQuadrant . RB
| | CurrentSelectInfo . HitQuadrant = = HitQuadrant . RT )
2016-02-17 08:23:09 -08:00
{
2016-02-20 09:17:25 -08:00
// switch to the other side
xSnapOffset = selectedBounds . maxXYZ . x ;
2016-02-17 08:23:09 -08:00
}
2016-02-20 09:17:25 -08:00
double xToSnap = xSnapOffset + delta . x ;
2016-05-11 12:26:20 -07:00
double snappedX = ( Math . Round ( ( xToSnap / snapGridDistance ) ) ) * snapGridDistance ;
2016-02-20 09:17:25 -08:00
delta . x = snappedX - xSnapOffset ;
2016-02-17 08:23:09 -08:00
2016-02-20 15:39:54 -08:00
double ySnapOffset = selectedBounds . minXYZ . y ;
2016-02-17 08:23:09 -08:00
// snap the y position
2016-02-20 09:17:25 -08:00
if ( CurrentSelectInfo . HitQuadrant = = HitQuadrant . LT
| | CurrentSelectInfo . HitQuadrant = = HitQuadrant . RT )
2016-02-17 18:06:32 -08:00
{
2016-02-20 09:17:25 -08:00
// switch to the other side
ySnapOffset = selectedBounds . maxXYZ . y ;
2016-02-17 18:06:32 -08:00
}
2016-02-20 09:17:25 -08:00
double yToSnap = ySnapOffset + delta . y ;
2016-05-11 12:26:20 -07:00
double snappedY = ( Math . Round ( ( yToSnap / snapGridDistance ) ) ) * snapGridDistance ;
2016-02-20 09:17:25 -08:00
delta . y = snappedY - ySnapOffset ;
2016-02-17 08:23:09 -08:00
}
2016-02-18 09:36:01 -08:00
// move the mesh back to the new position
{
Matrix4X4 totalTransform = Matrix4X4 . CreateTranslation ( new Vector3 ( delta ) ) ;
2015-02-27 11:09:37 -08:00
2016-02-26 14:19:52 -08:00
SelectedMeshGroupTransform * = totalTransform ;
2016-02-18 09:36:01 -08:00
2016-02-19 08:29:49 -08:00
CurrentSelectInfo . LastMoveDelta = delta ;
2016-02-18 09:36:01 -08:00
}
LastHitPosition = info . hitPosition ;
2015-02-27 11:09:37 -08:00
2015-05-30 12:48:16 -07:00
Invalidate ( ) ;
2015-02-27 11:09:37 -08:00
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
base . OnMouseMove ( mouseEvent ) ;
2015-04-08 15:20:10 -07:00
}
2016-02-27 13:56:57 -08:00
public void AddUndoForSelectedMeshGroupTransform ( Matrix4X4 undoTransform )
{
2016-02-28 08:21:00 -08:00
if ( undoTransform ! = SelectedMeshGroupTransform )
{
2016-08-08 14:44:21 -07:00
UndoBuffer . Add ( new TransformUndoCommand ( this , SelectedMeshGroupIndex , undoTransform , SelectedMeshGroupTransform ) ) ;
2016-02-28 08:21:00 -08:00
}
2016-02-27 13:56:57 -08:00
}
2015-05-30 12:48:16 -07:00
public override void OnMouseUp ( MouseEventArgs mouseEvent )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( meshViewerWidget . TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . None
2016-02-19 08:29:49 -08:00
& & CurrentSelectInfo . DownOnPart
& & CurrentSelectInfo . LastMoveDelta ! = Vector3 . Zero )
2015-04-08 15:20:10 -07:00
{
2016-02-27 13:56:57 -08:00
if ( SelectedMeshGroupTransform ! = transformOnMouseDown )
{
AddUndoForSelectedMeshGroupTransform ( transformOnMouseDown ) ;
PartHasBeenChanged ( ) ;
}
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
2016-02-19 08:29:49 -08:00
CurrentSelectInfo . DownOnPart = false ;
2015-04-08 15:20:10 -07:00
2015-05-29 15:13:56 -07:00
if ( activeButtonBeforeMouseOverride ! = null )
{
viewControls3D . ActiveButton = ( ViewControls3DButtons ) activeButtonBeforeMouseOverride ;
activeButtonBeforeMouseOverride = null ;
}
2015-05-30 12:48:16 -07:00
base . OnMouseUp ( mouseEvent ) ;
}
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
public void PartHasBeenChanged ( )
{
saveButtons . Visible = true ;
2016-02-28 11:54:42 -08:00
SelectedTransformChanged ? . Invoke ( this , null ) ;
2016-02-27 15:01:28 -08:00
Invalidate ( ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
public void ThemeChanged ( object sender , EventArgs e )
{
2015-07-14 13:38:22 -07:00
processingProgressControl . FillColor = ActiveTheme . Instance . PrimaryAccentColor ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
MeshViewerWidget . SetMaterialColor ( 1 , ActiveTheme . Instance . PrimaryAccentColor ) ;
}
private void AddMaterialControls ( FlowLayoutWidget buttonPanel )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
extruderButtons . Clear ( ) ;
2016-06-16 10:31:18 -07:00
for ( int extruderIndex = 0 ; extruderIndex < ActiveSliceSettings . Instance . GetValue < int > ( SettingsKey . extruder_count ) ; extruderIndex + + )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
FlowLayoutWidget colorSelectionContainer = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
colorSelectionContainer . HAnchor = HAnchor . ParentLeftRight ;
colorSelectionContainer . Padding = new BorderDouble ( 5 ) ;
2016-04-18 11:31:31 -07:00
string colorLabelText = string . Format ( "{0} {1}" , "Material" . Localize ( ) , extruderIndex + 1 ) ;
2015-05-30 12:48:16 -07:00
RadioButton extruderSelection = new RadioButton ( colorLabelText , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
extruderButtons . Add ( extruderSelection ) ;
extruderSelection . SiblingRadioButtonList = extruderButtons ;
colorSelectionContainer . AddChild ( extruderSelection ) ;
colorSelectionContainer . AddChild ( new HorizontalSpacer ( ) ) ;
int extruderIndexLocal = extruderIndex ;
extruderSelection . Click + = ( sender , e ) = >
2015-02-05 16:14:30 -08:00
{
2015-05-30 12:48:16 -07:00
if ( SelectedMeshGroupIndex ! = - 1 )
2015-02-05 16:14:30 -08:00
{
2015-05-30 12:48:16 -07:00
foreach ( Mesh mesh in SelectedMeshGroup . Meshes )
2015-02-05 16:14:30 -08:00
{
2015-05-30 12:48:16 -07:00
MeshMaterialData material = MeshMaterialData . Get ( mesh ) ;
if ( material . MaterialIndex ! = extruderIndexLocal + 1 )
2015-02-05 16:14:30 -08:00
{
2015-05-30 12:48:16 -07:00
material . MaterialIndex = extruderIndexLocal + 1 ;
PartHasBeenChanged ( ) ;
2015-02-05 16:14:30 -08:00
}
}
}
2015-05-30 12:48:16 -07:00
} ;
2014-10-24 17:27:38 -07:00
2015-05-30 12:48:16 -07:00
this . SelectionChanged + = ( sender , e ) = >
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( SelectedMeshGroup ! = null )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
Mesh mesh = SelectedMeshGroup . Meshes [ 0 ] ;
MeshMaterialData material = MeshMaterialData . Get ( mesh ) ;
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
for ( int i = 0 ; i < extruderButtons . Count ; i + + )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( material . MaterialIndex - 1 = = i )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
( ( RadioButton ) extruderButtons [ i ] ) . Checked = true ;
2015-04-08 15:20:10 -07:00
}
}
}
2015-05-30 12:48:16 -07:00
} ;
2014-10-13 19:29:25 -07:00
2015-05-30 12:48:16 -07:00
buttonPanel . AddChild ( colorSelectionContainer ) ;
2015-04-08 15:20:10 -07:00
}
}
2014-09-26 15:04:04 -07:00
2015-05-30 12:48:16 -07:00
private void AddRotateControls ( FlowLayoutWidget buttonPanel )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
List < GuiWidget > rotateControls = new List < GuiWidget > ( ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
textImageButtonFactory . FixedWidth = EditButtonHeight ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
FlowLayoutWidget degreesContainer = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
degreesContainer . HAnchor = HAnchor . ParentLeftRight ;
degreesContainer . Padding = new BorderDouble ( 5 ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
string degreesLabelText = "Degrees" . Localize ( ) ;
string degreesLabelTextFull = "{0}:" . FormatWith ( degreesLabelText ) ;
TextWidget degreesLabel = new TextWidget ( degreesLabelText , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
degreesContainer . AddChild ( degreesLabel ) ;
degreesContainer . AddChild ( new HorizontalSpacer ( ) ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
MHNumberEdit degreesControl = new MHNumberEdit ( 45 , pixelWidth : 40 , allowNegatives : true , allowDecimals : true , increment : 5 , minValue : - 360 , maxValue : 360 ) ;
degreesControl . VAnchor = Agg . UI . VAnchor . ParentTop ;
degreesContainer . AddChild ( degreesControl ) ;
rotateControls . Add ( degreesControl ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
buttonPanel . AddChild ( degreesContainer ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
FlowLayoutWidget rotateButtonContainer = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
rotateButtonContainer . HAnchor = HAnchor . ParentLeftRight ;
2015-04-08 15:20:10 -07:00
2016-05-07 17:18:05 -07:00
ImageBuffer rotateImage = StaticData . Instance . LoadIcon ( "icon_rotate_32x32.png" , 32 , 32 ) ;
Button rotateXButton = textImageButtonFactory . Generate ( "" , rotateImage ) ;
2015-05-30 12:48:16 -07:00
TextWidget centeredX = new TextWidget ( "X" , pointSize : 10 , textColor : ActiveTheme . Instance . PrimaryTextColor ) ; centeredX . Margin = new BorderDouble ( 3 , 0 , 0 , 0 ) ; centeredX . AnchorCenter ( ) ; rotateXButton . AddChild ( centeredX ) ;
rotateButtonContainer . AddChild ( rotateXButton ) ;
rotateControls . Add ( rotateXButton ) ;
rotateXButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( SelectedMeshGroupIndex ! = - 1 )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
double radians = MathHelper . DegreesToRadians ( degreesControl . ActuallNumberEdit . Value ) ;
2016-02-26 14:19:52 -08:00
Matrix4X4 rotation = Matrix4X4 . CreateRotationX ( radians ) ;
2016-03-16 15:00:21 -07:00
Matrix4X4 undoTransform = SelectedMeshGroupTransform ;
2016-02-26 14:19:52 -08:00
SelectedMeshGroupTransform = PlatingHelper . ApplyAtCenter ( SelectedMeshGroup , SelectedMeshGroupTransform , rotation ) ;
2016-07-07 10:28:51 -07:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2016-08-08 14:44:21 -07:00
UndoBuffer . Add ( new TransformUndoCommand ( this , SelectedMeshGroupIndex , undoTransform , SelectedMeshGroupTransform ) ) ;
2015-05-30 12:48:16 -07:00
PartHasBeenChanged ( ) ;
Invalidate ( ) ;
}
} ;
2015-04-08 15:20:10 -07:00
2016-05-07 17:18:05 -07:00
Button rotateYButton = textImageButtonFactory . Generate ( "" , rotateImage ) ;
2015-05-30 12:48:16 -07:00
TextWidget centeredY = new TextWidget ( "Y" , pointSize : 10 , textColor : ActiveTheme . Instance . PrimaryTextColor ) ; centeredY . Margin = new BorderDouble ( 3 , 0 , 0 , 0 ) ; centeredY . AnchorCenter ( ) ; rotateYButton . AddChild ( centeredY ) ;
rotateButtonContainer . AddChild ( rotateYButton ) ;
rotateControls . Add ( rotateYButton ) ;
rotateYButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( SelectedMeshGroupIndex ! = - 1 )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
double radians = MathHelper . DegreesToRadians ( degreesControl . ActuallNumberEdit . Value ) ;
2016-02-26 14:19:52 -08:00
Matrix4X4 rotation = Matrix4X4 . CreateRotationY ( radians ) ;
2016-03-16 15:00:21 -07:00
Matrix4X4 undoTransform = SelectedMeshGroupTransform ;
2016-02-26 14:19:52 -08:00
SelectedMeshGroupTransform = PlatingHelper . ApplyAtCenter ( SelectedMeshGroup , SelectedMeshGroupTransform , rotation ) ;
2016-07-07 10:28:51 -07:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2016-08-08 14:44:21 -07:00
UndoBuffer . Add ( new TransformUndoCommand ( this , SelectedMeshGroupIndex , undoTransform , SelectedMeshGroupTransform ) ) ;
2016-02-26 14:19:52 -08:00
PartHasBeenChanged ( ) ;
2015-05-30 12:48:16 -07:00
Invalidate ( ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
} ;
2015-04-08 15:20:10 -07:00
2016-05-07 17:18:05 -07:00
Button rotateZButton = textImageButtonFactory . Generate ( "" , rotateImage ) ;
2015-05-30 12:48:16 -07:00
TextWidget centeredZ = new TextWidget ( "Z" , pointSize : 10 , textColor : ActiveTheme . Instance . PrimaryTextColor ) ; centeredZ . Margin = new BorderDouble ( 3 , 0 , 0 , 0 ) ; centeredZ . AnchorCenter ( ) ; rotateZButton . AddChild ( centeredZ ) ;
rotateButtonContainer . AddChild ( rotateZButton ) ;
rotateControls . Add ( rotateZButton ) ;
rotateZButton . Click + = ( object sender , EventArgs mouseEvent ) = >
{
if ( SelectedMeshGroupIndex ! = - 1 )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
double radians = MathHelper . DegreesToRadians ( degreesControl . ActuallNumberEdit . Value ) ;
2016-02-26 14:19:52 -08:00
Matrix4X4 rotation = Matrix4X4 . CreateRotationZ ( radians ) ;
2016-03-16 15:00:21 -07:00
Matrix4X4 undoTransform = SelectedMeshGroupTransform ;
2016-02-26 14:19:52 -08:00
SelectedMeshGroupTransform = PlatingHelper . ApplyAtCenter ( SelectedMeshGroup , SelectedMeshGroupTransform , rotation ) ;
2016-07-07 10:28:51 -07:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2016-08-08 14:44:21 -07:00
UndoBuffer . Add ( new TransformUndoCommand ( this , SelectedMeshGroupIndex , undoTransform , SelectedMeshGroupTransform ) ) ;
2015-05-30 12:48:16 -07:00
PartHasBeenChanged ( ) ;
Invalidate ( ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
} ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
buttonPanel . AddChild ( rotateButtonContainer ) ;
2015-04-08 15:20:10 -07:00
2016-02-29 10:59:30 -08:00
Button layFlatButton = WhiteButtonFactory . Generate ( "Align to Bed" . Localize ( ) , centerText : true ) ;
2015-05-30 12:48:16 -07:00
layFlatButton . Cursor = Cursors . Hand ;
buttonPanel . AddChild ( layFlatButton ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
layFlatButton . Click + = ( object sender , EventArgs mouseEvent ) = >
{
if ( SelectedMeshGroupIndex ! = - 1 )
{
2016-03-16 15:00:21 -07:00
Matrix4X4 undoTransform = SelectedMeshGroupTransform ;
2015-05-30 12:48:16 -07:00
MakeLowestFaceFlat ( SelectedMeshGroupIndex ) ;
2016-07-07 10:28:51 -07:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2016-08-08 14:44:21 -07:00
UndoBuffer . Add ( new TransformUndoCommand ( this , SelectedMeshGroupIndex , undoTransform , SelectedMeshGroupTransform ) ) ;
2015-05-30 12:48:16 -07:00
PartHasBeenChanged ( ) ;
Invalidate ( ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
} ;
2015-04-08 15:20:10 -07:00
2016-02-26 21:54:15 -08:00
buttonPanel . AddChild ( GenerateHorizontalRule ( ) ) ;
2015-05-30 12:48:16 -07:00
textImageButtonFactory . FixedWidth = 0 ;
2015-04-08 15:20:10 -07:00
}
private void AddSaveAndSaveAs ( FlowLayoutWidget flowToAddTo )
{
TupleList < string , Func < bool > > buttonList = new TupleList < string , Func < bool > > ( ) ;
2016-01-20 10:12:01 -08:00
buttonList . Add ( "Save" . Localize ( ) , ( ) = >
2015-04-08 15:20:10 -07:00
{
MergeAndSavePartsToCurrentMeshFile ( ) ;
return true ;
} ) ;
2015-12-22 15:26:51 -08:00
2016-01-20 10:12:01 -08:00
buttonList . Add ( "Save As" . Localize ( ) , ( ) = >
2015-04-08 15:20:10 -07:00
{
2015-01-26 16:49:21 -08:00
UiThread . RunOnIdle ( OpenSaveAsWindow ) ;
2015-04-08 15:20:10 -07:00
return true ;
} ) ;
2015-08-10 13:36:31 -07:00
2015-04-08 15:20:10 -07:00
SplitButtonFactory splitButtonFactory = new SplitButtonFactory ( ) ;
2016-05-06 17:56:27 -07:00
splitButtonFactory . FixedHeight = 40 * GuiWidget . DeviceScale ;
2015-04-08 15:20:10 -07:00
saveButtons = splitButtonFactory . Generate ( buttonList , Direction . Up , imageName : "icon_save_32x32.png" ) ;
saveButtons . Visible = false ;
2014-12-12 12:57:44 -08:00
2015-04-08 15:20:10 -07:00
saveButtons . Margin = new BorderDouble ( ) ;
saveButtons . VAnchor | = VAnchor . ParentCenter ;
2014-12-12 12:57:44 -08:00
2015-04-08 15:20:10 -07:00
flowToAddTo . AddChild ( saveButtons ) ;
}
2014-11-17 15:50:39 -08:00
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
private bool AllowDragDrop ( )
{
2015-07-13 10:08:08 -07:00
if ( ( ! enterEditButtonsContainer . Visible
2015-05-30 12:48:16 -07:00
& & ! doEdittingButtonsContainer . Visible )
2015-12-22 15:26:51 -08:00
| | printItemWrapper = = null | | printItemWrapper . PrintItem . ReadOnly )
2015-05-30 12:48:16 -07:00
{
return false ;
}
return true ;
}
2015-06-11 12:06:40 -07:00
private void AutoSpin ( )
2015-05-30 12:48:16 -07:00
{
2016-04-25 12:51:29 -07:00
if ( ! HasBeenClosed & & autoRotating )
2015-05-30 12:48:16 -07:00
{
// add it back in to keep it running.
UiThread . RunOnIdle ( AutoSpin , . 04 ) ;
if ( ( ! timeSinceLastSpin . IsRunning | | timeSinceLastSpin . ElapsedMilliseconds > 50 )
& & hasDrawn )
{
hasDrawn = false ;
timeSinceLastSpin . Restart ( ) ;
Quaternion currentRotation = meshViewerWidget . TrackballTumbleWidget . TrackBallController . CurrentRotation . GetRotation ( ) ;
Quaternion invertedRotation = Quaternion . Invert ( currentRotation ) ;
Quaternion rotateAboutZ = Quaternion . FromEulerAngles ( new Vector3 ( 0 , 0 , . 01 ) ) ;
rotateAboutZ = invertedRotation * rotateAboutZ * currentRotation ;
meshViewerWidget . TrackballTumbleWidget . TrackBallController . Rotate ( rotateAboutZ ) ;
Invalidate ( ) ;
}
}
}
2016-02-14 08:41:50 -08:00
private void ReportProgressChanged ( double progress0To1 , string processingState )
{
bool continueProcessing ;
ReportProgressChanged ( progress0To1 , processingState , out continueProcessing ) ;
}
2015-07-02 11:23:44 -07:00
private void ReportProgressChanged ( double progress0To1 , string processingState , out bool continueProcessing )
2015-05-30 12:48:16 -07:00
{
if ( ! timeSinceReported . IsRunning | | timeSinceReported . ElapsedMilliseconds > 100
| | processingState ! = processingProgressControl . ProgressMessage )
{
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2015-05-30 12:48:16 -07:00
{
2015-07-14 13:38:22 -07:00
processingProgressControl . RatioComplete = progress0To1 ;
2015-05-30 12:48:16 -07:00
processingProgressControl . ProgressMessage = processingState ;
} ) ;
timeSinceReported . Restart ( ) ;
}
continueProcessing = true ;
}
private void ClearBedAndLoadPrintItemWrapper ( PrintItemWrapper printItemWrapper )
{
SwitchStateToNotEditing ( ) ;
MeshGroups . Clear ( ) ;
MeshGroupExtraData . Clear ( ) ;
MeshGroupTransforms . Clear ( ) ;
if ( printItemWrapper ! = null )
{
// remove it first to make sure we don't double add it
2015-09-23 13:33:14 -07:00
PrintItemWrapper . FileHasChanged . UnregisterEvent ( ReloadMeshIfChangeExternaly , ref unregisterEvents ) ;
2016-12-01 15:14:53 -08:00
PrintItemWrapper . FileHasChanged . RegisterEvent ( ReloadMeshIfChangeExternaly , ref unregisterEvents ) ;
2015-05-30 12:48:16 -07:00
// don't load the mesh until we get all the rest of the interface built
meshViewerWidget . LoadDone + = new EventHandler ( meshViewerWidget_LoadDone ) ;
2015-08-10 15:35:56 -07:00
Vector2 bedCenter = new Vector2 ( ) ;
MeshViewerWidget . CenterPartAfterLoad doCentering = MeshViewerWidget . CenterPartAfterLoad . DONT ;
2016-06-21 09:38:37 -07:00
if ( ActiveSliceSettings . Instance ? . GetValue < bool > ( SettingsKey . center_part_on_bed ) = = true )
2015-08-10 15:35:56 -07:00
{
doCentering = MeshViewerWidget . CenterPartAfterLoad . DO ;
2016-06-21 09:38:37 -07:00
bedCenter = ActiveSliceSettings . Instance . GetValue < Vector2 > ( SettingsKey . print_center ) ;
2015-08-10 15:35:56 -07:00
}
meshViewerWidget . LoadMesh ( printItemWrapper . FileLocation , doCentering , bedCenter ) ;
2015-05-30 12:48:16 -07:00
}
partHasBeenEdited = false ;
}
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
private void CreateOptionsContent ( )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
AddRotateControls ( rotateOptionContainer ) ;
}
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
private void CreateRenderTypeRadioButtons ( FlowLayoutWidget viewOptionContainer )
{
2016-08-30 10:30:55 -07:00
string renderTypeString = UserSettings . Instance . get ( UserSettingsKey . defaultRenderSetting ) ;
2015-05-30 12:48:16 -07:00
if ( renderTypeString = = null )
{
2016-04-29 07:45:15 -07:00
if ( UserSettings . Instance . DisplayMode = = ApplicationDisplayType . Touchscreen )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
renderTypeString = "Shaded" ;
2015-04-08 15:20:10 -07:00
}
else
{
2015-05-30 12:48:16 -07:00
renderTypeString = "Outlines" ;
2015-04-08 15:20:10 -07:00
}
2016-08-30 10:30:55 -07:00
UserSettings . Instance . set ( UserSettingsKey . defaultRenderSetting , renderTypeString ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
RenderOpenGl . RenderTypes renderType ;
bool canParse = Enum . TryParse < RenderOpenGl . RenderTypes > ( renderTypeString , out renderType ) ;
if ( canParse )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
meshViewerWidget . RenderType = renderType ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
RadioButton renderTypeShaded = new RadioButton ( "Shaded" . Localize ( ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
renderTypeShaded . Checked = ( meshViewerWidget . RenderType = = RenderTypes . Shaded ) ;
renderTypeShaded . CheckedStateChanged + = ( sender , e ) = >
{
meshViewerWidget . RenderType = RenderTypes . Shaded ;
2016-08-30 10:30:55 -07:00
UserSettings . Instance . set ( UserSettingsKey . defaultRenderSetting , meshViewerWidget . RenderType . ToString ( ) ) ;
2015-05-30 12:48:16 -07:00
} ;
viewOptionContainer . AddChild ( renderTypeShaded ) ;
2015-04-08 15:20:10 -07:00
}
{
2015-05-30 12:48:16 -07:00
RadioButton renderTypeOutlines = new RadioButton ( "Outlines" . Localize ( ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
renderTypeOutlines . Checked = ( meshViewerWidget . RenderType = = RenderTypes . Outlines ) ;
renderTypeOutlines . CheckedStateChanged + = ( sender , e ) = >
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
meshViewerWidget . RenderType = RenderTypes . Outlines ;
2016-08-30 10:30:55 -07:00
UserSettings . Instance . set ( UserSettingsKey . defaultRenderSetting , meshViewerWidget . RenderType . ToString ( ) ) ;
2015-05-30 12:48:16 -07:00
} ;
viewOptionContainer . AddChild ( renderTypeOutlines ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
{
RadioButton renderTypePolygons = new RadioButton ( "Polygons" . Localize ( ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
renderTypePolygons . Checked = ( meshViewerWidget . RenderType = = RenderTypes . Polygons ) ;
renderTypePolygons . CheckedStateChanged + = ( sender , e ) = >
{
meshViewerWidget . RenderType = RenderTypes . Polygons ;
2016-08-30 10:30:55 -07:00
UserSettings . Instance . set ( UserSettingsKey . defaultRenderSetting , meshViewerWidget . RenderType . ToString ( ) ) ;
2015-05-30 12:48:16 -07:00
} ;
viewOptionContainer . AddChild ( renderTypePolygons ) ;
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
private FlowLayoutWidget CreateRightButtonPanel ( double buildHeight )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
FlowLayoutWidget buttonRightPanel = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
buttonRightPanel . Width = 200 ;
2016-02-29 10:59:30 -08:00
// put in undo redo
2016-08-08 14:44:21 -07:00
if ( true ) // this will not be enabled until the new scene_bundle gets merged
2016-02-29 10:59:30 -08:00
{
FlowLayoutWidget undoRedoButtons = new FlowLayoutWidget ( )
{
VAnchor = VAnchor . FitToChildren | VAnchor . ParentTop ,
HAnchor = HAnchor . FitToChildren | HAnchor . ParentCenter ,
} ;
double oldWidth = WhiteButtonFactory . FixedWidth ;
WhiteButtonFactory . FixedWidth = WhiteButtonFactory . FixedWidth / 2 ;
Button undoButton = WhiteButtonFactory . Generate ( "Undo" . Localize ( ) , centerText : true ) ;
2016-03-01 16:20:39 -08:00
undoButton . Name = "3D View Undo" ;
2016-02-29 10:59:30 -08:00
undoButton . Enabled = false ;
undoButton . Click + = ( sender , e ) = >
{
2016-08-08 14:44:21 -07:00
UndoBuffer . Undo ( ) ;
2016-02-29 10:59:30 -08:00
} ;
undoRedoButtons . AddChild ( undoButton ) ;
Button redoButton = WhiteButtonFactory . Generate ( "Redo" . Localize ( ) , centerText : true ) ;
2016-03-01 16:20:39 -08:00
redoButton . Name = "3D View Redo" ;
2016-02-29 10:59:30 -08:00
redoButton . Enabled = false ;
redoButton . Click + = ( sender , e ) = >
{
2016-08-08 14:44:21 -07:00
UndoBuffer . Redo ( ) ;
2016-02-29 10:59:30 -08:00
} ;
undoRedoButtons . AddChild ( redoButton ) ;
buttonRightPanel . AddChild ( undoRedoButtons ) ;
2016-08-08 14:44:21 -07:00
UndoBuffer . Changed + = ( sender , e ) = >
2016-02-29 10:59:30 -08:00
{
2016-08-08 14:44:21 -07:00
undoButton . Enabled = UndoBuffer . UndoCount > 0 ;
redoButton . Enabled = UndoBuffer . RedoCount > 0 ;
2016-02-29 10:59:30 -08:00
} ;
WhiteButtonFactory . FixedWidth = oldWidth ;
}
2015-05-30 12:48:16 -07:00
{
BorderDouble buttonMargin = new BorderDouble ( top : 3 ) ;
2016-10-06 10:59:51 -07:00
expandRotateOptions = ExpandMenuOptionFactory . GenerateCheckBoxButton (
"Rotate" . Localize ( ) . ToUpper ( ) ,
View3DWidget . ArrowRight ,
View3DWidget . ArrowDown ) ;
2015-05-30 12:48:16 -07:00
expandRotateOptions . Margin = new BorderDouble ( bottom : 2 ) ;
buttonRightPanel . AddChild ( expandRotateOptions ) ;
2016-02-29 10:59:30 -08:00
expandRotateOptions . CheckedStateChanged + = expandRotateOptions_CheckedStateChanged ;
2015-05-30 12:48:16 -07:00
rotateOptionContainer = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
rotateOptionContainer . HAnchor = HAnchor . ParentLeftRight ;
rotateOptionContainer . Visible = false ;
buttonRightPanel . AddChild ( rotateOptionContainer ) ;
2016-02-28 11:54:42 -08:00
buttonRightPanel . AddChild ( new ScaleControls ( this ) ) ;
2015-05-30 12:48:16 -07:00
2016-02-26 21:54:15 -08:00
buttonRightPanel . AddChild ( new MirrorControls ( this ) ) ;
2015-05-30 12:48:16 -07:00
2016-03-04 10:11:05 -08:00
PluginFinder < SideBarPlugin > SideBarPlugins = new PluginFinder < SideBarPlugin > ( ) ;
foreach ( SideBarPlugin plugin in SideBarPlugins . Plugins )
{
2016-03-18 12:02:46 -07:00
buttonRightPanel . AddChild ( plugin . CreateSideBarTool ( this ) ) ;
2016-03-04 10:11:05 -08:00
}
2015-05-30 12:48:16 -07:00
// put in the material options
2016-06-16 10:31:18 -07:00
int numberOfExtruders = ActiveSliceSettings . Instance . GetValue < int > ( SettingsKey . extruder_count ) ;
2015-05-30 12:48:16 -07:00
2016-10-06 10:59:51 -07:00
expandMaterialOptions = ExpandMenuOptionFactory . GenerateCheckBoxButton ( "Materials" . Localize ( ) . ToUpper ( ) ,
View3DWidget . ArrowRight ,
View3DWidget . ArrowDown ) ;
2015-05-30 12:48:16 -07:00
expandMaterialOptions . Margin = new BorderDouble ( bottom : 2 ) ;
2016-02-29 10:59:30 -08:00
expandMaterialOptions . CheckedStateChanged + = expandMaterialOptions_CheckedStateChanged ;
2015-05-30 12:48:16 -07:00
if ( numberOfExtruders > 1 )
{
buttonRightPanel . AddChild ( expandMaterialOptions ) ;
materialOptionContainer = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
materialOptionContainer . HAnchor = HAnchor . ParentLeftRight ;
materialOptionContainer . Visible = false ;
buttonRightPanel . AddChild ( materialOptionContainer ) ;
AddMaterialControls ( materialOptionContainer ) ;
}
// put in the view options
{
2016-10-06 10:59:51 -07:00
expandViewOptions = ExpandMenuOptionFactory . GenerateCheckBoxButton ( "Display" . Localize ( ) . ToUpper ( ) ,
View3DWidget . ArrowRight ,
View3DWidget . ArrowDown ) ;
2015-05-30 12:48:16 -07:00
expandViewOptions . Margin = new BorderDouble ( bottom : 2 ) ;
buttonRightPanel . AddChild ( expandViewOptions ) ;
2016-02-29 10:59:30 -08:00
expandViewOptions . CheckedStateChanged + = expandViewOptions_CheckedStateChanged ;
2015-05-30 12:48:16 -07:00
viewOptionContainer = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
viewOptionContainer . HAnchor = HAnchor . ParentLeftRight ;
viewOptionContainer . Padding = new BorderDouble ( left : 4 ) ;
viewOptionContainer . Visible = false ;
{
2015-12-16 18:14:32 -08:00
CheckBox showBedCheckBox = new CheckBox ( "Show Print Bed" . Localize ( ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2015-05-30 12:48:16 -07:00
showBedCheckBox . Checked = true ;
showBedCheckBox . CheckedStateChanged + = ( sender , e ) = >
{
meshViewerWidget . RenderBed = showBedCheckBox . Checked ;
} ;
viewOptionContainer . AddChild ( showBedCheckBox ) ;
if ( buildHeight > 0 )
{
2015-12-16 18:14:32 -08:00
CheckBox showBuildVolumeCheckBox = new CheckBox ( "Show Print Area" . Localize ( ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2015-05-30 12:48:16 -07:00
showBuildVolumeCheckBox . Checked = false ;
showBuildVolumeCheckBox . Margin = new BorderDouble ( bottom : 5 ) ;
showBuildVolumeCheckBox . CheckedStateChanged + = ( sender , e ) = >
{
meshViewerWidget . RenderBuildVolume = showBuildVolumeCheckBox . Checked ;
} ;
viewOptionContainer . AddChild ( showBuildVolumeCheckBox ) ;
}
2016-04-29 07:45:15 -07:00
if ( UserSettings . Instance . IsTouchScreen )
2015-05-30 12:48:16 -07:00
{
2016-08-30 10:30:55 -07:00
UserSettings . Instance . set ( UserSettingsKey . defaultRenderSetting , RenderTypes . Shaded . ToString ( ) ) ;
2015-05-30 12:48:16 -07:00
}
else
{
CreateRenderTypeRadioButtons ( viewOptionContainer ) ;
}
}
buttonRightPanel . AddChild ( viewOptionContainer ) ;
}
GuiWidget verticalSpacer = new GuiWidget ( ) ;
verticalSpacer . VAnchor = VAnchor . ParentBottomTop ;
buttonRightPanel . AddChild ( verticalSpacer ) ;
2016-02-14 17:53:44 -08:00
AddGridSnapSettings ( buttonRightPanel ) ;
2015-05-30 12:48:16 -07:00
}
buttonRightPanel . Padding = new BorderDouble ( 6 , 6 ) ;
buttonRightPanel . Margin = new BorderDouble ( 0 , 1 ) ;
buttonRightPanel . BackgroundColor = ActiveTheme . Instance . PrimaryBackgroundColor ;
buttonRightPanel . VAnchor = VAnchor . ParentBottomTop ;
return buttonRightPanel ;
}
private void DeleteSelectedMesh ( )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
// don't ever delete the last mesh
2016-02-27 15:20:12 -08:00
if ( SelectedMeshGroupIndex ! = - 1
2015-05-30 12:48:16 -07:00
& & MeshGroups . Count > 1 )
2015-04-08 15:20:10 -07:00
{
2016-03-02 07:46:14 -08:00
int removingIndex = SelectedMeshGroupIndex ;
2016-08-08 14:44:21 -07:00
UndoBuffer . Add ( new DeleteUndoCommand ( this , removingIndex ) ) ;
2016-02-27 15:01:28 -08:00
2016-03-02 07:46:14 -08:00
MeshGroups . RemoveAt ( removingIndex ) ;
MeshGroupExtraData . RemoveAt ( removingIndex ) ;
MeshGroupTransforms . RemoveAt ( removingIndex ) ;
2016-02-27 15:20:12 -08:00
this . SelectedMeshGroupIndex = - 1 ;
2016-02-29 16:18:33 -08:00
PartHasBeenChanged ( ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
}
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
private void ExitEditingAndSaveIfRequired ( bool response )
{
if ( response = = true )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
MergeAndSavePartsToCurrentMeshFile ( SwitchStateToNotEditing ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
else
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
SwitchStateToNotEditing ( ) ;
// and reload the part
ClearBedAndLoadPrintItemWrapper ( printItemWrapper ) ;
2015-04-08 15:20:10 -07:00
}
}
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
private void expandMaterialOptions_CheckedStateChanged ( object sender , EventArgs e )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( expandMaterialOptions . Checked = = true )
{
expandRotateOptions . Checked = false ;
expandViewOptions . Checked = false ;
}
materialOptionContainer . Visible = expandMaterialOptions . Checked ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
private void expandRotateOptions_CheckedStateChanged ( object sender , EventArgs e )
2015-01-23 21:56:44 -08:00
{
2015-05-30 12:48:16 -07:00
if ( rotateOptionContainer . Visible ! = expandRotateOptions . Checked )
2015-01-23 21:56:44 -08:00
{
2015-05-30 12:48:16 -07:00
if ( expandRotateOptions . Checked = = true )
{
expandViewOptions . Checked = false ;
expandMaterialOptions . Checked = false ;
}
rotateOptionContainer . Visible = expandRotateOptions . Checked ;
2015-01-23 21:56:44 -08:00
}
}
2015-05-30 12:48:16 -07:00
private void expandViewOptions_CheckedStateChanged ( object sender , EventArgs e )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( viewOptionContainer . Visible ! = expandViewOptions . Checked )
2015-01-23 21:56:44 -08:00
{
2015-05-30 12:48:16 -07:00
if ( expandViewOptions . Checked = = true )
2015-01-23 21:56:44 -08:00
{
2015-05-30 12:48:16 -07:00
expandRotateOptions . Checked = false ;
expandMaterialOptions . Checked = false ;
2015-01-23 21:56:44 -08:00
}
2015-05-30 12:48:16 -07:00
viewOptionContainer . Visible = expandViewOptions . Checked ;
2015-01-23 21:56:44 -08:00
}
2015-04-08 15:20:10 -07:00
}
2014-05-16 17:13:18 -07:00
2016-03-25 17:32:05 -07:00
IPrimitive allObjects ;
private bool FindMeshGroupHitPosition ( Vector2 screenPosition , out int meshHitIndex , ref IntersectInfo info )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
meshHitIndex = 0 ;
if ( MeshGroupExtraData . Count = = 0 | | MeshGroupExtraData [ 0 ] . meshTraceableData = = null )
2015-01-23 21:56:44 -08:00
{
2015-05-30 12:48:16 -07:00
return false ;
}
List < IPrimitive > mesheTraceables = new List < IPrimitive > ( ) ;
for ( int i = 0 ; i < MeshGroupExtraData . Count ; i + + )
{
foreach ( IPrimitive traceData in MeshGroupExtraData [ i ] . meshTraceableData )
2015-01-23 21:56:44 -08:00
{
2016-02-26 14:19:52 -08:00
mesheTraceables . Add ( new Transform ( traceData , MeshGroupTransforms [ i ] ) ) ;
2015-01-23 21:56:44 -08:00
}
2015-05-30 12:48:16 -07:00
}
2016-03-25 17:32:05 -07:00
allObjects = BoundingVolumeHierarchy . CreateNewHierachy ( mesheTraceables , 0 ) ;
2014-05-16 17:13:18 -07:00
2015-05-30 12:48:16 -07:00
Vector2 meshViewerWidgetScreenPosition = meshViewerWidget . TransformFromParentSpace ( this , screenPosition ) ;
Ray ray = meshViewerWidget . TrackballTumbleWidget . GetRayFromScreen ( meshViewerWidgetScreenPosition ) ;
2016-02-19 08:29:49 -08:00
info = allObjects . GetClosestIntersection ( ray ) ;
2015-05-30 12:48:16 -07:00
if ( info ! = null )
{
2016-02-19 08:29:49 -08:00
CurrentSelectInfo . PlaneDownHitPos = info . hitPosition ;
CurrentSelectInfo . LastMoveDelta = new Vector3 ( ) ;
2015-05-30 12:48:16 -07:00
for ( int i = 0 ; i < MeshGroupExtraData . Count ; i + + )
2015-01-23 21:56:44 -08:00
{
2015-05-30 12:48:16 -07:00
List < IPrimitive > insideBounds = new List < IPrimitive > ( ) ;
foreach ( IPrimitive traceData in MeshGroupExtraData [ i ] . meshTraceableData )
2015-02-05 16:14:30 -08:00
{
2015-05-30 12:48:16 -07:00
traceData . GetContained ( insideBounds , info . closestHitObject . GetAxisAlignedBoundingBox ( ) ) ;
2015-02-05 16:14:30 -08:00
}
2015-05-30 12:48:16 -07:00
if ( insideBounds . Contains ( info . closestHitObject ) )
2015-02-05 16:14:30 -08:00
{
2015-05-30 12:48:16 -07:00
meshHitIndex = i ;
return true ;
2015-02-05 16:14:30 -08:00
}
2015-01-23 21:56:44 -08:00
}
}
2014-05-16 17:13:18 -07:00
2015-05-30 12:48:16 -07:00
return false ;
2015-04-08 15:20:10 -07:00
}
2014-05-16 17:13:18 -07:00
2016-02-26 21:54:15 -08:00
public GuiWidget GenerateHorizontalRule ( )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
GuiWidget horizontalRule = new GuiWidget ( ) ;
horizontalRule . Height = 1 ;
horizontalRule . Margin = new BorderDouble ( 0 , 1 , 0 , 3 ) ;
horizontalRule . HAnchor = HAnchor . ParentLeftRight ;
horizontalRule . BackgroundColor = new RGBA_Bytes ( 255 , 255 , 255 , 200 ) ;
return horizontalRule ;
}
2015-04-08 15:20:10 -07:00
2015-07-02 11:23:44 -07:00
private async void LoadAndAddPartsToPlate ( string [ ] filesToLoad )
2015-05-30 12:48:16 -07:00
{
if ( MeshGroups . Count > 0 & & filesToLoad ! = null & & filesToLoad . Length > 0 )
{
string loadingPartLabel = "Loading Parts" . Localize ( ) ;
string loadingPartLabelFull = "{0}:" . FormatWith ( loadingPartLabel ) ;
processingProgressControl . ProcessType = loadingPartLabelFull ;
processingProgressControl . Visible = true ;
processingProgressControl . PercentComplete = 0 ;
LockEditControls ( ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
PushMeshGroupDataToAsynchLists ( TraceInfoOpperation . DO_COPY ) ;
2015-04-08 15:20:10 -07:00
2015-07-02 11:23:44 -07:00
await Task . Run ( ( ) = > loadAndAddPartsToPlate ( filesToLoad ) ) ;
2015-04-08 15:20:10 -07:00
2016-04-25 12:51:29 -07:00
if ( HasBeenClosed )
2015-07-02 11:23:44 -07:00
{
return ;
}
UnlockEditControls ( ) ;
PartHasBeenChanged ( ) ;
2016-02-19 11:27:55 -08:00
bool addingOnlyOneItem = asyncMeshGroups . Count = = MeshGroups . Count + 1 ;
2015-04-08 15:20:10 -07:00
2015-07-02 11:23:44 -07:00
if ( MeshGroups . Count > 0 )
{
PullMeshGroupDataFromAsynchLists ( ) ;
if ( addingOnlyOneItem )
{
// if we are only adding one part to the plate set the selection to it
2016-02-19 11:27:55 -08:00
SelectedMeshGroupIndex = asyncMeshGroups . Count - 1 ;
2015-07-02 11:23:44 -07:00
}
}
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
}
2014-01-29 19:09:30 -08:00
2015-07-02 11:23:44 -07:00
private void loadAndAddPartsToPlate ( string [ ] filesToLoadIncludingZips )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
Thread . CurrentThread . CurrentCulture = CultureInfo . InvariantCulture ;
2014-05-16 12:57:49 -07:00
2015-05-30 12:48:16 -07:00
List < string > filesToLoad = new List < string > ( ) ;
if ( filesToLoadIncludingZips ! = null & & filesToLoadIncludingZips . Length > 0 )
{
for ( int i = 0 ; i < filesToLoadIncludingZips . Length ; i + + )
{
string loadedFileName = filesToLoadIncludingZips [ i ] ;
string extension = Path . GetExtension ( loadedFileName ) . ToUpper ( ) ;
2015-08-03 16:46:57 -07:00
if ( ( extension ! = "" & & MeshFileIo . ValidFileExtensions ( ) . Contains ( extension ) ) )
2015-05-30 12:48:16 -07:00
{
filesToLoad . Add ( loadedFileName ) ;
}
else if ( extension = = ".ZIP" )
{
ProjectFileHandler project = new ProjectFileHandler ( null ) ;
List < PrintItem > partFiles = project . ImportFromProjectArchive ( loadedFileName ) ;
if ( partFiles ! = null )
{
foreach ( PrintItem part in partFiles )
{
filesToLoad . Add ( part . FileLocation ) ;
}
}
}
}
2014-10-12 20:40:38 -07:00
2015-05-30 12:48:16 -07:00
string progressMessage = "Loading Parts..." . Localize ( ) ;
double ratioPerFile = 1.0 / filesToLoad . Count ;
double currentRatioDone = 0 ;
for ( int i = 0 ; i < filesToLoad . Count ; i + + )
{
string loadedFileName = filesToLoad [ i ] ;
List < MeshGroup > loadedMeshGroups = MeshFileIo . Load ( Path . GetFullPath ( loadedFileName ) , ( double progress0To1 , string processingState , out bool continueProcessing ) = >
{
2016-04-25 12:51:29 -07:00
continueProcessing = ! this . HasBeenClosed ;
2015-05-30 12:48:16 -07:00
double ratioAvailable = ( ratioPerFile * . 5 ) ;
double currentRatio = currentRatioDone + progress0To1 * ratioAvailable ;
2015-07-02 11:23:44 -07:00
ReportProgressChanged ( currentRatio , progressMessage , out continueProcessing ) ;
2015-05-30 12:48:16 -07:00
} ) ;
2014-01-29 19:09:30 -08:00
2016-04-25 12:51:29 -07:00
if ( HasBeenClosed )
2015-05-30 12:48:16 -07:00
{
return ;
}
if ( loadedMeshGroups ! = null )
{
double ratioPerSubMesh = ratioPerFile / loadedMeshGroups . Count ;
double subMeshRatioDone = 0 ;
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
for ( int subMeshIndex = 0 ; subMeshIndex < loadedMeshGroups . Count ; subMeshIndex + + )
{
MeshGroup meshGroup = loadedMeshGroups [ subMeshIndex ] ;
2014-01-29 19:09:30 -08:00
2016-02-26 14:19:52 -08:00
PlatingHelper . FindPositionForGroupAndAddToPlate ( meshGroup , Matrix4X4 . Identity , asyncPlatingDatas , asyncMeshGroups , asyncMeshGroupTransforms ) ;
2016-04-25 12:51:29 -07:00
if ( HasBeenClosed )
2015-05-30 12:48:16 -07:00
{
return ;
}
2016-02-19 11:27:55 -08:00
PlatingHelper . CreateITraceableForMeshGroup ( asyncPlatingDatas , asyncMeshGroups , asyncMeshGroups . Count - 1 , ( double progress0To1 , string processingState , out bool continueProcessing ) = >
2015-05-30 12:48:16 -07:00
{
2016-04-25 12:51:29 -07:00
continueProcessing = ! this . HasBeenClosed ;
2015-05-30 12:48:16 -07:00
double ratioAvailable = ( ratioPerFile * . 5 ) ;
// done outer loop + done this loop +first 1/2 (load)+ this part * ratioAvailable
double currentRatio = currentRatioDone + subMeshRatioDone + ratioAvailable + progress0To1 * ratioPerSubMesh ;
2015-07-02 11:23:44 -07:00
ReportProgressChanged ( currentRatio , progressMessage , out continueProcessing ) ;
2015-05-30 12:48:16 -07:00
} ) ;
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
subMeshRatioDone + = ratioPerSubMesh ;
}
}
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
currentRatioDone + = ratioPerFile ;
}
}
}
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
private void LockEditControls ( )
{
viewIsInEditModePreLock = doEdittingButtonsContainer . Visible ;
enterEditButtonsContainer . Visible = false ;
doEdittingButtonsContainer . Visible = false ;
buttonRightPanelDisabledCover . Visible = true ;
if ( viewControls3D . PartSelectVisible = = true )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
viewControls3D . PartSelectVisible = false ;
2015-05-29 15:13:56 -07:00
if ( viewControls3D . ActiveButton = = ViewControls3DButtons . PartSelect )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
wasInSelectMode = true ;
2015-05-29 15:13:56 -07:00
viewControls3D . ActiveButton = ViewControls3DButtons . Rotate ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
}
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
private void MakeLowestFaceFlat ( int indexToLayFlat )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
Vertex lowestVertex = MeshGroups [ indexToLayFlat ] . Meshes [ 0 ] . Vertices [ 0 ] ;
2016-02-26 14:19:52 -08:00
Vector3 lowestVertexPosition = Vector3 . Transform ( lowestVertex . Position , MeshGroupTransforms [ indexToLayFlat ] ) ;
2015-05-30 12:48:16 -07:00
Mesh meshToLayFlat = null ;
foreach ( Mesh meshToCheck in MeshGroups [ indexToLayFlat ] . Meshes )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
// find the lowest point on the model
for ( int testIndex = 1 ; testIndex < meshToCheck . Vertices . Count ; testIndex + + )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
Vertex vertex = meshToCheck . Vertices [ testIndex ] ;
2016-02-26 14:19:52 -08:00
Vector3 vertexPosition = Vector3 . Transform ( vertex . Position , MeshGroupTransforms [ indexToLayFlat ] ) ;
2015-05-30 12:48:16 -07:00
if ( vertexPosition . z < lowestVertexPosition . z )
{
lowestVertex = meshToCheck . Vertices [ testIndex ] ;
lowestVertexPosition = vertexPosition ;
meshToLayFlat = meshToCheck ;
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
}
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
Face faceToLayFlat = null ;
double lowestAngleOfAnyFace = double . MaxValue ;
// Check all the faces that are connected to the lowest point to find out which one to lay flat.
foreach ( Face face in lowestVertex . ConnectedFaces ( ) )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
double biggestAngleToFaceVertex = double . MinValue ;
foreach ( Vertex faceVertex in face . Vertices ( ) )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( faceVertex ! = lowestVertex )
{
2016-02-26 14:19:52 -08:00
Vector3 faceVertexPosition = Vector3 . Transform ( faceVertex . Position , MeshGroupTransforms [ indexToLayFlat ] ) ;
2015-05-30 12:48:16 -07:00
Vector3 pointRelLowest = faceVertexPosition - lowestVertexPosition ;
double xLeg = new Vector2 ( pointRelLowest . x , pointRelLowest . y ) . Length ;
double yLeg = pointRelLowest . z ;
double angle = Math . Atan2 ( yLeg , xLeg ) ;
if ( angle > biggestAngleToFaceVertex )
{
biggestAngleToFaceVertex = angle ;
}
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
if ( biggestAngleToFaceVertex < lowestAngleOfAnyFace )
{
lowestAngleOfAnyFace = biggestAngleToFaceVertex ;
faceToLayFlat = face ;
}
}
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
double maxDistFromLowestZ = 0 ;
List < Vector3 > faceVertexes = new List < Vector3 > ( ) ;
foreach ( Vertex vertex in faceToLayFlat . Vertices ( ) )
2015-04-08 15:20:10 -07:00
{
2016-02-26 14:19:52 -08:00
Vector3 vertexPosition = Vector3 . Transform ( vertex . Position , MeshGroupTransforms [ indexToLayFlat ] ) ;
2015-05-30 12:48:16 -07:00
faceVertexes . Add ( vertexPosition ) ;
maxDistFromLowestZ = Math . Max ( maxDistFromLowestZ , vertexPosition . z - lowestVertexPosition . z ) ;
}
2014-10-12 08:18:24 -07:00
2015-05-30 12:48:16 -07:00
if ( maxDistFromLowestZ > . 001 )
{
Vector3 xPositive = ( faceVertexes [ 1 ] - faceVertexes [ 0 ] ) . GetNormal ( ) ;
Vector3 yPositive = ( faceVertexes [ 2 ] - faceVertexes [ 0 ] ) . GetNormal ( ) ;
Vector3 planeNormal = Vector3 . Cross ( xPositive , yPositive ) . GetNormal ( ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
// this code takes the minimum rotation required and looks much better.
Quaternion rotation = new Quaternion ( planeNormal , new Vector3 ( 0 , 0 , - 1 ) ) ;
Matrix4X4 partLevelMatrix = Matrix4X4 . CreateRotation ( rotation ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
// rotate it
2016-02-26 14:19:52 -08:00
SelectedMeshGroupTransform = PlatingHelper . ApplyAtCenter ( SelectedMeshGroup , SelectedMeshGroupTransform , partLevelMatrix ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
PartHasBeenChanged ( ) ;
Invalidate ( ) ;
}
}
2016-01-10 10:18:53 -08:00
public static Regex fileNameNumberMatch = new Regex ( "\\(\\d+\\)" , RegexOptions . Compiled ) ;
2015-09-09 11:05:17 -07:00
private void MergeAndSavePartsDoWork ( SaveAsWindow . SaveAsReturnInfo returnInfo )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( returnInfo ! = null )
2015-04-08 15:20:10 -07:00
{
2015-08-31 16:32:09 -07:00
PrintItem printItem = new PrintItem ( ) ;
printItem . Name = returnInfo . newName ;
printItem . FileLocation = Path . GetFullPath ( returnInfo . fileNameAndPath ) ;
2015-09-11 14:36:57 -07:00
printItemWrapper = new PrintItemWrapper ( printItem , returnInfo . destinationLibraryProvider . GetProviderLocator ( ) ) ;
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
2016-02-19 11:27:55 -08:00
// we sent the data to the async lists but we will not pull it back out (only use it as a temp holder).
2015-05-30 12:48:16 -07:00
PushMeshGroupDataToAsynchLists ( TraceInfoOpperation . DO_COPY ) ;
Thread . CurrentThread . CurrentCulture = CultureInfo . InvariantCulture ;
try
{
// push all the transforms into the meshes
2016-02-19 11:27:55 -08:00
for ( int i = 0 ; i < asyncMeshGroups . Count ; i + + )
2015-04-08 15:20:10 -07:00
{
2016-02-26 14:19:52 -08:00
asyncMeshGroups [ i ] . Transform ( asyncMeshGroupTransforms [ i ] ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
bool continueProcessing ;
2016-02-19 11:27:55 -08:00
ReportProgressChanged ( ( i + 1 ) * . 4 / asyncMeshGroups . Count , "" , out continueProcessing ) ;
2015-05-30 12:48:16 -07:00
}
2015-07-17 16:12:14 -07:00
string [ ] metaData = { "Created By" , "MatterControl" , "BedPosition" , "Absolute" } ;
MeshOutputSettings outputInfo = new MeshOutputSettings ( MeshOutputSettings . OutputType . Binary , metaData ) ;
2016-01-05 14:15:59 -08:00
2016-01-05 15:15:13 -08:00
// If null we are replacing a file from the current print item wrapper
2016-01-05 14:15:59 -08:00
if ( returnInfo = = null )
2015-09-09 11:05:17 -07:00
{
2016-01-10 10:18:53 -08:00
var fileInfo = new FileInfo ( printItemWrapper . FileLocation ) ;
2016-01-11 14:06:47 -08:00
bool requiresTypeChange = ! fileInfo . Extension . Equals ( ".amf" , StringComparison . OrdinalIgnoreCase ) ;
if ( requiresTypeChange & & ! printItemWrapper . UseIncrementedNameDuringTypeChange )
2016-01-10 10:18:53 -08:00
{
2016-01-11 14:06:47 -08:00
// Not using incremented file name, simply change to AMF
printItemWrapper . FileLocation = Path . ChangeExtension ( printItemWrapper . FileLocation , ".amf" ) ;
2016-01-10 10:18:53 -08:00
}
2016-01-11 14:06:47 -08:00
else if ( requiresTypeChange )
2016-01-10 10:18:53 -08:00
{
2016-01-11 14:06:47 -08:00
string newFileName ;
string incrementedFileName ;
2016-01-10 10:18:53 -08:00
// Switching from .stl, .obj or similar to AMF. Save the file and update the
// the filename with an incremented (n) value to reflect the extension change in the UI
string fileName = Path . GetFileNameWithoutExtension ( fileInfo . Name ) ;
2016-01-05 14:15:59 -08:00
2016-01-10 10:18:53 -08:00
// Drop bracketed number sections from our source filename to ensure we don't generate something like "file (1) (1).amf"
if ( fileName . Contains ( "(" ) )
{
fileName = fileNameNumberMatch . Replace ( fileName , "" ) . Trim ( ) ;
}
2016-01-05 14:15:59 -08:00
2016-01-11 14:06:47 -08:00
// Generate and search for an incremented file name until no match is found at the target directory
2016-01-10 10:18:53 -08:00
int foundCount = 0 ;
do
{
newFileName = string . Format ( "{0} ({1})" , fileName , + + foundCount ) ;
2016-01-11 14:06:47 -08:00
incrementedFileName = Path . Combine ( fileInfo . DirectoryName , newFileName + ".amf" ) ;
2015-09-09 11:05:17 -07:00
2016-01-10 10:18:53 -08:00
// Continue incrementing while any matching file exists
} while ( Directory . GetFiles ( fileInfo . DirectoryName , newFileName + ".*" ) . Any ( ) ) ;
2016-01-11 14:06:47 -08:00
// Change the FileLocation to the new AMF file
printItemWrapper . FileLocation = incrementedFileName ;
2016-01-10 10:18:53 -08:00
}
2016-01-05 14:15:59 -08:00
try
{
2016-01-11 14:06:47 -08:00
// get a new location to save to
2016-01-14 13:50:42 -08:00
string tempFileNameToSaveTo = ApplicationDataStorage . Instance . GetTempFileName ( "amf" ) ;
2016-01-11 14:06:47 -08:00
2016-01-10 10:18:53 -08:00
// save to the new temp location
2016-02-19 11:27:55 -08:00
bool savedSuccessfully = MeshFileIo . Save ( asyncMeshGroups , tempFileNameToSaveTo , outputInfo , ReportProgressChanged ) ;
2016-01-10 10:18:53 -08:00
// Swap out the files if the save operation completed successfully
if ( savedSuccessfully & & File . Exists ( tempFileNameToSaveTo ) )
{
// Ensure the target path is clear
2016-01-11 14:06:47 -08:00
if ( File . Exists ( printItemWrapper . FileLocation ) )
2016-01-10 10:18:53 -08:00
{
File . Delete ( printItemWrapper . FileLocation ) ;
}
// Move the newly saved file back into place
2016-01-11 14:06:47 -08:00
File . Move ( tempFileNameToSaveTo , printItemWrapper . FileLocation ) ;
// Once the file is swapped back into place, update the PrintItem to account for extension change
printItemWrapper . PrintItem . Commit ( ) ;
2016-01-10 10:18:53 -08:00
}
2016-01-05 14:15:59 -08:00
}
2016-01-10 10:18:53 -08:00
catch ( Exception ex )
2016-01-05 14:15:59 -08:00
{
2016-01-10 10:18:53 -08:00
Trace . WriteLine ( "Error saving file: " , ex . Message ) ;
2016-01-05 14:15:59 -08:00
}
}
else // we are saving a new file and it will not exist until we are done
{
2016-02-19 11:27:55 -08:00
MeshFileIo . Save ( asyncMeshGroups , printItemWrapper . FileLocation , outputInfo , ReportProgressChanged ) ;
2016-01-05 14:15:59 -08:00
}
2015-08-31 16:32:09 -07:00
2015-11-04 12:20:20 -08:00
// Wait for a second to report the file changed to give the OS a chance to finish closing it.
UiThread . RunOnIdle ( printItemWrapper . ReportFileChange , 3 ) ;
2015-09-23 13:33:14 -07:00
2015-08-31 16:32:09 -07:00
if ( returnInfo ! = null
& & returnInfo . destinationLibraryProvider ! = null )
{
// save this part to correct library provider
2015-09-11 14:36:57 -07:00
LibraryProvider libraryToSaveTo = returnInfo . destinationLibraryProvider ;
if ( libraryToSaveTo ! = null )
{
libraryToSaveTo . AddItem ( printItemWrapper ) ;
libraryToSaveTo . Dispose ( ) ;
}
2015-08-31 16:32:09 -07:00
}
2016-01-05 14:15:59 -08:00
else // we have already saved it and the library should pick it up
2015-08-31 16:32:09 -07:00
{
}
2015-11-04 17:42:07 -08:00
saveSucceded = true ;
2015-05-30 12:48:16 -07:00
}
2015-09-11 10:48:24 -07:00
catch ( System . UnauthorizedAccessException e2 )
2015-05-30 12:48:16 -07:00
{
2015-09-11 10:48:24 -07:00
Debug . Print ( e2 . Message ) ;
2015-09-17 13:45:26 -07:00
GuiWidget . BreakInDebugger ( ) ;
2015-05-30 12:48:16 -07:00
saveSucceded = false ;
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2015-05-30 12:48:16 -07:00
{
//Do something special when unauthorized?
StyledMessageBox . ShowMessageBox ( null , "Oops! Unable to save changes." , "Unable to save" ) ;
} ) ;
}
2015-12-22 15:26:51 -08:00
catch ( Exception e )
2015-05-30 12:48:16 -07:00
{
2015-09-11 10:48:24 -07:00
Debug . Print ( e . Message ) ;
2015-09-17 13:45:26 -07:00
GuiWidget . BreakInDebugger ( ) ;
2015-05-30 12:48:16 -07:00
saveSucceded = false ;
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
StyledMessageBox . ShowMessageBox ( null , "Oops! Unable to save changes." , "Unable to save" ) ;
} ) ;
}
}
2014-10-13 18:20:01 -07:00
2015-09-09 11:05:17 -07:00
private void MergeAndSavePartsDoCompleted ( )
2015-05-30 12:48:16 -07:00
{
2016-04-25 12:51:29 -07:00
if ( HasBeenClosed )
2015-05-30 12:48:16 -07:00
{
return ;
}
UnlockEditControls ( ) ;
2015-04-08 15:20:10 -07:00
2016-02-19 11:27:55 -08:00
// NOTE: we do not pull the data back out of the async lists.
2015-05-30 12:48:16 -07:00
if ( saveSucceded )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
saveButtons . Visible = false ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
if ( afterSaveCallback ! = null )
{
afterSaveCallback ( ) ;
}
2015-04-08 15:20:10 -07:00
}
2015-09-09 11:05:17 -07:00
private async void MergeAndSavePartsToCurrentMeshFile ( Action eventToCallAfterSave = null )
2015-04-08 15:20:10 -07:00
{
2015-04-15 16:59:12 -07:00
editorThatRequestedSave = true ;
2015-05-30 12:48:16 -07:00
afterSaveCallback = eventToCallAfterSave ;
2015-04-08 15:20:10 -07:00
if ( MeshGroups . Count > 0 )
{
string progressSavingPartsLabel = "Saving" . Localize ( ) ;
string progressSavingPartsLabelFull = "{0}:" . FormatWith ( progressSavingPartsLabel ) ;
processingProgressControl . ProcessType = progressSavingPartsLabelFull ;
processingProgressControl . Visible = true ;
processingProgressControl . PercentComplete = 0 ;
LockEditControls ( ) ;
2015-09-09 11:05:17 -07:00
await Task . Run ( ( ) = > MergeAndSavePartsDoWork ( null ) ) ;
MergeAndSavePartsDoCompleted ( ) ;
2015-04-08 15:20:10 -07:00
}
}
2014-01-29 19:09:30 -08:00
2015-09-09 11:05:17 -07:00
private async void MergeAndSavePartsToNewMeshFile ( SaveAsWindow . SaveAsReturnInfo returnInfo )
2015-04-08 15:20:10 -07:00
{
2015-04-16 10:38:53 -07:00
editorThatRequestedSave = true ;
2015-04-08 15:20:10 -07:00
if ( MeshGroups . Count > 0 )
{
string progressSavingPartsLabel = "Saving" . Localize ( ) ;
string progressSavingPartsLabelFull = "{0}:" . FormatWith ( progressSavingPartsLabel ) ;
processingProgressControl . ProcessType = progressSavingPartsLabelFull ;
processingProgressControl . Visible = true ;
processingProgressControl . PercentComplete = 0 ;
LockEditControls ( ) ;
2015-09-09 11:05:17 -07:00
await Task . Run ( ( ) = > MergeAndSavePartsDoWork ( returnInfo ) ) ;
MergeAndSavePartsDoCompleted ( ) ;
2015-04-08 15:20:10 -07:00
}
}
2015-05-30 12:48:16 -07:00
private void meshViewerWidget_LoadDone ( object sender , EventArgs e )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( windowType = = WindowMode . Embeded )
{
switch ( PrinterConnectionAndCommunication . Instance . CommunicationState )
{
case PrinterConnectionAndCommunication . CommunicationStates . Printing :
case PrinterConnectionAndCommunication . CommunicationStates . Paused :
break ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
default :
UnlockEditControls ( ) ;
break ;
}
}
else
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
UnlockEditControls ( ) ;
2015-04-08 15:20:10 -07:00
}
2016-02-29 10:13:51 -08:00
SelectionChanged ? . Invoke ( this , null ) ;
2015-04-08 15:20:10 -07:00
2015-08-29 09:23:04 -07:00
if ( openMode = = OpenMode . Editing )
2015-04-08 15:20:10 -07:00
{
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( EnterEditAndCreateSelectionData ) ;
2015-05-30 12:48:16 -07:00
}
2015-11-09 12:36:47 -08:00
2016-02-29 14:04:52 -08:00
meshViewerWidget . ResetView ( ) ;
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
2015-08-06 15:20:04 -07:00
private bool PartsAreInPrintVolume ( )
{
2016-06-22 16:29:14 -07:00
if ( ActiveSliceSettings . Instance ? . GetValue < bool > ( SettingsKey . center_part_on_bed ) = = false )
2015-08-10 15:35:56 -07:00
{
AxisAlignedBoundingBox allBounds = MeshViewerWidget . GetAxisAlignedBoundingBox ( MeshGroups ) ;
bool onBed = allBounds . minXYZ . z > - . 001 & & allBounds . minXYZ . z < . 001 ; // really close to the bed
2016-06-16 10:22:38 -07:00
RectangleDouble bedRect = new RectangleDouble ( 0 , 0 , ActiveSliceSettings . Instance . GetValue < Vector2 > ( SettingsKey . bed_size ) . x , ActiveSliceSettings . Instance . GetValue < Vector2 > ( SettingsKey . bed_size ) . y ) ;
2016-06-21 09:38:37 -07:00
bedRect . Offset ( ActiveSliceSettings . Instance . GetValue < Vector2 > ( SettingsKey . print_center ) - ActiveSliceSettings . Instance . GetValue < Vector2 > ( SettingsKey . bed_size ) / 2 ) ;
2015-08-10 15:35:56 -07:00
bool inBounds = bedRect . Contains ( new Vector2 ( allBounds . minXYZ ) ) & & bedRect . Contains ( new Vector2 ( allBounds . maxXYZ ) ) ;
2015-08-06 15:20:04 -07:00
2015-08-10 15:35:56 -07:00
return onBed & & inBounds ;
}
2015-08-06 15:20:04 -07:00
2015-08-10 15:35:56 -07:00
return true ;
2015-08-06 15:20:04 -07:00
}
2015-05-30 12:48:16 -07:00
private void OpenExportWindow ( )
{
if ( exportingWindow = = null )
{
exportingWindow = new ExportPrintItemWindow ( this . printItemWrapper ) ;
exportingWindow . Closed + = ( sender , e ) = >
{
exportingWindow = null ;
} ;
exportingWindow . ShowAsSystemWindow ( ) ;
}
else
{
exportingWindow . BringToFront ( ) ;
}
}
2014-01-29 19:09:30 -08:00
2015-06-11 12:06:40 -07:00
private void OpenSaveAsWindow ( )
2015-05-30 12:48:16 -07:00
{
if ( saveAsWindow = = null )
{
2015-07-31 18:18:21 -07:00
List < ProviderLocatorNode > providerLocator = null ;
2015-09-11 14:36:57 -07:00
if ( printItemWrapper . SourceLibraryProviderLocator ! = null )
2015-07-31 18:18:21 -07:00
{
2015-09-11 14:36:57 -07:00
providerLocator = printItemWrapper . SourceLibraryProviderLocator ;
2015-07-31 18:18:21 -07:00
}
2015-09-04 13:47:48 -07:00
saveAsWindow = new SaveAsWindow ( MergeAndSavePartsToNewMeshFile , providerLocator , true , true ) ;
2015-05-30 12:48:16 -07:00
saveAsWindow . Closed + = new EventHandler ( SaveAsWindow_Closed ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
else
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
saveAsWindow . BringToFront ( ) ;
}
}
private void PullMeshGroupDataFromAsynchLists ( )
{
2016-02-19 11:27:55 -08:00
if ( MeshGroups . Count ! = asyncMeshGroups . Count )
2015-05-30 12:48:16 -07:00
{
PartHasBeenChanged ( ) ;
}
MeshGroups . Clear ( ) ;
2016-02-19 11:27:55 -08:00
foreach ( MeshGroup meshGroup in asyncMeshGroups )
2015-05-30 12:48:16 -07:00
{
MeshGroups . Add ( meshGroup ) ;
}
MeshGroupTransforms . Clear ( ) ;
2016-02-26 14:19:52 -08:00
foreach ( Matrix4X4 transform in asyncMeshGroupTransforms )
2015-05-30 12:48:16 -07:00
{
MeshGroupTransforms . Add ( transform ) ;
}
MeshGroupExtraData . Clear ( ) ;
2016-02-19 11:27:55 -08:00
foreach ( PlatingMeshGroupData meshData in asyncPlatingDatas )
2015-05-30 12:48:16 -07:00
{
MeshGroupExtraData . Add ( meshData ) ;
}
if ( MeshGroups . Count ! = MeshGroupTransforms . Count
| | MeshGroups . Count ! = MeshGroupExtraData . Count )
{
throw new Exception ( "These all need to remain in sync." ) ;
}
}
private void PushMeshGroupDataToAsynchLists ( TraceInfoOpperation traceInfoOpperation , ReportProgressRatio reportProgress = null )
{
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2015-05-30 12:48:16 -07:00
{
processingProgressControl . ProgressMessage = "Async Copy" ;
} ) ;
2016-02-19 11:27:55 -08:00
asyncMeshGroups . Clear ( ) ;
asyncMeshGroupTransforms . Clear ( ) ;
2015-05-30 12:48:16 -07:00
for ( int meshGroupIndex = 0 ; meshGroupIndex < MeshGroups . Count ; meshGroupIndex + + )
{
MeshGroup meshGroup = MeshGroups [ meshGroupIndex ] ;
MeshGroup newMeshGroup = new MeshGroup ( ) ;
for ( int meshIndex = 0 ; meshIndex < meshGroup . Meshes . Count ; meshIndex + + )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
Mesh mesh = meshGroup . Meshes [ meshIndex ] ;
newMeshGroup . Meshes . Add ( Mesh . Copy ( mesh ) ) ;
}
2016-02-19 11:27:55 -08:00
asyncMeshGroups . Add ( newMeshGroup ) ;
asyncMeshGroupTransforms . Add ( MeshGroupTransforms [ meshGroupIndex ] ) ;
2015-04-08 15:20:10 -07:00
}
2016-02-19 11:27:55 -08:00
asyncPlatingDatas . Clear ( ) ;
2015-05-30 12:48:16 -07:00
for ( int meshGroupIndex = 0 ; meshGroupIndex < MeshGroupExtraData . Count ; meshGroupIndex + + )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
PlatingMeshGroupData meshData = new PlatingMeshGroupData ( ) ;
MeshGroup meshGroup = MeshGroups [ meshGroupIndex ] ;
if ( traceInfoOpperation = = TraceInfoOpperation . DO_COPY )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
meshData . meshTraceableData . AddRange ( MeshGroupExtraData [ meshGroupIndex ] . meshTraceableData ) ;
}
2016-02-19 11:27:55 -08:00
asyncPlatingDatas . Add ( meshData ) ;
2015-05-30 12:48:16 -07:00
}
2015-06-11 12:06:40 -07:00
UiThread . RunOnIdle ( ( ) = >
2015-05-30 12:48:16 -07:00
{
processingProgressControl . ProgressMessage = "" ;
} ) ;
}
private void ReloadMeshIfChangeExternaly ( Object sender , EventArgs e )
{
2015-09-23 13:33:14 -07:00
PrintItemWrapper senderItem = sender as PrintItemWrapper ;
if ( senderItem ! = null
& & senderItem . FileLocation = = printItemWrapper . FileLocation )
2015-05-30 12:48:16 -07:00
{
2015-09-23 13:33:14 -07:00
if ( ! editorThatRequestedSave )
{
ClearBedAndLoadPrintItemWrapper ( printItemWrapper ) ;
}
2014-11-11 12:09:09 -08:00
2015-09-23 13:33:14 -07:00
editorThatRequestedSave = false ;
}
2015-05-30 12:48:16 -07:00
}
private bool rotateQueueMenu_Click ( )
{
return true ;
}
private void SaveAsWindow_Closed ( object sender , EventArgs e )
{
this . saveAsWindow = null ;
}
private bool scaleQueueMenu_Click ( )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
return true ;
}
2014-11-11 12:09:09 -08:00
2015-05-30 12:48:16 -07:00
private void SetEditControlsBasedOnPrinterState ( object sender , EventArgs e )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( windowType = = WindowMode . Embeded )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
switch ( PrinterConnectionAndCommunication . Instance . CommunicationState )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
case PrinterConnectionAndCommunication . CommunicationStates . Printing :
case PrinterConnectionAndCommunication . CommunicationStates . Paused :
LockEditControls ( ) ;
break ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
default :
UnlockEditControls ( ) ;
break ;
2015-04-08 15:20:10 -07:00
}
}
}
2015-05-30 12:48:16 -07:00
private void SwitchStateToNotEditing ( )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( ! enterEditButtonsContainer . Visible )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
enterEditButtonsContainer . Visible = true ;
processingProgressControl . Visible = false ;
buttonRightPanel . Visible = false ;
doEdittingButtonsContainer . Visible = false ;
viewControls3D . PartSelectVisible = false ;
2015-05-29 15:13:56 -07:00
if ( viewControls3D . ActiveButton = = ViewControls3DButtons . PartSelect )
2015-04-08 15:20:10 -07:00
{
2015-05-29 15:13:56 -07:00
viewControls3D . ActiveButton = ViewControls3DButtons . Rotate ;
2015-12-22 15:26:51 -08:00
}
2015-05-30 12:48:16 -07:00
SelectedMeshGroupIndex = - 1 ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
private void UnlockEditControls ( )
{
buttonRightPanelDisabledCover . Visible = false ;
processingProgressControl . Visible = false ;
if ( viewIsInEditModePreLock )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( ! enterEditButtonsContainer . Visible )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
viewControls3D . PartSelectVisible = true ;
doEdittingButtonsContainer . Visible = true ;
2015-04-08 15:20:10 -07:00
}
}
2015-05-30 12:48:16 -07:00
else
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
enterEditButtonsContainer . Visible = true ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
if ( wasInSelectMode )
2015-04-08 15:20:10 -07:00
{
2015-05-29 15:13:56 -07:00
viewControls3D . ActiveButton = ViewControls3DButtons . PartSelect ;
2015-05-30 12:48:16 -07:00
wasInSelectMode = false ;
}
2015-04-08 15:20:10 -07:00
2016-02-28 11:54:42 -08:00
SelectedTransformChanged ? . Invoke ( this , null ) ;
2015-04-08 15:20:10 -07:00
}
2016-02-19 08:29:49 -08:00
}
2015-05-30 12:48:16 -07:00
2016-02-19 08:29:49 -08:00
public enum HitQuadrant { LB , LT , RB , RT }
public class MeshSelectInfo
{
public HitQuadrant HitQuadrant ;
public bool DownOnPart ;
public PlaneShape HitPlane ;
public Vector3 LastMoveDelta ;
public Vector3 PlaneDownHitPos ;
2015-04-08 15:20:10 -07:00
}
}