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
modification , are permitted provided that the following conditions are met :
1. Redistributions of source code must retain the above copyright notice , this
list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies ,
either expressed or implied , of the FreeBSD Project .
* /
using System ;
using System.Collections.Generic ;
2014-10-18 13:23:53 -07:00
using System.Collections.ObjectModel ;
2014-04-15 18:13:27 -07:00
using System.ComponentModel ;
2014-01-29 19:09:30 -08:00
using System.Diagnostics ;
using System.Globalization ;
2014-04-15 18:13:27 -07:00
using System.IO ;
2014-01-29 19:09:30 -08:00
using System.Threading ;
using MatterHackers.Agg ;
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 ;
2014-10-24 14:55:27 -07:00
using MatterHackers.MatterControl.PrintLibrary ;
2014-11-22 20:35:40 -08:00
using MatterHackers.RenderOpenGl.OpenGl ;
2014-04-15 18:13:27 -07:00
using MatterHackers.MatterControl.PrintQueue ;
2014-11-22 20:35:40 -08:00
using MatterHackers.Agg.Transform ;
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 ;
2014-11-27 08:37:31 -08:00
using MatterHackers.Agg.PlatformAbstract ;
2014-01-29 19:09:30 -08:00
namespace MatterHackers.MatterControl.PartPreviewWindow
{
2014-10-16 17:52:21 -07:00
public partial class View3DWidget : PartPreview3DWidget
2014-01-29 19:09:30 -08:00
{
2014-12-16 11:59:20 -08:00
EventHandler unregisterEvents ;
public enum WindowMode { Embeded , StandAlone } ;
public enum AutoRotate { Enabled , Disabled } ;
public enum OpenMode { Viewing , Editing }
2015-01-08 11:55:50 -08:00
OpenMode openMode ;
2014-12-16 11:59:20 -08:00
2014-12-12 12:57:44 -08:00
readonly int EditButtonHeight = 44 ;
2014-12-16 11:59:20 -08:00
public WindowMode windowType { get ; set ; }
Matrix4X4 transformOnMouseDown = Matrix4X4 . Identity ;
MeshSelectInfo meshSelectInfo ;
2014-07-02 13:28:51 -07:00
2014-10-13 18:20:01 -07:00
EventHandler SelectionChanged ;
2014-11-24 12:25:40 -08:00
UpArrow3D upArrow ;
2014-12-12 21:57:05 -08:00
internal HeightValueDisplay heightDisplay ;
2014-10-13 18:20:01 -07:00
2014-01-29 19:09:30 -08:00
FlowLayoutWidget viewOptionContainer ;
FlowLayoutWidget rotateOptionContainer ;
FlowLayoutWidget scaleOptionContainer ;
2014-09-24 11:15:38 -07:00
FlowLayoutWidget mirrorOptionContainer ;
2014-09-26 15:04:04 -07:00
FlowLayoutWidget materialOptionContainer ;
2014-01-29 19:09:30 -08:00
2014-05-16 17:13:18 -07:00
List < string > pendingPartsToLoad = new List < string > ( ) ;
2014-10-24 17:27:38 -07:00
bool DoAddFileAfterCreatingEditData { get ; set ; }
2014-05-16 17:13:18 -07:00
2014-01-29 19:09:30 -08:00
ProgressControl processingProgressControl ;
2014-03-07 09:50:41 -08:00
FlowLayoutWidget enterEditButtonsContainer ;
FlowLayoutWidget doEdittingButtonsContainer ;
2014-10-12 20:40:38 -07:00
2014-01-29 19:09:30 -08:00
Dictionary < string , List < GuiWidget > > transformControls = new Dictionary < string , List < GuiWidget > > ( ) ;
2014-05-06 11:22:48 -07:00
MHNumberEdit scaleRatioControl ;
2014-01-29 19:09:30 -08:00
CheckBox expandViewOptions ;
CheckBox expandRotateOptions ;
CheckBox expandScaleOptions ;
2014-09-24 11:15:38 -07:00
CheckBox expandMirrorOptions ;
2014-09-26 15:04:04 -07:00
CheckBox expandMaterialOptions ;
2014-01-29 19:09:30 -08:00
Button autoArrangeButton ;
2014-11-17 15:50:39 -08:00
SplitButton saveButtons ;
2014-01-29 19:09:30 -08:00
Button applyScaleButton ;
2014-10-10 14:52:50 -07:00
PrintItemWrapper printItemWrapper ;
2014-11-11 12:09:09 -08:00
SaveAsWindow saveAsWindow = null ;
ExportPrintItemWindow exportingWindow = null ;
2014-01-29 19:09:30 -08:00
2014-12-20 23:45:13 -08:00
bool partHasBeenEdited = false ;
2014-10-15 14:11:14 -07:00
List < MeshGroup > asynchMeshGroups = new List < MeshGroup > ( ) ;
2014-10-07 18:00:17 -07:00
List < ScaleRotateTranslate > asynchMeshGroupTransforms = new List < ScaleRotateTranslate > ( ) ;
2014-10-15 14:11:14 -07:00
List < PlatingMeshGroupData > asynchPlatingDatas = new List < PlatingMeshGroupData > ( ) ;
2014-01-29 19:09:30 -08:00
2014-10-07 18:00:17 -07:00
List < PlatingMeshGroupData > MeshGroupExtraData ;
2014-01-29 19:09:30 -08:00
2014-12-12 21:57:05 -08:00
public bool DisplayAllValueData { get ; set ; }
2014-10-07 18:00:17 -07:00
public ScaleRotateTranslate SelectedMeshGroupTransform
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
get { return meshViewerWidget . SelectedMeshGroupTransform ; }
set { meshViewerWidget . SelectedMeshGroupTransform = value ; }
2014-01-29 19:09:30 -08:00
}
2014-10-07 18:00:17 -07:00
public MeshGroup SelectedMeshGroup
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
get { return meshViewerWidget . SelectedMeshGroup ; }
2014-01-29 19:09:30 -08:00
}
2014-11-23 07:31:02 -08:00
public bool HaveSelection
{
get { return MeshGroups . Count > 0 & & SelectedMeshGroupIndex > - 1 ; }
}
2014-10-07 18:00:17 -07:00
public int SelectedMeshGroupIndex
2014-01-29 19:09:30 -08:00
{
2014-11-23 07:31:02 -08:00
get
{
return meshViewerWidget . SelectedMeshGroupIndex ;
}
set
{
if ( value ! = SelectedMeshGroupIndex )
{
meshViewerWidget . SelectedMeshGroupIndex = value ;
2015-01-08 15:25:50 -08:00
if ( SelectionChanged ! = null )
{
SelectionChanged ( this , null ) ;
}
2014-11-23 07:31:02 -08:00
Invalidate ( ) ;
}
}
2014-01-29 19:09:30 -08:00
}
2014-10-07 18:00:17 -07:00
public List < MeshGroup > MeshGroups
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
get { return meshViewerWidget . MeshGroups ; }
2014-01-29 19:09:30 -08:00
}
2014-10-07 18:00:17 -07:00
public List < ScaleRotateTranslate > MeshGroupTransforms
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
get { return meshViewerWidget . MeshGroupTransforms ; }
2014-01-29 19:09:30 -08:00
}
internal struct MeshSelectInfo
{
internal bool downOnPart ;
internal PlaneShape hitPlane ;
internal Vector3 planeDownHitPos ;
internal Vector3 lastMoveDelta ;
}
2014-10-07 18:00:17 -07:00
private bool FindMeshGroupHitPosition ( Vector2 screenPosition , out int meshHitIndex )
2014-01-29 19:09:30 -08:00
{
meshHitIndex = 0 ;
2014-10-07 18:00:17 -07:00
if ( MeshGroupExtraData . Count = = 0 | | MeshGroupExtraData [ 0 ] . meshTraceableData = = null )
2014-01-29 19:09:30 -08:00
{
return false ;
}
List < IRayTraceable > mesheTraceables = new List < IRayTraceable > ( ) ;
2014-10-07 18:00:17 -07:00
for ( int i = 0 ; i < MeshGroupExtraData . Count ; i + + )
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
foreach ( IRayTraceable traceData in MeshGroupExtraData [ i ] . meshTraceableData )
{
mesheTraceables . Add ( new Transform ( traceData , MeshGroupTransforms [ i ] . TotalTransform ) ) ;
}
2014-01-29 19:09:30 -08:00
}
IRayTraceable allObjects = BoundingVolumeHierarchy . CreateNewHierachy ( mesheTraceables ) ;
2014-11-22 20:35:40 -08:00
Vector2 meshViewerWidgetScreenPosition = meshViewerWidget . TransformFromParentSpace ( this , screenPosition ) ;
Ray ray = meshViewerWidget . TrackballTumbleWidget . GetRayFromScreen ( meshViewerWidgetScreenPosition ) ;
2014-01-29 19:09:30 -08:00
IntersectInfo info = allObjects . GetClosestIntersection ( ray ) ;
if ( info ! = null )
{
meshSelectInfo . planeDownHitPos = info . hitPosition ;
meshSelectInfo . lastMoveDelta = new Vector3 ( ) ;
2014-10-07 18:00:17 -07:00
for ( int i = 0 ; i < MeshGroupExtraData . Count ; i + + )
2014-01-29 19:09:30 -08:00
{
List < IRayTraceable > insideBounds = new List < IRayTraceable > ( ) ;
2014-10-07 18:00:17 -07:00
foreach ( IRayTraceable traceData in MeshGroupExtraData [ i ] . meshTraceableData )
{
traceData . GetContained ( insideBounds , info . closestHitObject . GetAxisAlignedBoundingBox ( ) ) ;
}
2014-01-29 19:09:30 -08:00
if ( insideBounds . Contains ( info . closestHitObject ) )
{
meshHitIndex = i ;
return true ;
}
}
}
return false ;
}
public override void OnMouseDown ( MouseEventArgs mouseEvent )
{
2014-11-11 17:15:35 -08:00
autoRotating = false ;
2014-01-29 19:09:30 -08:00
base . OnMouseDown ( mouseEvent ) ;
if ( meshViewerWidget . TrackballTumbleWidget . UnderMouseState = = Agg . UI . UnderMouseState . FirstUnderMouse )
{
2014-10-12 18:49:46 -07:00
if ( meshViewerWidget . TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . None
& & mouseEvent . Button = = MouseButtons . Left
& & ModifierKeys ! = Keys . Shift
& & ModifierKeys ! = Keys . Control
& & ModifierKeys ! = Keys . Alt )
2014-01-29 19:09:30 -08:00
{
2014-11-24 14:34:59 -08:00
if ( ! meshViewerWidget . MouseDownOnInteractionVolume )
2014-01-29 19:09:30 -08:00
{
2014-11-24 14:34:59 -08:00
int meshGroupHitIndex ;
if ( FindMeshGroupHitPosition ( mouseEvent . Position , out meshGroupHitIndex ) )
{
meshSelectInfo . hitPlane = new PlaneShape ( Vector3 . UnitZ , meshSelectInfo . planeDownHitPos . z , null ) ;
SelectedMeshGroupIndex = meshGroupHitIndex ;
2014-08-14 09:58:17 -07:00
2014-11-24 14:34:59 -08:00
transformOnMouseDown = SelectedMeshGroupTransform . translation ;
2014-10-12 20:40:38 -07:00
2014-11-24 14:34:59 -08:00
Invalidate ( ) ;
meshSelectInfo . downOnPart = true ;
}
else
2014-10-13 18:20:01 -07:00
{
2014-11-24 14:34:59 -08:00
SelectedMeshGroupIndex = - 1 ;
2014-10-13 18:20:01 -07:00
}
2014-11-25 09:58:30 -08:00
UpdateSizeInfo ( ) ;
2014-01-29 19:09:30 -08:00
}
}
}
}
2015-01-05 11:18:30 -08:00
bool firstDraw = true ;
2014-01-29 19:09:30 -08:00
public override void OnDraw ( Graphics2D graphics2D )
{
2015-01-05 11:18:30 -08:00
if ( firstDraw )
{
ClearBedAndLoadPrintItemWrapper ( printItemWrapper ) ;
firstDraw = false ;
}
2014-11-24 12:25:40 -08:00
if ( HaveSelection )
{
upArrow . SetPosition ( ) ;
2014-12-13 23:25:08 -08:00
heightDisplay . SetPosition ( ) ;
2014-11-24 12:25:40 -08:00
}
2014-03-20 18:41:22 -07:00
hasDrawn = true ;
2014-01-29 19:09:30 -08:00
base . OnDraw ( graphics2D ) ;
2014-11-22 20:35:40 -08:00
DrawStuffForSelectedPart ( graphics2D ) ;
}
private void DrawStuffForSelectedPart ( Graphics2D graphics2D )
{
if ( SelectedMeshGroup ! = null )
{
AxisAlignedBoundingBox selectedBounds = SelectedMeshGroup . GetAxisAlignedBoundingBox ( SelectedMeshGroupTransform . TotalTransform ) ;
Vector3 boundsCenter = selectedBounds . Center ;
Vector3 centerTop = new Vector3 ( boundsCenter . x , boundsCenter . y , selectedBounds . maxXYZ . z ) ;
Vector2 centerTopScreenPosition = meshViewerWidget . TrackballTumbleWidget . GetScreenPosition ( centerTop ) ;
centerTopScreenPosition = meshViewerWidget . TransformToParentSpace ( this , centerTopScreenPosition ) ;
//graphics2D.Circle(screenPosition.x, screenPosition.y, 5, RGBA_Bytes.Cyan);
PathStorage zArrow = new PathStorage ( ) ;
zArrow . MoveTo ( - 6 , - 2 ) ;
zArrow . curve3 ( 0 , - 4 ) ;
zArrow . LineTo ( 6 , - 2 ) ;
zArrow . LineTo ( 0 , 12 ) ;
zArrow . LineTo ( - 6 , - 2 ) ;
VertexSourceApplyTransform translate = new VertexSourceApplyTransform ( zArrow , Affine . NewTranslation ( centerTopScreenPosition ) ) ;
//graphics2D.Render(translate, RGBA_Bytes.Black);
}
2014-01-29 19:09:30 -08:00
}
public override void OnMouseMove ( MouseEventArgs mouseEvent )
{
if ( meshViewerWidget . TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . None & & meshSelectInfo . downOnPart )
{
2014-11-22 20:35:40 -08:00
Vector2 meshViewerWidgetScreenPosition = meshViewerWidget . TransformFromParentSpace ( this , new Vector2 ( mouseEvent . X , mouseEvent . Y ) ) ;
Ray ray = meshViewerWidget . TrackballTumbleWidget . GetRayFromScreen ( meshViewerWidgetScreenPosition ) ;
2014-01-29 19:09:30 -08:00
IntersectInfo info = meshSelectInfo . hitPlane . GetClosestIntersection ( ray ) ;
if ( info ! = null )
{
Vector3 delta = info . hitPosition - meshSelectInfo . planeDownHitPos ;
Matrix4X4 totalTransfrom = Matrix4X4 . CreateTranslation ( new Vector3 ( - meshSelectInfo . lastMoveDelta ) ) ;
totalTransfrom * = Matrix4X4 . CreateTranslation ( new Vector3 ( delta ) ) ;
meshSelectInfo . lastMoveDelta = delta ;
2014-10-12 20:40:38 -07:00
2014-10-07 18:00:17 -07:00
ScaleRotateTranslate translated = SelectedMeshGroupTransform ;
2014-08-14 09:58:17 -07:00
translated . translation * = totalTransfrom ;
2014-10-07 18:00:17 -07:00
SelectedMeshGroupTransform = translated ;
2014-10-12 20:40:38 -07:00
2014-01-29 19:09:30 -08:00
Invalidate ( ) ;
}
}
base . OnMouseMove ( mouseEvent ) ;
}
public override void OnMouseUp ( MouseEventArgs mouseEvent )
{
if ( meshViewerWidget . TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . None
& & meshSelectInfo . downOnPart
& & meshSelectInfo . lastMoveDelta ! = Vector3 . Zero )
{
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-01-29 19:09:30 -08:00
}
meshSelectInfo . downOnPart = false ;
base . OnMouseUp ( mouseEvent ) ;
}
2014-05-27 09:16:35 -07:00
public override void OnClosed ( EventArgs e )
{
if ( unregisterEvents ! = null )
{
unregisterEvents ( this , null ) ;
}
base . OnClosed ( e ) ;
}
2014-12-16 11:59:20 -08:00
public View3DWidget ( PrintItemWrapper printItemWrapper , Vector3 viewerVolume , Vector2 bedCenter , MeshViewerWidget . BedShape bedShape , WindowMode windowType , AutoRotate autoRotate , OpenMode openMode = OpenMode . Viewing )
2014-01-29 19:09:30 -08:00
{
2015-01-08 11:55:50 -08:00
this . openMode = openMode ;
2014-07-02 13:28:51 -07:00
this . windowType = windowType ;
2014-11-11 17:15:35 -08:00
allowAutoRotate = ( autoRotate = = AutoRotate . Enabled ) ;
autoRotating = allowAutoRotate ;
2014-10-07 18:00:17 -07:00
MeshGroupExtraData = new List < PlatingMeshGroupData > ( ) ;
MeshGroupExtraData . Add ( new PlatingMeshGroupData ( ) ) ;
2014-01-29 19:09:30 -08:00
this . printItemWrapper = printItemWrapper ;
FlowLayoutWidget mainContainerTopToBottom = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
mainContainerTopToBottom . HAnchor = Agg . UI . HAnchor . Max_FitToChildren_ParentWidth ;
mainContainerTopToBottom . VAnchor = Agg . UI . VAnchor . Max_FitToChildren_ParentHeight ;
FlowLayoutWidget centerPartPreviewAndControls = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
centerPartPreviewAndControls . AnchorAll ( ) ;
GuiWidget viewArea = new GuiWidget ( ) ;
viewArea . AnchorAll ( ) ;
{
2014-07-25 17:13:42 -07:00
meshViewerWidget = new MeshViewerWidget ( viewerVolume , bedCenter , bedShape , "Press 'Add' to select an item." . Localize ( ) ) ;
2014-05-09 18:37:15 -07:00
2014-09-09 15:17:49 -07:00
PutOemImageOnBed ( ) ;
2014-05-09 18:37:15 -07:00
2014-01-29 19:09:30 -08:00
meshViewerWidget . AnchorAll ( ) ;
}
viewArea . AddChild ( meshViewerWidget ) ;
centerPartPreviewAndControls . AddChild ( viewArea ) ;
mainContainerTopToBottom . AddChild ( centerPartPreviewAndControls ) ;
FlowLayoutWidget buttonBottomPanel = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
buttonBottomPanel . HAnchor = HAnchor . ParentLeftRight ;
buttonBottomPanel . Padding = new BorderDouble ( 3 , 3 ) ;
buttonBottomPanel . BackgroundColor = ActiveTheme . Instance . PrimaryBackgroundColor ;
2014-04-27 17:19:06 -07:00
buttonRightPanel = CreateRightButtonPanel ( viewerVolume . y ) ;
2014-10-27 11:49:59 -07:00
buttonRightPanel . Visible = false ;
2014-01-29 19:09:30 -08:00
CreateOptionsContent ( ) ;
// add in the plater tools
{
FlowLayoutWidget editToolBar = new FlowLayoutWidget ( ) ;
2014-11-06 11:57:32 -08:00
string progressFindPartsLabel = "Entering Editor" . Localize ( ) ;
2014-04-15 10:11:56 -07:00
string progressFindPartsLabelFull = "{0}:" . FormatWith ( progressFindPartsLabel ) ;
2014-01-29 19:09:30 -08:00
2014-07-20 14:56:13 -07:00
processingProgressControl = new ProgressControl ( progressFindPartsLabelFull , ActiveTheme . Instance . PrimaryTextColor , ActiveTheme . Instance . PrimaryAccentColor ) ;
2014-01-29 19:09:30 -08:00
processingProgressControl . VAnchor = Agg . UI . VAnchor . ParentCenter ;
editToolBar . AddChild ( processingProgressControl ) ;
editToolBar . VAnchor | = Agg . UI . VAnchor . ParentCenter ;
processingProgressControl . Visible = false ;
2014-05-02 12:07:27 -07:00
// If the window is embeded (in the center pannel) and there is no item loaded then don't show the add button
2014-03-07 09:50:41 -08:00
enterEditButtonsContainer = new FlowLayoutWidget ( ) ;
{
2014-12-20 09:07:13 -08:00
Button addButton = textImageButtonFactory . Generate ( "Insert" . Localize ( ) , "icon_insert_32x32.png" ) ;
2014-12-28 17:28:09 -08:00
addButton . Margin = new BorderDouble ( right : 0 ) ;
2014-03-07 09:50:41 -08:00
enterEditButtonsContainer . AddChild ( addButton ) ;
addButton . Click + = ( sender , e ) = >
{
UiThread . RunOnIdle ( ( state ) = >
{
2014-10-24 17:27:38 -07:00
DoAddFileAfterCreatingEditData = true ;
2014-10-09 11:29:33 -07:00
EnterEditAndCreateSelectionData ( ) ;
2014-03-07 09:50:41 -08:00
} ) ;
} ;
2014-12-19 12:24:49 -08:00
Button enterEdittingButton = textImageButtonFactory . Generate ( "Edit" . Localize ( ) , "icon_edit_32x32.png" ) ;
2014-12-28 17:28:09 -08:00
enterEdittingButton . Margin = new BorderDouble ( right : 4 ) ;
2014-03-07 09:50:41 -08:00
enterEdittingButton . Click + = ( sender , e ) = >
{
2014-10-09 11:29:33 -07:00
EnterEditAndCreateSelectionData ( ) ;
2014-03-07 09:50:41 -08:00
} ;
2014-11-06 11:57:32 -08:00
Button exportButton = textImageButtonFactory . Generate ( "Export..." . Localize ( ) ) ;
2014-10-10 14:52:50 -07:00
exportButton . Margin = new BorderDouble ( right : 10 ) ;
exportButton . Click + = ( sender , e ) = >
{
UiThread . RunOnIdle ( ( state ) = >
{
OpenExportWindow ( ) ;
} ) ;
} ;
2014-03-07 09:50:41 -08:00
enterEditButtonsContainer . AddChild ( enterEdittingButton ) ;
2014-10-10 14:52:50 -07:00
enterEditButtonsContainer . AddChild ( exportButton ) ;
2014-03-07 09:50:41 -08:00
}
editToolBar . AddChild ( enterEditButtonsContainer ) ;
2014-01-29 19:09:30 -08:00
2014-03-07 09:50:41 -08:00
doEdittingButtonsContainer = new FlowLayoutWidget ( ) ;
doEdittingButtonsContainer . Visible = false ;
2014-01-29 19:09:30 -08:00
{
2014-12-20 09:07:13 -08:00
Button addButton = textImageButtonFactory . Generate ( "Insert" . Localize ( ) , "icon_insert_32x32.png" ) ;
2014-03-07 09:50:41 -08:00
addButton . Margin = new BorderDouble ( right : 10 ) ;
doEdittingButtonsContainer . AddChild ( addButton ) ;
addButton . Click + = ( sender , e ) = >
2014-01-29 19:09:30 -08:00
{
2014-03-07 09:50:41 -08:00
UiThread . RunOnIdle ( ( state ) = >
{
2014-10-31 17:37:40 -07:00
FileDialog . OpenFileDialog (
new OpenFileDialogParams ( ApplicationSettings . OpenDesignFileParams , multiSelect : true ) ,
( openParams ) = >
{
LoadAndAddPartsToPlate ( openParams . FileNames ) ;
} ) ;
2014-03-07 09:50:41 -08:00
} ) ;
} ;
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
2014-11-06 11:57:32 -08:00
Button ungroupButton = textImageButtonFactory . Generate ( "Ungroup" . Localize ( ) ) ;
2014-10-13 18:20:01 -07:00
doEdittingButtonsContainer . AddChild ( ungroupButton ) ;
ungroupButton . Click + = ( sender , e ) = >
{
UngroupSelectedMeshGroup ( ) ;
} ;
2014-11-06 11:57:32 -08:00
Button groupButton = textImageButtonFactory . Generate ( "Group" . Localize ( ) ) ;
2014-10-29 13:15:53 -07:00
doEdittingButtonsContainer . AddChild ( groupButton ) ;
groupButton . Click + = ( sender , e ) = >
{
GroupSelectedMeshs ( ) ;
} ;
2014-11-06 11:57:32 -08:00
Button alignButton = textImageButtonFactory . Generate ( "Align" . Localize ( ) ) ;
2014-10-15 14:11:14 -07:00
doEdittingButtonsContainer . AddChild ( alignButton ) ;
alignButton . Click + = ( sender , e ) = >
{
2014-10-28 12:07:51 -07:00
AlignToSelectedMeshGroup ( ) ;
2014-10-15 14:11:14 -07:00
} ;
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 ) ;
2014-11-06 11:57:32 -08:00
Button copyButton = textImageButtonFactory . Generate ( "Copy" . Localize ( ) ) ;
2014-03-07 09:50:41 -08:00
doEdittingButtonsContainer . AddChild ( copyButton ) ;
copyButton . Click + = ( sender , e ) = >
{
2014-10-07 18:00:17 -07:00
MakeCopyOfGroup ( ) ;
2014-03-07 09:50:41 -08:00
} ;
2014-01-29 19:09:30 -08:00
2014-12-20 09:07:13 -08:00
Button deleteButton = textImageButtonFactory . Generate ( "Remove" . Localize ( ) ) ;
2014-03-07 09:50:41 -08: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 ) ;
Button leaveEditModeButton = textImageButtonFactory . Generate ( "Cancel" . Localize ( ) , centerText : true ) ;
leaveEditModeButton . Click + = ( sender , e ) = >
{
UiThread . RunOnIdle ( ( state ) = >
{
if ( saveButtons . Visible )
{
2014-12-20 23:45:13 -08:00
StyledMessageBox . ShowMessageBox ( ExitEditingAndSaveIfRequired , "Would you like to save your changes before exiting the editor?" , "Save Changes" , StyledMessageBox . MessageType . YES_NO ) ;
2014-12-20 09:07:13 -08:00
}
else
{
2014-12-20 23:45:13 -08:00
if ( partHasBeenEdited )
{
ExitEditingAndSaveIfRequired ( false ) ;
}
else
{
SwitchStateToNotEditing ( ) ;
}
2014-12-20 09:07:13 -08:00
}
} ) ;
} ;
doEdittingButtonsContainer . AddChild ( leaveEditModeButton ) ;
// put in the save button
AddSaveAndSaveAs ( doEdittingButtonsContainer ) ;
2014-03-07 09:50:41 -08:00
}
2014-01-29 19:09:30 -08:00
KeyDown + = ( sender , e ) = >
{
KeyEventArgs keyEvent = e as KeyEventArgs ;
if ( keyEvent ! = null & & ! keyEvent . Handled )
{
if ( keyEvent . KeyCode = = Keys . Delete | | keyEvent . KeyCode = = Keys . Back )
{
DeleteSelectedMesh ( ) ;
}
if ( keyEvent . KeyCode = = Keys . Escape )
{
if ( meshSelectInfo . downOnPart )
{
meshSelectInfo . downOnPart = false ;
2014-10-12 20:40:38 -07:00
2014-10-07 18:00:17 -07:00
ScaleRotateTranslate translated = SelectedMeshGroupTransform ;
2014-10-30 13:39:03 -07:00
translated . translation = transformOnMouseDown ;
2014-10-07 18:00:17 -07:00
SelectedMeshGroupTransform = translated ;
2014-08-14 09:58:17 -07:00
2014-01-29 19:09:30 -08:00
Invalidate ( ) ;
}
}
}
} ;
2014-03-07 09:50:41 -08:00
editToolBar . AddChild ( doEdittingButtonsContainer ) ;
2014-01-29 19:09:30 -08:00
buttonBottomPanel . AddChild ( editToolBar ) ;
}
GuiWidget buttonRightPanelHolder = new GuiWidget ( HAnchor . FitToChildren , VAnchor . ParentBottomTop ) ;
centerPartPreviewAndControls . AddChild ( buttonRightPanelHolder ) ;
buttonRightPanelHolder . AddChild ( buttonRightPanel ) ;
2014-05-25 11:11:11 -07:00
viewControls3D = new ViewControls3D ( meshViewerWidget ) ;
2014-01-29 19:09:30 -08:00
buttonRightPanelDisabledCover = new Cover ( HAnchor . ParentLeftRight , VAnchor . ParentBottomTop ) ;
buttonRightPanelDisabledCover . BackgroundColor = new RGBA_Bytes ( ActiveTheme . Instance . PrimaryBackgroundColor , 150 ) ;
buttonRightPanelHolder . AddChild ( buttonRightPanelDisabledCover ) ;
2014-10-24 13:53:00 -07:00
viewControls3D . PartSelectVisible = false ;
2014-01-29 19:09:30 -08:00
LockEditControls ( ) ;
GuiWidget leftRightSpacer = new GuiWidget ( ) ;
leftRightSpacer . HAnchor = HAnchor . ParentLeftRight ;
buttonBottomPanel . AddChild ( leftRightSpacer ) ;
2014-12-16 11:59:20 -08:00
if ( windowType = = WindowMode . StandAlone )
2014-04-09 21:47:00 -07:00
{
2014-11-06 11:57:32 -08:00
Button closeButton = textImageButtonFactory . Generate ( "Close" . Localize ( ) ) ;
2014-04-09 21:47:00 -07:00
buttonBottomPanel . AddChild ( closeButton ) ;
closeButton . Click + = ( sender , e ) = >
{
CloseOnIdle ( ) ;
} ;
}
2014-01-29 19:09:30 -08:00
mainContainerTopToBottom . AddChild ( buttonBottomPanel ) ;
this . AddChild ( mainContainerTopToBottom ) ;
this . AnchorAll ( ) ;
meshViewerWidget . TrackballTumbleWidget . TransformState = TrackBallController . MouseDownType . Rotation ;
2014-05-25 11:11:11 -07:00
AddChild ( viewControls3D ) ;
2014-01-29 19:09:30 -08:00
AddHandlers ( ) ;
2014-03-01 23:27:34 -08:00
2014-03-20 18:20:52 -07:00
UiThread . RunOnIdle ( AutoSpin ) ;
2014-05-02 12:07:27 -07:00
2014-12-16 11:59:20 -08:00
if ( printItemWrapper = = null & & windowType = = WindowMode . Embeded )
2014-05-02 12:07:27 -07:00
{
enterEditButtonsContainer . Visible = false ;
}
2014-05-27 09:16:35 -07:00
2014-12-16 11:59:20 -08:00
if ( windowType = = WindowMode . Embeded )
2014-06-05 12:55:05 -07:00
{
2014-06-11 14:52:58 -07:00
PrinterConnectionAndCommunication . Instance . CommunicationStateChanged . RegisterEvent ( SetEditControlsBasedOnPrinterState , ref unregisterEvents ) ;
2014-12-16 11:59:20 -08:00
if ( windowType = = WindowMode . Embeded )
2014-07-26 13:43:55 -07:00
{
// 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 ;
}
}
2014-06-05 12:55:05 -07:00
}
2014-08-08 10:25:44 -07:00
2014-08-19 11:41:13 -07:00
ActiveTheme . Instance . ThemeChanged . RegisterEvent ( ThemeChanged , ref unregisterEvents ) ;
2014-10-05 16:07:06 -07:00
2014-12-12 12:57:44 -08:00
upArrow = new UpArrow3D ( this ) ;
2014-12-12 21:57:05 -08:00
heightDisplay = new HeightValueDisplay ( this ) ;
2014-12-14 07:34:50 -08:00
heightDisplay . Visible = false ;
2014-11-24 22:24:30 -08:00
meshViewerWidget . interactionVolumes . Add ( upArrow ) ;
2014-11-24 08:08:56 -08:00
2014-11-01 14:33:59 -07:00
// make sure the colors are set correctl
ThemeChanged ( this , null ) ;
2014-12-20 23:45:13 -08:00
saveButtons . VisibleChanged + = ( sender , e ) = >
{
partHasBeenEdited = true ;
} ;
2014-08-08 10:25:44 -07:00
}
2014-12-20 11:12:02 -08:00
private void ClearBedAndLoadPrintItemWrapper ( PrintItemWrapper printItemWrapper )
{
MeshGroups . Clear ( ) ;
MeshGroupExtraData . Clear ( ) ;
MeshGroupTransforms . Clear ( ) ;
if ( printItemWrapper ! = null )
{
// Controls if the part should be automattically centered. Ideally, we should autocenter any time a user has
// not moved parts around on the bed (as we do now) but skip autocentering if the user has moved and placed
// parts themselves. For now, simply mock that determination to allow testing of the proposed change and convey
// when we would want to autocenter (i.e. autocenter when part was loaded outside of the new closed loop system)
MeshVisualizer . MeshViewerWidget . CenterPartAfterLoad centerOnBed = MeshViewerWidget . CenterPartAfterLoad . DO ;
if ( printItemWrapper . FileLocation . Contains ( ApplicationDataStorage . Instance . ApplicationLibraryDataPath ) )
{
centerOnBed = MeshViewerWidget . CenterPartAfterLoad . DONT ;
}
// don't load the mesh until we get all the rest of the interface built
meshViewerWidget . LoadDone + = new EventHandler ( meshViewerWidget_LoadDone ) ;
meshViewerWidget . LoadMesh ( printItemWrapper . FileLocation , centerOnBed ) ;
}
2014-12-20 23:45:13 -08:00
partHasBeenEdited = false ;
2014-12-20 11:12:02 -08:00
}
2014-12-20 23:45:13 -08:00
void ExitEditingAndSaveIfRequired ( bool response )
2014-12-19 09:39:29 -08:00
{
if ( response = = true )
{
2014-12-19 10:10:14 -08:00
MergeAndSavePartsToCurrentMeshFile ( SwitchStateToNotEditing ) ;
}
else
{
SwitchStateToNotEditing ( ) ;
2014-12-20 11:12:02 -08:00
// and reload the part
ClearBedAndLoadPrintItemWrapper ( printItemWrapper ) ;
2014-12-19 09:39:29 -08:00
}
}
2014-12-19 10:10:14 -08:00
void SwitchStateToNotEditing ( )
{
enterEditButtonsContainer . Visible = true ;
autoArrangeButton . Visible = false ;
processingProgressControl . Visible = false ;
buttonRightPanel . Visible = false ;
doEdittingButtonsContainer . Visible = false ;
viewControls3D . PartSelectVisible = false ;
if ( viewControls3D . partSelectButton . Checked )
{
viewControls3D . rotateButton . ClickButton ( null ) ;
}
SelectedMeshGroupIndex = - 1 ;
}
2014-11-24 12:25:40 -08:00
private void OpenExportWindow ( )
2014-10-10 14:52:50 -07:00
{
2014-11-11 12:09:09 -08:00
if ( exportingWindow = = null )
2014-10-10 14:52:50 -07:00
{
2014-10-23 14:40:12 -07:00
exportingWindow = new ExportPrintItemWindow ( this . printItemWrapper ) ;
2014-11-11 12:09:09 -08:00
exportingWindow . Closed + = ( sender , e ) = >
{
exportingWindow = null ;
} ;
2014-10-10 14:52:50 -07:00
exportingWindow . ShowAsSystemWindow ( ) ;
}
else
{
2014-11-11 12:09:09 -08:00
exportingWindow . BringToFront ( ) ;
2014-10-10 14:52:50 -07:00
}
}
2014-08-19 11:41:13 -07:00
public void ThemeChanged ( object sender , EventArgs e )
2014-08-08 10:25:44 -07:00
{
2014-08-19 11:41:13 -07:00
processingProgressControl . fillColor = ActiveTheme . Instance . PrimaryAccentColor ;
2014-11-01 14:33:59 -07:00
MeshViewerWidget . SetMaterialColor ( 1 , ActiveTheme . Instance . PrimaryAccentColor ) ;
2014-05-27 09:16:35 -07:00
}
2014-10-12 20:40:38 -07:00
2014-05-27 09:16:35 -07:00
void SetEditControlsBasedOnPrinterState ( object sender , EventArgs e )
{
2014-12-16 11:59:20 -08:00
if ( windowType = = WindowMode . Embeded )
2014-07-02 13:28:51 -07:00
{
switch ( PrinterConnectionAndCommunication . Instance . CommunicationState )
{
case PrinterConnectionAndCommunication . CommunicationStates . Printing :
case PrinterConnectionAndCommunication . CommunicationStates . Paused :
LockEditControls ( ) ;
break ;
default :
UnlockEditControls ( ) ;
break ;
}
}
2014-03-20 18:20:52 -07:00
}
2014-03-20 18:41:22 -07:00
bool hasDrawn = false ;
2014-03-20 18:20:52 -07:00
Stopwatch timeSinceLastSpin = new Stopwatch ( ) ;
void AutoSpin ( object state )
{
2014-11-11 17:15:35 -08:00
if ( ! WidgetHasBeenClosed & & autoRotating )
2014-03-20 18:20:52 -07:00
{
// add it back in to keep it running.
2014-12-18 18:18:11 -08:00
UiThread . RunOnIdle ( AutoSpin , . 04 ) ;
2014-03-20 18:20:52 -07:00
2014-03-20 18:41:22 -07:00
if ( ( ! timeSinceLastSpin . IsRunning | | timeSinceLastSpin . ElapsedMilliseconds > 50 )
& & hasDrawn )
2014-03-20 18:20:52 -07:00
{
2014-03-20 18:41:22 -07:00
hasDrawn = false ;
2014-03-20 18:20:52 -07:00
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 ( ) ;
}
}
2014-01-29 19:09:30 -08:00
}
private void LoadAndAddPartsToPlate ( string [ ] filesToLoad )
{
2014-10-07 18:00:17 -07:00
if ( MeshGroups . Count > 0 & & filesToLoad ! = null & & filesToLoad . Length > 0 )
2014-01-29 19:09:30 -08:00
{
2014-11-06 11:57:32 -08:00
string loadingPartLabel = "Loading Parts" . Localize ( ) ;
2014-10-12 20:40:38 -07:00
string loadingPartLabelFull = "{0}:" . FormatWith ( loadingPartLabel ) ;
2014-11-04 10:27:59 -08:00
processingProgressControl . ProcessType = loadingPartLabelFull ;
2014-01-29 19:09:30 -08:00
processingProgressControl . Visible = true ;
processingProgressControl . PercentComplete = 0 ;
LockEditControls ( ) ;
2014-10-16 17:52:21 -07:00
PushMeshGroupDataToAsynchLists ( TraceInfoOpperation . DO_COPY ) ;
2014-01-29 19:09:30 -08:00
BackgroundWorker loadAndAddPartsToPlateBackgroundWorker = null ;
loadAndAddPartsToPlateBackgroundWorker = new BackgroundWorker ( ) ;
loadAndAddPartsToPlateBackgroundWorker . DoWork + = new DoWorkEventHandler ( loadAndAddPartsToPlateBackgroundWorker_DoWork ) ;
loadAndAddPartsToPlateBackgroundWorker . RunWorkerCompleted + = new RunWorkerCompletedEventHandler ( loadAndAddPartsToPlateBackgroundWorker_RunWorkerCompleted ) ;
loadAndAddPartsToPlateBackgroundWorker . RunWorkerAsync ( filesToLoad ) ;
}
}
2014-10-16 17:52:21 -07:00
enum TraceInfoOpperation { DONT_COPY , DO_COPY } ;
2014-11-04 10:27:59 -08:00
private void PushMeshGroupDataToAsynchLists ( TraceInfoOpperation traceInfoOpperation , ReportProgressRatio reportProgress = null )
2014-01-29 19:09:30 -08:00
{
2014-11-04 10:27:59 -08:00
UiThread . RunOnIdle ( ( state ) = >
{
processingProgressControl . ProgressMessage = "Async Copy" ;
} ) ;
2014-10-15 14:11:14 -07:00
asynchMeshGroups . Clear ( ) ;
2014-10-07 18:00:17 -07:00
asynchMeshGroupTransforms . Clear ( ) ;
for ( int meshGroupIndex = 0 ; meshGroupIndex < MeshGroups . Count ; meshGroupIndex + + )
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
MeshGroup meshGroup = MeshGroups [ meshGroupIndex ] ;
MeshGroup newMeshGroup = new MeshGroup ( ) ;
for ( int meshIndex = 0 ; meshIndex < meshGroup . Meshes . Count ; meshIndex + + )
{
2014-10-08 16:34:25 -07:00
Mesh mesh = meshGroup . Meshes [ meshIndex ] ;
2014-10-07 18:00:17 -07:00
newMeshGroup . Meshes . Add ( Mesh . Copy ( mesh ) ) ;
}
2014-10-15 14:11:14 -07:00
asynchMeshGroups . Add ( newMeshGroup ) ;
2014-10-28 12:07:51 -07:00
asynchMeshGroupTransforms . Add ( MeshGroupTransforms [ meshGroupIndex ] ) ;
2014-01-29 19:09:30 -08:00
}
2014-10-15 14:11:14 -07:00
asynchPlatingDatas . Clear ( ) ;
2014-10-09 14:10:17 -07:00
2014-10-07 18:00:17 -07:00
for ( int meshGroupIndex = 0 ; meshGroupIndex < MeshGroupExtraData . Count ; meshGroupIndex + + )
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
PlatingMeshGroupData meshData = new PlatingMeshGroupData ( ) ;
meshData . currentScale = MeshGroupExtraData [ meshGroupIndex ] . currentScale ;
MeshGroup meshGroup = MeshGroups [ meshGroupIndex ] ;
for ( int meshIndex = 0 ; meshIndex < meshGroup . Meshes . Count ; meshIndex + + )
2014-01-29 19:09:30 -08:00
{
2014-10-16 17:52:21 -07:00
if ( traceInfoOpperation = = TraceInfoOpperation . DO_COPY )
2014-10-07 18:00:17 -07:00
{
meshData . meshTraceableData . AddRange ( MeshGroupExtraData [ meshGroupIndex ] . meshTraceableData ) ;
}
2014-01-29 19:09:30 -08:00
}
2014-10-15 14:11:14 -07:00
asynchPlatingDatas . Add ( meshData ) ;
2014-01-29 19:09:30 -08:00
}
2014-11-04 10:27:59 -08:00
UiThread . RunOnIdle ( ( state ) = >
{
processingProgressControl . ProgressMessage = "" ;
} ) ;
2014-01-29 19:09:30 -08:00
}
2014-10-07 18:00:17 -07:00
private void PullMeshGroupDataFromAsynchLists ( )
2014-01-29 19:09:30 -08:00
{
2014-10-15 14:11:14 -07:00
if ( MeshGroups . Count ! = asynchMeshGroups . Count )
{
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-10-15 14:11:14 -07:00
}
2014-10-07 18:00:17 -07:00
MeshGroups . Clear ( ) ;
2014-10-15 14:11:14 -07:00
foreach ( MeshGroup meshGroup in asynchMeshGroups )
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
MeshGroups . Add ( meshGroup ) ;
2014-01-29 19:09:30 -08:00
}
2014-10-07 18:00:17 -07:00
MeshGroupTransforms . Clear ( ) ;
foreach ( ScaleRotateTranslate transform in asynchMeshGroupTransforms )
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
MeshGroupTransforms . Add ( transform ) ;
2014-01-29 19:09:30 -08:00
}
2014-10-07 18:00:17 -07:00
MeshGroupExtraData . Clear ( ) ;
2014-10-15 14:11:14 -07:00
foreach ( PlatingMeshGroupData meshData in asynchPlatingDatas )
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
MeshGroupExtraData . Add ( meshData ) ;
2014-01-29 19:09:30 -08:00
}
2014-10-28 12:07:51 -07:00
if ( MeshGroups . Count ! = MeshGroupTransforms . Count
| | MeshGroups . Count ! = MeshGroupExtraData . Count )
{
throw new Exception ( "These all need to remain in sync." ) ;
}
2014-01-29 19:09:30 -08:00
}
void loadAndAddPartsToPlateBackgroundWorker_DoWork ( object sender , DoWorkEventArgs e )
{
Thread . CurrentThread . CurrentCulture = CultureInfo . InvariantCulture ;
BackgroundWorker backgroundWorker = ( BackgroundWorker ) sender ;
string [ ] filesToLoad = e . Argument as string [ ] ;
if ( filesToLoad ! = null & & filesToLoad . Length > 0 )
{
2014-10-24 17:27:38 -07:00
double ratioPerFile = 1.0 / filesToLoad . Length ;
double currentRatioDone = 0 ;
2014-01-29 19:09:30 -08:00
for ( int i = 0 ; i < filesToLoad . Length ; i + + )
{
string loadedFileName = filesToLoad [ i ] ;
2014-10-26 18:08:03 -07:00
List < MeshGroup > loadedMeshGroups = MeshFileIo . Load ( Path . GetFullPath ( loadedFileName ) , ( double progress0To1 , string processingState , out bool continueProcessing ) = >
2014-10-24 17:27:38 -07:00
{
2014-10-26 18:08:03 -07:00
continueProcessing = ! this . WidgetHasBeenClosed ;
2014-10-24 17:27:38 -07:00
double ratioAvailable = ( ratioPerFile * . 5 ) ;
double currentRatio = currentRatioDone + progress0To1 * ratioAvailable ;
2014-11-04 10:27:59 -08:00
BackgroundWorker_ProgressChanged ( currentRatio , processingState , out continueProcessing ) ;
2014-10-24 17:27:38 -07:00
} ) ;
2014-10-03 18:01:00 -07:00
2014-09-26 15:04:04 -07:00
if ( WidgetHasBeenClosed )
{
return ;
}
2014-10-09 14:10:17 -07:00
if ( loadedMeshGroups ! = null )
2014-01-29 19:09:30 -08:00
{
2014-10-24 17:27:38 -07:00
double ratioPerSubMesh = 1.0 / loadedMeshGroups . Count ;
double currentPlatingRatioDone = 0 ;
2014-01-29 19:09:30 -08:00
2014-10-12 20:40:38 -07:00
for ( int subMeshIndex = 0 ; subMeshIndex < loadedMeshGroups . Count ; subMeshIndex + + )
2014-01-29 19:09:30 -08:00
{
2014-10-09 14:10:17 -07:00
MeshGroup meshGroup = loadedMeshGroups [ subMeshIndex ] ;
2014-08-14 09:58:17 -07:00
2014-10-15 14:11:14 -07:00
PlatingHelper . FindPositionForGroupAndAddToPlate ( meshGroup , ScaleRotateTranslate . Identity ( ) , asynchPlatingDatas , asynchMeshGroups , asynchMeshGroupTransforms ) ;
2014-09-26 15:04:04 -07:00
if ( WidgetHasBeenClosed )
{
return ;
}
2014-10-26 18:08:03 -07:00
PlatingHelper . CreateITraceableForMeshGroup ( asynchPlatingDatas , asynchMeshGroups , asynchMeshGroups . Count - 1 , ( double progress0To1 , string processingState , out bool continueProcessing ) = >
2014-10-24 17:27:38 -07:00
{
2014-10-26 18:08:03 -07:00
continueProcessing = ! this . WidgetHasBeenClosed ;
2014-10-24 17:27:38 -07:00
double ratioAvailable = ( ratioPerFile * . 5 ) ;
double currentRatio = currentRatioDone + currentPlatingRatioDone + ratioAvailable + progress0To1 * ratioAvailable ;
2014-11-04 10:27:59 -08:00
BackgroundWorker_ProgressChanged ( currentRatio , processingState , out continueProcessing ) ;
2014-10-24 17:27:38 -07:00
} ) ;
2014-01-29 19:09:30 -08:00
2014-10-24 17:27:38 -07:00
currentPlatingRatioDone + = ratioPerSubMesh ;
2014-01-29 19:09:30 -08:00
}
}
}
2014-10-24 17:27:38 -07:00
currentRatioDone + = ratioPerFile ;
2014-01-29 19:09:30 -08:00
}
}
2014-10-26 18:08:03 -07:00
void loadAndAddPartsToPlateBackgroundWorker_RunWorkerCompleted ( object sender , RunWorkerCompletedEventArgs e )
{
if ( WidgetHasBeenClosed )
{
return ;
}
UnlockEditControls ( ) ;
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-10-26 18:08:03 -07:00
2015-01-09 12:20:29 -08:00
bool addingOnlyOneItem = asynchMeshGroups . Count = = MeshGroups . Count + 1 ;
2014-10-26 18:08:03 -07:00
if ( MeshGroups . Count > 0 )
{
PullMeshGroupDataFromAsynchLists ( ) ;
2015-01-09 12:20:29 -08:00
if ( addingOnlyOneItem )
{
// if we are only adding one part to the plate set the selection to it
SelectedMeshGroupIndex = asynchMeshGroups . Count - 1 ;
}
2014-10-26 18:08:03 -07:00
}
}
2014-01-29 19:09:30 -08:00
void meshViewerWidget_LoadDone ( object sender , EventArgs e )
{
2014-12-16 11:59:20 -08:00
if ( windowType = = WindowMode . Embeded )
2014-05-27 09:16:35 -07:00
{
2014-08-14 18:08:51 -07:00
switch ( PrinterConnectionAndCommunication . Instance . CommunicationState )
{
case PrinterConnectionAndCommunication . CommunicationStates . Printing :
case PrinterConnectionAndCommunication . CommunicationStates . Paused :
break ;
2014-05-27 09:16:35 -07:00
2014-08-14 18:08:51 -07:00
default :
UnlockEditControls ( ) ;
break ;
}
}
else
{
UnlockEditControls ( ) ;
2014-05-27 09:16:35 -07:00
}
2014-10-18 13:23:53 -07:00
SelectionChanged ( this , null ) ;
2015-01-08 11:55:50 -08:00
if ( openMode = = OpenMode . Editing )
{
UiThread . RunOnIdle ( ( state ) = >
{
EnterEditAndCreateSelectionData ( ) ;
} ) ;
}
2014-01-29 19:09:30 -08:00
}
2014-07-26 13:43:55 -07:00
bool viewIsInEditModePreLock = false ;
2014-10-24 13:41:13 -07:00
bool wasInSelectMode = false ;
2014-01-29 19:09:30 -08:00
void LockEditControls ( )
{
2014-07-26 13:43:55 -07:00
viewIsInEditModePreLock = doEdittingButtonsContainer . Visible ;
2014-05-27 09:16:35 -07:00
enterEditButtonsContainer . Visible = false ;
2014-03-07 09:50:41 -08:00
doEdittingButtonsContainer . Visible = false ;
2014-01-29 19:09:30 -08:00
buttonRightPanelDisabledCover . Visible = true ;
2014-10-24 13:41:13 -07:00
if ( viewControls3D . PartSelectVisible = = true )
{
viewControls3D . PartSelectVisible = false ;
2014-10-24 13:53:00 -07:00
if ( viewControls3D . partSelectButton . Checked )
{
wasInSelectMode = true ;
viewControls3D . rotateButton . ClickButton ( null ) ;
viewControls3D . scaleButton . Click + = StopReturnToSelectionButton ;
viewControls3D . translateButton . Click + = StopReturnToSelectionButton ;
}
2014-10-24 13:41:13 -07:00
}
}
void StopReturnToSelectionButton ( object sender , EventArgs e )
{
wasInSelectMode = false ;
RadioButton button = sender as RadioButton ;
button . Click - = StopReturnToSelectionButton ;
2014-01-29 19:09:30 -08:00
}
void UnlockEditControls ( )
{
buttonRightPanelDisabledCover . Visible = false ;
processingProgressControl . Visible = false ;
2014-07-26 13:43:55 -07:00
if ( viewIsInEditModePreLock )
2014-05-27 09:16:35 -07:00
{
if ( ! enterEditButtonsContainer . Visible )
{
2014-05-27 09:46:10 -07:00
viewControls3D . PartSelectVisible = true ;
doEdittingButtonsContainer . Visible = true ;
2014-05-27 09:16:35 -07:00
}
}
else
2014-01-29 19:09:30 -08:00
{
2014-05-27 09:16:35 -07:00
enterEditButtonsContainer . Visible = true ;
2014-01-29 19:09:30 -08:00
}
2014-05-06 11:22:48 -07:00
2014-10-24 13:41:13 -07:00
if ( wasInSelectMode )
{
viewControls3D . partSelectButton . ClickButton ( null ) ;
wasInSelectMode = false ;
}
viewControls3D . scaleButton . Click - = StopReturnToSelectionButton ;
viewControls3D . translateButton . Click - = StopReturnToSelectionButton ;
2014-05-06 11:22:48 -07:00
UpdateSizeInfo ( ) ;
2014-01-29 19:09:30 -08:00
}
private void DeleteSelectedMesh ( )
{
2014-10-05 18:12:37 -07:00
// don't ever delete the last mesh
2014-12-16 17:16:05 -08:00
if ( SelectedMeshGroupIndex ! = - 1
& & MeshGroups . Count > 1 )
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
MeshGroups . RemoveAt ( SelectedMeshGroupIndex ) ;
MeshGroupExtraData . RemoveAt ( SelectedMeshGroupIndex ) ;
MeshGroupTransforms . RemoveAt ( SelectedMeshGroupIndex ) ;
SelectedMeshGroupIndex = Math . Min ( SelectedMeshGroupIndex , MeshGroups . Count - 1 ) ;
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-01-29 19:09:30 -08:00
Invalidate ( ) ;
}
}
2014-11-04 10:27:59 -08:00
Stopwatch timeSinceReported = new Stopwatch ( ) ;
void BackgroundWorker_ProgressChanged ( double progress0To1 , string processingState , out bool continueProcessing )
2014-01-29 19:09:30 -08:00
{
2014-11-04 12:19:35 -08:00
if ( ! timeSinceReported . IsRunning | | timeSinceReported . ElapsedMilliseconds > 100
| | processingState ! = processingProgressControl . ProgressMessage )
2014-11-04 10:27:59 -08:00
{
UiThread . RunOnIdle ( ( state ) = >
{
processingProgressControl . PercentComplete = ( int ) ( progress0To1 * 100 + . 5 ) ;
processingProgressControl . ProgressMessage = processingState ;
} ) ;
timeSinceReported . Restart ( ) ;
}
continueProcessing = true ;
2014-01-29 19:09:30 -08:00
}
private void CreateOptionsContent ( )
{
AddRotateControls ( rotateOptionContainer ) ;
AddScaleControls ( scaleOptionContainer ) ;
}
2014-04-27 17:19:06 -07:00
private FlowLayoutWidget CreateRightButtonPanel ( double buildHeight )
2014-01-29 19:09:30 -08:00
{
FlowLayoutWidget buttonRightPanel = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
buttonRightPanel . Width = 200 ;
{
BorderDouble buttonMargin = new BorderDouble ( top : 3 ) ;
2014-04-08 20:57:00 -07:00
expandRotateOptions = expandMenuOptionFactory . GenerateCheckBoxButton ( LocalizedString . Get ( "Rotate" ) , "icon_arrow_right_no_border_32x32.png" , "icon_arrow_down_no_border_32x32.png" ) ;
2014-01-29 19:09:30 -08:00
expandRotateOptions . Margin = new BorderDouble ( bottom : 2 ) ;
buttonRightPanel . AddChild ( expandRotateOptions ) ;
rotateOptionContainer = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
rotateOptionContainer . HAnchor = HAnchor . ParentLeftRight ;
rotateOptionContainer . Visible = false ;
buttonRightPanel . AddChild ( rotateOptionContainer ) ;
2014-04-08 20:57:00 -07:00
expandScaleOptions = expandMenuOptionFactory . GenerateCheckBoxButton ( LocalizedString . Get ( "Scale" ) , "icon_arrow_right_no_border_32x32.png" , "icon_arrow_down_no_border_32x32.png" ) ;
2014-01-29 19:09:30 -08:00
expandScaleOptions . Margin = new BorderDouble ( bottom : 2 ) ;
buttonRightPanel . AddChild ( expandScaleOptions ) ;
scaleOptionContainer = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
scaleOptionContainer . HAnchor = HAnchor . ParentLeftRight ;
scaleOptionContainer . Visible = false ;
buttonRightPanel . AddChild ( scaleOptionContainer ) ;
// put in the mirror options
{
2014-09-24 11:15:38 -07:00
expandMirrorOptions = expandMenuOptionFactory . GenerateCheckBoxButton ( LocalizedString . Get ( "Mirror" ) , "icon_arrow_right_no_border_32x32.png" , "icon_arrow_down_no_border_32x32.png" ) ;
2014-01-29 19:09:30 -08:00
expandMirrorOptions . Margin = new BorderDouble ( bottom : 2 ) ;
buttonRightPanel . AddChild ( expandMirrorOptions ) ;
2014-09-24 11:15:38 -07:00
mirrorOptionContainer = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
2014-01-29 19:09:30 -08:00
mirrorOptionContainer . HAnchor = HAnchor . ParentLeftRight ;
mirrorOptionContainer . Visible = false ;
buttonRightPanel . AddChild ( mirrorOptionContainer ) ;
AddMirrorControls ( mirrorOptionContainer ) ;
}
2014-09-26 15:04:04 -07:00
// put in the material options
2014-10-13 18:20:01 -07:00
int numberOfExtruders = ActiveSliceSettings . Instance . ExtruderCount ;
2014-10-13 19:29:25 -07:00
expandMaterialOptions = expandMenuOptionFactory . GenerateCheckBoxButton ( LocalizedString . Get ( "Material" ) , "icon_arrow_right_no_border_32x32.png" , "icon_arrow_down_no_border_32x32.png" ) ;
expandMaterialOptions . Margin = new BorderDouble ( bottom : 2 ) ;
2014-10-13 18:20:01 -07:00
if ( numberOfExtruders > 1 )
2014-09-26 15:04:04 -07:00
{
buttonRightPanel . AddChild ( expandMaterialOptions ) ;
materialOptionContainer = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
materialOptionContainer . HAnchor = HAnchor . ParentLeftRight ;
materialOptionContainer . Visible = false ;
2014-10-13 19:29:25 -07:00
buttonRightPanel . AddChild ( materialOptionContainer ) ;
2014-09-26 15:04:04 -07:00
AddMaterialControls ( materialOptionContainer ) ;
}
2014-01-29 19:09:30 -08:00
// put in the view options
{
2014-04-08 20:57:00 -07:00
expandViewOptions = expandMenuOptionFactory . GenerateCheckBoxButton ( LocalizedString . Get ( "Display" ) , "icon_arrow_right_no_border_32x32.png" , "icon_arrow_down_no_border_32x32.png" ) ;
2014-01-29 19:09:30 -08:00
expandViewOptions . Margin = new BorderDouble ( bottom : 2 ) ;
buttonRightPanel . AddChild ( expandViewOptions ) ;
viewOptionContainer = new FlowLayoutWidget ( FlowDirection . TopToBottom ) ;
viewOptionContainer . HAnchor = HAnchor . ParentLeftRight ;
2014-09-24 11:15:38 -07:00
viewOptionContainer . Padding = new BorderDouble ( left : 4 ) ;
2014-01-29 19:09:30 -08:00
viewOptionContainer . Visible = false ;
{
2014-03-31 17:08:27 -07:00
CheckBox showBedCheckBox = new CheckBox ( LocalizedString . Get ( "Show Print Bed" ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2014-01-29 19:09:30 -08:00
showBedCheckBox . Checked = true ;
2014-03-31 17:08:27 -07:00
showBedCheckBox . CheckedStateChanged + = ( sender , e ) = >
{
meshViewerWidget . RenderBed = showBedCheckBox . Checked ;
} ;
2014-01-29 19:09:30 -08:00
viewOptionContainer . AddChild ( showBedCheckBox ) ;
2014-04-08 20:57:00 -07:00
2014-01-29 19:09:30 -08:00
if ( buildHeight > 0 )
{
2014-03-31 17:08:27 -07:00
CheckBox showBuildVolumeCheckBox = new CheckBox ( LocalizedString . Get ( "Show Print Area" ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2014-01-29 19:09:30 -08:00
showBuildVolumeCheckBox . Checked = false ;
2014-08-27 14:15:41 -07:00
showBuildVolumeCheckBox . Margin = new BorderDouble ( bottom : 5 ) ;
2014-03-31 17:08:27 -07:00
showBuildVolumeCheckBox . CheckedStateChanged + = ( sender , e ) = >
{
meshViewerWidget . RenderBuildVolume = showBuildVolumeCheckBox . Checked ;
} ;
2014-01-29 19:09:30 -08:00
viewOptionContainer . AddChild ( showBuildVolumeCheckBox ) ;
}
2014-12-29 11:45:26 -08:00
#if __ANDROID__
UserSettings . Instance . set ( "defaultRenderSetting" , RenderTypes . Shaded . ToString ( ) ) ;
#else
2014-08-18 11:02:00 -07:00
CreateRenderTypeRadioButtons ( viewOptionContainer ) ;
2014-12-29 11:45:26 -08:00
#endif
2014-01-29 19:09:30 -08:00
}
buttonRightPanel . AddChild ( viewOptionContainer ) ;
}
2014-04-08 20:57:00 -07:00
autoArrangeButton = whiteButtonFactory . Generate ( LocalizedString . Get ( "Auto-Arrange" ) , centerText : true ) ;
2014-01-29 19:09:30 -08:00
autoArrangeButton . Cursor = Cursors . Hand ;
buttonRightPanel . AddChild ( autoArrangeButton ) ;
2014-10-15 10:50:22 -07:00
autoArrangeButton . Visible = false ;
autoArrangeButton . Click + = ( sender , e ) = >
{
2014-10-17 19:17:10 -07:00
AutoArrangePartsInBackground ( ) ;
2014-10-15 10:50:22 -07:00
} ;
2014-01-29 19:09:30 -08:00
GuiWidget verticalSpacer = new GuiWidget ( ) ;
verticalSpacer . VAnchor = VAnchor . ParentBottomTop ;
buttonRightPanel . AddChild ( verticalSpacer ) ;
}
buttonRightPanel . Padding = new BorderDouble ( 6 , 6 ) ;
buttonRightPanel . Margin = new BorderDouble ( 0 , 1 ) ;
buttonRightPanel . BackgroundColor = ActiveTheme . Instance . PrimaryBackgroundColor ;
buttonRightPanel . VAnchor = VAnchor . ParentBottomTop ;
return buttonRightPanel ;
}
2014-12-12 12:57:44 -08:00
private void AddSaveAndSaveAs ( FlowLayoutWidget flowToAddTo )
{
TupleList < string , Func < bool > > buttonList = new TupleList < string , Func < bool > > ( ) ;
buttonList . Add ( "Save" , ( ) = >
{
MergeAndSavePartsToCurrentMeshFile ( ) ;
return true ;
} ) ;
buttonList . Add ( "Save As" , ( ) = >
{
if ( saveAsWindow = = null )
{
saveAsWindow = new SaveAsWindow ( MergeAndSavePartsToNewMeshFile ) ;
saveAsWindow . Closed + = ( sender2 , e2 ) = >
{
saveAsWindow = null ;
} ;
}
else
{
saveAsWindow . BringToFront ( ) ;
}
return true ;
} ) ;
SplitButtonFactory splitButtonFactory = new SplitButtonFactory ( ) ;
splitButtonFactory . FixedHeight = 40 ;
2014-12-20 09:07:13 -08:00
saveButtons = splitButtonFactory . Generate ( buttonList , Direction . Up , imageName : "icon_save_32x32.png" ) ;
2014-12-12 12:57:44 -08:00
saveButtons . Visible = false ;
saveButtons . Margin = new BorderDouble ( ) ;
saveButtons . VAnchor | = VAnchor . ParentCenter ;
flowToAddTo . AddChild ( saveButtons ) ;
}
2014-11-17 15:50:39 -08:00
2014-12-12 12:57:44 -08:00
public void PartHasBeenChanged ( )
{
saveButtons . Visible = true ;
}
2014-11-17 15:50:39 -08:00
2014-04-08 20:57:00 -07:00
private FlowLayoutWidget CreateSaveButtons ( )
{
2014-04-09 12:33:43 -07:00
FlowLayoutWidget saveButtons = new FlowLayoutWidget ( ) ;
//Create Save Button
2014-11-06 11:57:32 -08:00
double oldWidth = whiteButtonFactory . FixedWidth ;
whiteButtonFactory . FixedWidth = 56 ;
Button saveButton = whiteButtonFactory . Generate ( "Save" . Localize ( ) , centerText : true ) ;
2014-04-09 12:33:43 -07:00
saveButton . Cursor = Cursors . Hand ;
saveButtons . AddChild ( saveButton ) ;
saveButton . Click + = ( sender , e ) = >
{
2014-11-11 12:09:09 -08:00
MergeAndSavePartsToCurrentMeshFile ( ) ;
2014-04-09 12:33:43 -07:00
} ;
2014-04-08 20:57:00 -07:00
//Create Save As Button
2014-11-06 11:57:32 -08:00
whiteButtonFactory . FixedWidth = SideBarButtonWidth - whiteButtonFactory . FixedWidth - 2 ;
Button saveAsButton = whiteButtonFactory . Generate ( "Save As" . Localize ( ) , centerText : true ) ;
whiteButtonFactory . FixedWidth = oldWidth ;
2014-04-08 20:57:00 -07:00
saveAsButton . Cursor = Cursors . Hand ;
saveButtons . AddChild ( saveAsButton ) ;
saveAsButton . Click + = ( sender , e ) = >
{
2014-11-11 12:09:09 -08:00
if ( saveAsWindow = = null )
2014-10-12 20:40:38 -07:00
{
2014-11-11 12:09:09 -08:00
saveAsWindow = new SaveAsWindow ( MergeAndSavePartsToNewMeshFile ) ;
saveAsWindow . Closed + = ( sender2 , e2 ) = >
{
saveAsWindow = null ;
} ;
2014-10-12 20:40:38 -07:00
}
else
{
2014-11-11 12:09:09 -08:00
saveAsWindow . BringToFront ( ) ;
2014-10-12 20:40:38 -07:00
}
2014-04-08 20:57:00 -07:00
} ;
saveButtons . Visible = false ;
return saveButtons ;
}
2014-01-29 19:09:30 -08:00
private void AddScaleControls ( FlowLayoutWidget buttonPanel )
{
List < GuiWidget > scaleControls = new List < GuiWidget > ( ) ;
transformControls . Add ( "Scale" , scaleControls ) ;
2014-05-06 11:22:48 -07:00
// Put in the scale ratio edit field
2014-01-29 19:09:30 -08:00
{
2014-05-06 11:22:48 -07:00
FlowLayoutWidget scaleRatioContainer = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
scaleRatioContainer . HAnchor = HAnchor . ParentLeftRight ;
scaleRatioContainer . Padding = new BorderDouble ( 5 ) ;
2014-11-06 11:57:32 -08:00
string scaleRatioLabelText = "Ratio" . Localize ( ) ;
2014-05-06 11:22:48 -07:00
string scaleRatioLabelTextFull = "{0}:" . FormatWith ( scaleRatioLabelText ) ;
TextWidget scaleRatioLabel = new TextWidget ( scaleRatioLabelTextFull , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2014-05-08 11:30:56 -07:00
scaleRatioLabel . Margin = new BorderDouble ( 0 , 0 , 3 , 0 ) ;
2014-05-06 11:22:48 -07:00
scaleRatioLabel . VAnchor = VAnchor . ParentCenter ;
scaleRatioContainer . AddChild ( scaleRatioLabel ) ;
2014-10-18 10:26:36 -07:00
scaleRatioContainer . AddChild ( new HorizontalSpacer ( ) ) ;
2014-05-06 11:22:48 -07:00
scaleRatioControl = new MHNumberEdit ( 1 , pixelWidth : 50 , allowDecimals : true , increment : . 05 ) ;
2015-01-06 16:03:12 -08:00
scaleRatioControl . SelectAllOnFocus = true ;
2014-05-08 11:30:56 -07:00
scaleRatioControl . VAnchor = VAnchor . ParentCenter ;
2014-05-06 11:22:48 -07:00
scaleRatioContainer . AddChild ( scaleRatioControl ) ;
scaleRatioControl . ActuallNumberEdit . KeyPressed + = ( sender , e ) = >
2014-01-29 19:09:30 -08:00
{
2014-10-13 18:20:01 -07:00
SetApplyScaleVisability ( this , null ) ;
2014-05-06 11:22:48 -07:00
} ;
scaleRatioControl . ActuallNumberEdit . KeyDown + = ( sender , e ) = >
2014-01-29 19:09:30 -08:00
{
2014-10-13 18:20:01 -07:00
SetApplyScaleVisability ( this , null ) ;
2014-05-06 11:22:48 -07:00
} ;
2014-01-29 19:09:30 -08:00
2014-05-06 11:22:48 -07:00
scaleRatioControl . ActuallNumberEdit . EnterPressed + = ( object sender , KeyEventArgs keyEvent ) = >
{
ApplyScaleFromEditField ( ) ;
} ;
2014-01-29 19:09:30 -08:00
2014-05-08 11:30:56 -07:00
scaleRatioContainer . AddChild ( CreateScaleDropDownMenu ( ) ) ;
2014-05-06 11:22:48 -07:00
buttonPanel . AddChild ( scaleRatioContainer ) ;
2014-01-29 19:09:30 -08:00
2014-05-06 11:22:48 -07:00
scaleControls . Add ( scaleRatioControl ) ;
}
2014-03-31 17:08:27 -07:00
2014-11-06 11:57:32 -08:00
applyScaleButton = whiteButtonFactory . Generate ( "Apply Scale" . Localize ( ) , centerText : true ) ;
2014-03-31 17:08:27 -07:00
applyScaleButton . Visible = false ;
applyScaleButton . Cursor = Cursors . Hand ;
buttonPanel . AddChild ( applyScaleButton ) ;
scaleControls . Add ( applyScaleButton ) ;
2014-10-24 13:41:13 -07:00
applyScaleButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2014-03-31 17:08:27 -07:00
{
ApplyScaleFromEditField ( ) ;
} ;
2014-05-06 11:22:48 -07:00
// add in the dimensions
{
buttonPanel . AddChild ( createAxisScalingControl ( "x" , 0 ) ) ;
buttonPanel . AddChild ( createAxisScalingControl ( "y" , 1 ) ) ;
buttonPanel . AddChild ( createAxisScalingControl ( "z" , 2 ) ) ;
2014-11-06 11:57:32 -08:00
uniformScale = new CheckBox ( "Lock Ratio" . Localize ( ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2014-05-06 11:22:48 -07:00
uniformScale . Checked = true ;
2014-10-12 20:40:38 -07:00
2014-05-07 18:34:27 -07:00
FlowLayoutWidget leftToRight = new FlowLayoutWidget ( ) ;
leftToRight . Padding = new BorderDouble ( 5 , 3 ) ;
leftToRight . AddChild ( uniformScale ) ;
buttonPanel . AddChild ( leftToRight ) ;
2014-05-06 11:22:48 -07:00
}
2014-03-31 17:08:27 -07:00
buttonPanel . AddChild ( generateHorizontalRule ( ) ) ;
}
2014-05-06 11:22:48 -07:00
CheckBox uniformScale ;
EditableNumberDisplay [ ] sizeDisplay = new EditableNumberDisplay [ 3 ] ;
private GuiWidget createAxisScalingControl ( string axis , int axisIndex )
{
FlowLayoutWidget leftToRight = new FlowLayoutWidget ( ) ;
leftToRight . Padding = new BorderDouble ( 5 , 3 ) ;
2014-05-08 08:01:45 -07:00
TextWidget sizeDescription = new TextWidget ( "{0}:" . FormatWith ( axis ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2014-05-06 11:22:48 -07:00
sizeDescription . VAnchor = Agg . UI . VAnchor . ParentCenter ;
leftToRight . AddChild ( sizeDescription ) ;
sizeDisplay [ axisIndex ] = new EditableNumberDisplay ( textImageButtonFactory , "100" , "1000.00" ) ;
sizeDisplay [ axisIndex ] . EditComplete + = ( sender , e ) = >
{
2015-01-06 15:59:41 -08:00
if ( HaveSelection )
{
SetNewModelSize ( sizeDisplay [ axisIndex ] . GetValue ( ) , axisIndex ) ;
sizeDisplay [ axisIndex ] . SetDisplayString ( "{0:0.00}" . FormatWith ( SelectedMeshGroup . GetAxisAlignedBoundingBox ( ) . Size [ axisIndex ] ) ) ;
UpdateSizeInfo ( ) ;
}
else
{
sizeDisplay [ axisIndex ] . SetDisplayString ( "---" ) ;
}
2014-05-06 11:22:48 -07:00
} ;
leftToRight . AddChild ( sizeDisplay [ axisIndex ] ) ;
return leftToRight ;
}
void SetNewModelSize ( double sizeInMm , int axis )
{
2014-11-24 22:24:30 -08:00
if ( HaveSelection )
2014-05-07 18:34:27 -07:00
{
2014-11-24 22:24:30 -08:00
// because we remove any current scale before we change to a new one we only get the size of the base mesh data
AxisAlignedBoundingBox originalMeshBounds = SelectedMeshGroup . GetAxisAlignedBoundingBox ( ) ;
2014-05-07 18:34:27 -07:00
2014-11-24 22:24:30 -08:00
double currentSize = originalMeshBounds . Size [ axis ] ;
double desiredSize = sizeDisplay [ axis ] . GetValue ( ) ;
double scaleFactor = 1 ;
if ( currentSize ! = 0 )
{
scaleFactor = desiredSize / currentSize ;
}
if ( uniformScale . Checked )
{
scaleRatioControl . ActuallNumberEdit . Value = scaleFactor ;
ApplyScaleFromEditField ( ) ;
}
else
{
ScaleAxis ( scaleFactor , axis ) ;
}
2014-05-07 18:34:27 -07:00
}
2014-05-06 11:22:48 -07:00
}
void UpdateSizeInfo ( )
{
2014-10-12 20:40:38 -07:00
if ( sizeDisplay [ 0 ] ! = null
2014-10-07 18:00:17 -07:00
& & SelectedMeshGroup ! = null )
2014-05-06 11:22:48 -07:00
{
2014-10-07 18:00:17 -07:00
AxisAlignedBoundingBox bounds = SelectedMeshGroup . GetAxisAlignedBoundingBox ( SelectedMeshGroupTransform . scale ) ;
2014-05-06 11:22:48 -07:00
sizeDisplay [ 0 ] . SetDisplayString ( "{0:0.00}" . FormatWith ( bounds . Size [ 0 ] ) ) ;
sizeDisplay [ 1 ] . SetDisplayString ( "{0:0.00}" . FormatWith ( bounds . Size [ 1 ] ) ) ;
sizeDisplay [ 2 ] . SetDisplayString ( "{0:0.00}" . FormatWith ( bounds . Size [ 2 ] ) ) ;
}
2014-11-24 22:24:30 -08:00
else
{
sizeDisplay [ 0 ] . SetDisplayString ( "---" ) ;
sizeDisplay [ 1 ] . SetDisplayString ( "---" ) ;
sizeDisplay [ 2 ] . SetDisplayString ( "---" ) ;
}
2014-05-06 11:22:48 -07:00
}
2014-10-13 18:20:01 -07:00
private void SetApplyScaleVisability ( Object sender , EventArgs e )
2014-05-06 11:22:48 -07:00
{
2014-11-23 07:31:02 -08:00
if ( HaveSelection )
2014-05-06 11:22:48 -07:00
{
2014-11-23 07:31:02 -08:00
double scale = scaleRatioControl . ActuallNumberEdit . Value ;
if ( scale ! = MeshGroupExtraData [ SelectedMeshGroupIndex ] . currentScale [ 0 ]
| | scale ! = MeshGroupExtraData [ SelectedMeshGroupIndex ] . currentScale [ 1 ]
| | scale ! = MeshGroupExtraData [ SelectedMeshGroupIndex ] . currentScale [ 2 ] )
{
applyScaleButton . Visible = true ;
}
else
{
applyScaleButton . Visible = false ;
}
2014-05-06 11:22:48 -07:00
}
UpdateSizeInfo ( ) ;
}
2014-03-31 17:08:27 -07:00
private DropDownMenu CreateScaleDropDownMenu ( )
{
2014-05-08 11:30:56 -07:00
DropDownMenu presetScaleMenu = new DropDownMenu ( "" , Direction . Down ) ;
presetScaleMenu . NormalArrowColor = ActiveTheme . Instance . PrimaryTextColor ;
presetScaleMenu . HoverArrowColor = ActiveTheme . Instance . PrimaryTextColor ;
2014-01-29 19:09:30 -08:00
presetScaleMenu . MenuAsWideAsItems = false ;
2014-05-08 11:30:56 -07:00
presetScaleMenu . AlignToRightEdge = true ;
//presetScaleMenu.OpenOffset = new Vector2(-50, 0);
presetScaleMenu . HAnchor = HAnchor . None ;
presetScaleMenu . VAnchor = VAnchor . None ;
presetScaleMenu . Width = 25 ;
presetScaleMenu . Height = scaleRatioControl . Height + 2 ;
presetScaleMenu . AddItem ( "mm to in (.0393)" ) ;
2014-01-29 19:09:30 -08:00
presetScaleMenu . AddItem ( "in to mm (25.4)" ) ;
presetScaleMenu . AddItem ( "mm to cm (.1)" ) ;
presetScaleMenu . AddItem ( "cm to mm (10)" ) ;
2014-11-06 11:57:32 -08:00
string resetLable = "reset" . Localize ( ) ;
2014-03-31 17:08:27 -07:00
string resetLableFull = "{0} (1)" . FormatWith ( resetLable ) ;
presetScaleMenu . AddItem ( resetLableFull ) ;
2014-01-29 19:09:30 -08:00
presetScaleMenu . SelectionChanged + = ( sender , e ) = >
{
double scale = 1 ;
switch ( presetScaleMenu . SelectedIndex )
{
case 0 :
scale = 1.0 / 25.4 ;
break ;
case 1 :
scale = 25.4 ;
break ;
case 2 :
scale = . 1 ;
break ;
case 3 :
scale = 10 ;
break ;
case 4 :
scale = 1 ;
break ;
}
scaleRatioControl . ActuallNumberEdit . Value = scale ;
ApplyScaleFromEditField ( ) ;
} ;
2014-03-31 17:08:27 -07:00
return presetScaleMenu ;
}
2014-01-29 19:09:30 -08:00
2014-08-18 11:02:00 -07:00
private void CreateRenderTypeRadioButtons ( FlowLayoutWidget viewOptionContainer )
2014-03-31 17:08:27 -07:00
{
2014-08-27 14:15:41 -07:00
string renderTypeString = UserSettings . Instance . get ( "defaultRenderSetting" ) ;
if ( renderTypeString = = null )
2014-10-27 19:54:01 -07:00
{
if ( ActiveTheme . Instance . DisplayMode = = ActiveTheme . ApplicationDisplayType . Touchscreen )
{
renderTypeString = "Shaded" ;
}
else
{
renderTypeString = "Outlines" ;
}
UserSettings . Instance . set ( "defaultRenderSetting" , renderTypeString ) ;
2014-08-27 14:15:41 -07:00
}
RenderOpenGl . RenderTypes renderType ;
bool canParse = Enum . TryParse < RenderOpenGl . RenderTypes > ( renderTypeString , out renderType ) ;
if ( canParse )
{
meshViewerWidget . RenderType = renderType ;
}
2014-10-12 20:40:38 -07:00
2014-01-29 19:09:30 -08:00
{
2014-08-18 11:02:00 -07:00
RadioButton renderTypeShaded = new RadioButton ( "Shaded" . Localize ( ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2014-08-27 14:15:41 -07:00
renderTypeShaded . Checked = ( meshViewerWidget . RenderType = = RenderTypes . Shaded ) ;
2014-08-18 11:02:00 -07:00
renderTypeShaded . CheckedStateChanged + = ( sender , e ) = >
2014-10-12 20:40:38 -07:00
{
2014-08-18 11:02:00 -07:00
meshViewerWidget . RenderType = RenderTypes . Shaded ;
2014-08-27 14:15:41 -07:00
UserSettings . Instance . set ( "defaultRenderSetting" , meshViewerWidget . RenderType . ToString ( ) ) ;
2014-08-18 11:02:00 -07:00
} ;
viewOptionContainer . AddChild ( renderTypeShaded ) ;
}
2014-01-29 19:09:30 -08:00
2014-08-18 11:02:00 -07:00
{
RadioButton renderTypeOutlines = new RadioButton ( "Outlines" . Localize ( ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2014-08-27 14:15:41 -07:00
renderTypeOutlines . Checked = ( meshViewerWidget . RenderType = = RenderTypes . Outlines ) ;
2014-08-18 11:02:00 -07:00
renderTypeOutlines . CheckedStateChanged + = ( sender , e ) = >
2014-10-12 20:40:38 -07:00
{
2014-08-18 11:02:00 -07:00
meshViewerWidget . RenderType = RenderTypes . Outlines ;
2014-08-27 14:15:41 -07:00
UserSettings . Instance . set ( "defaultRenderSetting" , meshViewerWidget . RenderType . ToString ( ) ) ;
2014-08-18 11:02:00 -07:00
} ;
viewOptionContainer . AddChild ( renderTypeOutlines ) ;
}
{
RadioButton renderTypePolygons = new RadioButton ( "Polygons" . Localize ( ) , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2014-08-27 14:15:41 -07:00
renderTypePolygons . Checked = ( meshViewerWidget . RenderType = = RenderTypes . Polygons ) ;
2014-08-18 11:02:00 -07:00
renderTypePolygons . CheckedStateChanged + = ( sender , e ) = >
2014-10-12 20:40:38 -07:00
{
2014-08-18 11:02:00 -07:00
meshViewerWidget . RenderType = RenderTypes . Polygons ;
2014-08-27 14:15:41 -07:00
UserSettings . Instance . set ( "defaultRenderSetting" , meshViewerWidget . RenderType . ToString ( ) ) ;
2014-08-18 11:02:00 -07:00
} ;
viewOptionContainer . AddChild ( renderTypePolygons ) ;
}
2014-10-12 20:40:38 -07:00
2014-01-29 19:09:30 -08:00
}
private GuiWidget generateHorizontalRule ( )
{
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 ;
}
private void ApplyScaleFromEditField ( )
{
2014-11-24 22:24:30 -08:00
if ( HaveSelection )
2014-01-29 19:09:30 -08:00
{
2014-11-24 22:24:30 -08:00
double scale = scaleRatioControl . ActuallNumberEdit . Value ;
if ( scale > 0 )
{
ScaleAxis ( scale , 0 ) ;
ScaleAxis ( scale , 1 ) ;
ScaleAxis ( scale , 2 ) ;
}
2014-05-07 18:34:27 -07:00
}
}
2014-01-29 19:09:30 -08:00
2014-05-16 17:13:18 -07:00
public override void OnDragEnter ( FileDropEventArgs fileDropEventArgs )
{
foreach ( string file in fileDropEventArgs . DroppedFiles )
{
string extension = Path . GetExtension ( file ) . ToUpper ( ) ;
2014-10-14 14:38:17 -07:00
if ( MeshFileIo . ValidFileExtensions ( ) . Contains ( extension ) )
2014-05-16 17:13:18 -07:00
{
fileDropEventArgs . AcceptDrop = true ;
}
}
base . OnDragEnter ( fileDropEventArgs ) ;
}
public override void OnDragOver ( FileDropEventArgs fileDropEventArgs )
{
foreach ( string file in fileDropEventArgs . DroppedFiles )
{
string extension = Path . GetExtension ( file ) . ToUpper ( ) ;
2014-10-14 14:38:17 -07:00
if ( MeshFileIo . ValidFileExtensions ( ) . Contains ( extension ) )
2014-05-16 17:13:18 -07:00
{
fileDropEventArgs . AcceptDrop = true ;
}
}
base . OnDragOver ( fileDropEventArgs ) ;
}
public override void OnDragDrop ( FileDropEventArgs fileDropEventArgs )
{
2014-06-10 18:19:17 -07:00
pendingPartsToLoad . Clear ( ) ;
2014-05-16 17:13:18 -07:00
foreach ( string droppedFileName in fileDropEventArgs . DroppedFiles )
{
string extension = Path . GetExtension ( droppedFileName ) . ToUpper ( ) ;
2014-10-14 14:38:17 -07:00
if ( MeshFileIo . ValidFileExtensions ( ) . Contains ( extension ) )
2014-05-16 17:13:18 -07:00
{
2014-06-10 18:19:17 -07:00
pendingPartsToLoad . Add ( droppedFileName ) ;
2014-05-16 17:13:18 -07:00
}
}
2014-06-10 18:19:17 -07:00
bool enterEditModeBeforeAddingParts = enterEditButtonsContainer . Visible = = true ;
if ( enterEditModeBeforeAddingParts )
{
2014-10-09 11:29:33 -07:00
EnterEditAndCreateSelectionData ( ) ;
2014-06-10 18:19:17 -07:00
}
else
{
LoadAndAddPartsToPlate ( pendingPartsToLoad . ToArray ( ) ) ;
}
2014-05-16 17:13:18 -07:00
base . OnDragDrop ( fileDropEventArgs ) ;
}
2014-05-07 18:34:27 -07:00
private void ScaleAxis ( double scaleIn , int axis )
{
2014-10-07 18:00:17 -07:00
AxisAlignedBoundingBox originalMeshBounds = SelectedMeshGroup . GetAxisAlignedBoundingBox ( ) ;
AxisAlignedBoundingBox scaledBounds = SelectedMeshGroup . GetAxisAlignedBoundingBox ( SelectedMeshGroupTransform . scale ) ;
2014-01-29 19:09:30 -08:00
2014-05-07 18:34:27 -07:00
// first we remove any scale we have applied and then scale to the new value
2014-05-16 12:57:49 -07:00
Vector3 axisRemoveScalings = new Vector3 ( ) ;
axisRemoveScalings . x = scaledBounds . Size . x / originalMeshBounds . Size . x ;
axisRemoveScalings . y = scaledBounds . Size . y / originalMeshBounds . Size . y ;
axisRemoveScalings . z = scaledBounds . Size . z / originalMeshBounds . Size . z ;
Matrix4X4 removeScaleMatrix = Matrix4X4 . CreateScale ( 1 / axisRemoveScalings ) ;
2014-10-12 20:40:38 -07:00
2014-10-07 18:00:17 -07:00
Vector3 newScale = MeshGroupExtraData [ SelectedMeshGroupIndex ] . currentScale ;
2014-05-07 18:34:27 -07:00
newScale [ axis ] = scaleIn ;
2014-08-14 09:58:17 -07:00
Matrix4X4 totalScale = removeScaleMatrix * Matrix4X4 . CreateScale ( newScale ) ;
2014-01-29 19:09:30 -08:00
2014-10-07 18:00:17 -07:00
ScaleRotateTranslate scale = SelectedMeshGroupTransform ;
2014-08-14 09:58:17 -07:00
scale . scale * = totalScale ;
2014-10-07 18:00:17 -07:00
SelectedMeshGroupTransform = scale ;
2014-01-29 19:09:30 -08:00
2014-12-05 16:23:24 -08:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-05-07 18:34:27 -07:00
Invalidate ( ) ;
2014-10-07 18:00:17 -07:00
MeshGroupExtraData [ SelectedMeshGroupIndex ] . currentScale [ axis ] = scaleIn ;
2014-10-13 18:20:01 -07:00
SetApplyScaleVisability ( this , null ) ;
2014-01-29 19:09:30 -08:00
}
private void AddRotateControls ( FlowLayoutWidget buttonPanel )
{
List < GuiWidget > rotateControls = new List < GuiWidget > ( ) ;
2014-11-06 11:57:32 -08:00
transformControls . Add ( "Rotate" . Localize ( ) , rotateControls ) ;
2014-01-29 19:09:30 -08:00
2014-12-12 12:57:44 -08:00
textImageButtonFactory . FixedWidth = EditButtonHeight ;
2014-01-29 19:09:30 -08:00
FlowLayoutWidget degreesContainer = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
degreesContainer . HAnchor = HAnchor . ParentLeftRight ;
degreesContainer . Padding = new BorderDouble ( 5 ) ;
2014-11-06 11:57:32 -08:00
string degreesLabelText = "Degrees" . Localize ( ) ;
2014-10-12 20:40:38 -07:00
string degreesLabelTextFull = "{0}:" . FormatWith ( degreesLabelText ) ;
2014-04-15 10:11:56 -07:00
TextWidget degreesLabel = new TextWidget ( degreesLabelText , textColor : ActiveTheme . Instance . PrimaryTextColor ) ;
2014-01-29 19:09:30 -08:00
degreesContainer . AddChild ( degreesLabel ) ;
2014-10-18 10:26:36 -07:00
degreesContainer . AddChild ( new HorizontalSpacer ( ) ) ;
2014-01-29 19:09:30 -08:00
2014-09-26 10:57:11 -07:00
MHNumberEdit degreesControl = new MHNumberEdit ( 45 , pixelWidth : 40 , allowNegatives : true , allowDecimals : true , increment : 5 , minValue : - 360 , maxValue : 360 ) ;
2014-01-29 19:09:30 -08:00
degreesControl . VAnchor = Agg . UI . VAnchor . ParentTop ;
degreesContainer . AddChild ( degreesControl ) ;
rotateControls . Add ( degreesControl ) ;
buttonPanel . AddChild ( degreesContainer ) ;
FlowLayoutWidget rotateButtonContainer = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
rotateButtonContainer . HAnchor = HAnchor . ParentLeftRight ;
Button rotateXButton = textImageButtonFactory . Generate ( "" , "icon_rotate_32x32.png" ) ;
2014-03-21 16:18:47 -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 ) ;
2014-01-29 19:09:30 -08:00
rotateButtonContainer . AddChild ( rotateXButton ) ;
rotateControls . Add ( rotateXButton ) ;
2014-10-24 13:41:13 -07:00
rotateXButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2014-01-29 19:09:30 -08:00
{
2014-11-25 09:58:30 -08:00
if ( SelectedMeshGroupIndex ! = - 1 )
{
double radians = MathHelper . DegreesToRadians ( degreesControl . ActuallNumberEdit . Value ) ;
// rotate it
ScaleRotateTranslate rotated = SelectedMeshGroupTransform ;
rotated . rotation * = Matrix4X4 . CreateRotationX ( radians ) ;
SelectedMeshGroupTransform = rotated ;
2014-12-05 16:23:24 -08:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-11-25 09:58:30 -08:00
Invalidate ( ) ;
}
2014-01-29 19:09:30 -08:00
} ;
Button rotateYButton = textImageButtonFactory . Generate ( "" , "icon_rotate_32x32.png" ) ;
2014-03-21 16:18:47 -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 ) ;
2014-01-29 19:09:30 -08:00
rotateButtonContainer . AddChild ( rotateYButton ) ;
rotateControls . Add ( rotateYButton ) ;
2014-10-24 13:41:13 -07:00
rotateYButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2014-01-29 19:09:30 -08:00
{
2014-11-25 09:58:30 -08:00
if ( SelectedMeshGroupIndex ! = - 1 )
{
double radians = MathHelper . DegreesToRadians ( degreesControl . ActuallNumberEdit . Value ) ;
// rotate it
ScaleRotateTranslate rotated = SelectedMeshGroupTransform ;
rotated . rotation * = Matrix4X4 . CreateRotationY ( radians ) ;
SelectedMeshGroupTransform = rotated ;
2014-12-05 16:23:24 -08:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2014-11-25 09:58:30 -08:00
saveButtons . Visible = true ;
Invalidate ( ) ;
}
2014-01-29 19:09:30 -08:00
} ;
Button rotateZButton = textImageButtonFactory . Generate ( "" , "icon_rotate_32x32.png" ) ;
2014-03-21 16:18:47 -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 ) ;
2014-01-29 19:09:30 -08:00
rotateButtonContainer . AddChild ( rotateZButton ) ;
rotateControls . Add ( rotateZButton ) ;
2014-10-24 13:41:13 -07:00
rotateZButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2014-01-29 19:09:30 -08:00
{
2014-11-25 09:58:30 -08:00
if ( SelectedMeshGroupIndex ! = - 1 )
{
double radians = MathHelper . DegreesToRadians ( degreesControl . ActuallNumberEdit . Value ) ;
// rotate it
ScaleRotateTranslate rotated = SelectedMeshGroupTransform ;
rotated . rotation * = Matrix4X4 . CreateRotationZ ( radians ) ;
SelectedMeshGroupTransform = rotated ;
2014-12-05 16:23:24 -08:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-11-25 09:58:30 -08:00
Invalidate ( ) ;
}
2014-01-29 19:09:30 -08:00
} ;
buttonPanel . AddChild ( rotateButtonContainer ) ;
2014-11-06 11:57:32 -08:00
Button layFlatButton = whiteButtonFactory . Generate ( "Align to Bed" . Localize ( ) , centerText : true ) ;
2014-01-29 19:09:30 -08:00
layFlatButton . Cursor = Cursors . Hand ;
buttonPanel . AddChild ( layFlatButton ) ;
2014-10-24 13:41:13 -07:00
layFlatButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2014-01-29 19:09:30 -08:00
{
2014-11-25 09:58:30 -08:00
if ( SelectedMeshGroupIndex ! = - 1 )
{
MakeLowestFaceFlat ( SelectedMeshGroupIndex ) ;
2014-01-29 19:09:30 -08:00
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-11-25 09:58:30 -08:00
Invalidate ( ) ;
}
2014-01-29 19:09:30 -08:00
} ;
buttonPanel . AddChild ( generateHorizontalRule ( ) ) ;
textImageButtonFactory . FixedWidth = 0 ;
}
private void AddMirrorControls ( FlowLayoutWidget buttonPanel )
{
List < GuiWidget > mirrorControls = new List < GuiWidget > ( ) ;
transformControls . Add ( "Mirror" , mirrorControls ) ;
2014-12-12 12:57:44 -08:00
textImageButtonFactory . FixedWidth = EditButtonHeight ;
2014-01-29 19:09:30 -08:00
FlowLayoutWidget buttonContainer = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
buttonContainer . HAnchor = HAnchor . ParentLeftRight ;
Button mirrorXButton = textImageButtonFactory . Generate ( "X" , centerText : true ) ;
buttonContainer . AddChild ( mirrorXButton ) ;
mirrorControls . Add ( mirrorXButton ) ;
2014-10-24 13:41:13 -07:00
mirrorXButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2014-01-29 19:09:30 -08:00
{
2014-11-25 09:58:30 -08:00
if ( SelectedMeshGroupIndex ! = - 1 )
{
SelectedMeshGroup . ReverseFaceEdges ( ) ;
2014-01-29 19:09:30 -08:00
2014-11-25 09:58:30 -08:00
ScaleRotateTranslate scale = SelectedMeshGroupTransform ;
scale . scale * = Matrix4X4 . CreateScale ( - 1 , 1 , 1 ) ;
SelectedMeshGroupTransform = scale ;
2014-08-14 09:58:17 -07:00
2014-12-05 16:23:24 -08:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2014-01-29 19:09:30 -08:00
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-11-25 09:58:30 -08:00
Invalidate ( ) ;
}
2014-01-29 19:09:30 -08:00
} ;
Button mirrorYButton = textImageButtonFactory . Generate ( "Y" , centerText : true ) ;
buttonContainer . AddChild ( mirrorYButton ) ;
mirrorControls . Add ( mirrorYButton ) ;
2014-10-24 13:41:13 -07:00
mirrorYButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2014-01-29 19:09:30 -08:00
{
2014-11-25 09:58:30 -08:00
if ( SelectedMeshGroupIndex ! = - 1 )
{
SelectedMeshGroup . ReverseFaceEdges ( ) ;
2014-01-29 19:09:30 -08:00
2014-11-25 09:58:30 -08:00
ScaleRotateTranslate scale = SelectedMeshGroupTransform ;
scale . scale * = Matrix4X4 . CreateScale ( 1 , - 1 , 1 ) ;
SelectedMeshGroupTransform = scale ;
2014-08-14 09:58:17 -07:00
2014-12-05 16:23:24 -08:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2014-01-29 19:09:30 -08:00
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-11-25 09:58:30 -08:00
Invalidate ( ) ;
}
2014-01-29 19:09:30 -08:00
} ;
Button mirrorZButton = textImageButtonFactory . Generate ( "Z" , centerText : true ) ;
buttonContainer . AddChild ( mirrorZButton ) ;
mirrorControls . Add ( mirrorZButton ) ;
2014-10-24 13:41:13 -07:00
mirrorZButton . Click + = ( object sender , EventArgs mouseEvent ) = >
2014-01-29 19:09:30 -08:00
{
2014-11-25 09:58:30 -08:00
if ( SelectedMeshGroupIndex ! = - 1 )
{
SelectedMeshGroup . ReverseFaceEdges ( ) ;
2014-01-29 19:09:30 -08:00
2014-11-25 09:58:30 -08:00
ScaleRotateTranslate scale = SelectedMeshGroupTransform ;
scale . scale * = Matrix4X4 . CreateScale ( 1 , 1 , - 1 ) ;
SelectedMeshGroupTransform = scale ;
2014-01-29 19:09:30 -08:00
2014-12-05 16:23:24 -08:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2014-01-29 19:09:30 -08:00
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-11-25 09:58:30 -08:00
Invalidate ( ) ;
}
2014-01-29 19:09:30 -08:00
} ;
buttonPanel . AddChild ( buttonContainer ) ;
buttonPanel . AddChild ( generateHorizontalRule ( ) ) ;
textImageButtonFactory . FixedWidth = 0 ;
}
2014-10-18 13:23:53 -07:00
ObservableCollection < GuiWidget > extruderButtons = new ObservableCollection < GuiWidget > ( ) ;
2014-09-26 15:04:04 -07:00
void AddMaterialControls ( FlowLayoutWidget buttonPanel )
{
2014-10-18 13:23:53 -07:00
extruderButtons . Clear ( ) ;
for ( int extruderIndex = 0 ; extruderIndex < ActiveSliceSettings . Instance . ExtruderCount ; extruderIndex + + )
{
FlowLayoutWidget colorSelectionContainer = new FlowLayoutWidget ( FlowDirection . LeftToRight ) ;
colorSelectionContainer . HAnchor = HAnchor . ParentLeftRight ;
colorSelectionContainer . Padding = new BorderDouble ( 5 ) ;
string colorLabelText = "Extruder {0}" . Localize ( ) . FormatWith ( extruderIndex + 1 ) ;
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 ) = >
2014-10-12 08:18:24 -07:00
{
2014-12-16 15:02:40 -08:00
if ( SelectedMeshGroupIndex ! = - 1 )
2014-10-13 18:20:01 -07:00
{
2014-12-16 15:02:40 -08:00
foreach ( Mesh mesh in SelectedMeshGroup . Meshes )
2014-10-14 11:15:42 -07:00
{
2014-12-16 15:02:40 -08:00
MeshMaterialData material = MeshMaterialData . Get ( mesh ) ;
if ( material . MaterialIndex ! = extruderIndexLocal + 1 )
{
material . MaterialIndex = extruderIndexLocal + 1 ;
PartHasBeenChanged ( ) ;
}
2014-10-14 11:15:42 -07:00
}
2014-10-13 18:20:01 -07:00
}
2014-10-12 08:18:24 -07:00
} ;
2014-10-18 13:23:53 -07:00
this . SelectionChanged + = ( sender , e ) = >
2014-10-12 08:18:24 -07:00
{
2014-10-27 10:33:41 -07:00
if ( SelectedMeshGroup ! = null )
2014-10-13 18:20:01 -07:00
{
2014-10-27 10:33:41 -07:00
Mesh mesh = SelectedMeshGroup . Meshes [ 0 ] ;
MeshMaterialData material = MeshMaterialData . Get ( mesh ) ;
for ( int i = 0 ; i < extruderButtons . Count ; i + + )
2014-10-18 13:23:53 -07:00
{
2014-10-27 10:33:41 -07:00
if ( material . MaterialIndex - 1 = = i )
{
( ( RadioButton ) extruderButtons [ i ] ) . Checked = true ;
}
2014-10-18 13:23:53 -07:00
}
2014-10-13 18:20:01 -07:00
}
2014-10-12 08:18:24 -07:00
} ;
2014-10-13 18:20:01 -07:00
2014-11-01 14:33:59 -07:00
#if false // no color swatch for this build
2014-10-18 13:23:53 -07:00
GuiWidget colorSwatch = new GuiWidget ( 15 , 15 ) ;
colorSwatch . Draw + = ( sender , e ) = >
2014-10-18 10:26:36 -07:00
{
2014-10-18 13:23:53 -07:00
DrawEventArgs drawEvent = e as DrawEventArgs ;
GuiWidget widget = sender as GuiWidget ;
if ( widget ! = null & & drawEvent ! = null & & drawEvent . graphics2D ! = null )
2014-10-13 18:20:01 -07:00
{
2014-10-18 13:23:53 -07:00
drawEvent . graphics2D . Rectangle ( widget . LocalBounds , RGBA_Bytes . Black ) ;
2014-10-13 18:20:01 -07:00
}
2014-10-12 08:18:24 -07:00
} ;
2014-10-29 12:02:35 -07:00
colorSwatch . BackgroundColor = MeshViewerWidget . GetMaterialColor ( extruderIndexLocal + 1 ) ;
2014-10-20 17:02:25 -07:00
Button swatchButton = new Button ( 0 , 0 , colorSwatch ) ;
swatchButton . Click + = ( sender , e ) = >
{
nextColor + + ;
RGBA_Bytes color = SelectionColors [ nextColor % SelectionColors . Length ] ;
2014-10-29 12:02:35 -07:00
MeshViewerWidget . SetMaterialColor ( extruderIndexLocal + 1 , color ) ;
2014-10-20 17:02:25 -07:00
colorSwatch . BackgroundColor = color ;
} ;
colorSelectionContainer . AddChild ( swatchButton ) ;
2014-11-01 14:33:59 -07:00
#endif
2014-09-26 15:04:04 -07:00
2014-10-18 13:23:53 -07:00
buttonPanel . AddChild ( colorSelectionContainer ) ;
2014-10-12 08:18:24 -07:00
}
2014-10-18 10:26:36 -07:00
}
2014-10-20 17:02:25 -07:00
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 ) } ;
2014-01-29 19:09:30 -08:00
private void AddHandlers ( )
{
2014-09-26 15:04:04 -07:00
expandViewOptions . CheckedStateChanged + = expandViewOptions_CheckedStateChanged ;
expandMirrorOptions . CheckedStateChanged + = expandMirrorOptions_CheckedStateChanged ;
2014-10-13 18:20:01 -07:00
if ( expandMaterialOptions ! = null )
{
expandMaterialOptions . CheckedStateChanged + = expandMaterialOptions_CheckedStateChanged ;
}
2014-09-26 15:04:04 -07:00
expandRotateOptions . CheckedStateChanged + = expandRotateOptions_CheckedStateChanged ;
expandScaleOptions . CheckedStateChanged + = expandScaleOptions_CheckedStateChanged ;
2014-10-13 18:20:01 -07:00
SelectionChanged + = SetApplyScaleVisability ;
2014-01-29 19:09:30 -08:00
}
2014-11-11 12:09:09 -08:00
private void MergeAndSavePartsToNewMeshFile ( SaveAsWindow . SaveAsReturnInfo returnInfo )
2014-01-29 19:09:30 -08:00
{
2014-11-11 12:09:09 -08:00
if ( MeshGroups . Count > 0 )
2014-04-08 20:57:00 -07:00
{
2014-11-11 12:09:09 -08:00
string progressSavingPartsLabel = "Saving" . Localize ( ) ;
string progressSavingPartsLabelFull = "{0}:" . FormatWith ( progressSavingPartsLabel ) ;
processingProgressControl . ProcessType = progressSavingPartsLabelFull ;
processingProgressControl . Visible = true ;
processingProgressControl . PercentComplete = 0 ;
LockEditControls ( ) ;
BackgroundWorker mergeAndSavePartsBackgroundWorker = new BackgroundWorker ( ) ;
mergeAndSavePartsBackgroundWorker . DoWork + = new DoWorkEventHandler ( mergeAndSavePartsBackgroundWorker_DoWork ) ;
mergeAndSavePartsBackgroundWorker . RunWorkerCompleted + = new RunWorkerCompletedEventHandler ( mergeAndSavePartsBackgroundWorker_RunWorkerCompleted ) ;
mergeAndSavePartsBackgroundWorker . RunWorkerAsync ( returnInfo ) ;
2014-04-08 20:57:00 -07:00
}
2014-11-11 12:09:09 -08:00
}
2014-04-08 20:57:00 -07:00
2014-12-19 10:10:14 -08:00
public delegate void AfterSaveCallback ( ) ;
AfterSaveCallback afterSaveCallback = null ;
private void MergeAndSavePartsToCurrentMeshFile ( AfterSaveCallback eventToCallAfterSave = null )
2014-11-11 12:09:09 -08:00
{
2014-12-19 10:10:14 -08:00
afterSaveCallback = eventToCallAfterSave ;
2014-10-12 20:40:38 -07:00
if ( MeshGroups . Count > 0 )
2014-01-29 19:09:30 -08:00
{
2014-11-06 11:57:32 -08:00
string progressSavingPartsLabel = "Saving" . Localize ( ) ;
2014-04-15 10:11:56 -07:00
string progressSavingPartsLabelFull = "{0}:" . FormatWith ( progressSavingPartsLabel ) ;
2014-11-04 10:27:59 -08:00
processingProgressControl . ProcessType = progressSavingPartsLabelFull ;
2014-01-29 19:09:30 -08:00
processingProgressControl . Visible = true ;
processingProgressControl . PercentComplete = 0 ;
LockEditControls ( ) ;
BackgroundWorker mergeAndSavePartsBackgroundWorker = new BackgroundWorker ( ) ;
mergeAndSavePartsBackgroundWorker . DoWork + = new DoWorkEventHandler ( mergeAndSavePartsBackgroundWorker_DoWork ) ;
mergeAndSavePartsBackgroundWorker . RunWorkerCompleted + = new RunWorkerCompletedEventHandler ( mergeAndSavePartsBackgroundWorker_RunWorkerCompleted ) ;
2014-11-11 12:09:09 -08:00
mergeAndSavePartsBackgroundWorker . RunWorkerAsync ( printItemWrapper ) ;
2014-01-29 19:09:30 -08:00
}
}
void mergeAndSavePartsBackgroundWorker_DoWork ( object sender , DoWorkEventArgs e )
{
2014-11-11 12:09:09 -08:00
SaveAsWindow . SaveAsReturnInfo returnInfo = e . Argument as SaveAsWindow . SaveAsReturnInfo ;
if ( returnInfo ! = null )
{
printItemWrapper = returnInfo . printItemWrapper ;
}
2014-02-07 15:14:29 -08:00
// we sent the data to the asynch lists but we will not pull it back out (only use it as a temp holder).
2014-10-16 17:52:21 -07:00
PushMeshGroupDataToAsynchLists ( TraceInfoOpperation . DO_COPY ) ;
2014-02-07 15:14:29 -08:00
2014-01-29 19:09:30 -08:00
Thread . CurrentThread . CurrentCulture = CultureInfo . InvariantCulture ;
BackgroundWorker backgroundWorker = ( BackgroundWorker ) sender ;
try
{
// push all the transforms into the meshes
2014-10-15 14:11:14 -07:00
for ( int i = 0 ; i < asynchMeshGroups . Count ; i + + )
2014-01-29 19:09:30 -08:00
{
2014-10-15 14:11:14 -07:00
asynchMeshGroups [ i ] . Transform ( asynchMeshGroupTransforms [ i ] . TotalTransform ) ;
2014-01-29 19:09:30 -08:00
2014-11-04 10:27:59 -08:00
bool continueProcessing ;
BackgroundWorker_ProgressChanged ( ( i + 1 ) * . 4 / asynchMeshGroups . Count , "" , out continueProcessing ) ;
2014-01-29 19:09:30 -08:00
}
2014-10-24 15:37:03 -07:00
LibraryData . SaveToLibraryFolder ( printItemWrapper , asynchMeshGroups ) ;
2014-01-29 19:09:30 -08:00
}
catch ( System . UnauthorizedAccessException )
{
2014-10-23 10:05:29 -07:00
UiThread . RunOnIdle ( ( state ) = >
{
//Do something special when unauthorized?
StyledMessageBox . ShowMessageBox ( null , "Oops! Unable to save changes." , "Unable to save" ) ;
} ) ;
2014-01-29 19:09:30 -08:00
}
catch
{
2014-10-23 10:05:29 -07:00
UiThread . RunOnIdle ( ( state ) = >
{
StyledMessageBox . ShowMessageBox ( null , "Oops! Unable to save changes." , "Unable to save" ) ;
} ) ;
2014-01-29 19:09:30 -08:00
}
2014-11-11 12:09:09 -08:00
e . Result = e . Argument ;
2014-01-29 19:09:30 -08:00
}
void mergeAndSavePartsBackgroundWorker_RunWorkerCompleted ( object sender , RunWorkerCompletedEventArgs e )
{
2014-11-11 12:09:09 -08:00
SaveAsWindow . SaveAsReturnInfo returnInfo = e . Result as SaveAsWindow . SaveAsReturnInfo ;
if ( returnInfo ! = null )
{
QueueData . Instance . AddItem ( printItemWrapper ) ;
2014-11-11 12:17:41 -08:00
if ( ! PrinterConnectionAndCommunication . Instance . PrintIsActive )
{
QueueData . Instance . SelectedIndex = QueueData . Instance . Count - 1 ;
}
2014-11-11 12:09:09 -08:00
if ( returnInfo . placeInLibrary )
{
LibraryData . Instance . AddItem ( printItemWrapper ) ;
}
}
2014-09-26 15:04:04 -07:00
if ( WidgetHasBeenClosed )
{
return ;
}
2014-01-29 19:09:30 -08:00
UnlockEditControls ( ) ;
// NOTE: we do not pull the data back out of the asynch lists.
2014-04-08 20:57:00 -07:00
saveButtons . Visible = false ;
2014-12-19 10:10:14 -08:00
if ( afterSaveCallback ! = null )
{
afterSaveCallback ( ) ;
}
2014-01-29 19:09:30 -08:00
}
void expandViewOptions_CheckedStateChanged ( object sender , EventArgs e )
{
2014-09-24 11:15:38 -07:00
if ( viewOptionContainer . Visible ! = expandViewOptions . Checked )
{
if ( expandViewOptions . Checked = = true )
2014-10-12 20:40:38 -07:00
{
2014-09-24 11:15:38 -07:00
expandScaleOptions . Checked = false ;
expandRotateOptions . Checked = false ;
expandMirrorOptions . Checked = false ;
2014-09-26 15:04:04 -07:00
expandMaterialOptions . Checked = false ;
2014-09-24 11:15:38 -07:00
}
viewOptionContainer . Visible = expandViewOptions . Checked ;
2014-10-12 20:40:38 -07:00
}
2014-01-29 19:09:30 -08:00
}
2014-09-24 11:15:38 -07:00
void expandMirrorOptions_CheckedStateChanged ( object sender , EventArgs e )
{
if ( mirrorOptionContainer . Visible ! = expandMirrorOptions . Checked )
{
if ( expandMirrorOptions . Checked = = true )
2014-10-12 20:40:38 -07:00
{
2014-09-24 11:15:38 -07:00
expandScaleOptions . Checked = false ;
expandRotateOptions . Checked = false ;
expandViewOptions . Checked = false ;
2014-09-26 15:04:04 -07:00
expandMaterialOptions . Checked = false ;
2014-09-24 11:15:38 -07:00
}
mirrorOptionContainer . Visible = expandMirrorOptions . Checked ;
2014-10-12 20:40:38 -07:00
}
2014-09-24 11:15:38 -07:00
}
2014-09-26 15:04:04 -07:00
void expandMaterialOptions_CheckedStateChanged ( object sender , EventArgs e )
{
if ( expandMaterialOptions . Checked = = true )
{
expandScaleOptions . Checked = false ;
expandRotateOptions . Checked = false ;
expandViewOptions . Checked = false ;
}
materialOptionContainer . Visible = expandMaterialOptions . Checked ;
}
2014-09-24 11:15:38 -07:00
2014-01-29 19:09:30 -08:00
void expandRotateOptions_CheckedStateChanged ( object sender , EventArgs e )
{
2014-09-24 11:15:38 -07:00
if ( rotateOptionContainer . Visible ! = expandRotateOptions . Checked )
{
if ( expandRotateOptions . Checked = = true )
{
expandViewOptions . Checked = false ;
expandScaleOptions . Checked = false ;
expandMirrorOptions . Checked = false ;
2014-09-26 15:04:04 -07:00
expandMaterialOptions . Checked = false ;
2014-09-24 11:15:38 -07:00
}
rotateOptionContainer . Visible = expandRotateOptions . Checked ;
}
2014-01-29 19:09:30 -08:00
}
void expandScaleOptions_CheckedStateChanged ( object sender , EventArgs e )
{
2014-09-24 11:15:38 -07:00
if ( scaleOptionContainer . Visible ! = expandScaleOptions . Checked )
{
if ( expandScaleOptions . Checked = = true )
{
expandViewOptions . Checked = false ;
expandRotateOptions . Checked = false ;
expandMirrorOptions . Checked = false ;
2014-09-26 15:04:04 -07:00
expandMaterialOptions . Checked = false ;
2014-09-24 11:15:38 -07:00
}
scaleOptionContainer . Visible = expandScaleOptions . Checked ;
}
2014-01-29 19:09:30 -08:00
}
bool scaleQueueMenu_Click ( )
{
return true ;
}
bool rotateQueueMenu_Click ( )
{
return true ;
}
private void MakeLowestFaceFlat ( int indexToLayFlat )
{
2014-10-07 18:00:17 -07:00
Vertex lowestVertex = MeshGroups [ indexToLayFlat ] . Meshes [ 0 ] . Vertices [ 0 ] ;
Vector3 lowestVertexPosition = Vector3 . Transform ( lowestVertex . Position , MeshGroupTransforms [ indexToLayFlat ] . rotation ) ;
Mesh meshToLayFlat = null ;
2014-10-10 09:30:44 -07:00
foreach ( Mesh meshToCheck in MeshGroups [ indexToLayFlat ] . Meshes )
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
// find the lowest point on the model
2014-10-10 09:30:44 -07:00
for ( int testIndex = 1 ; testIndex < meshToCheck . Vertices . Count ; testIndex + + )
2014-01-29 19:09:30 -08:00
{
2014-10-10 09:30:44 -07:00
Vertex vertex = meshToCheck . Vertices [ testIndex ] ;
2014-10-07 18:00:17 -07:00
Vector3 vertexPosition = Vector3 . Transform ( vertex . Position , MeshGroupTransforms [ indexToLayFlat ] . rotation ) ;
if ( vertexPosition . z < lowestVertexPosition . z )
{
2014-10-10 09:30:44 -07:00
lowestVertex = meshToCheck . Vertices [ testIndex ] ;
2014-10-07 18:00:17 -07:00
lowestVertexPosition = vertexPosition ;
2014-10-10 09:30:44 -07:00
meshToLayFlat = meshToCheck ;
2014-10-07 18:00:17 -07:00
}
2014-01-29 19:09:30 -08: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.
2014-04-13 21:29:18 -07:00
foreach ( Face face in lowestVertex . ConnectedFaces ( ) )
2014-01-29 19:09:30 -08:00
{
double biggestAngleToFaceVertex = double . MinValue ;
2014-04-13 21:29:18 -07:00
foreach ( Vertex faceVertex in face . Vertices ( ) )
2014-01-29 19:09:30 -08:00
{
if ( faceVertex ! = lowestVertex )
{
2014-10-07 18:00:17 -07:00
Vector3 faceVertexPosition = Vector3 . Transform ( faceVertex . Position , MeshGroupTransforms [ indexToLayFlat ] . rotation ) ;
2014-01-29 19:09:30 -08: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 ;
}
}
}
if ( biggestAngleToFaceVertex < lowestAngleOfAnyFace )
{
lowestAngleOfAnyFace = biggestAngleToFaceVertex ;
faceToLayFlat = face ;
}
}
2014-08-14 09:58:17 -07:00
double maxDistFromLowestZ = 0 ;
2014-01-29 19:09:30 -08:00
List < Vector3 > faceVertexes = new List < Vector3 > ( ) ;
2014-04-13 21:29:18 -07:00
foreach ( Vertex vertex in faceToLayFlat . Vertices ( ) )
2014-01-29 19:09:30 -08:00
{
2014-10-07 18:00:17 -07:00
Vector3 vertexPosition = Vector3 . Transform ( vertex . Position , MeshGroupTransforms [ indexToLayFlat ] . rotation ) ;
2014-01-29 19:09:30 -08:00
faceVertexes . Add ( vertexPosition ) ;
2014-08-14 09:58:17 -07:00
maxDistFromLowestZ = Math . Max ( maxDistFromLowestZ , vertexPosition . z - lowestVertexPosition . z ) ;
2014-01-29 19:09:30 -08:00
}
2014-08-14 09:58:17 -07:00
if ( maxDistFromLowestZ > . 001 )
2014-01-29 19:09:30 -08:00
{
Vector3 xPositive = ( faceVertexes [ 1 ] - faceVertexes [ 0 ] ) . GetNormal ( ) ;
Vector3 yPositive = ( faceVertexes [ 2 ] - faceVertexes [ 0 ] ) . GetNormal ( ) ;
Vector3 planeNormal = Vector3 . Cross ( xPositive , yPositive ) . GetNormal ( ) ;
// 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 ) ;
// rotate it
2014-10-07 18:00:17 -07:00
ScaleRotateTranslate rotated = SelectedMeshGroupTransform ;
2014-08-14 09:58:17 -07:00
rotated . rotation * = partLevelMatrix ;
2014-10-07 18:00:17 -07:00
SelectedMeshGroupTransform = rotated ;
2014-08-14 09:58:17 -07:00
2014-12-05 16:23:24 -08:00
PlatingHelper . PlaceMeshGroupOnBed ( MeshGroups , MeshGroupTransforms , SelectedMeshGroupIndex ) ;
2014-08-14 09:58:17 -07:00
2014-12-12 12:57:44 -08:00
PartHasBeenChanged ( ) ;
2014-01-29 19:09:30 -08:00
Invalidate ( ) ;
}
}
}
}