2014-01-29 19:09:30 -08:00
/ *
2018-04-03 08:36:21 -07:00
Copyright ( c ) 2018 , Lars Brubaker , John Lewin
2014-01-29 19:09:30 -08:00
All rights reserved .
Redistribution and use in source and binary forms , with or without
2015-04-08 15:20:10 -07:00
modification , are permitted provided that the following conditions are met :
2014-01-29 19:09:30 -08:00
1. Redistributions of source code must retain the above copyright notice , this
2015-04-08 15:20:10 -07:00
list of conditions and the following disclaimer .
2014-01-29 19:09:30 -08:00
2. Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
2015-04-08 15:20:10 -07:00
and / or other materials provided with the distribution .
2014-01-29 19:09:30 -08:00
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
The views and conclusions contained in the software and documentation are those
2015-04-08 15:20:10 -07:00
of the authors and should not be interpreted as representing official policies ,
2014-01-29 19:09:30 -08:00
either expressed or implied , of the FreeBSD Project .
* /
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using System ;
using System.Collections.Generic ;
using System.Diagnostics ;
using System.Linq ;
using System.Text.RegularExpressions ;
2014-01-29 19:09:30 -08:00
using MatterHackers.Agg ;
2018-05-18 16:58:18 -07:00
using MatterHackers.Agg.Image ;
2014-01-29 19:09:30 -08:00
using MatterHackers.Agg.UI ;
2017-03-15 16:17:06 -07:00
using MatterHackers.DataConverters3D ;
2014-10-15 14:11:14 -07:00
using MatterHackers.Localizations ;
2014-10-23 14:40:12 -07:00
using MatterHackers.MatterControl.CustomWidgets ;
2018-08-28 18:45:58 -07:00
using MatterHackers.MatterControl.DesignTools ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
using MatterHackers.MatterControl.Library ;
2014-01-29 19:09:30 -08:00
using MatterHackers.MeshVisualizer ;
using MatterHackers.RayTracer ;
2014-04-15 18:13:27 -07:00
using MatterHackers.RenderOpenGl ;
2018-05-09 16:41:24 -07:00
using MatterHackers.RenderOpenGl.OpenGl ;
2014-04-15 18:13:27 -07:00
using MatterHackers.VectorMath ;
2018-04-03 08:36:21 -07:00
using MatterHackers.VectorMath.TrackBall ;
2014-01-29 19:09:30 -08:00
namespace MatterHackers.MatterControl.PartPreviewWindow
{
2018-02-07 18:01:49 -08:00
public class View3DWidget : GuiWidget
2015-04-08 15:20:10 -07:00
{
2017-04-05 19:03:04 -07:00
private bool deferEditorTillMouseUp = false ;
2016-02-26 21:54:15 -08:00
public readonly int EditButtonHeight = 44 ;
2017-03-15 16:17:06 -07:00
2015-05-30 12:48:16 -07:00
private bool hasDrawn = false ;
2017-03-15 16:17:06 -07:00
2017-10-31 11:43:25 -07:00
private Color [ ] SelectionColors = new Color [ ] { new Color ( 131 , 4 , 66 ) , new Color ( 227 , 31 , 61 ) , new Color ( 255 , 148 , 1 ) , new Color ( 247 , 224 , 23 ) , new Color ( 143 , 212 , 1 ) } ;
2015-05-30 12:48:16 -07:00
private Stopwatch timeSinceLastSpin = new Stopwatch ( ) ;
private Stopwatch timeSinceReported = new Stopwatch ( ) ;
2018-04-23 14:33:27 -07:00
public Matrix4X4 TransformOnMouseDown { get ; private set ; } = Matrix4X4 . Identity ;
2015-04-08 15:20:10 -07:00
2018-05-22 12:51:04 -07:00
private TreeView treeView ;
2017-06-19 09:17:57 -07:00
private ThemeConfig theme ;
2016-10-06 10:59:51 -07:00
2017-09-05 18:02:19 -07:00
public Vector3 BedCenter
{
get
{
2017-09-15 16:49:21 -07:00
return new Vector3 ( sceneContext . BedCenter ) ;
2017-09-05 18:02:19 -07:00
}
}
2017-09-16 01:28:05 -07:00
private WorldView World = > sceneContext . World ;
2017-07-10 14:00:27 -07:00
2018-04-23 14:33:27 -07:00
public TrackballTumbleWidget TrackballTumbleWidget { get ; private set ; }
2017-07-10 14:00:27 -07:00
2017-07-11 08:10:57 -07:00
public InteractionLayer InteractionLayer { get ; }
2018-01-30 11:50:22 -08:00
public BedConfig sceneContext ;
2017-09-15 16:49:21 -07:00
2018-04-23 18:48:17 -07:00
public PrinterConfig Printer { get ; private set ; }
2017-10-16 17:09:00 -07:00
2017-10-30 08:53:53 -07:00
private PrinterTabPage printerTabPage ;
2017-10-16 17:09:00 -07:00
2017-11-07 14:55:45 -08:00
public View3DWidget ( PrinterConfig printer , BedConfig sceneContext , AutoRotate autoRotate , ViewControls3D viewControls3D , ThemeConfig theme , PartTabPage printerTabBase , MeshViewerWidget . EditorType editorType = MeshViewerWidget . EditorType . Part )
2015-05-30 12:48:16 -07:00
{
2017-09-15 16:49:21 -07:00
this . sceneContext = sceneContext ;
2017-10-30 08:53:53 -07:00
this . printerTabPage = printerTabBase as PrinterTabPage ;
2018-04-23 18:48:17 -07:00
this . Printer = printer ;
2017-07-10 14:00:27 -07:00
2018-04-23 14:33:27 -07:00
this . InteractionLayer = new InteractionLayer ( this . World , Scene . UndoBuffer , Scene )
2017-07-11 08:10:57 -07:00
{
Name = "InteractionLayer" ,
} ;
this . InteractionLayer . AnchorAll ( ) ;
2017-07-05 14:34:38 -07:00
this . viewControls3D = viewControls3D ;
2017-06-19 09:17:57 -07:00
this . theme = theme ;
2016-03-01 11:25:15 -08:00
this . Name = "View3DWidget" ;
2018-01-16 22:55:28 -08:00
this . BackgroundColor = theme . ActiveTabColor ;
2018-02-17 09:06:49 -08:00
this . HAnchor = HAnchor . Stretch ; // HAnchor.MaxFitOrStretch,
this . VAnchor = VAnchor . Stretch ; // VAnchor.MaxFitOrStretch
2017-05-24 14:19:02 -07:00
2017-08-18 08:34:05 -07:00
autoRotating = allowAutoRotate ;
allowAutoRotate = ( autoRotate = = AutoRotate . Enabled ) ;
2017-05-26 13:46:12 -07:00
viewControls3D . TransformStateChanged + = ViewControls3D_TransformStateChanged ;
2017-08-18 08:34:05 -07:00
// MeshViewer
2018-07-12 09:22:28 -07:00
meshViewerWidget = new MeshViewerWidget ( sceneContext , this . InteractionLayer , theme , editorType : editorType ) ;
2017-07-05 15:37:32 -07:00
meshViewerWidget . AnchorAll ( ) ;
2018-02-17 09:06:49 -08:00
this . AddChild ( meshViewerWidget ) ;
2015-04-08 15:20:10 -07:00
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget = new TrackballTumbleWidget ( sceneContext . World , meshViewerWidget )
2018-02-20 15:23:55 -08:00
{
2018-04-03 08:36:21 -07:00
TransformState = TrackBallTransformType . Rotation
2018-02-20 15:23:55 -08:00
} ;
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget . AnchorAll ( ) ;
2018-02-20 15:23:55 -08:00
2018-04-18 09:36:53 -07:00
this . BoundsChanged + = UpdateRenderView ;
2017-08-18 08:34:05 -07:00
// TumbleWidget
2018-04-23 14:33:27 -07:00
this . InteractionLayer . AddChild ( TrackballTumbleWidget ) ;
2017-08-18 12:40:49 -07:00
this . InteractionLayer . SetRenderTarget ( this . meshViewerWidget ) ;
2017-07-10 14:00:27 -07:00
2018-02-17 10:42:58 -08:00
// Add splitter support with the InteractionLayer on the left and resize containers on the right
var splitContainer = new FlowLayoutWidget ( )
{
Name = "SplitContainer" ,
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Stretch ,
} ;
splitContainer . AddChild ( this . InteractionLayer ) ;
this . AddChild ( splitContainer ) ;
2015-04-08 15:20:10 -07:00
2018-04-23 14:33:27 -07:00
Scene . SelectionChanged + = Scene_SelectionChanged ;
2015-04-08 15:20:10 -07:00
2017-10-25 17:04:55 -07:00
// if the scene is invalidated invalidate the widget
2018-04-23 14:33:27 -07:00
Scene . Invalidated + = ( s , e ) = > Invalidate ( ) ;
2017-10-25 17:04:55 -07:00
2015-04-08 15:20:10 -07:00
this . AnchorAll ( ) ;
2014-01-29 19:09:30 -08:00
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget . TransformState = TrackBallTransformType . Rotation ;
2014-03-01 23:27:34 -08:00
2018-05-31 20:07:49 -07:00
selectedObjectPanel = new SelectedObjectPanel ( this , sceneContext , theme )
2017-03-15 16:17:06 -07:00
{
2018-01-05 11:45:11 -08:00
VAnchor = VAnchor . Stretch ,
2017-03-15 16:17:06 -07:00
} ;
2017-10-19 15:29:01 -07:00
2018-05-21 16:42:40 -07:00
modelViewSidePanel = new LeftResizeContainer ( theme )
2017-10-19 15:29:01 -07:00
{
2018-01-08 23:53:39 -08:00
Width = printer ? . ViewState . SelectedObjectPanelWidth ? ? 200 ,
2018-01-05 11:45:11 -08:00
VAnchor = VAnchor . Stretch ,
2018-02-17 10:42:58 -08:00
HAnchor = HAnchor . Absolute ,
2018-04-05 15:57:32 -07:00
BackgroundColor = theme . InteractionLayerOverlayColor ,
2017-11-27 16:41:52 -08:00
SpliterBarColor = theme . SplitterBackground ,
SplitterWidth = theme . SplitterWidth ,
2018-04-18 09:36:53 -07:00
MinimumSize = new Vector2 ( theme . SplitterWidth , 0 )
2017-10-19 15:29:01 -07:00
} ;
2018-04-18 09:36:53 -07:00
modelViewSidePanel . BoundsChanged + = UpdateRenderView ;
2018-04-05 15:40:38 -07:00
2018-05-30 16:42:17 -07:00
modelViewSidePanel . Resized + = ModelViewSidePanel_Resized ;
2018-09-07 15:15:53 -07:00
var viewOptionButtons = ApplicationController . Instance . GetViewOptionButtons ( sceneContext , printer , theme ) ;
viewOptionButtons . AddChild ( new ViewStyleButton ( sceneContext , theme ) ) ;
2018-04-05 15:59:16 -07:00
modelViewSidePanel . AddChild (
2018-04-05 15:40:38 -07:00
new SectionWidget (
"Options" . Localize ( ) ,
2018-09-07 15:15:53 -07:00
new GuiWidget ( ) ,
2018-04-05 15:40:38 -07:00
theme ,
2018-09-07 15:15:53 -07:00
viewOptionButtons ,
expandingContent : false )
2018-04-05 15:40:38 -07:00
{
HAnchor = HAnchor . Stretch ,
VAnchor = VAnchor . Fit ,
2018-07-15 10:07:30 -07:00
BorderColor = Color . Transparent // Disable top border to produce a more flat, dark top edge
} ) ;
2018-04-05 15:40:38 -07:00
2018-05-22 12:51:04 -07:00
// add the tree view
2018-06-01 08:49:02 -07:00
treeView = new TreeView ( theme )
{
2018-06-23 07:13:19 -07:00
Margin = new BorderDouble ( left : 18 ) ,
2018-06-01 08:49:02 -07:00
} ;
treeView . AfterSelect + = ( s , e ) = >
{
2018-06-07 13:46:04 -07:00
// Ignore AfterSelect events if they're being driven by a SelectionChanged event
if ( ! assigningTreeNode )
{
Scene . SelectedItem = ( IObject3D ) treeView . SelectedNode . Tag ;
}
2018-06-07 17:53:19 -07:00
selectedObjectPanel . SetActiveItem ( ( IObject3D ) treeView . SelectedNode . Tag ) ;
2018-06-01 08:49:02 -07:00
} ;
2018-08-07 16:42:59 -07:00
treeView . NodeMouseClick + = ( s , e ) = >
{
2018-08-07 17:41:41 -07:00
if ( e is MouseEventArgs sourceEvent
& & s is GuiWidget clickedWidget
& & sourceEvent . Button = = MouseButtons . Right )
2018-08-07 16:42:59 -07:00
{
UiThread . RunOnIdle ( ( ) = >
{
var menu = ApplicationController . Instance . GetActionMenuForSceneItem ( ( IObject3D ) treeView . SelectedNode . Tag , Scene ) ;
var systemWindow = this . Parents < SystemWindow > ( ) . FirstOrDefault ( ) ;
systemWindow . ShowPopup (
2018-08-07 17:41:41 -07:00
new MatePoint ( clickedWidget )
{
Mate = new MateOptions ( MateEdge . Left , MateEdge . Top ) ,
AltMate = new MateOptions ( MateEdge . Left , MateEdge . Top )
} ,
new MatePoint ( menu )
{
Mate = new MateOptions ( MateEdge . Left , MateEdge . Top ) ,
AltMate = new MateOptions ( MateEdge . Right , MateEdge . Top )
} ,
altBounds : new RectangleDouble ( sourceEvent . X + 1 , sourceEvent . Y + 1 , sourceEvent . X + 1 , sourceEvent . Y + 1 ) ) ;
2018-08-07 16:42:59 -07:00
} ) ;
}
} ;
2018-06-23 07:12:41 -07:00
treeView . ScrollArea . ChildAdded + = ( s , e ) = >
{
if ( e is GuiWidgetEventArgs childEventArgs
& & childEventArgs . Child is TreeNode treeNode )
{
treeNode . AlwaysExpandable = true ;
}
} ;
2018-06-22 18:39:03 -07:00
2018-09-10 16:42:46 -07:00
Splitter historyAndProperties = new Splitter ( )
2018-06-22 18:39:03 -07:00
{
2018-09-10 16:42:46 -07:00
Orientation = Orientation . Horizontal ,
SplitterDistance = sceneContext . ViewState . SceneTreeHeight ,
SplitterSize = theme . SplitterWidth ,
SplitterBackground = theme . SplitterBackground
2018-06-22 18:39:03 -07:00
} ;
2018-05-22 12:51:04 -07:00
2018-09-10 16:42:46 -07:00
modelViewSidePanel . AddChild ( historyAndProperties ) ;
historyAndProperties . Panel1 . AddChild ( treeView ) ;
historyAndProperties . DistanceChanged + = ( s , e ) = >
{
sceneContext . ViewState . SceneTreeHeight = historyAndProperties . SplitterDistance ;
} ;
historyAndProperties . Panel2 . AddChild ( selectedObjectPanel ) ;
2018-04-05 15:59:16 -07:00
splitContainer . AddChild ( modelViewSidePanel ) ;
2017-03-15 16:17:06 -07:00
2018-07-19 16:49:44 -07:00
this . InteractionLayer . AddChild ( new TumbleCubeControl ( this . InteractionLayer , theme )
2017-11-29 16:40:46 -08:00
{
2018-05-24 12:05:25 -07:00
Margin = new BorderDouble ( 0 , 0 , 30 , 30 ) ,
2017-11-29 16:40:46 -08:00
VAnchor = VAnchor . Top ,
2018-05-24 12:05:25 -07:00
HAnchor = HAnchor . Right ,
2017-11-29 16:40:46 -08:00
} ) ;
2015-04-08 15:20:10 -07:00
UiThread . RunOnIdle ( AutoSpin ) ;
2014-05-27 09:16:35 -07:00
2017-07-12 21:57:30 -07:00
var interactionVolumes = this . InteractionLayer . InteractionVolumes ;
interactionVolumes . Add ( new MoveInZControl ( this . InteractionLayer ) ) ;
interactionVolumes . Add ( new SelectionShadow ( this . InteractionLayer ) ) ;
interactionVolumes . Add ( new SnappingIndicators ( this . InteractionLayer , this . CurrentSelectInfo ) ) ;
2015-04-08 15:20:10 -07:00
2017-07-20 00:50:50 -07:00
var interactionVolumePlugins = PluginFinder . CreateInstancesOf < InteractionVolumePlugin > ( ) ;
foreach ( InteractionVolumePlugin plugin in interactionVolumePlugins )
2016-02-21 13:18:29 -08:00
{
2017-07-12 21:57:30 -07:00
interactionVolumes . Add ( plugin . CreateInteractionVolume ( this . InteractionLayer ) ) ;
2016-02-21 13:18:29 -08:00
}
2017-05-31 17:47:12 -07:00
meshViewerWidget . AfterDraw + = AfterDraw3DContent ;
2017-05-29 16:56:56 -07:00
2018-04-23 14:33:27 -07:00
Scene . SelectFirstChild ( ) ;
2017-09-15 23:17:03 -07:00
2018-02-05 14:25:52 -08:00
viewControls3D . ActiveButton = ViewControls3DButtons . PartSelect ;
2018-01-14 16:39:30 -08:00
2017-09-20 14:14:11 -07:00
this . InteractionLayer . DrawGlOpaqueContent + = Draw_GlOpaqueContent ;
2017-11-29 07:35:37 -08:00
this . sceneContext . SceneLoaded + = SceneContext_SceneLoaded ;
}
2018-08-08 07:10:24 -07:00
public Dictionary < string , NamedAction > WorkspaceActions { get ; set ; }
2018-05-30 16:42:17 -07:00
private void ModelViewSidePanel_Resized ( object sender , EventArgs e )
{
if ( this . Printer ! = null )
{
this . Printer . ViewState . SelectedObjectPanelWidth = selectedObjectPanel . Width ;
}
}
2018-04-18 09:36:53 -07:00
private void UpdateRenderView ( object sender , EventArgs e )
{
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget . CenterOffsetX = - modelViewSidePanel . Width ;
2018-04-18 09:36:53 -07:00
}
2017-11-29 07:35:37 -08:00
private void SceneContext_SceneLoaded ( object sender , EventArgs e )
{
2018-05-07 14:42:13 -07:00
if ( printerTabPage ? . printerActionsBar ? . sliceButton is GuiWidget sliceButton )
2017-11-29 13:50:25 -08:00
{
sliceButton . Enabled = sceneContext . EditableScene ;
}
2018-05-07 14:42:13 -07:00
if ( printerTabPage ? . printerActionsBar ? . modelViewButton is GuiWidget button )
2018-02-07 18:43:09 -08:00
{
button . Enabled = sceneContext . EditableScene ;
2018-05-07 17:15:08 -07:00
if ( sceneContext . ContentType = = "gcode"
& & printerTabPage ? . printerActionsBar ? . layers3DButton is GuiWidget gcodeButton )
{
gcodeButton . InvokeClick ( ) ;
}
2018-02-07 18:43:09 -08:00
}
2017-11-29 07:35:37 -08:00
this . Invalidate ( ) ;
2017-03-15 16:17:06 -07:00
}
2017-05-26 13:46:12 -07:00
private void ViewControls3D_TransformStateChanged ( object sender , TransformStateChangedEventArgs e )
{
switch ( e . TransformMode )
{
case ViewControls3DButtons . Rotate :
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget . TransformState = TrackBallTransformType . Rotation ;
2017-05-26 13:46:12 -07:00
break ;
case ViewControls3DButtons . Translate :
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget . TransformState = TrackBallTransformType . Translation ;
2017-05-26 13:46:12 -07:00
break ;
case ViewControls3DButtons . Scale :
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget . TransformState = TrackBallTransformType . Scale ;
2017-05-26 13:46:12 -07:00
break ;
case ViewControls3DButtons . PartSelect :
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget . TransformState = TrackBallTransformType . None ;
2017-05-26 13:46:12 -07:00
break ;
}
}
2017-03-15 16:17:06 -07:00
public void SelectAll ( )
{
2018-04-23 14:33:27 -07:00
Scene . ClearSelection ( ) ;
2018-06-01 16:16:17 -07:00
// Select All - set selection to all scene children
Scene . SetSelection ( Scene . Children . ToList ( ) ) ;
2017-03-15 16:17:06 -07:00
}
2017-07-01 08:21:29 -07:00
2017-09-20 14:14:11 -07:00
private void Draw_GlOpaqueContent ( object sender , DrawEventArgs e )
2016-03-25 17:32:05 -07:00
{
2017-09-11 10:17:09 -07:00
if ( CurrentSelectInfo . DownOnPart
2018-04-23 14:33:27 -07:00
& & TrackballTumbleWidget . TransformState = = TrackBallTransformType . None
2017-09-11 10:17:09 -07:00
& & Keyboard . IsKeyDown ( Keys . ShiftKey ) )
{
// draw marks on the bed to show that the part is constrained to x and y
2018-04-23 14:33:27 -07:00
AxisAlignedBoundingBox selectedBounds = Scene . SelectedItem . GetAxisAlignedBoundingBox ( Matrix4X4 . Identity ) ;
2017-09-11 10:17:09 -07:00
var drawCenter = CurrentSelectInfo . PlaneDownHitPos ;
2017-10-31 11:43:25 -07:00
var drawColor = new Color ( Color . Red , 20 ) ;
2017-09-11 10:17:09 -07:00
bool zBuffer = false ;
for ( int i = 0 ; i < 2 ; i + + )
{
2018-05-02 11:06:52 -07:00
World . Render3DLine (
2017-09-11 10:17:09 -07:00
drawCenter - new Vector3 ( - 50 , 0 , 0 ) ,
drawCenter - new Vector3 ( 50 , 0 , 0 ) , drawColor , zBuffer , 2 ) ;
2018-05-02 11:06:52 -07:00
World . Render3DLine (
2017-09-11 10:17:09 -07:00
drawCenter - new Vector3 ( 0 , - 50 , 0 ) ,
drawCenter - new Vector3 ( 0 , 50 , 0 ) , drawColor , zBuffer , 2 ) ;
2017-10-31 11:43:25 -07:00
drawColor = Color . Black ;
2017-10-31 12:51:16 -07:00
drawCenter . Z = 0 ;
2017-09-11 10:17:09 -07:00
zBuffer = true ;
}
2018-05-09 16:41:24 -07:00
GL . Enable ( EnableCap . Lighting ) ;
2017-09-11 10:17:09 -07:00
}
2018-03-14 15:23:32 -07:00
// Render 3D GCode if applicable
if ( sceneContext . LoadedGCode ! = null
& & sceneContext . GCodeRenderer ! = null
& & printerTabPage ? . printer . ViewState . ViewMode = = PartViewMode . Layers3D )
2017-07-10 14:00:27 -07:00
{
2018-03-14 15:25:39 -07:00
sceneContext . RenderGCode3D ( e ) ;
2017-07-10 14:00:27 -07:00
}
2018-03-14 15:23:32 -07:00
// This shows the BVH as rects around the scene items
//Scene?.TraceData().RenderBvhRecursive(0, 3);
2015-12-22 15:26:51 -08:00
}
2017-03-15 16:17:06 -07:00
public void AddUndoOperation ( IUndoRedoCommand operation )
2016-02-14 17:53:44 -08:00
{
2018-04-23 14:33:27 -07:00
Scene . UndoBuffer . Add ( operation ) ;
2016-02-14 17:53:44 -08:00
}
2015-12-22 15:26:51 -08:00
public enum AutoRotate { Enabled , Disabled } ;
2015-04-15 16:39:37 -07:00
2015-05-30 12:48:16 -07:00
public bool DisplayAllValueData { get ; set ; }
2014-12-20 11:12:02 -08:00
2018-08-23 16:44:11 -07:00
public override void OnClosed ( EventArgs e )
2015-05-30 12:48:16 -07:00
{
2017-05-26 13:46:12 -07:00
viewControls3D . TransformStateChanged - = ViewControls3D_TransformStateChanged ;
2018-04-23 14:33:27 -07:00
Scene . SelectionChanged - = Scene_SelectionChanged ;
2017-10-21 18:11:01 -07:00
this . InteractionLayer . DrawGlOpaqueContent - = Draw_GlOpaqueContent ;
2017-11-29 07:35:37 -08:00
this . sceneContext . SceneLoaded - = SceneContext_SceneLoaded ;
2018-05-30 16:42:17 -07:00
modelViewSidePanel . Resized - = ModelViewSidePanel_Resized ;
2017-10-16 17:09:00 -07:00
2017-07-05 15:43:58 -07:00
if ( meshViewerWidget ! = null )
{
meshViewerWidget . AfterDraw - = AfterDraw3DContent ;
}
2017-03-15 16:17:06 -07:00
base . OnClosed ( e ) ;
2015-05-30 12:48:16 -07:00
}
2017-03-15 16:17:06 -07:00
private GuiWidget topMostParent ;
private PlaneShape bedPlane = new PlaneShape ( Vector3 . UnitZ , 0 , null ) ;
2017-09-19 19:59:55 -07:00
public bool DragOperationActive { get ; private set ; }
2018-06-21 21:02:37 -07:00
public InsertionGroupObject3D DragDropObject { get ; private set ; }
2018-05-10 17:21:59 -07:00
2018-02-12 13:55:31 -08:00
public ILibraryAssetStream SceneReplacement { get ; private set ; }
2017-09-19 19:59:55 -07:00
2017-03-15 16:17:06 -07:00
/// <summary>
/// Provides a View3DWidget specific drag implementation
/// </summary>
/// <param name="screenSpaceMousePosition">The screen space mouse position.</param>
2017-09-19 19:59:55 -07:00
public void ExternalDragOver ( Vector2 screenSpaceMousePosition )
2015-04-08 15:20:10 -07:00
{
2017-09-19 19:59:55 -07:00
if ( this . HasBeenClosed )
2017-03-15 16:17:06 -07:00
{
2017-09-19 19:59:55 -07:00
return ;
2017-03-15 16:17:06 -07:00
}
2017-09-19 19:59:55 -07:00
// If the mouse is within the MeshViewer process the Drag move
2017-03-15 16:17:06 -07:00
var meshViewerPosition = this . meshViewerWidget . TransformToScreenSpace ( meshViewerWidget . LocalBounds ) ;
2017-09-19 19:59:55 -07:00
if ( meshViewerPosition . Contains ( screenSpaceMousePosition ) )
2015-05-30 12:48:16 -07:00
{
2017-09-19 19:59:55 -07:00
// If already started, process drag move
if ( this . DragOperationActive )
2015-05-30 12:48:16 -07:00
{
2017-09-19 19:59:55 -07:00
this . DragOver ( screenSpaceMousePosition ) ;
2017-03-15 16:17:06 -07:00
}
2017-09-19 19:59:55 -07:00
else
2017-03-15 16:17:06 -07:00
{
2018-05-10 17:21:59 -07:00
if ( this . Printer ! = null
& & this . Printer . ViewState . ViewMode ! = PartViewMode . Model )
{
this . Printer . ViewState . ViewMode = PartViewMode . Model ;
}
2017-09-19 19:59:55 -07:00
2018-05-10 17:21:59 -07:00
// Otherwise begin an externally started DragDropOperation hard-coded to use LibraryView->SelectedItems
2017-09-19 19:59:55 -07:00
this . StartDragDrop (
// Project from ListViewItem to ILibraryItem
ApplicationController . Instance . Library . ActiveViewWidget . SelectedItems . Select ( l = > l . Model ) ,
screenSpaceMousePosition ) ;
2015-05-30 12:48:16 -07:00
}
}
2017-09-19 19:59:55 -07:00
}
2017-03-15 16:17:06 -07:00
2017-09-19 19:59:55 -07:00
private void DragOver ( Vector2 screenSpaceMousePosition )
{
2018-05-18 16:58:18 -07:00
IObject3D selectedItem = Scene . SelectedItem ;
2017-09-19 19:59:55 -07:00
// Move the object being dragged
if ( this . DragOperationActive
& & this . DragDropObject ! = null )
{
// Move the DropDropObject the target item
2018-05-18 16:58:18 -07:00
DragSelectedObject ( selectedItem , localMousePosition : this . TransformFromParentSpace ( topMostParent , screenSpaceMousePosition ) ) ;
2017-09-19 19:59:55 -07:00
}
2015-04-08 15:20:10 -07:00
}
2017-12-19 14:49:48 -08:00
private void StartDragDrop ( IEnumerable < ILibraryItem > items , Vector2 screenSpaceMousePosition , bool trackSourceFiles = false )
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
{
2017-09-19 19:59:55 -07:00
this . DragOperationActive = true ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2017-11-29 14:16:21 -08:00
var firstItem = items . FirstOrDefault ( ) ;
2018-02-12 13:55:31 -08:00
if ( ( firstItem is ILibraryAssetStream contentStream
2017-11-29 13:50:25 -08:00
& & contentStream . ContentType = = "gcode" )
2017-11-29 14:16:21 -08:00
| | firstItem is SceneReplacementFileItem )
2017-11-29 13:50:25 -08:00
{
DragDropObject = null ;
2018-02-12 13:55:31 -08:00
this . SceneReplacement = firstItem as ILibraryAssetStream ;
2017-11-29 13:50:25 -08:00
// TODO: Figure out a mechanism to disable View3DWidget with dark overlay, displaying something like "Switch to xxx.gcode", make disappear on mouseLeaveBounds and dragfinish
this . InteractionLayer . BackgroundColor = new Color ( Color . Black , 200 ) ;
return ;
}
2017-09-19 19:59:55 -07:00
// Set the hitplane to the bed plane
CurrentSelectInfo . HitPlane = bedPlane ;
2017-06-05 09:27:30 -07:00
2018-06-21 21:02:37 -07:00
var insertionGroup = new InsertionGroupObject3D (
2017-09-28 15:51:31 -07:00
items ,
this ,
2018-04-23 14:33:27 -07:00
Scene ,
2017-10-25 17:04:55 -07:00
sceneContext . BedCenter ,
2017-12-19 14:49:48 -08:00
( ) = > this . DragOperationActive ,
trackSourceFiles ) ;
2017-07-11 17:31:50 -07:00
2017-09-19 19:59:55 -07:00
// Find intersection position of the mouse with the bed plane
var intersectInfo = GetIntersectPosition ( screenSpaceMousePosition ) ;
if ( intersectInfo ! = null )
{
2018-01-23 16:56:15 -08:00
CalculateDragStartPosition ( insertionGroup , intersectInfo ) ;
}
else
{
CurrentSelectInfo . LastMoveDelta = Vector3 . PositiveInfinity ;
2017-09-19 19:59:55 -07:00
}
2017-09-16 01:11:44 -07:00
2017-09-19 19:59:55 -07:00
this . deferEditorTillMouseUp = true ;
2015-04-08 15:20:10 -07:00
2017-09-19 19:59:55 -07:00
// Add item to scene and select it
2018-04-23 14:33:27 -07:00
Scene . Children . Modify ( list = >
2017-03-15 16:17:06 -07:00
{
2017-11-29 07:05:48 -08:00
list . Add ( insertionGroup ) ;
2017-09-19 19:59:55 -07:00
} ) ;
2018-04-23 14:33:27 -07:00
Scene . SelectedItem = insertionGroup ;
2017-03-15 16:17:06 -07:00
2017-11-29 07:05:48 -08:00
this . DragDropObject = insertionGroup ;
2017-09-19 19:59:55 -07:00
}
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2018-01-23 16:56:15 -08:00
private void CalculateDragStartPosition ( IObject3D insertionGroup , IntersectInfo intersectInfo )
{
// Set the initial transform on the inject part to the current transform mouse position
var sourceItemBounds = insertionGroup . GetAxisAlignedBoundingBox ( Matrix4X4 . Identity ) ;
var center = sourceItemBounds . Center ;
insertionGroup . Matrix * = Matrix4X4 . CreateTranslation ( - center . X , - center . Y , - sourceItemBounds . minXYZ . Z ) ;
insertionGroup . Matrix * = Matrix4X4 . CreateTranslation ( new Vector3 ( intersectInfo . HitPosition ) ) ;
CurrentSelectInfo . PlaneDownHitPos = intersectInfo . HitPosition ;
CurrentSelectInfo . LastMoveDelta = Vector3 . Zero ;
}
2017-09-19 19:59:55 -07:00
internal void FinishDrop ( bool mouseUpInBounds )
{
if ( this . DragOperationActive )
2017-03-15 16:17:06 -07:00
{
2017-11-29 13:50:25 -08:00
this . InteractionLayer . BackgroundColor = Color . Transparent ;
2017-09-19 19:59:55 -07:00
this . DragOperationActive = false ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2017-09-19 19:59:55 -07:00
if ( mouseUpInBounds )
{
2017-11-29 13:50:25 -08:00
if ( this . DragDropObject = = null
& & this . SceneReplacement ! = null )
2017-10-23 13:36:08 -07:00
{
2017-11-29 13:50:25 -08:00
// Drop handler for special case of GCode or similar (change loaded scene to new context)
sceneContext . LoadContent (
new EditContext ( )
{
SourceItem = this . SceneReplacement ,
2017-11-29 14:16:21 -08:00
// No content store for GCode, otherwise PlatingHistory
2018-05-07 17:11:46 -07:00
ContentStore = sceneContext . EditContext . ContentStore
2017-11-29 13:50:25 -08:00
} ) . ConfigureAwait ( false ) ;
this . SceneReplacement = null ;
}
else if ( this . DragDropObject . ContentAcquired )
{
2018-02-07 18:43:09 -08:00
// TODO: Unclear when this is needed and how it would be enabled if the content hadn't loaded by FinishDrop (i.e. how would long running InsertionGroup operations be doing the same thing?)
//this.viewControls3D.modelViewButton.Enabled = true;
2017-11-29 13:50:25 -08:00
// Drop handler for InsertionGroup - all normal content
2017-10-23 13:36:08 -07:00
this . DragDropObject . Collapse ( ) ;
}
2017-04-05 19:03:04 -07:00
}
2017-09-19 19:59:55 -07:00
else
2017-04-05 19:03:04 -07:00
{
2018-04-23 14:33:27 -07:00
Scene . Children . Modify ( list = > list . Remove ( this . DragDropObject ) ) ;
Scene . ClearSelection ( ) ;
2017-09-19 19:59:55 -07:00
}
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2017-09-19 19:59:55 -07:00
this . DragDropObject = null ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2017-09-19 19:59:55 -07:00
this . deferEditorTillMouseUp = false ;
Scene_SelectionChanged ( null , null ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2018-06-20 08:09:35 -07:00
Scene . Invalidate ( new InvalidateArgs ( null , InvalidateType . Content , null ) ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2017-09-19 19:59:55 -07:00
// Set focus to View3DWidget after drag-drop
UiThread . RunOnIdle ( this . Focus ) ;
2017-03-15 16:17:06 -07:00
2017-09-19 19:59:55 -07:00
}
}
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2017-09-19 19:59:55 -07:00
public override void OnLoad ( EventArgs args )
{
topMostParent = this . TopmostParent ( ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
2017-09-19 19:59:55 -07:00
// Set reference on show
var dragDropData = ApplicationController . Instance . DragDropData ;
dragDropData . View3DWidget = this ;
2017-10-05 22:32:23 -07:00
dragDropData . SceneContext = sceneContext ;
2017-06-05 09:27:30 -07:00
2017-09-19 19:59:55 -07:00
base . OnLoad ( args ) ;
2017-03-15 16:17:06 -07:00
}
2016-07-24 17:26:24 -07:00
public override void OnDraw ( Graphics2D graphics2D )
{
2018-04-23 14:33:27 -07:00
var selectedItem = Scene . SelectedItem ;
2017-12-21 09:42:30 -08:00
2018-07-13 06:55:00 -07:00
if ( selectedItem ! = null )
2015-05-30 12:48:16 -07:00
{
2017-03-15 16:17:06 -07:00
2017-07-11 08:10:57 -07:00
foreach ( InteractionVolume volume in this . InteractionLayer . InteractionVolumes )
2016-02-16 08:30:13 -08:00
{
2017-03-15 16:17:06 -07:00
volume . SetPosition ( selectedItem ) ;
2016-02-16 08:30:13 -08:00
}
2015-04-08 15:20:10 -07:00
}
2014-03-20 18:20:52 -07:00
2015-05-30 12:48:16 -07:00
hasDrawn = true ;
2017-05-29 11:44:53 -07:00
2015-05-30 12:48:16 -07:00
base . OnDraw ( graphics2D ) ;
2018-05-18 16:58:18 -07:00
if ( selectedItem ! = null )
{
//DrawTestToGl(graphics2D, selectedItem);
}
}
2017-05-31 17:47:12 -07:00
private void AfterDraw3DContent ( object sender , DrawEventArgs e )
2017-05-29 16:56:56 -07:00
{
2017-06-01 09:42:40 -07:00
if ( DragSelectionInProgress )
{
2017-06-05 15:44:52 -07:00
var selectionRectangle = new RectangleDouble ( DragSelectionStartPosition , DragSelectionEndPosition ) ;
2018-04-11 10:22:06 -07:00
e . Graphics2D . Rectangle ( selectionRectangle , Color . Red ) ;
2017-06-05 15:44:52 -07:00
}
}
2017-06-06 10:06:38 -07:00
bool foundTriangleInSelectionBounds ;
2017-06-06 10:57:13 -07:00
private void DoRectangleSelection ( DrawEventArgs e )
2017-06-05 15:44:52 -07:00
{
2017-06-05 17:23:55 -07:00
var allResults = new List < BvhIterator > ( ) ;
2018-04-23 14:33:27 -07:00
var matchingSceneChildren = Scene . Children . Where ( item = >
2017-06-05 15:44:52 -07:00
{
2017-06-06 10:06:38 -07:00
foundTriangleInSelectionBounds = false ;
2017-06-06 10:57:13 -07:00
// Filter the IPrimitive trace data finding matches as defined in InSelectionBounds
2017-06-06 10:06:38 -07:00
var filteredResults = item . TraceData ( ) . Filter ( InSelectionBounds ) ;
2017-06-05 17:23:55 -07:00
2017-06-06 10:57:13 -07:00
// Accumulate all matching BvhIterator results for debug rendering
2017-06-05 17:23:55 -07:00
allResults . AddRange ( filteredResults ) ;
2017-06-06 10:06:38 -07:00
return foundTriangleInSelectionBounds ;
2017-06-05 15:44:52 -07:00
} ) ;
2017-06-06 10:57:13 -07:00
// Apply selection
if ( matchingSceneChildren . Any ( ) )
2017-06-05 17:23:55 -07:00
{
2017-06-21 15:56:25 -07:00
// If we are actually doing the selection rather than debugging the data
if ( e = = null )
{
2018-04-23 14:33:27 -07:00
Scene . ClearSelection ( ) ;
2018-06-01 09:04:10 -07:00
Scene . SetSelection ( matchingSceneChildren . ToList ( ) ) ;
2017-06-21 15:56:25 -07:00
}
else
2017-06-05 17:23:55 -07:00
{
2018-01-02 15:25:40 -08:00
InteractionLayer . RenderBounds ( e , World , allResults ) ;
2017-06-05 17:23:55 -07:00
}
}
2017-06-06 10:06:38 -07:00
}
2017-06-05 15:44:52 -07:00
2017-06-06 10:06:38 -07:00
private bool InSelectionBounds ( BvhIterator x )
{
var selectionRectangle = new RectangleDouble ( DragSelectionStartPosition , DragSelectionEndPosition ) ;
2017-06-05 15:44:52 -07:00
2017-06-06 10:06:38 -07:00
Vector2 [ ] traceBottoms = new Vector2 [ 4 ] ;
Vector2 [ ] traceTops = new Vector2 [ 4 ] ;
2017-06-05 15:44:52 -07:00
2017-06-06 10:06:38 -07:00
if ( foundTriangleInSelectionBounds )
{
return false ;
}
if ( x . Bvh is TriangleShape tri )
{
// check if any vertex in screen rect
// calculate all the top and bottom screen positions
for ( int i = 0 ; i < 3 ; i + + )
{
Vector3 bottomStartPosition = Vector3 . Transform ( tri . GetVertex ( i ) , x . TransformToWorld ) ;
2017-07-10 14:00:27 -07:00
traceBottoms [ i ] = this . World . GetScreenPosition ( bottomStartPosition ) ;
2017-06-05 15:44:52 -07:00
}
2017-06-06 10:06:38 -07:00
for ( int i = 0 ; i < 3 ; i + + )
2017-06-05 15:44:52 -07:00
{
2017-06-06 10:06:38 -07:00
if ( selectionRectangle . ClipLine ( traceBottoms [ i ] , traceBottoms [ ( i + 1 ) % 3 ] ) )
2017-06-05 15:44:52 -07:00
{
2017-06-06 10:06:38 -07:00
foundTriangleInSelectionBounds = true ;
return true ;
2017-06-05 15:44:52 -07:00
}
}
2017-06-06 10:06:38 -07:00
}
else
{
// calculate all the top and bottom screen positions
for ( int i = 0 ; i < 4 ; i + + )
2017-06-05 15:44:52 -07:00
{
2017-06-06 10:06:38 -07:00
Vector3 bottomStartPosition = Vector3 . Transform ( x . Bvh . GetAxisAlignedBoundingBox ( ) . GetBottomCorner ( i ) , x . TransformToWorld ) ;
2017-07-10 14:00:27 -07:00
traceBottoms [ i ] = this . World . GetScreenPosition ( bottomStartPosition ) ;
2017-06-06 10:06:38 -07:00
Vector3 topStartPosition = Vector3 . Transform ( x . Bvh . GetAxisAlignedBoundingBox ( ) . GetTopCorner ( i ) , x . TransformToWorld ) ;
2017-07-10 14:00:27 -07:00
traceTops [ i ] = this . World . GetScreenPosition ( topStartPosition ) ;
2017-06-05 15:44:52 -07:00
}
2017-06-01 09:42:40 -07:00
2017-06-06 10:06:38 -07:00
RectangleDouble . OutCode allPoints = RectangleDouble . OutCode . Inside ;
// check if we are inside all the points
for ( int i = 0 ; i < 4 ; i + + )
{
allPoints | = selectionRectangle . ComputeOutCode ( traceBottoms [ i ] ) ;
allPoints | = selectionRectangle . ComputeOutCode ( traceTops [ i ] ) ;
}
if ( allPoints = = RectangleDouble . OutCode . Surrounded )
2017-05-30 17:51:52 -07:00
{
return true ;
}
2017-06-06 10:06:38 -07:00
for ( int i = 0 ; i < 4 ; i + + )
{
if ( selectionRectangle . ClipLine ( traceBottoms [ i ] , traceBottoms [ ( i + 1 ) % 4 ] )
| | selectionRectangle . ClipLine ( traceTops [ i ] , traceTops [ ( i + 1 ) % 4 ] )
| | selectionRectangle . ClipLine ( traceTops [ i ] , traceBottoms [ i ] ) )
{
return true ;
}
}
}
2017-05-31 11:56:25 -07:00
2017-06-06 10:06:38 -07:00
return false ;
}
2017-05-31 11:56:25 -07:00
2015-12-22 15:26:51 -08:00
private ViewControls3DButtons ? activeButtonBeforeMouseOverride = null ;
2015-05-29 15:13:56 -07:00
2018-05-18 16:58:18 -07:00
Vector2 lastMouseMove ;
2018-08-07 16:22:37 -07:00
Vector2 mouseDownPositon = Vector2 . Zero ;
2018-05-09 16:41:24 -07:00
Matrix4X4 worldMatrixOnMouseDown ;
2015-05-30 12:48:16 -07:00
public override void OnMouseDown ( MouseEventArgs mouseEvent )
2015-04-08 15:20:10 -07:00
{
2018-08-11 08:50:40 -07:00
var selectedItem = Scene . SelectedItem ;
2018-08-07 16:22:37 -07:00
mouseDownPositon = mouseEvent . Position ;
2018-05-09 16:41:24 -07:00
worldMatrixOnMouseDown = World . GetTransform4X4 ( ) ;
2015-05-29 15:13:56 -07:00
// Show transform override
2018-02-07 18:01:49 -08:00
if ( activeButtonBeforeMouseOverride = = null
2018-01-18 09:38:57 -08:00
& & ( mouseEvent . Button = = MouseButtons . Right | | Keyboard . IsKeyDown ( Keys . Control ) ) )
2015-05-29 15:13:56 -07:00
{
2018-01-18 09:38:57 -08:00
if ( Keyboard . IsKeyDown ( Keys . Shift ) )
{
activeButtonBeforeMouseOverride = viewControls3D . ActiveButton ;
viewControls3D . ActiveButton = ViewControls3DButtons . Translate ;
}
2018-02-07 18:01:49 -08:00
else if ( Keyboard . IsKeyDown ( Keys . Alt ) )
2018-01-20 22:17:39 -08:00
{
activeButtonBeforeMouseOverride = viewControls3D . ActiveButton ;
viewControls3D . ActiveButton = ViewControls3DButtons . Scale ;
}
2018-01-18 09:38:57 -08:00
else
{
activeButtonBeforeMouseOverride = viewControls3D . ActiveButton ;
viewControls3D . ActiveButton = ViewControls3DButtons . Rotate ;
}
2015-05-29 15:13:56 -07:00
}
else if ( activeButtonBeforeMouseOverride = = null & & mouseEvent . Button = = MouseButtons . Middle )
{
activeButtonBeforeMouseOverride = viewControls3D . ActiveButton ;
viewControls3D . ActiveButton = ViewControls3DButtons . Translate ;
}
2018-02-07 18:01:49 -08:00
if ( mouseEvent . Button = = MouseButtons . Right | |
2017-03-15 16:17:06 -07:00
mouseEvent . Button = = MouseButtons . Middle )
{
meshViewerWidget . SuppressUiVolumes = true ;
}
2015-05-30 12:48:16 -07:00
autoRotating = false ;
base . OnMouseDown ( mouseEvent ) ;
2017-03-15 16:17:06 -07:00
2018-05-10 17:14:54 -07:00
if ( TrackballTumbleWidget . UnderMouseState = = UnderMouseState . FirstUnderMouse
& & sceneContext . ViewState . ModelView )
2015-04-08 15:20:10 -07:00
{
2017-03-15 16:17:06 -07:00
if ( mouseEvent . Button = = MouseButtons . Left
2018-01-18 09:38:57 -08:00
& & viewControls3D . ActiveButton = = ViewControls3DButtons . PartSelect
2018-05-09 16:41:24 -07:00
& & ModifierKeys = = Keys . Shift
2017-06-06 14:41:49 -07:00
| | (
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget . TransformState = = TrackBallTransformType . None
2017-06-06 14:41:49 -07:00
& & ModifierKeys ! = Keys . Control
& & ModifierKeys ! = Keys . Alt ) )
2015-04-08 15:20:10 -07:00
{
2017-07-11 08:10:57 -07:00
if ( ! this . InteractionLayer . MouseDownOnInteractionVolume )
2015-05-30 12:48:16 -07:00
{
2017-03-15 16:17:06 -07:00
meshViewerWidget . SuppressUiVolumes = true ;
2016-02-19 08:29:49 -08:00
IntersectInfo info = new IntersectInfo ( ) ;
2017-03-15 16:17:06 -07:00
IObject3D hitObject = FindHitObject3D ( mouseEvent . Position , ref info ) ;
2017-05-31 17:47:12 -07:00
if ( hitObject = = null )
{
2018-08-11 08:50:40 -07:00
if ( selectedItem ! = null )
2017-05-31 17:47:12 -07:00
{
2018-04-23 14:33:27 -07:00
Scene . ClearSelection ( ) ;
2018-08-11 08:50:40 -07:00
selectedItem = null ;
2017-05-31 17:47:12 -07:00
}
// start a selection rect
DragSelectionStartPosition = mouseEvent . Position - OffsetToMeshViewerWidget ( ) ;
2017-06-05 15:44:52 -07:00
DragSelectionEndPosition = DragSelectionStartPosition ;
2017-05-31 17:47:12 -07:00
DragSelectionInProgress = true ;
}
else
2015-05-30 12:48:16 -07:00
{
2017-10-31 12:51:16 -07:00
CurrentSelectInfo . HitPlane = new PlaneShape ( Vector3 . UnitZ , CurrentSelectInfo . PlaneDownHitPos . Z , null ) ;
2014-03-20 18:20:52 -07:00
2018-08-11 08:50:40 -07:00
if ( hitObject ! = selectedItem )
2017-03-15 16:17:06 -07:00
{
2018-08-11 08:50:40 -07:00
if ( selectedItem = = null )
2017-03-15 16:17:06 -07:00
{
// No selection exists
2018-08-11 09:54:16 -07:00
Scene . SelectedItem = hitObject ;
2017-03-15 16:17:06 -07:00
}
2017-06-06 13:34:42 -07:00
else if ( ( ModifierKeys = = Keys . Shift | | ModifierKeys = = Keys . Control )
2018-08-11 08:50:40 -07:00
& & ! selectedItem . Children . Contains ( hitObject ) )
2017-03-15 16:17:06 -07:00
{
2018-04-23 14:33:27 -07:00
Scene . AddToSelection ( hitObject ) ;
2017-03-15 16:17:06 -07:00
}
2018-08-11 08:50:40 -07:00
else if ( selectedItem = = hitObject | | selectedItem . Children . Contains ( hitObject ) )
2017-03-15 16:17:06 -07:00
{
// Selection should not be cleared and drag should occur
}
else if ( ModifierKeys ! = Keys . Shift )
{
2018-04-23 14:33:27 -07:00
Scene . SelectedItem = hitObject ;
2017-03-15 16:17:06 -07:00
}
2018-08-11 09:54:16 -07:00
// Selection may have changed, update local reference to current value
selectedItem = Scene . SelectedItem ;
2017-10-25 17:04:55 -07:00
Invalidate ( ) ;
2017-03-15 16:17:06 -07:00
}
2018-08-11 08:50:40 -07:00
TransformOnMouseDown = selectedItem . Matrix ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
Invalidate ( ) ;
2016-02-19 08:29:49 -08:00
CurrentSelectInfo . DownOnPart = true ;
2018-08-11 08:50:40 -07:00
AxisAlignedBoundingBox selectedBounds = selectedItem . GetAxisAlignedBoundingBox ( Matrix4X4 . Identity ) ;
2016-02-19 08:29:49 -08:00
2017-10-31 12:51:16 -07:00
if ( info . HitPosition . X < selectedBounds . Center . X )
2016-02-19 08:29:49 -08:00
{
2017-10-31 12:51:16 -07:00
if ( info . HitPosition . Y < selectedBounds . Center . Y )
2016-02-19 08:29:49 -08:00
{
CurrentSelectInfo . HitQuadrant = HitQuadrant . LB ;
}
else
{
CurrentSelectInfo . HitQuadrant = HitQuadrant . LT ;
}
}
else
{
2017-10-31 12:51:16 -07:00
if ( info . HitPosition . Y < selectedBounds . Center . Y )
2016-02-19 08:29:49 -08:00
{
CurrentSelectInfo . HitQuadrant = HitQuadrant . RB ;
}
else
{
CurrentSelectInfo . HitQuadrant = HitQuadrant . RT ;
}
}
2015-05-30 12:48:16 -07:00
}
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
}
}
2015-02-27 11:09:37 -08:00
2018-01-19 13:43:39 -08:00
public override void OnMouseMove ( MouseEventArgs mouseEvent )
{
2018-05-18 16:58:18 -07:00
IObject3D selectedItem = Scene . SelectedItem ;
lastMouseMove = mouseEvent . Position ;
2018-08-07 16:22:37 -07:00
if ( lastMouseMove ! = mouseDownPositon )
{
mouseDownPositon = Vector2 . Zero ;
}
2018-01-19 13:43:39 -08:00
// File system Drop validation
mouseEvent . AcceptDrop = this . AllowDragDrop ( )
& & mouseEvent . DragFiles ? . Count > 0
2018-05-09 07:35:42 -07:00
& & mouseEvent . DragFiles . TrueForAll ( filePath = >
{
return ApplicationController . Instance . IsLoadableFile ( filePath )
// Disallow GCode drop in part view
2018-05-09 07:36:08 -07:00
& & ( this . Printer ! = null | | ! string . Equals ( System . IO . Path . GetExtension ( filePath ) , ".gcode" , StringComparison . OrdinalIgnoreCase ) ) ;
2018-05-09 07:35:42 -07:00
} ) ;
2018-01-19 13:43:39 -08:00
// View3DWidgets Filesystem DropDrop handler
if ( mouseEvent . AcceptDrop
& & this . PositionWithinLocalBounds ( mouseEvent . X , mouseEvent . Y ) )
{
if ( this . DragOperationActive )
{
DragOver ( screenSpaceMousePosition : this . TransformToScreenSpace ( mouseEvent . Position ) ) ;
}
else
{
// Project DragFiles to IEnumerable<FileSystemFileItem>
this . StartDragDrop (
mouseEvent . DragFiles . Select ( path = > new FileSystemFileItem ( path ) ) ,
screenSpaceMousePosition : this . TransformToScreenSpace ( mouseEvent . Position ) ,
trackSourceFiles : true ) ;
}
}
2018-05-22 12:51:04 -07:00
if ( CurrentSelectInfo . DownOnPart
2018-05-18 16:58:18 -07:00
& & TrackballTumbleWidget . TransformState = = TrackBallTransformType . None
& & selectedItem ! = null )
2018-01-19 13:43:39 -08:00
{
2018-05-18 16:58:18 -07:00
DragSelectedObject ( selectedItem , new Vector2 ( mouseEvent . X , mouseEvent . Y ) ) ;
2018-01-19 13:43:39 -08:00
}
if ( DragSelectionInProgress )
{
DragSelectionEndPosition = mouseEvent . Position - OffsetToMeshViewerWidget ( ) ;
DragSelectionEndPosition = new Vector2 (
2018-03-08 17:23:03 -08:00
Math . Max ( Math . Min ( ( double ) DragSelectionEndPosition . X , meshViewerWidget . LocalBounds . Right ) , meshViewerWidget . LocalBounds . Left ) ,
Math . Max ( Math . Min ( ( double ) DragSelectionEndPosition . Y , meshViewerWidget . LocalBounds . Top ) , meshViewerWidget . LocalBounds . Bottom ) ) ;
2018-01-19 13:43:39 -08:00
Invalidate ( ) ;
}
base . OnMouseMove ( mouseEvent ) ;
}
2017-03-15 16:17:06 -07:00
public IntersectInfo GetIntersectPosition ( Vector2 screenSpacePosition )
{
//Vector2 meshViewerWidgetScreenPosition = meshViewerWidget.TransformFromParentSpace(this, new Vector2(mouseEvent.X, mouseEvent.Y));
2016-02-17 08:23:09 -08:00
2017-03-15 16:17:06 -07:00
// Translate to local
Vector2 localPosition = this . TransformFromScreenSpace ( screenSpacePosition ) ;
2017-07-10 14:00:27 -07:00
Ray ray = this . World . GetRayForLocalBounds ( localPosition ) ;
2017-03-15 16:17:06 -07:00
return CurrentSelectInfo . HitPlane . GetClosestIntersection ( ray ) ;
}
2018-05-18 16:58:18 -07:00
public void DragSelectedObject ( IObject3D selectedItem , Vector2 localMousePosition )
2015-05-30 12:48:16 -07:00
{
2018-04-04 15:58:57 -07:00
Vector2 meshViewerWidgetScreenPosition = meshViewerWidget . TransformFromParentSpace ( this , localMousePosition ) ;
2017-07-10 14:00:27 -07:00
Ray ray = this . World . GetRayForLocalBounds ( meshViewerWidgetScreenPosition ) ;
2017-03-15 16:17:06 -07:00
2018-07-16 17:00:00 -07:00
if ( ! PositionWithinLocalBounds ( localMousePosition . X , localMousePosition . Y ) )
{
Matrix4X4 totalTransform = Matrix4X4 . CreateTranslation ( new Vector3 ( - CurrentSelectInfo . LastMoveDelta ) ) ;
selectedItem . Matrix * = totalTransform ;
CurrentSelectInfo . LastMoveDelta = Vector3 . Zero ;
Invalidate ( ) ;
return ;
}
2017-03-15 16:17:06 -07:00
IntersectInfo info = CurrentSelectInfo . HitPlane . GetClosestIntersection ( ray ) ;
if ( info ! = null )
2015-05-30 12:48:16 -07:00
{
2018-01-23 16:56:15 -08:00
if ( CurrentSelectInfo . LastMoveDelta = = Vector3 . PositiveInfinity )
{
2018-05-18 16:58:18 -07:00
CalculateDragStartPosition ( selectedItem , info ) ;
2018-01-23 16:56:15 -08:00
}
2017-03-15 16:17:06 -07:00
// move the mesh back to the start position
{
Matrix4X4 totalTransform = Matrix4X4 . CreateTranslation ( new Vector3 ( - CurrentSelectInfo . LastMoveDelta ) ) ;
2018-05-18 16:58:18 -07:00
selectedItem . Matrix * = totalTransform ;
2017-03-15 16:17:06 -07:00
}
2017-06-16 11:12:24 -07:00
Vector3 delta = info . HitPosition - CurrentSelectInfo . PlaneDownHitPos ;
2017-03-15 16:17:06 -07:00
2017-07-11 08:10:57 -07:00
double snapGridDistance = this . InteractionLayer . SnapGridDistance ;
2017-03-15 16:17:06 -07:00
if ( snapGridDistance > 0 )
2015-02-27 11:09:37 -08:00
{
2017-03-15 16:17:06 -07:00
// snap this position to the grid
2018-05-18 16:58:18 -07:00
AxisAlignedBoundingBox selectedBounds = selectedItem . GetAxisAlignedBoundingBox ( Matrix4X4 . Identity ) ;
2017-03-15 16:17:06 -07:00
2017-10-31 12:51:16 -07:00
double xSnapOffset = selectedBounds . minXYZ . X ;
2017-03-15 16:17:06 -07:00
// snap the x position
if ( CurrentSelectInfo . HitQuadrant = = HitQuadrant . RB
| | CurrentSelectInfo . HitQuadrant = = HitQuadrant . RT )
2016-02-18 09:36:01 -08:00
{
2017-03-15 16:17:06 -07:00
// switch to the other side
2017-10-31 12:51:16 -07:00
xSnapOffset = selectedBounds . maxXYZ . X ;
2016-02-18 09:36:01 -08:00
}
2017-10-31 12:51:16 -07:00
double xToSnap = xSnapOffset + delta . X ;
2016-02-18 09:36:01 -08:00
2017-03-15 16:17:06 -07:00
double snappedX = ( ( int ) ( ( xToSnap / snapGridDistance ) + . 5 ) ) * snapGridDistance ;
2017-10-31 12:51:16 -07:00
delta . X = snappedX - xSnapOffset ;
2015-02-27 11:09:37 -08:00
2017-10-31 12:51:16 -07:00
double ySnapOffset = selectedBounds . minXYZ . Y ;
2017-03-15 16:17:06 -07:00
// snap the y position
if ( CurrentSelectInfo . HitQuadrant = = HitQuadrant . LT
| | CurrentSelectInfo . HitQuadrant = = HitQuadrant . RT )
2016-02-17 08:23:09 -08:00
{
2017-03-15 16:17:06 -07:00
// switch to the other side
2017-10-31 12:51:16 -07:00
ySnapOffset = selectedBounds . maxXYZ . Y ;
2017-03-15 16:17:06 -07:00
}
2017-10-31 12:51:16 -07:00
double yToSnap = ySnapOffset + delta . Y ;
2016-02-17 08:23:09 -08:00
2017-03-15 16:17:06 -07:00
double snappedY = ( ( int ) ( ( yToSnap / snapGridDistance ) + . 5 ) ) * snapGridDistance ;
2017-10-31 12:51:16 -07:00
delta . Y = snappedY - ySnapOffset ;
2017-03-15 16:17:06 -07:00
}
2016-02-17 08:23:09 -08:00
2017-08-15 11:05:32 -07:00
// if the shift key is down only move on the major axis of x or y
2018-02-07 18:01:49 -08:00
if ( Keyboard . IsKeyDown ( Keys . ShiftKey ) )
2017-08-15 11:05:32 -07:00
{
2018-02-07 18:01:49 -08:00
if ( Math . Abs ( delta . X ) < Math . Abs ( delta . Y ) )
2017-08-15 11:05:32 -07:00
{
2017-10-31 12:51:16 -07:00
delta . X = 0 ;
2017-08-15 11:05:32 -07:00
}
else
{
2017-10-31 12:51:16 -07:00
delta . Y = 0 ;
2017-08-15 11:05:32 -07:00
}
}
2017-03-15 16:17:06 -07:00
// move the mesh back to the new position
{
Matrix4X4 totalTransform = Matrix4X4 . CreateTranslation ( new Vector3 ( delta ) ) ;
2015-02-27 11:09:37 -08:00
2018-05-18 16:58:18 -07:00
selectedItem . Matrix * = totalTransform ;
2016-02-18 09:36:01 -08:00
2017-03-15 16:17:06 -07:00
CurrentSelectInfo . LastMoveDelta = delta ;
}
2016-02-18 09:36:01 -08:00
2017-03-15 16:17:06 -07:00
Invalidate ( ) ;
}
}
2015-02-27 11:09:37 -08:00
2017-05-31 17:47:12 -07:00
Vector2 OffsetToMeshViewerWidget ( )
{
List < GuiWidget > parents = new List < GuiWidget > ( ) ;
GuiWidget parent = meshViewerWidget . Parent ;
while ( parent ! = this )
{
parents . Add ( parent ) ;
parent = parent . Parent ;
}
Vector2 offset = new Vector2 ( ) ;
2018-02-07 18:01:49 -08:00
for ( int i = parents . Count - 1 ; i > = 0 ; i - - )
2017-05-31 17:47:12 -07:00
{
offset + = parents [ i ] . OriginRelativeParent ;
}
return offset ;
}
2017-07-10 14:00:27 -07:00
public void ResetView ( )
{
2018-04-23 14:33:27 -07:00
TrackballTumbleWidget . ZeroVelocity ( ) ;
2017-07-10 14:00:27 -07:00
var world = this . World ;
world . Reset ( ) ;
world . Scale = . 03 ;
2017-09-15 16:49:21 -07:00
world . Translate ( - new Vector3 ( sceneContext . BedCenter ) ) ;
2017-11-08 14:45:36 -08:00
world . Rotate ( Quaternion . FromEulerAngles ( new Vector3 ( 0 , 0 , - MathHelper . Tau / 16 ) ) ) ;
world . Rotate ( Quaternion . FromEulerAngles ( new Vector3 ( MathHelper . Tau * . 19 , 0 , 0 ) ) ) ;
2018-04-23 14:33:27 -07:00
Invalidate ( ) ;
2017-07-10 14:00:27 -07:00
}
2015-05-30 12:48:16 -07:00
public override void OnMouseUp ( MouseEventArgs mouseEvent )
2015-04-08 15:20:10 -07:00
{
2018-08-11 08:50:40 -07:00
var selectedItem = Scene . SelectedItem ;
2017-09-19 19:59:55 -07:00
if ( this . DragOperationActive )
2017-04-05 16:25:43 -07:00
{
2017-09-19 19:59:55 -07:00
this . FinishDrop ( mouseUpInBounds : true ) ;
2017-04-05 16:25:43 -07:00
}
2018-04-23 14:33:27 -07:00
if ( TrackballTumbleWidget . TransformState = = TrackBallTransformType . None )
2015-04-08 15:20:10 -07:00
{
2018-08-11 08:50:40 -07:00
if ( selectedItem ! = null
2017-07-11 12:50:21 -07:00
& & CurrentSelectInfo . DownOnPart
& & CurrentSelectInfo . LastMoveDelta ! = Vector3 . Zero )
2016-02-27 13:56:57 -08:00
{
2018-04-23 14:33:27 -07:00
InteractionLayer . AddTransformSnapshot ( TransformOnMouseDown ) ;
2017-05-31 17:47:12 -07:00
}
else if ( DragSelectionInProgress )
{
2017-06-06 10:57:13 -07:00
DoRectangleSelection ( null ) ;
2017-05-31 17:47:12 -07:00
DragSelectionInProgress = false ;
2016-02-27 13:56:57 -08:00
}
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
2017-03-15 16:17:06 -07:00
meshViewerWidget . SuppressUiVolumes = false ;
2016-02-19 08:29:49 -08:00
CurrentSelectInfo . DownOnPart = false ;
2015-04-08 15:20:10 -07:00
2015-05-29 15:13:56 -07:00
if ( activeButtonBeforeMouseOverride ! = null )
{
viewControls3D . ActiveButton = ( ViewControls3DButtons ) activeButtonBeforeMouseOverride ;
activeButtonBeforeMouseOverride = null ;
}
2018-05-09 16:41:24 -07:00
// if we had a down and an up that did not move the view
if ( worldMatrixOnMouseDown = = World . GetTransform4X4 ( ) )
{
// and we are the first under mouse
if ( TrackballTumbleWidget . UnderMouseState = = UnderMouseState . FirstUnderMouse )
{
// and the control key is pressed
if ( ModifierKeys = = Keys . Control )
{
// find the think we clicked on
IntersectInfo info = new IntersectInfo ( ) ;
var hitObject = FindHitObject3D ( mouseEvent . Position , ref info ) ;
if ( hitObject ! = null )
{
2018-08-11 08:50:40 -07:00
if ( selectedItem = = hitObject
& & ! ( selectedItem is SelectionGroupObject3D ) )
2018-05-09 16:41:24 -07:00
{
Scene . SelectedItem = null ;
}
else
{
IObject3D selectedHitItem = null ;
2018-08-11 08:50:40 -07:00
if ( selectedItem ! = null )
2018-05-09 16:41:24 -07:00
{
2018-08-11 08:50:40 -07:00
foreach ( Object3D object3D in selectedItem . Children )
2018-05-09 16:41:24 -07:00
{
if ( object3D . TraceData ( ) . Contains ( info . HitPosition ) )
{
CurrentSelectInfo . PlaneDownHitPos = info . HitPosition ;
CurrentSelectInfo . LastMoveDelta = new Vector3 ( ) ;
selectedHitItem = object3D ;
break ;
}
}
}
if ( selectedHitItem ! = null )
{
2018-08-11 08:50:40 -07:00
selectedItem . Children . Remove ( selectedHitItem ) ;
if ( selectedItem . Children . Count = = 0 )
2018-05-09 16:41:24 -07:00
{
Scene . SelectedItem = null ;
}
Scene . Children . Add ( selectedHitItem ) ;
}
else
{
Scene . AddToSelection ( hitObject ) ;
}
2018-08-11 09:54:16 -07:00
// Selection may have changed, update local reference to current value
selectedItem = Scene . SelectedItem ;
2018-05-09 16:41:24 -07:00
}
}
}
}
}
2018-08-07 16:22:37 -07:00
if ( mouseEvent . Button = = MouseButtons . Right
& & mouseDownPositon = = mouseEvent . Position
& & this . TrackballTumbleWidget . FirstWidgetUnderMouse )
{
2018-08-08 07:00:43 -07:00
var info = new IntersectInfo ( ) ;
2018-08-27 13:49:57 -07:00
if ( FindHitObject3D ( mouseEvent . Position , ref info ) is IObject3D hitObject
2018-08-29 08:31:16 -07:00
& & ( this . Printer = = null // Allow Model -> Right Click in Part view
| | this . Printer ? . ViewState . ViewMode = = PartViewMode . Model ) ) // Disallow Model -> Right Click in GCode views
2018-08-07 16:22:37 -07:00
{
2018-08-08 07:28:02 -07:00
// Object3D/hit item context menu
2018-08-11 08:50:40 -07:00
if ( hitObject ! = selectedItem )
2018-08-07 16:22:37 -07:00
{
Scene . SelectedItem = null ;
Scene . SelectedItem = hitObject ;
2018-08-11 08:50:40 -07:00
selectedItem = hitObject ;
2018-08-07 16:22:37 -07:00
}
UiThread . RunOnIdle ( ( ) = >
{
2018-08-11 08:50:40 -07:00
var menu = ApplicationController . Instance . GetActionMenuForSceneItem ( selectedItem , Scene ) ;
2018-08-07 16:22:37 -07:00
var systemWindow = this . Parents < SystemWindow > ( ) . FirstOrDefault ( ) ;
systemWindow . ShowPopup (
2018-08-07 17:45:27 -07:00
new MatePoint ( this )
{
Mate = new MateOptions ( MateEdge . Left , MateEdge . Top ) ,
AltMate = new MateOptions ( MateEdge . Left , MateEdge . Top )
} ,
new MatePoint ( menu )
{
Mate = new MateOptions ( MateEdge . Left , MateEdge . Top ) ,
AltMate = new MateOptions ( MateEdge . Left , MateEdge . Top )
} ,
altBounds : new RectangleDouble ( mouseEvent . X + 1 , mouseEvent . Y + 1 , mouseEvent . X + 1 , mouseEvent . Y + 1 ) ) ;
2018-08-08 07:28:02 -07:00
var actions = new [ ] {
new ActionSeparator ( ) ,
WorkspaceActions [ "Cut" ] ,
WorkspaceActions [ "Copy" ] ,
WorkspaceActions [ "Paste" ] ,
new ActionSeparator ( ) ,
new NamedAction ( )
{
Title = "Save As" . Localize ( ) ,
Action = ( ) = > UiThread . RunOnIdle ( ( ) = >
{
DialogWindow . Show (
new SaveAsPage (
async ( newName , destinationContainer ) = >
{
// Save to the destination provider
if ( destinationContainer is ILibraryWritableContainer writableContainer )
{
// Wrap stream with ReadOnlyStream library item and add to container
writableContainer . Add ( new [ ]
{
new InMemoryLibraryItem ( selectedItem )
{
Name = newName
}
} ) ;
destinationContainer . Dispose ( ) ;
}
} ) ) ;
} ) ,
IsEnabled = ( ) = > sceneContext . EditableScene
} ,
new NamedAction ( )
{
ID = "Export" ,
Title = "Export" . Localize ( ) ,
Action = ( ) = >
{
UiThread . RunOnIdle ( async ( ) = >
{
DialogWindow . Show (
new ExportPrintItemPage ( new [ ]
{
new InMemoryLibraryItem ( selectedItem )
2018-09-07 10:25:29 -07:00
} , false ) ) ;
2018-08-08 07:28:02 -07:00
} ) ;
}
} } ;
theme . CreateMenuItems ( menu , actions , emptyMenu : false ) ;
2018-08-28 18:45:58 -07:00
menu . CreateHorizontalLine ( ) ;
string componentID = ( selectedItem as ComponentObject3D ) ? . ComponentID ;
var helpItem = menu . CreateMenuItem ( "Help" . Localize ( ) ) ;
helpItem . Enabled = ! string . IsNullOrEmpty ( componentID ) & & ApplicationController . Instance . HelpArticlesByID . ContainsKey ( componentID ) ;
helpItem . Click + = ( s , e ) = >
{
DialogWindow . Show ( new HelpPage ( componentID ) ) ;
} ;
2018-08-07 16:22:37 -07:00
} ) ;
}
2018-08-27 13:49:57 -07:00
else // Allow right click on bed in all modes
2018-08-07 16:22:37 -07:00
{
2018-08-08 07:28:02 -07:00
// Workspace/plate context menu
2018-08-07 16:22:37 -07:00
UiThread . RunOnIdle ( ( ) = >
{
2018-08-10 13:29:38 -07:00
var popupMenu = new PopupMenu ( ApplicationController . Instance . MenuTheme ) ;
2018-08-07 16:22:37 -07:00
2018-08-08 07:28:02 -07:00
var actions = new [ ] {
new ActionSeparator ( ) ,
WorkspaceActions [ "Insert" ] ,
new ActionSeparator ( ) ,
new NamedAction ( )
{
Title = "Paste" . Localize ( ) ,
Action = ( ) = >
{
Scene . Paste ( ) ;
popupMenu . Unfocus ( ) ;
} ,
IsEnabled = ( ) = > Clipboard . Instance . ContainsImage | | Clipboard . Instance . GetText ( ) = = "!--IObjectSelection--!"
} ,
WorkspaceActions [ "Save" ] ,
WorkspaceActions [ "SaveAs" ] ,
WorkspaceActions [ "Export" ] ,
new ActionSeparator ( ) ,
WorkspaceActions [ "ArrangeAll" ] ,
WorkspaceActions [ "ClearBed" ] ,
2018-08-07 16:22:37 -07:00
} ;
2018-08-08 07:28:02 -07:00
theme . CreateMenuItems ( popupMenu , actions , emptyMenu : false ) ;
2018-08-07 16:22:37 -07:00
var popupBounds = new RectangleDouble ( mouseEvent . X + 1 , mouseEvent . Y + 1 , mouseEvent . X + 1 , mouseEvent . Y + 1 ) ;
var systemWindow = this . Parents < SystemWindow > ( ) . FirstOrDefault ( ) ;
systemWindow . ShowPopup (
new MatePoint ( this )
{
Mate = new MateOptions ( MateEdge . Left , MateEdge . Bottom ) ,
AltMate = new MateOptions ( MateEdge . Left , MateEdge . Top )
} ,
new MatePoint ( popupMenu )
{
Mate = new MateOptions ( MateEdge . Left , MateEdge . Top ) ,
AltMate = new MateOptions ( MateEdge . Left , MateEdge . Top )
} ,
altBounds : popupBounds ) ;
} ) ;
}
}
2015-05-30 12:48:16 -07:00
base . OnMouseUp ( mouseEvent ) ;
Move to new library model and view
- Add new listview control for library content
- Migrate library providers to containers
- Cloud, Sqlite, Directories, Queue, History
- Migrate SideBar components to containers
- Primatives, Text, Braille, ImageConverter
- Create new library container types
- Zip files, Calibration parts, Printer SDCards
- Reduce leftnav to Library, Settings, Controls, Options
- Add DragDrop support for image content
2017-05-19 22:33:55 -07:00
if ( deferEditorTillMouseUp )
{
this . deferEditorTillMouseUp = false ;
Scene_SelectionChanged ( null , null ) ;
}
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
2017-09-16 01:36:19 -07:00
// TODO: Consider if we should always allow DragDrop or if we should prevent during printer or other scenarios
2017-09-15 22:34:46 -07:00
private bool AllowDragDrop ( ) = > true ;
2015-05-30 12:48:16 -07:00
2015-06-11 12:06:40 -07:00
private void AutoSpin ( )
2015-05-30 12:48:16 -07:00
{
2016-04-25 12:51:29 -07:00
if ( ! HasBeenClosed & & autoRotating )
2015-05-30 12:48:16 -07:00
{
if ( ( ! timeSinceLastSpin . IsRunning | | timeSinceLastSpin . ElapsedMilliseconds > 50 )
& & hasDrawn )
{
hasDrawn = false ;
timeSinceLastSpin . Restart ( ) ;
2017-07-11 08:10:57 -07:00
Quaternion currentRotation = this . World . RotationMatrix . GetRotation ( ) ;
2015-05-30 12:48:16 -07:00
Quaternion invertedRotation = Quaternion . Invert ( currentRotation ) ;
Quaternion rotateAboutZ = Quaternion . FromEulerAngles ( new Vector3 ( 0 , 0 , . 01 ) ) ;
rotateAboutZ = invertedRotation * rotateAboutZ * currentRotation ;
2017-07-10 14:00:27 -07:00
this . World . Rotate ( rotateAboutZ ) ;
2015-05-30 12:48:16 -07:00
Invalidate ( ) ;
}
}
}
2017-03-15 16:17:06 -07:00
private void Scene_SelectionChanged ( object sender , EventArgs e )
{
2018-07-13 06:55:00 -07:00
var selectedItem = Scene . SelectedItem ;
2018-04-11 11:29:21 -07:00
foreach ( var child in selectedObjectPanel . ContentPanel . Children )
{
2018-07-13 06:55:00 -07:00
child . Enabled = selectedItem ! = null ;
2018-04-11 11:29:21 -07:00
}
2018-04-05 15:43:52 -07:00
2018-07-13 06:55:00 -07:00
if ( selectedItem = = null )
2017-03-15 16:17:06 -07:00
{
2018-06-22 00:04:03 -07:00
this . Scene . ClearSelection ( ) ;
2018-01-09 09:14:12 -08:00
2018-06-22 00:04:03 -07:00
// Clear the TreeView and release node references when no item is selected
selectedObjectPanel . SetActiveItem ( null ) ;
treeView . Clear ( ) ;
2017-03-15 16:17:06 -07:00
return ;
}
2015-05-30 12:48:16 -07:00
2017-04-05 19:03:04 -07:00
if ( deferEditorTillMouseUp )
{
return ;
}
2018-05-22 12:51:04 -07:00
// Top level selection only - rebuild tree
2018-07-13 06:55:00 -07:00
if ( Scene . Children . Contains ( selectedItem ) )
2018-05-22 12:51:04 -07:00
{
2018-06-01 08:49:02 -07:00
treeView . ScrollArea . CloseAllChildren ( ) ;
2018-07-13 06:55:00 -07:00
var rootNode = Object3DTreeBuilder . BuildTree ( selectedItem , theme ) ;
2018-06-01 08:49:02 -07:00
treeView . AddChild ( rootNode ) ;
rootNode . TreeView = treeView ;
if ( this . Parent ! = null )
{
2018-06-07 13:46:04 -07:00
assigningTreeNode = true ;
2018-06-01 08:49:02 -07:00
treeView . SelectedNode = rootNode ;
2018-06-07 13:46:04 -07:00
assigningTreeNode = false ;
2018-06-01 08:49:02 -07:00
}
2018-05-22 12:51:04 -07:00
}
2017-03-15 16:17:06 -07:00
}
2015-05-30 12:48:16 -07:00
2018-06-22 00:04:03 -07:00
public void ClearPlate ( )
{
selectedObjectPanel . SetActiveItem ( null ) ;
sceneContext . ClearPlate ( ) . ContinueWith ( t = >
{
sceneContext . Scene . UndoBuffer . ClearHistory ( ) ;
GC . Collect ( ) ;
UiThread . RunOnIdle ( ( ) = >
{
GC . Collect ( ) ;
this . Invalidate ( ) ;
} , 1 ) ;
} ) ;
}
2016-01-10 10:18:53 -08:00
public static Regex fileNameNumberMatch = new Regex ( "\\(\\d+\\)" , RegexOptions . Compiled ) ;
2017-10-20 07:26:14 -07:00
private SelectedObjectPanel selectedObjectPanel ;
2018-05-30 16:42:17 -07:00
internal LeftResizeContainer modelViewSidePanel ;
2017-10-19 09:04:36 -07:00
2017-05-31 17:47:12 -07:00
public Vector2 DragSelectionStartPosition { get ; private set ; }
public bool DragSelectionInProgress { get ; private set ; }
public Vector2 DragSelectionEndPosition { get ; private set ; }
2018-01-21 21:07:14 -08:00
internal GuiWidget ShowOverflowMenu ( PopupMenu popupMenu )
2017-05-25 17:58:20 -07:00
{
2018-03-16 17:42:34 -07:00
this . ShowBedViewOptions ( popupMenu ) ;
2017-11-09 15:48:05 -08:00
2018-07-12 09:22:28 -07:00
popupMenu . AddChild ( new GridOptionsPanel ( this . InteractionLayer , theme ) ) ;
2017-05-25 17:58:20 -07:00
2017-11-09 18:26:32 -08:00
return popupMenu ;
2017-11-09 15:48:05 -08:00
}
2017-05-25 17:58:20 -07:00
2018-03-16 17:42:34 -07:00
internal void ShowBedViewOptions ( PopupMenu popupMenu )
{
2018-04-02 16:19:45 -07:00
// TODO: Extend popup menu if applicable
// popupMenu.CreateHorizontalLine();
2018-03-16 17:42:34 -07:00
}
2017-07-05 14:34:38 -07:00
protected bool autoRotating = false ;
protected bool allowAutoRotate = false ;
public MeshViewerWidget meshViewerWidget ;
2018-06-07 13:46:04 -07:00
private bool assigningTreeNode ;
2017-07-05 14:34:38 -07:00
2018-04-23 14:33:27 -07:00
public InteractiveScene Scene = > sceneContext . Scene ;
2017-07-05 14:34:38 -07:00
protected ViewControls3D viewControls3D { get ; }
2017-07-12 21:57:30 -07:00
public MeshSelectInfo CurrentSelectInfo { get ; } = new MeshSelectInfo ( ) ;
2017-07-05 14:34:38 -07:00
protected IObject3D FindHitObject3D ( Vector2 screenPosition , ref IntersectInfo intersectionInfo )
{
Vector2 meshViewerWidgetScreenPosition = meshViewerWidget . TransformFromParentSpace ( this , screenPosition ) ;
2017-07-10 14:00:27 -07:00
Ray ray = this . World . GetRayForLocalBounds ( meshViewerWidgetScreenPosition ) ;
2017-07-05 14:34:38 -07:00
2018-04-23 14:33:27 -07:00
intersectionInfo = Scene . TraceData ( ) . GetClosestIntersection ( ray ) ;
2017-07-05 14:34:38 -07:00
if ( intersectionInfo ! = null )
{
2018-04-23 14:33:27 -07:00
foreach ( Object3D object3D in Scene . Children )
2017-07-05 14:34:38 -07:00
{
2018-01-02 15:25:40 -08:00
if ( object3D . TraceData ( ) . Contains ( intersectionInfo . HitPosition ) )
2017-07-05 14:34:38 -07:00
{
CurrentSelectInfo . PlaneDownHitPos = intersectionInfo . HitPosition ;
CurrentSelectInfo . LastMoveDelta = new Vector3 ( ) ;
return object3D ;
}
}
}
return null ;
}
2018-02-07 18:01:49 -08:00
2018-04-23 14:33:27 -07:00
public void Save ( )
{
2018-04-23 18:48:17 -07:00
ApplicationController . Instance . Tasks . Execute ( "Saving" . Localize ( ) , Printer . Bed . SaveChanges ) ;
2018-04-23 14:33:27 -07:00
}
2016-02-19 08:29:49 -08:00
}
2015-05-30 12:48:16 -07:00
2016-02-19 08:29:49 -08:00
public enum HitQuadrant { LB , LT , RB , RT }
2018-03-01 09:56:50 -08:00
2016-02-19 08:29:49 -08:00
public class MeshSelectInfo
{
public HitQuadrant HitQuadrant ;
public bool DownOnPart ;
public PlaneShape HitPlane ;
public Vector3 LastMoveDelta ;
public Vector3 PlaneDownHitPos ;
2015-04-08 15:20:10 -07:00
}
2017-08-20 02:34:39 -07:00
}