2014-01-29 19:09:30 -08:00
/ *
2017-05-27 17:48:32 -07:00
Copyright ( c ) 2017 , 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.Collections.ObjectModel ;
using System.Diagnostics ;
using System.Globalization ;
using System.IO ;
using System.Linq ;
using System.Text.RegularExpressions ;
using System.Threading ;
using System.Threading.Tasks ;
2014-01-29 19:09:30 -08:00
using MatterHackers.Agg ;
2017-11-10 13:12:02 -08:00
using MatterHackers.Agg.Image ;
2017-07-10 14:00:27 -07:00
using MatterHackers.Agg.OpenGlGui ;
2017-08-20 02:34:39 -07:00
using MatterHackers.Agg.Platform ;
2015-04-08 15:20:10 -07:00
using MatterHackers.Agg.Transform ;
2014-01-29 19:09:30 -08:00
using MatterHackers.Agg.UI ;
2014-11-22 20:35:40 -08:00
using MatterHackers.Agg.VertexSource ;
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 ;
using MatterHackers.MatterControl.DataStorage ;
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-06-11 14:52:58 -07:00
using MatterHackers.MatterControl.PrinterCommunication ;
2017-09-19 19:59:55 -07:00
using MatterHackers.MatterControl.PrintLibrary ;
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.RayTracer ;
2014-04-15 18:13:27 -07:00
using MatterHackers.RenderOpenGl ;
using MatterHackers.VectorMath ;
2014-01-29 19:09:30 -08:00
namespace MatterHackers.MatterControl.PartPreviewWindow
{
2017-07-12 21:38:40 -07:00
public class View3DWidget : GuiWidget
2015-04-08 15:20:10 -07:00
{
2017-03-15 16:17:06 -07:00
private bool DoBooleanTest = false ;
2017-04-05 19:03:04 -07:00
private bool deferEditorTillMouseUp = false ;
2017-09-27 12:47:23 -07:00
public DisableablePanel bottomActionPanel ;
2016-02-26 21:54:15 -08:00
public readonly int EditButtonHeight = 44 ;
2017-03-15 16:17:06 -07:00
2017-10-25 10:49:24 -07:00
private ObservableCollection < GuiWidget > materialButtons = new ObservableCollection < GuiWidget > ( ) ;
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 ( ) ;
private Matrix4X4 transformOnMouseDown = Matrix4X4 . Identity ;
private EventHandler unregisterEvents ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
private bool wasInSelectMode = false ;
2015-04-08 15:20:10 -07:00
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
public TrackballTumbleWidget TrackballTumbleWidget { get ; }
2017-07-11 08:10:57 -07:00
public InteractionLayer InteractionLayer { get ; }
2017-09-15 16:49:21 -07:00
private BedConfig sceneContext ;
2017-10-16 17:09:00 -07:00
private PrinterConfig printer ;
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-08-18 08:34:05 -07:00
var smallMarginButtonFactory = theme . SmallMarginButtonFactory ;
2017-09-15 16:49:21 -07:00
this . sceneContext = sceneContext ;
2017-10-30 08:53:53 -07:00
this . printerTabPage = printerTabBase as PrinterTabPage ;
2017-09-15 16:49:21 -07:00
this . Scene = sceneContext . Scene ;
2017-10-16 17:09:00 -07:00
this . printer = printer ;
2017-07-10 14:00:27 -07:00
2017-09-16 01:19:35 -07:00
this . TrackballTumbleWidget = new TrackballTumbleWidget ( sceneContext . World )
2017-07-10 14:00:27 -07:00
{
TransformState = TrackBallController . MouseDownType . Rotation
} ;
this . TrackballTumbleWidget . AnchorAll ( ) ;
2017-10-25 17:04:55 -07:00
this . InteractionLayer = new InteractionLayer ( this . World , this . Scene . UndoBuffer , this . 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" ;
2017-11-27 16:41:52 -08:00
this . BackgroundColor = theme . TabBodyBackground ;
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-07-05 15:43:58 -07:00
var mainContainerTopToBottom = new FlowLayoutWidget ( FlowDirection . TopToBottom )
{
2017-08-07 15:47:27 -07:00
HAnchor = HAnchor . MaxFitOrStretch ,
VAnchor = VAnchor . MaxFitOrStretch
2017-07-05 15:43:58 -07:00
} ;
2015-04-08 15:20:10 -07:00
2017-08-18 08:34:05 -07:00
// MeshViewer
2017-09-15 16:49:21 -07:00
meshViewerWidget = new MeshViewerWidget ( sceneContext , this . InteractionLayer , editorType : editorType ) ;
2017-11-20 13:09:52 -08:00
meshViewerWidget . RenderBed = sceneContext . RendererOptions . RenderBed ;
2017-07-05 15:37:32 -07:00
meshViewerWidget . AnchorAll ( ) ;
2017-07-11 08:10:57 -07:00
this . InteractionLayer . AddChild ( meshViewerWidget ) ;
2015-04-08 15:20:10 -07:00
2017-08-18 08:34:05 -07:00
// TumbleWidget
2017-07-11 08:10:57 -07:00
this . InteractionLayer . AddChild ( this . TrackballTumbleWidget ) ;
2017-08-18 12:40:49 -07:00
this . InteractionLayer . SetRenderTarget ( this . meshViewerWidget ) ;
2017-07-10 14:00:27 -07:00
2017-07-11 08:10:57 -07:00
mainContainerTopToBottom . AddChild ( this . InteractionLayer ) ;
2015-04-08 15:20:10 -07:00
2017-06-08 10:14:06 -07:00
var buttonBottomPanel = new FlowLayoutWidget ( FlowDirection . LeftToRight )
{
2017-08-07 15:47:27 -07:00
HAnchor = HAnchor . Stretch ,
2017-11-27 16:41:52 -08:00
Padding = theme . ToolbarPadding ,
2017-08-04 15:42:23 -07:00
BackgroundColor = ActiveTheme . Instance . PrimaryBackgroundColor ,
2017-06-08 10:14:06 -07:00
} ;
2015-04-08 15:20:10 -07:00
2017-03-15 16:17:06 -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
Scene . Invalidated + = ( s , e ) = > Invalidate ( ) ;
2015-05-30 12:48:16 -07:00
// add in the plater tools
2015-04-08 15:20:10 -07:00
{
2017-09-27 12:47:23 -07:00
var selectionActionBar = new FlowLayoutWidget ( )
2017-08-12 00:40:03 -07:00
{
VAnchor = VAnchor . Center | VAnchor . Fit ,
HAnchor = HAnchor . Stretch
} ;
2017-08-07 07:41:30 -07:00
2017-09-27 12:47:23 -07:00
bottomActionPanel = new DisableablePanel ( selectionActionBar , enabled : true ) ;
2017-10-25 10:49:24 -07:00
var buttonSpacing = theme . ButtonSpacing ;
2014-01-29 19:09:30 -08:00
2017-10-14 23:18:06 -07:00
Button addButton = smallMarginButtonFactory . Generate ( "Insert" . Localize ( ) , AggContext . StaticData . LoadIcon ( "cube.png" , 14 , 14 , IconColor . Theme ) ) ;
2017-08-14 11:53:45 -07:00
addButton . Margin = 0 ;
2017-08-07 07:41:30 -07:00
addButton . Click + = ( sender , e ) = >
{
2017-09-27 07:20:35 -07:00
UiThread . RunOnIdle ( ( ) = >
2017-07-01 08:21:29 -07:00
{
2017-08-20 02:34:39 -07:00
AggContext . FileDialogs . OpenFileDialog (
2017-08-07 07:41:30 -07:00
new OpenFileDialogParams ( ApplicationSettings . OpenDesignFileParams , multiSelect : true ) ,
2017-09-27 07:20:35 -07:00
( openParams ) = >
2017-08-07 07:41:30 -07:00
{
2017-09-27 07:20:35 -07:00
this . LoadAndAddPartsToPlate ( openParams . FileNames ) ;
} ) ;
} ) ;
2017-08-07 07:41:30 -07:00
} ;
2017-08-07 09:17:20 -07:00
selectionActionBar . AddChild ( addButton ) ;
2014-12-19 09:39:29 -08:00
2017-09-27 12:47:23 -07:00
selectionActionBar . AddChild ( this . CreateActionSeparator ( ) ) ;
2014-10-13 18:20:01 -07:00
2017-08-07 07:41:30 -07:00
Button ungroupButton = smallMarginButtonFactory . Generate ( "Ungroup" . Localize ( ) ) ;
ungroupButton . Name = "3D View Ungroup" ;
2017-08-07 09:17:20 -07:00
ungroupButton . Margin = buttonSpacing ;
2017-08-07 07:41:30 -07:00
ungroupButton . Click + = ( sender , e ) = >
{
this . Scene . UngroupSelection ( this ) ;
} ;
2017-08-16 18:22:40 -07:00
this . Scene . SelectionChanged + = ( s , e ) = >
{
2017-08-17 17:18:33 -07:00
ungroupButton . Enabled = this . Scene . HasSelection ;
2017-08-16 18:22:40 -07:00
} ;
2017-08-07 09:17:20 -07:00
selectionActionBar . AddChild ( ungroupButton ) ;
2014-10-29 13:15:53 -07:00
2017-08-07 07:41:30 -07:00
Button groupButton = smallMarginButtonFactory . Generate ( "Group" . Localize ( ) ) ;
groupButton . Name = "3D View Group" ;
2017-08-07 09:17:20 -07:00
groupButton . Margin = buttonSpacing ;
2017-08-07 07:41:30 -07:00
groupButton . Click + = ( sender , e ) = >
{
this . Scene . GroupSelection ( this ) ;
} ;
2017-08-16 18:22:40 -07:00
this . Scene . SelectionChanged + = ( s , e ) = >
{
groupButton . Enabled = this . Scene . HasSelection
2017-10-13 15:00:08 -07:00
& & this . Scene . SelectedItem . ItemType ! = Object3DTypes . Group
2017-08-16 18:22:40 -07:00
& & this . Scene . SelectedItem . Children . Count > 1 ;
} ;
2017-08-07 09:17:20 -07:00
selectionActionBar . AddChild ( groupButton ) ;
2014-10-15 14:11:14 -07:00
2017-08-15 16:56:54 -07:00
// this is closer to the old align button
if ( false )
{
2017-08-17 15:21:29 -07:00
var absoluteButton = smallMarginButtonFactory . Generate ( "Absolute" . Localize ( ) ) ;
2017-08-15 16:56:54 -07:00
absoluteButton . Margin = buttonSpacing ;
absoluteButton . Click + = ( sender , e ) = >
{
if ( this . Scene . HasSelection )
{
this . Scene . SelectedItem . Matrix = Matrix4X4 . Identity ;
}
} ;
selectionActionBar . AddChild ( absoluteButton ) ;
}
2017-08-16 18:22:40 -07:00
// put in the material options
var alignButton = new PopupButton ( smallMarginButtonFactory . Generate ( "Align" . Localize ( ) ) )
2017-08-07 07:41:30 -07:00
{
2017-08-16 18:22:40 -07:00
PopDirection = Direction . Up ,
PopupContent = this . AddAlignControls ( ) ,
AlignToRightEdge = true ,
Margin = buttonSpacing
} ;
this . Scene . SelectionChanged + = ( s , e ) = >
{
alignButton . Enabled = this . Scene . HasSelection
2017-10-13 15:00:08 -07:00
& & this . Scene . SelectedItem . ItemType ! = Object3DTypes . Group
2017-08-16 18:22:40 -07:00
& & this . Scene . SelectedItem . Children . Count > 1 ;
2017-08-07 07:41:30 -07:00
} ;
2017-08-07 09:17:20 -07:00
selectionActionBar . AddChild ( alignButton ) ;
2015-05-01 09:45:50 -07:00
2017-08-17 15:21:29 -07:00
var layFlatButton = smallMarginButtonFactory . Generate ( "Lay Flat" . Localize ( ) ) ;
2017-08-15 16:56:54 -07:00
layFlatButton . Margin = buttonSpacing ;
layFlatButton . Click + = ( sender , e ) = >
{
if ( this . Scene . HasSelection )
{
MakeLowestFaceFlat ( this . Scene . SelectedItem ) ;
}
} ;
2017-08-16 18:22:40 -07:00
this . Scene . SelectionChanged + = ( s , e ) = >
{
layFlatButton . Enabled = this . Scene . HasSelection ;
} ;
2017-08-15 16:56:54 -07:00
selectionActionBar . AddChild ( layFlatButton ) ;
2017-09-27 12:47:23 -07:00
selectionActionBar . AddChild ( this . CreateActionSeparator ( ) ) ;
2014-01-29 19:09:30 -08:00
2017-12-19 10:29:35 -08:00
var duplicateButton = smallMarginButtonFactory . Generate ( "Duplicate" . Localize ( ) ) ;
duplicateButton . Name = "3D View Copy" ;
duplicateButton . Margin = buttonSpacing ;
duplicateButton . Click + = ( sender , e ) = >
2017-08-07 07:41:30 -07:00
{
this . Scene . DuplicateSelection ( this ) ;
} ;
2017-08-16 18:22:40 -07:00
this . Scene . SelectionChanged + = ( s , e ) = >
{
2017-12-19 10:29:35 -08:00
duplicateButton . Enabled = this . Scene . HasSelection ;
2017-08-16 18:22:40 -07:00
} ;
2017-12-19 10:29:35 -08:00
selectionActionBar . AddChild ( duplicateButton ) ;
2014-10-13 18:20:01 -07:00
2017-08-17 15:21:29 -07:00
var deleteButton = smallMarginButtonFactory . Generate ( "Remove" . Localize ( ) ) ;
2017-08-07 07:41:30 -07:00
deleteButton . Name = "3D View Remove" ;
2017-08-07 09:17:20 -07:00
deleteButton . Margin = buttonSpacing ;
2017-08-07 07:41:30 -07:00
deleteButton . Click + = ( sender , e ) = >
{
this . Scene . DeleteSelection ( this ) ;
} ;
2017-08-16 18:22:40 -07:00
this . Scene . SelectionChanged + = ( s , e ) = >
{
deleteButton . Enabled = this . Scene . HasSelection ;
} ;
2017-08-07 09:17:20 -07:00
selectionActionBar . AddChild ( deleteButton ) ;
2014-12-20 09:07:13 -08:00
2017-08-10 21:55:16 -07:00
var mirrorView = smallMarginButtonFactory . Generate ( "Mirror" . Localize ( ) ) ;
var mirrorButton = new PopupButton ( mirrorView )
{
2017-10-25 17:04:55 -07:00
Name = "Mirror Button" ,
2017-08-10 21:55:16 -07:00
PopDirection = Direction . Up ,
2017-09-16 01:11:44 -07:00
PopupContent = new MirrorControls ( this , Scene ) ,
2017-12-14 12:40:02 -08:00
AlignToRightEdge = true ,
2017-08-13 13:55:17 -07:00
Margin = buttonSpacing ,
2017-08-10 21:55:16 -07:00
} ;
2017-08-16 18:22:40 -07:00
this . Scene . SelectionChanged + = ( s , e ) = >
{
mirrorButton . Enabled = this . Scene . HasSelection ;
} ;
2017-08-10 21:55:16 -07:00
selectionActionBar . AddChild ( mirrorButton ) ;
2017-08-16 21:17:53 -07:00
// put in the material options
var materialsButton = new PopupButton ( smallMarginButtonFactory . Generate ( "Materials" . Localize ( ) ) )
{
PopDirection = Direction . Up ,
PopupContent = this . AddMaterialControls ( ) ,
AlignToRightEdge = true ,
Margin = buttonSpacing
} ;
this . Scene . SelectionChanged + = ( s , e ) = >
{
materialsButton . Enabled = this . Scene . HasSelection ;
} ;
selectionActionBar . AddChild ( materialsButton ) ;
selectionActionBar . AddChild ( new HorizontalSpacer ( ) ) ;
// Bed menu
var bedMenuActions = new [ ]
2017-08-10 21:55:16 -07:00
{
2017-08-13 13:55:17 -07:00
new NamedAction ( )
{
Title = "Save" . Localize ( ) ,
Action = async ( ) = >
{
2017-12-11 14:15:50 -08:00
await ApplicationController . Instance . Tasks . Execute ( this . SaveChanges ) ;
2017-11-29 13:50:25 -08:00
} ,
IsEnabled = ( ) = > sceneContext . EditableScene
2017-08-13 13:55:17 -07:00
} ,
new NamedAction ( )
{
Title = "Save As" . Localize ( ) ,
2017-11-29 13:50:25 -08:00
Action = ( ) = > UiThread . RunOnIdle ( OpenSaveAsWindow ) ,
IsEnabled = ( ) = > sceneContext . EditableScene
2017-08-13 13:55:17 -07:00
} ,
2017-08-12 00:23:41 -07:00
new NamedAction ( )
2017-07-28 17:35:04 -07:00
{
2017-11-15 07:41:36 -08:00
Title = "Export" . Localize ( ) ,
2017-08-12 00:23:41 -07:00
Action = ( ) = >
{
2017-11-13 16:09:10 -08:00
UiThread . RunOnIdle ( ( ) = >
{
DialogWindow . Show (
new ExportPrintItemPage ( new [ ]
{
2017-11-15 07:41:36 -08:00
new FileSystemFileItem ( sceneContext . EditContext . PartFilePath )
2017-11-13 16:09:10 -08:00
} ) ) ;
} ) ;
2017-11-29 13:50:25 -08:00
} ,
IsEnabled = ( ) = > sceneContext . EditableScene
2017-08-12 00:23:41 -07:00
} ,
new NamedAction ( )
2017-08-31 15:52:27 -07:00
{
2017-11-15 07:41:36 -08:00
Title = "Publish" . Localize ( ) ,
2017-08-31 15:52:27 -07:00
Action = ( ) = >
{
2017-11-08 15:56:37 -08:00
UiThread . RunOnIdle ( ( ) = > DialogWindow . Show < PublishPartToMatterHackers > ( ) ) ;
2017-11-29 13:50:25 -08:00
} ,
IsEnabled = ( ) = > sceneContext . EditableScene
2017-08-31 15:52:27 -07:00
} ,
2017-09-27 07:20:35 -07:00
new NamedAction ( )
2017-08-12 00:23:41 -07:00
{
Title = "Arrange All Parts" . Localize ( ) ,
Action = ( ) = >
{
this . Scene . AutoArrangeChildren ( this ) ;
2017-11-29 13:50:25 -08:00
} ,
IsEnabled = ( ) = > sceneContext . EditableScene
2017-08-12 00:23:41 -07:00
} ,
new NamedAction ( ) { Title = "----" } ,
new NamedAction ( )
{
Title = "Clear Bed" . Localize ( ) ,
Action = ( ) = >
{
2017-11-30 06:10:46 -08:00
UiThread . RunOnIdle ( ( ) = >
{
sceneContext . ClearPlate ( ) . ConfigureAwait ( false ) ;
} ) ;
2017-08-12 00:23:41 -07:00
}
}
2017-08-07 07:41:30 -07:00
} ;
2017-05-26 02:10:22 -07:00
2017-08-17 11:18:11 -07:00
bool isPrinterMode = meshViewerWidget . EditorMode = = MeshViewerWidget . EditorType . Printer ;
2017-10-14 23:18:06 -07:00
var buttonView = smallMarginButtonFactory . Generate (
label : ( isPrinterMode ) ? "Bed" . Localize ( ) : "Part" . Localize ( ) ,
normalImage : AggContext . StaticData . LoadIcon ( ( isPrinterMode ) ? "bed.png" : "cube.png" , IconColor . Theme ) ) ;
2017-08-17 11:18:11 -07:00
2017-10-14 23:18:06 -07:00
selectionActionBar . AddChild (
new PopupButton ( buttonView )
{
PopDirection = Direction . Up ,
2017-11-29 13:50:25 -08:00
DynamicPopupContent = ( ) = > theme . CreatePopupMenu ( bedMenuActions ) ,
2017-10-14 23:18:06 -07:00
AlignToRightEdge = true ,
Margin = buttonSpacing ,
Name = "Bed Options Menu" ,
} ) ;
2017-06-27 18:41:34 -07:00
}
2017-06-26 17:19:27 -07:00
2017-09-27 12:47:23 -07:00
buttonBottomPanel . AddChild ( bottomActionPanel ) ;
2017-08-07 07:41:30 -07:00
2017-06-27 18:41:34 -07:00
LockEditControls ( ) ;
2017-06-26 17:19:27 -07:00
2017-06-27 18:41:34 -07:00
mainContainerTopToBottom . AddChild ( buttonBottomPanel ) ;
2014-01-29 19:09:30 -08:00
2017-06-27 18:41:34 -07:00
this . AddChild ( mainContainerTopToBottom ) ;
2017-06-01 09:42:40 -07:00
2015-04-08 15:20:10 -07:00
this . AnchorAll ( ) ;
2014-01-29 19:09:30 -08:00
2017-07-10 14:00:27 -07:00
this . TrackballTumbleWidget . TransformState = TrackBallController . MouseDownType . Rotation ;
2014-03-01 23:27:34 -08:00
2017-11-29 16:40:46 -08:00
selectedObjectPanel = new SelectedObjectPanel ( this , this . Scene , theme , printer )
2017-03-15 16:17:06 -07:00
{
2017-11-27 16:41:52 -08:00
BackgroundColor = theme . InteractionLayerOverlayColor ,
2017-10-19 09:04:36 -07:00
VAnchor = VAnchor . Top | VAnchor . Fit ,
HAnchor = HAnchor . Left | HAnchor . Fit ,
2017-03-15 16:17:06 -07:00
} ;
2017-10-19 15:29:01 -07:00
2017-10-20 07:26:14 -07:00
selectedObjectContainer = new ResizeContainer ( selectedObjectPanel )
2017-10-19 15:29:01 -07:00
{
Width = 200 ,
VAnchor = VAnchor . Fit | VAnchor . Top ,
HAnchor = HAnchor . Right ,
2017-11-27 16:41:52 -08:00
SpliterBarColor = theme . SplitterBackground ,
SplitterWidth = theme . SplitterWidth ,
2017-10-20 07:26:14 -07:00
Visible = false ,
2017-10-19 15:29:01 -07:00
} ;
2017-11-29 16:40:46 -08:00
this . InteractionLayer . AddChild ( selectedObjectContainer ) ;
2017-10-20 07:26:14 -07:00
selectedObjectContainer . AddChild ( selectedObjectPanel ) ;
2017-03-15 16:17:06 -07:00
2017-11-29 16:40:46 -08:00
this . InteractionLayer . AddChild ( new TumbleCubeControl ( this . InteractionLayer )
{
Margin = new BorderDouble ( 50 , 0 , 0 , 50 ) ,
VAnchor = VAnchor . Top ,
HAnchor = HAnchor . Left ,
} ) ;
2015-04-08 15:20:10 -07:00
UiThread . RunOnIdle ( AutoSpin ) ;
2014-05-27 09:16:35 -07:00
2017-10-16 17:49:45 -07:00
// Wire up CommunicationStateChanged to lock footer bar when SyncToPrint is enabled
if ( sceneContext . Printer ! = null )
2015-04-08 15:20:10 -07:00
{
2017-10-16 17:49:45 -07:00
sceneContext . Printer . Connection . CommunicationStateChanged . RegisterEvent ( ( s , e ) = >
2015-04-08 15:20:10 -07:00
{
2017-10-16 17:49:45 -07:00
if ( sceneContext . RendererOptions . SyncToPrint
& & sceneContext . Printer ! = null )
{
switch ( sceneContext . Printer . Connection . CommunicationState )
2017-09-15 16:49:21 -07:00
{
2017-10-16 17:49:45 -07:00
case CommunicationStates . Printing :
case CommunicationStates . Paused :
LockEditControls ( ) ;
break ;
default :
UnlockEditControls ( ) ;
break ;
}
}
} ,
ref unregisterEvents ) ;
2017-09-15 16:49:21 -07:00
2017-10-16 17:49:45 -07:00
// make sure we lock the controls if we are printing or paused
switch ( sceneContext . Printer . Connection . CommunicationState )
{
case CommunicationStates . Printing :
case CommunicationStates . Paused :
if ( sceneContext . RendererOptions . SyncToPrint )
{
2017-09-15 16:49:21 -07:00
LockEditControls ( ) ;
2017-10-16 17:49:45 -07:00
}
break ;
2015-04-08 15:20:10 -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-03-15 16:17:06 -07:00
if ( DoBooleanTest )
{
BeforeDraw + = CreateBooleanTestGeometry ;
AfterDraw + = RemoveBooleanTestGeometry ;
}
2017-05-29 16:56:56 -07:00
2017-05-31 17:47:12 -07:00
meshViewerWidget . AfterDraw + = AfterDraw3DContent ;
2017-05-29 16:56:56 -07:00
2017-10-16 17:09:00 -07:00
sceneContext . LoadedGCodeChanged + = SceneContext_LoadedGCodeChanged ;
2017-09-15 23:17:03 -07:00
this . SwitchStateToEditing ( ) ;
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 ;
2017-11-29 13:50:25 -08:00
this . viewControls3D . modelViewButton . Enabled = sceneContext . EditableScene ;
2017-11-29 07:35:37 -08:00
}
private void SceneContext_SceneLoaded ( object sender , EventArgs e )
{
2017-11-29 17:47:22 -08:00
if ( this . printerTabPage ? . printerActionsBar ? . sliceButton is GuiWidget sliceButton )
2017-11-29 13:50:25 -08:00
{
sliceButton . Enabled = sceneContext . EditableScene ;
}
this . viewControls3D . modelViewButton . Enabled = sceneContext . EditableScene ;
2017-11-29 07:35:37 -08:00
this . Invalidate ( ) ;
2017-03-15 16:17:06 -07:00
}
2017-10-16 17:09:00 -07:00
private void SceneContext_LoadedGCodeChanged ( object sender , EventArgs e )
{
2017-10-30 08:53:53 -07:00
if ( printerTabPage ! = null )
2017-10-16 17:09:00 -07:00
{
// When GCode changes, switch to the 3D layer view
2017-11-27 17:36:36 -08:00
printer . ViewState . ViewMode = PartViewMode . Layers3D ;
2017-10-16 17:09:00 -07:00
2017-12-18 12:25:23 -08:00
if ( printerTabPage . gcode3DWidget ! = null )
{
// HACK: directly fire method which previously ran on SlicingDone event on PrintItemWrapper
UiThread . RunOnIdle ( ( ) = > printerTabPage . gcode3DWidget . CreateAndAddChildren ( printer ) ) ;
}
2017-10-16 17:09:00 -07:00
}
}
2017-09-27 12:47:23 -07:00
private GuiWidget CreateActionSeparator ( )
2017-08-07 09:17:20 -07:00
{
2017-09-27 12:47:23 -07:00
return new VerticalLine ( 60 )
2017-08-07 09:17:20 -07:00
{
2017-08-13 13:55:17 -07:00
Margin = new BorderDouble ( 3 , 2 , 0 , 2 ) ,
2017-09-27 12:47:23 -07:00
} ;
2017-08-07 09:17:20 -07:00
}
2017-05-26 13:46:12 -07:00
private void ViewControls3D_TransformStateChanged ( object sender , TransformStateChangedEventArgs e )
{
switch ( e . TransformMode )
{
case ViewControls3DButtons . Rotate :
2017-07-10 14:00:27 -07:00
this . TrackballTumbleWidget . TransformState = TrackBallController . MouseDownType . Rotation ;
2017-05-26 13:46:12 -07:00
break ;
case ViewControls3DButtons . Translate :
2017-07-10 14:00:27 -07:00
this . TrackballTumbleWidget . TransformState = TrackBallController . MouseDownType . Translation ;
2017-05-26 13:46:12 -07:00
break ;
case ViewControls3DButtons . Scale :
2017-07-10 14:00:27 -07:00
this . TrackballTumbleWidget . TransformState = TrackBallController . MouseDownType . Scale ;
2017-05-26 13:46:12 -07:00
break ;
case ViewControls3DButtons . PartSelect :
2017-07-10 14:00:27 -07:00
this . TrackballTumbleWidget . TransformState = TrackBallController . MouseDownType . None ;
2017-05-26 13:46:12 -07:00
break ;
}
}
2017-03-15 16:17:06 -07:00
public void SelectAll ( )
{
Scene . ClearSelection ( ) ;
2017-08-28 09:14:55 -07:00
foreach ( var child in Scene . Children . ToList ( ) )
2017-03-15 16:17:06 -07:00
{
Scene . AddToSelection ( child ) ;
}
}
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
& & TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . None
& & Keyboard . IsKeyDown ( Keys . ShiftKey ) )
{
// draw marks on the bed to show that the part is constrained to x and y
AxisAlignedBoundingBox selectedBounds = this . Scene . SelectedItem . GetAxisAlignedBoundingBox ( Matrix4X4 . Identity ) ;
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 + + )
{
GLHelper . Render3DLine ( World ,
drawCenter - new Vector3 ( - 50 , 0 , 0 ) ,
drawCenter - new Vector3 ( 50 , 0 , 0 ) , drawColor , zBuffer , 2 ) ;
GLHelper . Render3DLine ( World ,
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 ;
}
}
2017-05-29 14:24:59 -07:00
// This shows the BVH as rects around the scene items
//Scene?.TraceData().RenderBvhRecursive(0, 3);
2017-07-10 14:00:27 -07:00
2017-10-30 08:53:53 -07:00
if ( sceneContext . LoadedGCode = = null | | sceneContext . GCodeRenderer = = null | | printerTabPage ? . gcode3DWidget . Visible = = false )
2017-07-10 14:00:27 -07:00
{
return ;
}
2017-09-15 16:49:21 -07:00
sceneContext . Render3DLayerFeatures ( e ) ;
2015-12-22 15:26:51 -08:00
}
2016-02-27 13:56:57 -08:00
public override void OnKeyDown ( KeyEventArgs keyEvent )
{
2017-06-29 11:42:36 -07:00
// this must be called first to ensure we get the correct Handled state
2017-06-29 11:35:06 -07:00
base . OnKeyDown ( keyEvent ) ;
2016-02-27 13:56:57 -08:00
2017-06-29 11:35:06 -07:00
if ( ! keyEvent . Handled )
2017-06-07 15:56:02 -07:00
{
switch ( keyEvent . KeyCode )
{
case Keys . A :
if ( keyEvent . Control )
{
SelectAll ( ) ;
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
}
break ;
case Keys . Z :
if ( keyEvent . Control )
{
2017-08-14 08:57:24 -07:00
this . Scene . UndoBuffer . Undo ( ) ;
2017-06-07 15:56:02 -07:00
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
}
break ;
case Keys . Y :
if ( keyEvent . Control )
{
2017-08-14 08:57:24 -07:00
this . Scene . UndoBuffer . Redo ( ) ;
2017-06-07 15:56:02 -07:00
keyEvent . Handled = true ;
keyEvent . SuppressKeyPress = true ;
}
break ;
case Keys . Delete :
case Keys . Back :
2017-06-09 08:13:09 -07:00
this . Scene . DeleteSelection ( this ) ;
2017-06-07 15:56:02 -07:00
break ;
2016-02-27 13:56:57 -08:00
2017-06-07 15:56:02 -07:00
case Keys . Escape :
if ( CurrentSelectInfo . DownOnPart )
{
CurrentSelectInfo . DownOnPart = false ;
2016-02-27 13:56:57 -08:00
2017-06-07 15:56:02 -07:00
Scene . SelectedItem . Matrix = transformOnMouseDown ;
2016-02-27 13:56:57 -08:00
2017-10-25 17:04:55 -07:00
Scene . Invalidate ( ) ;
2017-06-07 15:56:02 -07:00
}
break ;
2017-07-11 17:34:22 -07:00
case Keys . Space :
this . Scene . ClearSelection ( ) ;
break ;
2017-06-07 15:56:02 -07:00
}
2016-02-27 13:56:57 -08:00
}
}
2016-02-17 18:06:32 -08:00
public bool DragingPart
{
2016-02-19 08:29:49 -08:00
get { return CurrentSelectInfo . DownOnPart ; }
2016-02-17 18:06:32 -08:00
}
2017-03-15 16:17:06 -07:00
public void AddUndoOperation ( IUndoRedoCommand operation )
2016-02-14 17:53:44 -08:00
{
2017-08-14 08:57:24 -07:00
this . Scene . UndoBuffer . Add ( operation ) ;
2016-02-14 17:53:44 -08:00
}
2017-06-01 09:42:40 -07:00
#region DoBooleanTest
Object3D booleanGroup ;
2016-03-12 14:16:34 -08:00
Vector3 offset = new Vector3 ( ) ;
Vector3 direction = new Vector3 ( . 11 , . 12 , . 13 ) ;
Vector3 rotCurrent = new Vector3 ( ) ;
Vector3 rotChange = new Vector3 ( . 011 , . 012 , . 013 ) ;
Vector3 scaleChange = new Vector3 ( . 0011 , . 0012 , . 0013 ) ;
Vector3 scaleCurrent = new Vector3 ( 1 , 1 , 1 ) ;
2017-03-15 16:17:06 -07:00
private void CreateBooleanTestGeometry ( object sender , DrawEventArgs e )
2016-03-07 14:23:22 -08:00
{
try
{
2017-10-13 15:00:08 -07:00
booleanGroup = new Object3D { ItemType = Object3DTypes . Group } ;
2017-03-15 16:17:06 -07:00
booleanGroup . Children . Add ( new Object3D ( )
{
Mesh = ApplyBoolean ( PolygonMesh . Csg . CsgOperations . Union , AxisAlignedBoundingBox . Union , new Vector3 ( 100 , 0 , 20 ) , "U" )
} ) ;
2016-03-07 14:23:22 -08:00
2017-03-15 16:17:06 -07:00
booleanGroup . Children . Add ( new Object3D ( )
{
Mesh = ApplyBoolean ( PolygonMesh . Csg . CsgOperations . Subtract , null , new Vector3 ( 100 , 100 , 20 ) , "S" )
} ) ;
booleanGroup . Children . Add ( new Object3D ( )
{
Mesh = ApplyBoolean ( PolygonMesh . Csg . CsgOperations . Intersect , AxisAlignedBoundingBox . Intersection , new Vector3 ( 100 , 200 , 20 ) , "I" )
} ) ;
2016-03-07 14:23:22 -08:00
offset + = direction ;
2016-03-12 14:16:34 -08:00
rotCurrent + = rotChange ;
scaleCurrent + = scaleChange ;
2016-03-07 14:23:22 -08:00
2017-09-26 12:52:54 -07:00
this . Scene . Children . Modify ( list = >
2017-03-15 16:17:06 -07:00
{
2017-09-26 12:52:54 -07:00
list . Add ( booleanGroup ) ;
2017-03-15 16:17:06 -07:00
} ) ;
2016-03-07 14:23:22 -08:00
}
2017-06-01 09:42:40 -07:00
catch ( Exception e2 )
2016-03-07 14:23:22 -08:00
{
string text = e2 . Message ;
2017-03-15 16:17:06 -07:00
int a = 0 ;
2016-03-07 14:23:22 -08:00
}
}
2016-03-13 10:29:45 -07:00
private Mesh ApplyBoolean ( Func < Mesh , Mesh , Mesh > meshOpperation , Func < AxisAlignedBoundingBox , AxisAlignedBoundingBox , AxisAlignedBoundingBox > aabbOpperation , Vector3 centering , string opp )
2016-03-07 14:23:22 -08:00
{
Mesh boxA = PlatonicSolids . CreateCube ( 40 , 40 , 40 ) ;
2017-03-15 16:17:06 -07:00
//boxA = PlatonicSolids.CreateIcosahedron(35);
2016-03-07 14:23:22 -08:00
boxA . Translate ( centering ) ;
2016-03-05 15:54:38 -08:00
Mesh boxB = PlatonicSolids . CreateCube ( 40 , 40 , 40 ) ;
2017-03-15 16:17:06 -07:00
//boxB = PlatonicSolids.CreateIcosahedron(35);
2015-12-22 15:26:51 -08:00
2016-03-07 14:23:22 -08:00
for ( int i = 0 ; i < 3 ; i + + )
{
if ( Math . Abs ( direction [ i ] + offset [ i ] ) > 10 )
{
2016-03-12 14:16:34 -08:00
direction [ i ] = direction [ i ] * - 1.00073112 ;
2016-03-07 14:23:22 -08:00
}
}
2016-03-12 14:16:34 -08:00
for ( int i = 0 ; i < 3 ; i + + )
{
if ( Math . Abs ( rotChange [ i ] + rotCurrent [ i ] ) > 6 )
{
rotChange [ i ] = rotChange [ i ] * - 1.000073112 ;
}
}
for ( int i = 0 ; i < 3 ; i + + )
{
if ( scaleChange [ i ] + scaleCurrent [ i ] > 1.1 | | scaleChange [ i ] + scaleCurrent [ i ] < . 9 )
{
scaleChange [ i ] = scaleChange [ i ] * - 1.000073112 ;
}
}
2016-03-08 12:13:58 -08:00
Vector3 offsetB = offset + centering ;
// switch to the failing offset
2016-03-13 10:29:45 -07:00
//offsetB = new Vector3(105.240172225344, 92.9716306394062, 18.4619570261172);
//rotCurrent = new Vector3(4.56890223673623, -2.67874102322035, 1.02768848238523);
//scaleCurrent = new Vector3(1.07853517569753, 0.964980885267323, 1.09290934544604);
2017-06-01 09:42:40 -07:00
Debug . WriteLine ( "t" + offsetB . ToString ( ) + " r" + rotCurrent . ToString ( ) + " s" + scaleCurrent . ToString ( ) + " " + opp ) ;
2016-03-12 14:16:34 -08:00
Matrix4X4 transformB = Matrix4X4 . CreateScale ( scaleCurrent ) * Matrix4X4 . CreateRotation ( rotCurrent ) * Matrix4X4 . CreateTranslation ( offsetB ) ;
2017-06-01 09:42:40 -07:00
boxB . Transform ( transformB ) ;
2015-12-22 15:26:51 -08:00
2016-03-13 10:29:45 -07:00
Mesh meshToAdd = meshOpperation ( boxA , boxB ) ;
2017-07-14 13:55:02 -07:00
meshToAdd . CleanAndMergMesh ( CancellationToken . None ) ;
2016-03-13 10:29:45 -07:00
2017-06-01 09:42:40 -07:00
if ( aabbOpperation ! = null )
2016-03-13 10:29:45 -07:00
{
AxisAlignedBoundingBox boundsA = boxA . GetAxisAlignedBoundingBox ( ) ;
AxisAlignedBoundingBox boundsB = boxB . GetAxisAlignedBoundingBox ( ) ;
AxisAlignedBoundingBox boundsAdd = meshToAdd . GetAxisAlignedBoundingBox ( ) ;
AxisAlignedBoundingBox boundsResult = aabbOpperation ( boundsA , boundsB ) ;
}
2016-03-07 14:23:22 -08:00
return meshToAdd ;
}
2017-03-15 16:17:06 -07:00
private void RemoveBooleanTestGeometry ( object sender , DrawEventArgs e )
2017-06-01 09:42:40 -07:00
{
2017-08-14 08:57:24 -07:00
if ( this . Scene . Children . Contains ( booleanGroup ) )
2016-03-07 14:23:22 -08:00
{
2017-08-14 08:57:24 -07:00
this . Scene . Children . Remove ( booleanGroup ) ;
2016-03-07 14:23:22 -08:00
UiThread . RunOnIdle ( ( ) = > Invalidate ( ) , 1.0 / 30.0 ) ;
}
2017-06-01 09:42:40 -07:00
}
2017-03-15 16:17:06 -07:00
#endregion DoBooleanTest
2015-04-08 15:20:10 -07:00
2015-12-22 15:26:51 -08:00
public enum AutoRotate { Enabled , Disabled } ;
2015-04-15 16:39:37 -07:00
2015-05-30 12:48:16 -07:00
public bool DisplayAllValueData { get ; set ; }
2014-12-20 11:12:02 -08:00
2017-03-15 16:17:06 -07:00
public override void OnClosed ( ClosedEventArgs e )
2015-05-30 12:48:16 -07:00
{
2017-05-26 13:46:12 -07:00
viewControls3D . TransformStateChanged - = ViewControls3D_TransformStateChanged ;
2017-10-16 17:09:00 -07:00
sceneContext . LoadedGCodeChanged - = SceneContext_LoadedGCodeChanged ;
2017-10-21 18:11:01 -07:00
this . Scene . SelectionChanged - = Scene_SelectionChanged ;
this . InteractionLayer . DrawGlOpaqueContent - = Draw_GlOpaqueContent ;
2017-11-29 07:35:37 -08:00
this . sceneContext . SceneLoaded - = SceneContext_SceneLoaded ;
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
unregisterEvents ? . Invoke ( this , null ) ;
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 ; }
2017-10-23 13:36:08 -07:00
public InsertionGroup DragDropObject { get ; private set ; }
2017-11-29 13:50:25 -08:00
public ILibraryContentStream 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
{
2017-09-19 19:59:55 -07:00
// Otherwise begin an externally started DragDropOperation hard-coded to use LibraryView->SelectedItems
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-03-15 16:17:06 -07:00
2017-09-19 19:59:55 -07:00
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 )
{
// Move the object being dragged
if ( this . DragOperationActive
& & this . DragDropObject ! = null )
{
// Move the DropDropObject the target item
DragSelectedObject ( localMousePostion : this . TransformFromParentSpace ( topMostParent , screenSpaceMousePosition ) ) ;
}
2015-04-08 15:20:10 -07:00
}
2017-09-19 19:59:55 -07:00
private void StartDragDrop ( IEnumerable < ILibraryItem > items , Vector2 screenSpaceMousePosition )
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 ( ) ;
if ( ( firstItem is ILibraryContentStream 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 ;
2017-11-29 14:16:21 -08:00
this . SceneReplacement = firstItem as ILibraryContentStream ;
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
2017-11-29 07:05:48 -08:00
var insertionGroup = new InsertionGroup (
2017-09-28 15:51:31 -07:00
items ,
this ,
2017-10-25 17:04:55 -07:00
this . Scene ,
sceneContext . BedCenter ,
2017-09-20 22:09:27 -07:00
( ) = > this . DragOperationActive ) ;
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 )
{
// Set the initial transform on the inject part to the current transform mouse position
2017-11-29 07:05:48 -08:00
var sourceItemBounds = insertionGroup . GetAxisAlignedBoundingBox ( Matrix4X4 . Identity ) ;
2017-09-19 19:59:55 -07:00
var center = sourceItemBounds . Center ;
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 07:05:48 -08:00
insertionGroup . Matrix * = Matrix4X4 . CreateTranslation ( - center . X , - center . Y , - sourceItemBounds . minXYZ . Z ) ;
insertionGroup . Matrix * = Matrix4X4 . CreateTranslation ( new Vector3 ( intersectInfo . HitPosition ) ) ;
2017-09-16 01:11:44 -07:00
2017-09-19 19:59:55 -07:00
CurrentSelectInfo . PlaneDownHitPos = intersectInfo . HitPosition ;
CurrentSelectInfo . LastMoveDelta = Vector3 . Zero ;
}
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
2017-09-26 12:52:54 -07:00
this . 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
} ) ;
2017-11-29 07:05:48 -08: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
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
ContentStore = ( this . SceneReplacement . ContentType = = "gcode" ) ? null : ApplicationController . Instance . Library . PlatingHistory
2017-11-29 13:50:25 -08:00
} ) . ConfigureAwait ( false ) ;
this . SceneReplacement = null ;
}
else if ( this . DragDropObject . ContentAcquired )
{
// Drop handler for InsertionGroup - all normal content
this . viewControls3D . modelViewButton . Enabled = true ;
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
{
2017-09-26 12:54:40 -07:00
this . Scene . Children . Modify ( list = > list . Remove ( this . DragDropObject ) ) ;
this . 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
2017-10-25 17:04:55 -07:00
Scene . Invalidate ( ) ;
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 )
{
2017-03-15 16:17:06 -07:00
if ( Scene . HasSelection )
2015-05-30 12:48:16 -07:00
{
2017-03-15 16:17:06 -07:00
var selectedItem = Scene . SelectedItem ;
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 ) ;
}
2015-04-08 15:20:10 -07:00
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 ) ;
2017-10-31 11:43:25 -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 > ( ) ;
2017-06-06 10:57:13 -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 )
{
Scene . ClearSelection ( ) ;
2017-06-05 17:23:55 -07:00
2017-08-22 15:55:52 -07:00
foreach ( var sceneItem in matchingSceneChildren . ToList ( ) )
2017-06-21 15:56:25 -07:00
{
Scene . AddToSelection ( sceneItem ) ;
}
}
else
2017-06-05 17:23:55 -07:00
{
2017-06-21 15:56:25 -07:00
RenderBounds ( e , 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
2017-06-06 10:06:38 -07:00
private void RenderBounds ( DrawEventArgs e , IEnumerable < BvhIterator > allResults )
{
foreach ( var x in allResults )
2017-05-29 16:56:56 -07:00
{
2017-05-31 11:56:25 -07:00
for ( int i = 0 ; i < 4 ; i + + )
{
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
var bottomStartScreenPos = this . World . GetScreenPosition ( bottomStartPosition ) ;
2017-05-31 11:56:25 -07:00
2017-06-06 10:06:38 -07:00
Vector3 bottomEndPosition = Vector3 . Transform ( x . Bvh . GetAxisAlignedBoundingBox ( ) . GetBottomCorner ( ( i + 1 ) % 4 ) , x . TransformToWorld ) ;
2017-07-10 14:00:27 -07:00
var bottomEndScreenPos = this . World . GetScreenPosition ( bottomEndPosition ) ;
2017-05-31 11:56:25 -07:00
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
var topStartScreenPos = this . World . GetScreenPosition ( topStartPosition ) ;
2017-05-31 11:56:25 -07:00
2017-06-06 10:06:38 -07:00
Vector3 topEndPosition = Vector3 . Transform ( x . Bvh . GetAxisAlignedBoundingBox ( ) . GetTopCorner ( ( i + 1 ) % 4 ) , x . TransformToWorld ) ;
2017-07-10 14:00:27 -07:00
var topEndScreenPos = this . World . GetScreenPosition ( topEndPosition ) ;
2017-05-31 11:56:25 -07:00
2017-10-31 11:43:25 -07:00
e . graphics2D . Line ( bottomStartScreenPos , bottomEndScreenPos , Color . Black ) ;
e . graphics2D . Line ( topStartScreenPos , topEndScreenPos , Color . Black ) ;
e . graphics2D . Line ( topStartScreenPos , bottomStartScreenPos , Color . Black ) ;
2017-05-31 11:56:25 -07:00
}
2017-06-06 10:06:38 -07:00
TriangleShape tri = x . Bvh as TriangleShape ;
2017-05-29 16:56:56 -07:00
if ( tri ! = null )
{
for ( int i = 0 ; i < 3 ; i + + )
{
var vertexPos = tri . GetVertex ( i ) ;
2017-06-06 10:06:38 -07:00
var screenCenter = Vector3 . Transform ( vertexPos , x . TransformToWorld ) ;
2017-07-10 14:00:27 -07:00
var screenPos = this . World . GetScreenPosition ( screenCenter ) ;
2017-05-29 16:56:56 -07:00
2017-10-31 11:43:25 -07:00
e . graphics2D . Circle ( screenPos , 3 , Color . Red ) ;
2017-05-29 16:56:56 -07:00
}
}
2017-05-30 17:51:52 -07:00
else
{
2017-06-06 10:06:38 -07:00
var center = x . Bvh . GetCenter ( ) ;
var worldCenter = Vector3 . Transform ( center , x . TransformToWorld ) ;
2017-07-10 14:00:27 -07:00
var screenPos2 = this . World . GetScreenPosition ( worldCenter ) ;
2017-10-31 11:43:25 -07:00
e . graphics2D . Circle ( screenPos2 , 3 , Color . Yellow ) ;
2017-10-31 12:51:16 -07:00
e . graphics2D . DrawString ( $"{x.Depth}," , screenPos2 . X + 12 * x . Depth , screenPos2 . Y ) ;
2017-05-30 17:51:52 -07:00
}
2017-05-29 16:56:56 -07:00
}
2017-06-01 09:42:40 -07:00
}
2017-05-31 17:47:12 -07:00
2017-06-06 10:06:38 -07:00
private void RendereSceneTraceData ( DrawEventArgs e )
2017-06-01 09:42:40 -07:00
{
2017-06-06 10:06:38 -07:00
var bvhIterator = new BvhIterator ( Scene ? . TraceData ( ) , decentFilter : ( x ) = >
2017-05-31 17:47:12 -07:00
{
2017-06-06 10:06:38 -07:00
var center = x . Bvh . GetCenter ( ) ;
var worldCenter = Vector3 . Transform ( center , x . TransformToWorld ) ;
2017-10-31 12:51:16 -07:00
if ( worldCenter . Z > 0 )
2017-06-01 09:42:40 -07:00
{
return true ;
}
return false ;
} ) ;
2017-06-06 10:06:38 -07:00
RenderBounds ( e , bvhIterator ) ;
2017-05-29 16:56:56 -07:00
}
2015-12-22 15:26:51 -08:00
private ViewControls3DButtons ? activeButtonBeforeMouseOverride = null ;
2015-05-29 15:13:56 -07:00
2015-05-30 12:48:16 -07:00
public override void OnMouseDown ( MouseEventArgs mouseEvent )
2015-04-08 15:20:10 -07:00
{
2015-05-29 15:13:56 -07:00
// Show transform override
if ( activeButtonBeforeMouseOverride = = null & & mouseEvent . Button = = MouseButtons . Right )
{
activeButtonBeforeMouseOverride = viewControls3D . ActiveButton ;
viewControls3D . ActiveButton = ViewControls3DButtons . Rotate ;
}
else if ( activeButtonBeforeMouseOverride = = null & & mouseEvent . Button = = MouseButtons . Middle )
{
activeButtonBeforeMouseOverride = viewControls3D . ActiveButton ;
viewControls3D . ActiveButton = ViewControls3DButtons . Translate ;
}
2017-03-15 16:17:06 -07:00
if ( mouseEvent . Button = = MouseButtons . Right | |
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
2017-07-10 14:00:27 -07:00
if ( this . TrackballTumbleWidget . UnderMouseState = = UnderMouseState . FirstUnderMouse )
2015-04-08 15:20:10 -07:00
{
2017-03-15 16:17:06 -07:00
if ( mouseEvent . Button = = MouseButtons . Left
& &
2017-06-06 13:34:42 -07:00
( ModifierKeys = = Keys . Shift | | ModifierKeys = = Keys . Control )
2017-06-06 14:41:49 -07:00
| | (
2017-07-10 14:00:27 -07:00
this . TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . 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 )
{
if ( Scene . HasSelection )
{
2017-08-22 15:55:52 -07:00
Scene . ClearSelection ( ) ;
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
2017-03-15 16:17:06 -07:00
if ( hitObject ! = Scene . SelectedItem )
{
if ( Scene . SelectedItem = = null )
{
// No selection exists
2017-08-22 15:55:52 -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 )
& & ! Scene . SelectedItem . Children . Contains ( hitObject ) )
2017-03-15 16:17:06 -07:00
{
Scene . AddToSelection ( hitObject ) ;
}
else if ( Scene . SelectedItem = = hitObject | | Scene . SelectedItem . Children . Contains ( hitObject ) )
{
// Selection should not be cleared and drag should occur
}
else if ( ModifierKeys ! = Keys . Shift )
{
2017-08-22 15:55:52 -07:00
Scene . SelectedItem = hitObject ;
2017-03-15 16:17:06 -07:00
}
2017-10-25 17:04:55 -07:00
Invalidate ( ) ;
2017-03-15 16:17:06 -07:00
}
transformOnMouseDown = Scene . 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 ;
2017-08-14 08:57:24 -07:00
AxisAlignedBoundingBox selectedBounds = this . Scene . 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
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 ) ;
}
public void DragSelectedObject ( Vector2 localMousePostion )
2015-05-30 12:48:16 -07:00
{
2017-03-15 16:17:06 -07:00
Vector2 meshViewerWidgetScreenPosition = meshViewerWidget . TransformFromParentSpace ( this , localMousePostion ) ;
2017-07-10 14:00:27 -07:00
Ray ray = this . World . GetRayForLocalBounds ( meshViewerWidgetScreenPosition ) ;
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
{
2017-03-15 16:17:06 -07:00
// move the mesh back to the start position
{
Matrix4X4 totalTransform = Matrix4X4 . CreateTranslation ( new Vector3 ( - CurrentSelectInfo . LastMoveDelta ) ) ;
Scene . SelectedItem . Matrix * = totalTransform ;
2017-12-15 12:20:17 -08:00
// Invalidate the item to account for the position change
Scene . SelectedItem . Invalidate ( ) ;
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
2017-08-14 08:57:24 -07:00
AxisAlignedBoundingBox selectedBounds = this . Scene . 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
if ( Keyboard . IsKeyDown ( Keys . ShiftKey ) )
{
2017-10-31 12:51:16 -07: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
2017-03-15 16:17:06 -07:00
Scene . 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-03-15 16:17:06 -07:00
public override void OnMouseMove ( MouseEventArgs mouseEvent )
{
2017-09-19 19:59:55 -07:00
// File system Drop validation
mouseEvent . AcceptDrop = this . AllowDragDrop ( )
& & mouseEvent . DragFiles ? . Count > 0
& & mouseEvent . DragFiles . TrueForAll ( filePath = > ApplicationController . Instance . IsLoadableFile ( filePath ) ) ;
// View3DWidgets Filesystem DropDrop handler
if ( mouseEvent . AcceptDrop
& & this . PositionWithinLocalBounds ( mouseEvent . X , mouseEvent . Y ) )
2017-04-05 16:25:43 -07:00
{
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
DragOver ( screenSpaceMousePosition : this . TransformToScreenSpace ( mouseEvent . Position ) ) ;
}
else
{
// Project DragFiles to IEnumerable<FileSystemFileItem>
this . StartDragDrop (
2017-12-19 14:48:36 -08:00
mouseEvent . DragFiles . Select ( path = > new FileSystemFileItem ( path ) ) ,
screenSpaceMousePosition : this . TransformToScreenSpace ( mouseEvent . Position ) ,
trackSourceFiles : true ) ;
2017-04-05 16:25:43 -07:00
}
}
2017-07-10 14:00:27 -07:00
if ( CurrentSelectInfo . DownOnPart & & this . TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . None )
2017-03-15 16:17:06 -07:00
{
DragSelectedObject ( new Vector2 ( mouseEvent . X , mouseEvent . Y ) ) ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
2017-05-31 17:47:12 -07:00
if ( DragSelectionInProgress )
{
DragSelectionEndPosition = mouseEvent . Position - OffsetToMeshViewerWidget ( ) ;
2017-06-30 18:33:49 -07:00
DragSelectionEndPosition = new Vector2 (
2017-10-31 12:51:16 -07:00
Math . Max ( Math . Min ( DragSelectionEndPosition . X , meshViewerWidget . LocalBounds . Right ) , meshViewerWidget . LocalBounds . Left ) ,
Math . Max ( Math . Min ( DragSelectionEndPosition . Y , meshViewerWidget . LocalBounds . Top ) , meshViewerWidget . LocalBounds . Bottom ) ) ;
2017-05-31 17:47:12 -07:00
Invalidate ( ) ;
}
2015-05-30 12:48:16 -07:00
base . OnMouseMove ( mouseEvent ) ;
2015-04-08 15:20:10 -07: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 ( ) ;
for ( int i = parents . Count - 1 ; i > = 0 ; i - - )
{
offset + = parents [ i ] . OriginRelativeParent ;
}
return offset ;
}
2017-07-10 14:00:27 -07:00
public void ResetView ( )
{
this . TrackballTumbleWidget . ZeroVelocity ( ) ;
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 ) ) ) ;
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
{
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
}
2017-07-10 14:00:27 -07:00
if ( this . TrackballTumbleWidget . TransformState = = TrackBallController . MouseDownType . None )
2015-04-08 15:20:10 -07:00
{
2017-07-11 12:50:21 -07:00
if ( Scene . SelectedItem ! = null
& & CurrentSelectInfo . DownOnPart
& & CurrentSelectInfo . LastMoveDelta ! = Vector3 . Zero )
2016-02-27 13:56:57 -08:00
{
2017-07-12 21:59:22 -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 ;
}
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-08-16 18:22:40 -07:00
internal GuiWidget AddAlignControls ( )
{
var widget = new IgnoredPopupWidget ( )
{
HAnchor = HAnchor . Fit ,
VAnchor = VAnchor . Fit ,
2017-10-31 11:43:25 -07:00
BackgroundColor = Color . White ,
2017-08-17 15:21:29 -07:00
Padding = new BorderDouble ( 5 , 5 , 5 , 0 )
2017-08-16 18:22:40 -07:00
} ;
FlowLayoutWidget buttonPanel = new FlowLayoutWidget ( FlowDirection . TopToBottom )
{
VAnchor = VAnchor . Fit ,
HAnchor = HAnchor . Fit ,
} ;
widget . AddChild ( buttonPanel ) ;
string [ ] axisNames = new string [ ] { "X" , "Y" , "Z" } ;
for ( int axisIndex = 0 ; axisIndex < 3 ; axisIndex + + )
{
FlowLayoutWidget alignButtons = new FlowLayoutWidget ( FlowDirection . LeftToRight )
{
HAnchor = HAnchor . Fit ,
Padding = new BorderDouble ( 5 )
} ;
buttonPanel . AddChild ( alignButtons ) ;
2017-08-17 17:18:33 -07:00
alignButtons . AddChild ( new TextWidget ( axisNames [ axisIndex ] )
2017-08-17 15:21:29 -07:00
{
VAnchor = VAnchor . Center ,
Margin = new BorderDouble ( 0 , 0 , 3 , 0 )
} ) ;
2017-08-16 18:22:40 -07:00
2017-08-17 15:21:29 -07:00
alignButtons . AddChild ( CreateAlignButton ( axisIndex , AxisAlignment . Min , "Min" ) ) ;
2017-08-16 18:22:40 -07:00
alignButtons . AddChild ( new HorizontalSpacer ( ) ) ;
2017-08-17 15:21:29 -07:00
alignButtons . AddChild ( CreateAlignButton ( axisIndex , AxisAlignment . Center , "Center" ) ) ;
2017-08-16 18:22:40 -07:00
alignButtons . AddChild ( new HorizontalSpacer ( ) ) ;
2017-08-17 15:21:29 -07:00
alignButtons . AddChild ( CreateAlignButton ( axisIndex , AxisAlignment . Max , "Max" ) ) ;
2017-08-16 18:22:40 -07:00
alignButtons . AddChild ( new HorizontalSpacer ( ) ) ;
}
2017-11-27 16:41:52 -08:00
var dualExtrusionAlignButton = theme . MenuButtonFactory . Generate ( "Align for Dual Extrusion" . Localize ( ) ) ;
2017-09-19 14:01:32 -07:00
dualExtrusionAlignButton . Margin = new BorderDouble ( 21 , 0 ) ;
dualExtrusionAlignButton . HAnchor = HAnchor . Left ;
buttonPanel . AddChild ( dualExtrusionAlignButton ) ;
AddAlignDelegates ( 0 , AxisAlignment . SourceCoordinateSystem , dualExtrusionAlignButton ) ;
2017-08-16 18:22:40 -07:00
return widget ;
}
2017-09-19 14:01:32 -07:00
internal enum AxisAlignment { Min , Center , Max , SourceCoordinateSystem } ;
2017-08-17 15:21:29 -07:00
private GuiWidget CreateAlignButton ( int axisIndex , AxisAlignment alignment , string lable )
2017-08-16 18:22:40 -07:00
{
2017-11-27 16:41:52 -08:00
var smallMarginButtonFactory = theme . MenuButtonFactory ;
2017-08-17 15:21:29 -07:00
var alignButton = smallMarginButtonFactory . Generate ( lable ) ;
alignButton . Margin = new BorderDouble ( 3 , 0 ) ;
2017-09-19 14:01:32 -07:00
AddAlignDelegates ( axisIndex , alignment , alignButton ) ;
return alignButton ;
}
private void AddAlignDelegates ( int axisIndex , AxisAlignment alignment , Button alignButton )
{
2017-08-16 18:22:40 -07:00
alignButton . Click + = ( sender , e ) = >
{
if ( Scene . HasSelection )
{
2017-08-22 15:55:52 -07:00
var transformDatas = GetTransforms ( axisIndex , alignment ) ;
2017-11-20 11:19:22 -08:00
this . Scene . UndoBuffer . AddAndDo ( new TransformCommand ( transformDatas ) ) ;
2017-08-17 15:21:29 -07:00
2017-08-16 18:22:40 -07:00
//Scene.SelectedItem.MaterialIndex = extruderIndexCanPassToClick;
2017-10-25 17:04:55 -07:00
Scene . Invalidate ( ) ;
2017-08-16 18:22:40 -07:00
}
} ;
alignButton . MouseEnter + = ( s2 , e2 ) = >
{
2017-09-19 14:01:32 -07:00
if ( Scene . HasSelection )
2017-08-22 15:55:52 -07:00
{
2017-09-19 14:01:32 -07:00
// make a preview of the new positions
var transformDatas = GetTransforms ( axisIndex , alignment ) ;
2017-10-04 16:06:35 -07:00
Scene . Children . Modify ( ( list ) = >
2017-09-19 14:01:32 -07:00
{
2017-10-04 16:06:35 -07:00
foreach ( var transform in transformDatas )
{
var copy = transform . TransformedObject . Clone ( ) ;
copy . Matrix = transform . RedoTransform ;
2017-10-31 11:43:25 -07:00
copy . Color = new Color ( Color . Gray , 126 ) ;
2017-10-04 16:06:35 -07:00
list . Add ( copy ) ;
}
} ) ;
2017-08-22 15:55:52 -07:00
}
2017-08-16 18:22:40 -07:00
} ;
alignButton . MouseLeave + = ( s3 , e3 ) = >
{
2017-09-19 14:01:32 -07:00
if ( Scene . HasSelection )
2017-08-22 15:55:52 -07:00
{
2017-09-19 14:01:32 -07:00
// clear the preview of the new positions
2017-10-04 16:06:35 -07:00
Scene . Children . Modify ( ( list ) = >
2017-08-22 15:55:52 -07:00
{
2017-10-04 16:06:35 -07:00
for ( int i = list . Count - 1 ; i > = 0 ; i - - )
2017-09-19 14:01:32 -07:00
{
2017-10-04 16:06:35 -07:00
if ( list [ i ] . Color . Alpha0To255 = = 126 )
{
list . RemoveAt ( i ) ;
}
2017-09-19 14:01:32 -07:00
}
2017-10-04 16:06:35 -07:00
} ) ;
2017-08-22 15:55:52 -07:00
}
2017-08-16 18:22:40 -07:00
} ;
}
2017-08-22 15:55:52 -07:00
private List < TransformData > GetTransforms ( int axisIndex , AxisAlignment alignment )
{
var transformDatas = new List < TransformData > ( ) ;
var totalAABB = Scene . SelectedItem . GetAxisAlignedBoundingBox ( Matrix4X4 . Identity ) ;
2017-09-19 14:01:32 -07:00
Vector3 firstSourceOrigin = new Vector3 ( double . MaxValue , double . MaxValue , double . MaxValue ) ;
2017-08-22 15:55:52 -07:00
// move the objects to the right place
foreach ( var child in Scene . SelectedItem . Children )
{
var childAABB = child . GetAxisAlignedBoundingBox ( Scene . SelectedItem . Matrix ) ;
var offset = new Vector3 ( ) ;
switch ( alignment )
{
case AxisAlignment . Min :
offset [ axisIndex ] = totalAABB . minXYZ [ axisIndex ] - childAABB . minXYZ [ axisIndex ] ;
break ;
case AxisAlignment . Center :
offset [ axisIndex ] = totalAABB . Center [ axisIndex ] - childAABB . Center [ axisIndex ] ;
break ;
case AxisAlignment . Max :
2017-09-19 14:01:32 -07:00
offset [ axisIndex ] = totalAABB . maxXYZ [ axisIndex ] - childAABB . maxXYZ [ axisIndex ] ;
break ;
case AxisAlignment . SourceCoordinateSystem :
2017-08-22 15:55:52 -07:00
{
2017-09-19 14:01:32 -07:00
// move the object back to the origin
offset = - Vector3 . Transform ( Vector3 . Zero , child . Matrix ) ;
// figure out how to move it back to the start center
2017-10-31 12:51:16 -07:00
if ( firstSourceOrigin . X = = double . MaxValue )
2017-09-19 14:01:32 -07:00
{
firstSourceOrigin = - offset ;
}
offset + = firstSourceOrigin ;
2017-08-22 15:55:52 -07:00
}
break ;
}
transformDatas . Add ( new TransformData ( )
{
TransformedObject = child ,
RedoTransform = child . Matrix * Matrix4X4 . CreateTranslation ( offset ) ,
UndoTransform = child . Matrix ,
} ) ;
}
return transformDatas ;
}
2017-05-26 02:10:22 -07:00
internal GuiWidget AddMaterialControls ( )
2015-04-08 15:20:10 -07:00
{
2017-08-16 18:22:40 -07:00
var widget = new IgnoredPopupWidget ( )
{
HAnchor = HAnchor . Fit ,
VAnchor = VAnchor . Fit ,
2017-10-31 11:43:25 -07:00
BackgroundColor = Color . White ,
2017-08-16 18:22:40 -07:00
Padding = new BorderDouble ( 0 , 5 , 5 , 0 )
} ;
2017-05-26 02:10:22 -07:00
FlowLayoutWidget buttonPanel = new FlowLayoutWidget ( FlowDirection . TopToBottom )
{
2017-08-07 15:47:27 -07:00
VAnchor = VAnchor . Fit ,
HAnchor = HAnchor . Fit ,
2017-05-26 02:10:22 -07:00
} ;
2017-08-16 18:22:40 -07:00
widget . AddChild ( buttonPanel ) ;
2017-05-26 02:10:22 -07:00
2017-10-25 10:49:24 -07:00
materialButtons . Clear ( ) ;
2017-08-01 17:38:07 -07:00
int extruderCount = 4 ;
for ( int extruderIndex = 0 ; extruderIndex < extruderCount ; extruderIndex + + )
2015-04-08 15:20:10 -07:00
{
2017-08-10 12:55:24 -07:00
FlowLayoutWidget colorSelectionContainer = new FlowLayoutWidget ( FlowDirection . LeftToRight )
{
HAnchor = HAnchor . Fit ,
Padding = new BorderDouble ( 5 )
} ;
buttonPanel . AddChild ( colorSelectionContainer ) ;
2015-05-30 12:48:16 -07:00
2017-09-08 17:13:06 -07:00
string materialLabelText = string . Format ( "{0} {1}" , "Material" . Localize ( ) , extruderIndex + 1 ) ;
2016-04-18 11:31:31 -07:00
2017-10-31 11:43:25 -07:00
RadioButton materialSelection = new RadioButton ( materialLabelText , textColor : Color . Black ) ;
2017-10-25 10:49:24 -07:00
materialButtons . Add ( materialSelection ) ;
materialSelection . SiblingRadioButtonList = materialButtons ;
2017-09-08 17:13:06 -07:00
colorSelectionContainer . AddChild ( materialSelection ) ;
2015-05-30 12:48:16 -07:00
colorSelectionContainer . AddChild ( new HorizontalSpacer ( ) ) ;
2017-07-12 14:28:43 -07:00
int extruderIndexCanPassToClick = extruderIndex ;
2017-09-08 17:13:06 -07:00
materialSelection . Click + = ( sender , e ) = >
2015-02-05 16:14:30 -08:00
{
2017-03-15 16:17:06 -07:00
if ( Scene . HasSelection )
2015-02-05 16:14:30 -08:00
{
2017-08-01 17:38:07 -07:00
Scene . SelectedItem . MaterialIndex = extruderIndexCanPassToClick ;
2017-10-25 17:04:55 -07:00
Scene . Invalidate ( ) ;
2017-09-08 17:13:06 -07:00
// "View 3D Overflow Menu" // the menu to click on
// "Materials Option" // the item to highlight
//HelpSystem.
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
} ;
2014-10-13 19:29:25 -07:00
2017-08-10 12:55:24 -07:00
colorSelectionContainer . AddChild ( new GuiWidget ( 16 , 16 )
{
2017-08-10 18:04:36 -07:00
BackgroundColor = MatterialRendering . Color ( extruderIndex ) ,
Margin = new BorderDouble ( 5 , 0 , 0 , 0 )
2017-08-10 12:55:24 -07:00
} ) ;
2015-04-08 15:20:10 -07:00
}
2017-05-26 02:10:22 -07:00
2017-08-16 18:22:40 -07:00
return widget ;
2015-04-08 15:20:10 -07:00
}
2014-09-26 15:04:04 -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
{
// add it back in to keep it running.
UiThread . RunOnIdle ( AutoSpin , . 04 ) ;
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 )
{
if ( ! Scene . HasSelection )
{
2017-10-20 07:26:14 -07:00
selectedObjectContainer . Visible = false ;
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 ;
}
2017-03-15 16:17:06 -07:00
var selectedItem = Scene . SelectedItem ;
2015-05-30 12:48:16 -07:00
2017-10-25 10:49:24 -07:00
if ( materialButtons ? . Count > 0 )
2017-07-12 14:28:43 -07:00
{
bool setSelection = false ;
// Set the material selector to have the correct material button selected
2017-10-25 10:49:24 -07:00
for ( int i = 0 ; i < materialButtons . Count ; i + + )
2017-07-12 14:28:43 -07:00
{
2017-08-01 17:38:07 -07:00
if ( selectedItem . MaterialIndex = = i )
2017-07-12 14:28:43 -07:00
{
2017-10-25 10:49:24 -07:00
( ( RadioButton ) materialButtons [ i ] ) . Checked = true ;
2017-07-12 14:28:43 -07:00
setSelection = true ;
}
}
if ( ! setSelection )
{
2017-10-25 10:49:24 -07:00
( ( RadioButton ) materialButtons [ 0 ] ) . Checked = true ;
2017-07-12 14:28:43 -07:00
}
}
2017-10-18 15:02:11 -07:00
2017-10-18 18:18:10 -07:00
selectedObjectPanel . SetActiveItem ( selectedItem ) ;
2017-03-15 16:17:06 -07:00
}
2015-05-30 12:48:16 -07:00
2017-03-15 16:17:06 -07:00
private void ShowObjectEditor ( IObject3DEditor editor )
{
editorPanel . CloseAllChildren ( ) ;
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-06-19 09:17:57 -07:00
var newEditor = editor . Create ( Scene . SelectedItem , this , this . theme ) ;
2017-10-18 15:02:11 -07:00
newEditor . HAnchor = HAnchor . Stretch ;
newEditor . VAnchor = VAnchor . Fit ;
2017-03-15 16:17:06 -07:00
editorPanel . AddChild ( newEditor ) ;
2015-05-30 12:48:16 -07:00
}
2017-03-15 16:17:06 -07:00
private void DrawStuffForSelectedPart ( Graphics2D graphics2D )
2015-05-30 12:48:16 -07:00
{
2017-03-15 16:17:06 -07:00
if ( Scene . HasSelection )
2015-04-08 15:20:10 -07:00
{
2017-03-15 16:17:06 -07:00
AxisAlignedBoundingBox selectedBounds = Scene . SelectedItem . GetAxisAlignedBoundingBox ( Scene . SelectedItem . Matrix ) ;
Vector3 boundsCenter = selectedBounds . Center ;
2017-10-31 12:51:16 -07:00
Vector3 centerTop = new Vector3 ( boundsCenter . X , boundsCenter . Y , selectedBounds . maxXYZ . Z ) ;
2014-01-29 19:09:30 -08:00
2017-07-10 14:00:27 -07:00
Vector2 centerTopScreenPosition = this . World . GetScreenPosition ( centerTop ) ;
2017-03-15 16:17:06 -07:00
centerTopScreenPosition = meshViewerWidget . TransformToParentSpace ( this , centerTopScreenPosition ) ;
2017-11-01 18:13:47 -07:00
//graphics2D.Circle(screenPosition.x, screenPosition.y, 5, Color.Cyan);
2015-04-08 15:20:10 -07:00
2017-10-10 15:42:33 -07:00
VertexStorage zArrow = new VertexStorage ( ) ;
2017-03-15 16:17:06 -07:00
zArrow . MoveTo ( - 6 , - 2 ) ;
zArrow . curve3 ( 0 , - 4 ) ;
zArrow . LineTo ( 6 , - 2 ) ;
zArrow . LineTo ( 0 , 12 ) ;
zArrow . LineTo ( - 6 , - 2 ) ;
2015-01-23 21:56:44 -08:00
2017-03-15 16:17:06 -07:00
VertexSourceApplyTransform translate = new VertexSourceApplyTransform ( zArrow , Affine . NewTranslation ( centerTopScreenPosition ) ) ;
2017-11-01 18:13:47 -07:00
//graphics2D.Render(translate, Color.Black);
2015-01-23 21:56:44 -08:00
}
2015-04-08 15:20:10 -07:00
}
2014-05-16 17:13:18 -07:00
2017-09-27 07:03:45 -07:00
public void StartProgress ( string rootTask )
{
this . LockEditControls ( ) ;
}
public void EndProgress ( )
{
this . UnlockEditControls ( ) ;
2017-10-25 17:04:55 -07:00
Scene . Invalidate ( ) ;
2017-09-27 07:03:45 -07:00
this . Invalidate ( ) ;
}
2015-07-02 11:23:44 -07:00
private async void LoadAndAddPartsToPlate ( string [ ] filesToLoad )
2015-05-30 12:48:16 -07:00
{
2017-09-27 07:03:45 -07:00
if ( filesToLoad ! = null & & filesToLoad . Length > 0 )
2015-05-30 12:48:16 -07:00
{
2017-09-27 07:03:45 -07:00
this . StartProgress ( "Loading Parts" . Localize ( ) + ":" ) ;
2015-04-08 15:20:10 -07:00
2015-07-02 11:23:44 -07:00
await Task . Run ( ( ) = > loadAndAddPartsToPlate ( filesToLoad ) ) ;
2015-04-08 15:20:10 -07:00
2016-04-25 12:51:29 -07:00
if ( HasBeenClosed )
2015-07-02 11:23:44 -07:00
{
return ;
}
2017-03-15 16:17:06 -07:00
bool addingOnlyOneItem = Scene . Children . Count = = Scene . Children . Count + 1 ;
2015-04-08 15:20:10 -07:00
2017-09-13 14:12:06 -07:00
if ( Scene . HasChildren ( ) )
2015-07-02 11:23:44 -07:00
{
if ( addingOnlyOneItem )
{
// if we are only adding one part to the plate set the selection to it
2017-03-15 16:17:06 -07:00
Scene . SelectLastChild ( ) ;
2015-07-02 11:23:44 -07:00
}
}
2017-09-27 07:03:45 -07:00
this . EndProgress ( ) ;
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
}
2014-01-29 19:09:30 -08:00
2017-09-27 07:03:45 -07:00
private async Task loadAndAddPartsToPlate ( string [ ] filesToLoadIncludingZips )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
Thread . CurrentThread . CurrentCulture = CultureInfo . InvariantCulture ;
2014-05-16 12:57:49 -07:00
2017-03-15 16:17:06 -07:00
if ( filesToLoadIncludingZips ? . Any ( ) = = true )
2015-05-30 12:48:16 -07:00
{
2017-03-15 16:17:06 -07:00
List < string > filesToLoad = new List < string > ( ) ;
foreach ( string loadedFileName in filesToLoadIncludingZips )
2015-05-30 12:48:16 -07:00
{
string extension = Path . GetExtension ( loadedFileName ) . ToUpper ( ) ;
2015-08-03 16:46:57 -07:00
if ( ( extension ! = "" & & MeshFileIo . ValidFileExtensions ( ) . Contains ( extension ) ) )
2015-05-30 12:48:16 -07:00
{
filesToLoad . Add ( loadedFileName ) ;
}
else if ( extension = = ".ZIP" )
{
2017-03-15 16:17:06 -07:00
List < PrintItem > partFiles = ProjectFileHandler . ImportFromProjectArchive ( loadedFileName ) ;
2015-05-30 12:48:16 -07:00
if ( partFiles ! = null )
{
foreach ( PrintItem part in partFiles )
{
filesToLoad . Add ( part . FileLocation ) ;
}
}
}
}
2014-10-12 20:40:38 -07:00
2015-05-30 12:48:16 -07:00
string progressMessage = "Loading Parts..." . Localize ( ) ;
2017-03-15 16:17:06 -07:00
var itemCache = new Dictionary < string , IObject3D > ( ) ;
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
foreach ( string filePath in filesToLoad )
2015-05-30 12:48:16 -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
var libraryItem = new FileSystemFileItem ( filePath ) ;
2017-04-05 19:03:04 -07:00
2017-12-11 14:15:50 -08:00
IObject3D object3D = null ;
await ApplicationController . Instance . Tasks . Execute ( async ( progressReporter , cancelationToken ) = >
2015-05-30 12:48:16 -07:00
{
2017-12-11 14:15:50 -08:00
var progressStatus = new ProgressStatus ( )
{
Status = "Loading " . Localize ( ) + Path . GetFileName ( filePath ) ,
} ;
progressReporter . Report ( progressStatus ) ;
2017-07-14 13:55:02 -07:00
2017-12-11 14:15:50 -08:00
object3D = await libraryItem . CreateContent ( ( double progress0To1 , string processingState ) = >
{
progressStatus . Progress0To1 = progress0To1 ;
progressStatus . Status = processingState ;
progressReporter . Report ( progressStatus ) ;
} ) ;
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-10-13 17:46:27 -07:00
if ( object3D ! = null )
2017-09-27 07:03:45 -07:00
{
2017-10-13 17:46:27 -07:00
Scene . Children . Modify ( list = > list . Add ( object3D ) ) ;
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-10-13 17:46:27 -07:00
PlatingHelper . MoveToOpenPositionRelativeGroup ( object3D , this . Scene . Children ) ;
2015-05-30 12:48:16 -07:00
}
}
}
}
2015-04-08 15:20:10 -07:00
2017-05-27 17:48:32 -07:00
internal void MakeLowestFaceFlat ( IObject3D objectToLayFlatGroup )
2015-04-08 15:20:10 -07:00
{
2017-08-15 16:56:54 -07:00
bool firstVertex = true ;
2017-03-15 16:17:06 -07:00
2017-08-15 16:56:54 -07:00
IObject3D objectToLayFlat = objectToLayFlatGroup ;
2016-02-26 14:19:52 -08:00
2017-08-15 16:56:54 -07:00
IVertex lowestVertex = null ;
Vector3 lowestVertexPosition = Vector3 . Zero ;
2017-10-18 11:56:37 -07:00
IObject3D itemToLayFlat = null ;
2017-03-15 16:17:06 -07:00
// Process each child, checking for the lowest vertex
2017-10-12 12:37:25 -07:00
var objectsToCheck = objectToLayFlat . VisibleMeshes ( ) ;
foreach ( var itemToCheck in objectsToCheck )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
// find the lowest point on the model
2017-10-12 12:37:25 -07:00
for ( int testIndex = 0 ; testIndex < itemToCheck . Mesh . Vertices . Count ; testIndex + + )
2015-04-08 15:20:10 -07:00
{
2017-07-18 20:51:32 -07:00
var vertex = itemToCheck . Mesh . Vertices [ testIndex ] ;
2017-10-18 11:56:37 -07:00
Vector3 vertexPosition = Vector3 . Transform ( vertex . Position , itemToCheck . WorldMatrix ( ) ) ;
2017-08-15 16:56:54 -07:00
if ( firstVertex )
{
lowestVertex = itemToCheck . Mesh . Vertices [ testIndex ] ;
lowestVertexPosition = vertexPosition ;
itemToLayFlat = itemToCheck ;
firstVertex = false ;
}
2017-10-31 12:51:16 -07:00
else if ( vertexPosition . Z < lowestVertexPosition . Z )
2015-05-30 12:48:16 -07:00
{
2017-03-15 16:17:06 -07:00
lowestVertex = itemToCheck . Mesh . Vertices [ testIndex ] ;
2015-05-30 12:48:16 -07:00
lowestVertexPosition = vertexPosition ;
2017-03-15 16:17:06 -07:00
itemToLayFlat = itemToCheck ;
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
}
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
Face faceToLayFlat = null ;
double lowestAngleOfAnyFace = double . MaxValue ;
// Check all the faces that are connected to the lowest point to find out which one to lay flat.
foreach ( Face face in lowestVertex . ConnectedFaces ( ) )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
double biggestAngleToFaceVertex = double . MinValue ;
2017-07-18 18:20:04 -07:00
foreach ( IVertex faceVertex in face . Vertices ( ) )
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
if ( faceVertex ! = lowestVertex )
{
2017-11-08 14:45:36 -08:00
Vector3 faceVertexPosition = Vector3 . Transform ( faceVertex . Position , itemToLayFlat . WorldMatrix ( ) ) ;
2015-05-30 12:48:16 -07:00
Vector3 pointRelLowest = faceVertexPosition - lowestVertexPosition ;
2017-10-31 12:51:16 -07:00
double xLeg = new Vector2 ( pointRelLowest . X , pointRelLowest . Y ) . Length ;
double yLeg = pointRelLowest . Z ;
2015-05-30 12:48:16 -07:00
double angle = Math . Atan2 ( yLeg , xLeg ) ;
if ( angle > biggestAngleToFaceVertex )
{
biggestAngleToFaceVertex = angle ;
}
}
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
if ( biggestAngleToFaceVertex < lowestAngleOfAnyFace )
{
lowestAngleOfAnyFace = biggestAngleToFaceVertex ;
faceToLayFlat = face ;
}
}
2014-01-29 19:09:30 -08:00
2015-05-30 12:48:16 -07:00
double maxDistFromLowestZ = 0 ;
2017-08-27 16:00:33 -07:00
List < Vector3 > faceVertices = new List < Vector3 > ( ) ;
2017-07-18 18:20:04 -07:00
foreach ( IVertex vertex in faceToLayFlat . Vertices ( ) )
2015-04-08 15:20:10 -07:00
{
2017-11-08 14:45:36 -08:00
Vector3 vertexPosition = Vector3 . Transform ( vertex . Position , itemToLayFlat . WorldMatrix ( ) ) ;
2017-08-27 16:00:33 -07:00
faceVertices . Add ( vertexPosition ) ;
2017-10-31 12:51:16 -07:00
maxDistFromLowestZ = Math . Max ( maxDistFromLowestZ , vertexPosition . Z - lowestVertexPosition . Z ) ;
2015-05-30 12:48:16 -07:00
}
2014-10-12 08:18:24 -07:00
2015-05-30 12:48:16 -07:00
if ( maxDistFromLowestZ > . 001 )
{
2017-08-27 16:00:33 -07:00
Vector3 xPositive = ( faceVertices [ 1 ] - faceVertices [ 0 ] ) . GetNormal ( ) ;
Vector3 yPositive = ( faceVertices [ 2 ] - faceVertices [ 0 ] ) . GetNormal ( ) ;
2015-05-30 12:48:16 -07:00
Vector3 planeNormal = Vector3 . Cross ( xPositive , yPositive ) . GetNormal ( ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
// this code takes the minimum rotation required and looks much better.
Quaternion rotation = new Quaternion ( planeNormal , new Vector3 ( 0 , 0 , - 1 ) ) ;
Matrix4X4 partLevelMatrix = Matrix4X4 . CreateRotation ( rotation ) ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
// rotate it
2017-03-15 16:17:06 -07:00
objectToLayFlatGroup . Matrix = PlatingHelper . ApplyAtCenter ( objectToLayFlatGroup , partLevelMatrix ) ;
2015-04-08 15:20:10 -07:00
2017-10-25 17:04:55 -07:00
Scene . Invalidate ( ) ;
2015-05-30 12:48:16 -07:00
Invalidate ( ) ;
}
2017-08-15 16:56:54 -07:00
2017-09-05 18:02:19 -07:00
PlatingHelper . PlaceOnBed ( objectToLayFlatGroup ) ;
2015-05-30 12:48:16 -07:00
}
2016-01-10 10:18:53 -08:00
public static Regex fileNameNumberMatch = new Regex ( "\\(\\d+\\)" , RegexOptions . Compiled ) ;
2017-03-15 16:17:06 -07:00
private FlowLayoutWidget editorPanel ;
2017-10-20 07:26:14 -07:00
private SelectedObjectPanel selectedObjectPanel ;
internal GuiWidget selectedObjectContainer ;
2017-10-19 09:04:36 -07:00
2017-12-11 14:15:50 -08:00
public Task SaveChanges ( IProgress < ProgressStatus > progress , CancellationToken cancellationToken )
2017-03-15 16:17:06 -07:00
{
2017-12-11 14:15:50 -08:00
var progressStatus = new ProgressStatus ( )
2015-05-30 12:48:16 -07:00
{
2017-12-11 14:15:50 -08:00
Status = "Saving Changes"
} ;
2016-01-11 14:06:47 -08:00
2017-12-11 14:15:50 -08:00
progress . Report ( progressStatus ) ;
2015-09-23 13:33:14 -07:00
2017-12-11 14:15:50 -08:00
sceneContext . Save ( ( progress0to1 , status ) = >
{
progressStatus . Status = status ;
progressStatus . Progress0To1 = progress0to1 ;
progress . Report ( progressStatus ) ;
} ) ;
2015-11-04 17:42:07 -08:00
2017-12-11 14:15:50 -08:00
return Task . CompletedTask ;
2015-04-08 15:20:10 -07:00
}
2015-05-30 12:48:16 -07:00
private void meshViewerWidget_LoadDone ( object sender , EventArgs e )
2015-04-08 15:20:10 -07:00
{
2017-09-15 16:49:21 -07:00
if ( sceneContext . RendererOptions . SyncToPrint )
2015-05-30 12:48:16 -07:00
{
2017-09-15 16:49:21 -07:00
switch ( sceneContext . Printer ? . Connection . CommunicationState )
2015-05-30 12:48:16 -07:00
{
2017-06-13 17:32:38 -07:00
case CommunicationStates . Printing :
case CommunicationStates . Paused :
2015-05-30 12:48:16 -07:00
break ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
default :
UnlockEditControls ( ) ;
break ;
}
}
else
2015-04-08 15:20:10 -07:00
{
2015-05-30 12:48:16 -07:00
UnlockEditControls ( ) ;
2015-04-08 15:20:10 -07:00
}
2017-10-06 12:30:48 -07:00
UiThread . RunOnIdle ( SwitchStateToEditing ) ;
2015-05-30 12:48:16 -07:00
}
2015-04-08 15:20:10 -07:00
2015-06-11 12:06:40 -07:00
private void OpenSaveAsWindow ( )
2015-05-30 12:48:16 -07:00
{
2017-11-08 15:56:37 -08:00
DialogWindow . Show (
2017-10-31 06:52:59 -07:00
new SaveAsPage (
async ( returnInfo ) = >
2017-10-31 06:44:42 -07:00
{
2017-10-31 06:52:59 -07:00
// Save the scene to disk
2017-12-11 14:15:50 -08:00
await ApplicationController . Instance . Tasks . Execute ( this . SaveChanges ) ;
2017-10-31 06:52:59 -07:00
// Save to the destination provider
if ( returnInfo ? . DestinationContainer ! = null )
2017-07-12 08:03:06 -07:00
{
2017-10-31 06:52:59 -07:00
// save this part to correct library provider
if ( returnInfo . DestinationContainer is ILibraryWritableContainer writableContainer )
2017-07-12 08:03:06 -07:00
{
2017-10-31 06:52:59 -07:00
writableContainer . Add ( new [ ]
2017-07-12 08:03:06 -07:00
{
2017-11-15 07:41:36 -08:00
new FileSystemFileItem ( sceneContext . EditContext . PartFilePath )
2017-10-31 06:52:59 -07:00
{
2017-10-31 06:59:55 -07:00
Name = returnInfo . ItemName
2017-10-31 06:52:59 -07:00
}
} ) ;
2017-07-12 08:03:06 -07:00
2017-10-31 06:52:59 -07:00
returnInfo . DestinationContainer . Dispose ( ) ;
}
2017-07-12 08:03:06 -07:00
}
2017-10-31 06:52:59 -07:00
} ) ) ;
2015-05-30 12:48:16 -07:00
}
private bool rotateQueueMenu_Click ( )
{
return true ;
}
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 ; }
2017-03-15 16:17:06 -07:00
internal async void SwitchStateToEditing ( )
{
viewControls3D . ActiveButton = ViewControls3DButtons . PartSelect ;
2017-09-27 07:03:45 -07:00
this . StartProgress ( "Preparing Meshes" . Localize ( ) + ":" ) ;
2017-03-15 16:17:06 -07:00
2017-09-13 14:12:06 -07:00
if ( Scene . HasChildren ( ) )
2017-03-15 16:17:06 -07:00
{
2017-09-27 07:03:45 -07:00
// TODO: Why is this in widget land? When we load content we should queue trace generation, not when we rebuild ui controls
2017-03-15 16:17:06 -07:00
// CreateSelectionData()
await Task . Run ( ( ) = >
{
Thread . CurrentThread . CurrentCulture = CultureInfo . InvariantCulture ;
// Force trace data generation
foreach ( var object3D in Scene . Children )
{
object3D . TraceData ( ) ;
}
} ) ;
if ( this . HasBeenClosed )
{
return ;
}
Scene . SelectFirstChild ( ) ;
}
2017-09-27 07:03:45 -07:00
this . EndProgress ( ) ;
2017-03-15 16:17:06 -07:00
2017-09-27 07:03:45 -07:00
viewControls3D . ActiveButton = ViewControls3DButtons . PartSelect ;
2017-03-15 16:17:06 -07:00
}
2017-09-27 12:47:23 -07:00
public void LockEditControls ( )
{
bottomActionPanel . Enabled = false ;
}
2017-03-15 16:17:06 -07:00
public void UnlockEditControls ( )
2015-05-30 12:48:16 -07:00
{
2017-09-27 12:47:23 -07:00
bottomActionPanel . Enabled = true ;
2015-04-08 15:20:10 -07:00
2015-05-30 12:48:16 -07:00
if ( wasInSelectMode )
2015-04-08 15:20:10 -07:00
{
2015-05-29 15:13:56 -07:00
viewControls3D . ActiveButton = ViewControls3DButtons . PartSelect ;
2015-05-30 12:48:16 -07:00
wasInSelectMode = false ;
}
2015-04-08 15:20:10 -07:00
}
2017-05-25 17:58:20 -07:00
2017-05-26 00:23:20 -07:00
internal GuiWidget ShowOverflowMenu ( )
2017-05-25 17:58:20 -07:00
{
2017-11-10 13:12:02 -08:00
var popupMenu = new PopupMenu ( theme ) ;
2017-05-25 17:58:20 -07:00
var meshViewer = meshViewerWidget ;
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Show Print Bed" . Localize ( ) ,
( ) = > sceneContext . RendererOptions . RenderBed ,
( value ) = >
{
meshViewer . RenderBed = value ;
sceneContext . RendererOptions . RenderBed = value ;
} ) ;
2017-11-09 18:26:32 -08:00
if ( sceneContext . BuildHeight > 0 )
{
2017-11-20 13:09:52 -08:00
popupMenu . CreateBoolMenuItem (
"Show Print Area" . Localize ( ) ,
( ) = > meshViewer . RenderBuildVolume ,
( value ) = > meshViewer . RenderBuildVolume = value ) ;
2017-11-09 15:48:05 -08:00
}
2017-11-09 18:26:32 -08:00
popupMenu . CreateHorizontalLine ( ) ;
2017-05-27 17:48:32 -07:00
2017-11-09 15:48:05 -08:00
// TODO: This should be moved to the MeshViewerWidget constructor or initializer calls
2017-05-25 17:58:20 -07:00
string renderTypeString = UserSettings . Instance . get ( UserSettingsKey . defaultRenderSetting ) ;
if ( renderTypeString = = null )
{
2017-11-09 15:48:05 -08:00
renderTypeString = ( UserSettings . Instance . IsTouchScreen ) ? "Shaded" : "Outlines" ;
2017-05-25 17:58:20 -07:00
UserSettings . Instance . set ( UserSettingsKey . defaultRenderSetting , renderTypeString ) ;
}
RenderTypes renderType ;
bool canParse = Enum . TryParse ( renderTypeString , out renderType ) ;
if ( canParse )
{
meshViewerWidget . RenderType = renderType ;
}
2017-11-09 18:26:32 -08:00
AddRadioButton ( "Shaded" . Localize ( ) , RenderTypes . Shaded , popupMenu ) ;
AddRadioButton ( "Outlines" . Localize ( ) , RenderTypes . Outlines , popupMenu ) ;
AddRadioButton ( "Polygons" . Localize ( ) , RenderTypes . Polygons , popupMenu ) ;
AddRadioButton ( "Materials Option" . Localize ( ) , RenderTypes . Materials , popupMenu ) ;
AddRadioButton ( "Overhang" . Localize ( ) , RenderTypes . Overhang , popupMenu , ( ) = >
2017-05-25 17:58:20 -07:00
{
2017-11-09 15:48:05 -08:00
meshViewerWidget . RenderType = RenderTypes . Overhang ;
2017-05-25 17:58:20 -07:00
2017-11-09 15:48:05 -08:00
UserSettings . Instance . set ( "defaultRenderSetting" , meshViewerWidget . RenderType . ToString ( ) ) ;
2017-05-25 17:58:20 -07:00
2017-11-09 15:48:05 -08:00
// Loop over all visible meshes, changing the face color depending on the face normal Z value
foreach ( var meshRenderData in this . Scene . VisibleMeshes ( ) )
2017-05-25 17:58:20 -07:00
{
2017-11-09 15:48:05 -08:00
meshRenderData . Mesh . MarkAsChanged ( ) ;
2017-05-25 17:58:20 -07:00
2017-11-09 15:48:05 -08:00
// change the color to be the right thing
GLMeshTrianglePlugin . Get (
meshRenderData . Mesh ,
2017-11-20 13:29:01 -08:00
( normal ) = >
2017-11-09 15:48:05 -08:00
{
normal = Vector3 . TransformVector ( normal , meshRenderData . WorldMatrix ( ) ) . GetNormal ( ) ;
2017-05-25 17:58:20 -07:00
2017-11-09 15:48:05 -08:00
double startColor = 223.0 / 360.0 ;
double endColor = 5.0 / 360.0 ;
double delta = endColor - startColor ;
2017-05-25 17:58:20 -07:00
2017-11-09 15:48:05 -08:00
var color = ColorF . FromHSL ( startColor , . 99 , . 49 ) . ToColor ( ) ;
if ( normal . Z < 0 )
{
color = ColorF . FromHSL ( startColor - delta * normal . Z , . 99 , . 49 ) . ToColor ( ) ;
}
2017-05-25 17:58:20 -07:00
2017-11-20 13:29:01 -08:00
return color ;
2017-11-09 15:48:05 -08:00
} ) ;
}
} ) ;
2017-05-25 17:58:20 -07:00
2017-11-09 18:26:32 -08:00
popupMenu . CreateHorizontalLine ( ) ;
2017-05-25 17:58:20 -07:00
2017-11-09 18:26:32 -08:00
popupMenu . AddChild ( new GridOptionsPanel ( this . InteractionLayer ) ) ;
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
2017-11-09 18:26:32 -08:00
private void AddRadioButton ( string label , RenderTypes renderTypes , PopupMenu popupMenu , Action action = null )
2017-11-09 15:48:05 -08:00
{
var radioButton = new RadioButton ( label , textColor : Color . Black )
{
Checked = ( meshViewerWidget . RenderType = = renderTypes ) ,
HAnchor = HAnchor . MaxFitOrStretch ,
Margin = 0
} ;
radioButton . CheckedStateChanged + = ( s , e ) = >
{
if ( radioButton . Checked )
{
if ( action = = null )
{
meshViewerWidget . RenderType = renderTypes ;
UserSettings . Instance . set ( UserSettingsKey . defaultRenderSetting , meshViewerWidget . RenderType . ToString ( ) ) ;
}
else
{
action . Invoke ( ) ;
}
}
} ;
2017-08-01 17:38:07 -07:00
2017-11-09 18:26:32 -08:00
popupMenu . CreateMenuItem ( radioButton , $"{label}-Menu" ) ;
2017-05-25 17:58:20 -07:00
}
2017-07-05 14:34:38 -07:00
protected bool autoRotating = false ;
protected bool allowAutoRotate = false ;
public MeshViewerWidget meshViewerWidget ;
2017-10-25 17:04:55 -07:00
public InteractiveScene Scene { get ; }
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
intersectionInfo = Scene . TraceData ( ) . GetClosestIntersection ( ray ) ;
if ( intersectionInfo ! = null )
{
foreach ( Object3D object3D in Scene . Children )
{
if ( object3D . TraceData ( ) . Contains ( intersectionInfo . closestHitObject ) )
{
CurrentSelectInfo . PlaneDownHitPos = intersectionInfo . HitPosition ;
CurrentSelectInfo . LastMoveDelta = new Vector3 ( ) ;
return object3D ;
}
}
}
return null ;
}
2016-02-19 08:29:49 -08:00
}
2015-05-30 12:48:16 -07:00
2016-02-19 08:29:49 -08:00
public enum HitQuadrant { LB , LT , RB , RT }
public class MeshSelectInfo
{
public HitQuadrant HitQuadrant ;
public bool DownOnPart ;
public PlaneShape HitPlane ;
public Vector3 LastMoveDelta ;
public Vector3 PlaneDownHitPos ;
2015-04-08 15:20:10 -07:00
}
2017-08-20 02:34:39 -07:00
}