2018-01-29 13:50:55 -08:00
/ *
Copyright ( c ) 2018 , Lars Brubaker , John Lewin
All rights reserved .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are met :
1. Redistributions of source code must retain the above copyright notice , this
list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright notice ,
this list of conditions and the following disclaimer in the documentation
and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies ,
either expressed or implied , of the FreeBSD Project .
* /
using System ;
2018-03-19 09:27:15 -07:00
using System.Collections.Generic ;
using System.ComponentModel ;
2018-03-26 16:29:23 -07:00
using System.Linq ;
2018-03-19 09:27:15 -07:00
using MatterHackers.Agg.UI ;
2018-01-29 13:50:55 -08:00
using MatterHackers.DataConverters3D ;
using MatterHackers.VectorMath ;
2018-05-15 13:56:05 -07:00
using Newtonsoft.Json ;
using Newtonsoft.Json.Converters ;
2018-01-29 13:50:55 -08:00
namespace MatterHackers.MatterControl.DesignTools.Operations
{
2018-03-19 09:27:15 -07:00
using Aabb = AxisAlignedBoundingBox ;
2018-05-15 13:56:05 -07:00
[JsonConverter(typeof(StringEnumConverter))]
2018-03-26 16:29:23 -07:00
public enum Align { None , Min , Center , Max , Origin }
2018-03-19 09:27:15 -07:00
2018-05-15 13:56:05 -07:00
[JsonConverter(typeof(StringEnumConverter))]
2018-01-29 13:50:55 -08:00
public enum Alignment { X , Y , Z , negX , negY , negZ } ;
2018-05-15 13:56:05 -07:00
[JsonConverter(typeof(StringEnumConverter))]
2018-01-29 13:50:55 -08:00
[Flags]
public enum Edge
{
2018-06-02 22:29:56 -07:00
LeftFront = FaceAlign . Left | FaceAlign . Front ,
LeftBack = FaceAlign . Left | FaceAlign . Back ,
LeftBottom = FaceAlign . Left | FaceAlign . Bottom ,
LeftTop = FaceAlign . Left | FaceAlign . Top ,
RightFront = FaceAlign . Right | FaceAlign . Front ,
RightBack = FaceAlign . Right | FaceAlign . Back ,
RightBottom = FaceAlign . Right | FaceAlign . Bottom ,
RightTop = FaceAlign . Right | FaceAlign . Top ,
FrontBottom = FaceAlign . Front | FaceAlign . Bottom ,
FrontTop = FaceAlign . Front | FaceAlign . Top ,
BackBottom = FaceAlign . Back | FaceAlign . Bottom ,
BackTop = FaceAlign . Back | FaceAlign . Top
2018-01-29 13:50:55 -08:00
}
2018-05-15 13:56:05 -07:00
[JsonConverter(typeof(StringEnumConverter))]
2018-01-29 13:50:55 -08:00
[Flags]
2018-06-02 22:29:56 -07:00
public enum FaceAlign
2018-01-29 13:50:55 -08:00
{
Left = 0x01 ,
Right = 0x02 ,
Front = 0x04 ,
Back = 0x08 ,
Bottom = 0x10 ,
Top = 0x20 ,
} ;
2018-05-15 13:56:05 -07:00
[JsonConverter(typeof(StringEnumConverter))]
2018-03-13 17:17:28 -07:00
[Flags]
public enum Side2D
{
Left = 0x01 ,
Right = 0x02 ,
Bottom = 0x10 ,
Top = 0x20 ,
} ;
2018-06-21 21:02:37 -07:00
public class AlignObject3D : Object3D , IPropertyGridModifier
2018-01-29 13:50:55 -08:00
{
2018-03-19 09:27:15 -07:00
// We need to serialize this so we can remove the arrange and get back to the objects before arranging
public List < Aabb > OriginalChildrenBounds = new List < Aabb > ( ) ;
2018-06-21 21:02:37 -07:00
public AlignObject3D ( )
2018-01-29 13:50:55 -08:00
{
2018-03-19 09:27:15 -07:00
Name = "Align" ;
2018-01-29 13:50:55 -08:00
}
2018-06-21 21:02:37 -07:00
public AlignObject3D ( IObject3D objectToAlign , FaceAlign boundingFacesToAlign , IObject3D objectToAlignTo , FaceAlign boundingFacesToAlignTo , double offsetX = 0 , double offsetY = 0 , double offsetZ = 0 , string name = "" )
2018-01-29 13:50:55 -08:00
: this ( objectToAlign , boundingFacesToAlign , GetPositionToAlignTo ( objectToAlignTo , boundingFacesToAlignTo , new Vector3 ( offsetX , offsetY , offsetZ ) ) , name )
{
if ( objectToAlign = = objectToAlignTo )
{
2018-03-13 17:17:28 -07:00
throw new Exception ( "You cannot align an object to itself." ) ;
2018-01-29 13:50:55 -08:00
}
}
2018-06-21 21:02:37 -07:00
public AlignObject3D ( IObject3D objectToAlign , FaceAlign boundingFacesToAlign , double positionToAlignToX = 0 , double positionToAlignToY = 0 , double positionToAlignToZ = 0 , string name = "" )
2018-03-13 08:26:54 -07:00
: this ( objectToAlign , boundingFacesToAlign , new Vector3 ( positionToAlignToX , positionToAlignToY , positionToAlignToZ ) , name )
2018-01-29 13:50:55 -08:00
{
}
2018-06-21 21:02:37 -07:00
public AlignObject3D ( IObject3D objectToAlign , FaceAlign boundingFacesToAlign , Vector3 positionToAlignTo , double offsetX , double offsetY , double offsetZ , string name = "" )
2018-01-29 13:50:55 -08:00
: this ( objectToAlign , boundingFacesToAlign , positionToAlignTo + new Vector3 ( offsetX , offsetY , offsetZ ) , name )
{
}
2018-06-21 21:02:37 -07:00
public AlignObject3D ( IObject3D item , FaceAlign boundingFacesToAlign , Vector3 positionToAlignTo , string name = "" )
2018-01-29 13:50:55 -08:00
{
AxisAlignedBoundingBox bounds = item . GetAxisAlignedBoundingBox ( ) ;
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlign , FaceAlign . Left , FaceAlign . Right ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . X = positionToAlignTo . X - bounds . minXYZ . X ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlign , FaceAlign . Right , FaceAlign . Left ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . X = positionToAlignTo . X - bounds . minXYZ . X - ( bounds . maxXYZ . X - bounds . minXYZ . X ) ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlign , FaceAlign . Front , FaceAlign . Back ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . Y = positionToAlignTo . Y - bounds . minXYZ . Y ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlign , FaceAlign . Back , FaceAlign . Front ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . Y = positionToAlignTo . Y - bounds . minXYZ . Y - ( bounds . maxXYZ . Y - bounds . minXYZ . Y ) ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlign , FaceAlign . Bottom , FaceAlign . Top ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . Z = positionToAlignTo . Z - bounds . minXYZ . Z ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlign , FaceAlign . Top , FaceAlign . Bottom ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . Z = positionToAlignTo . Z - bounds . minXYZ . Z - ( bounds . maxXYZ . Z - bounds . minXYZ . Z ) ;
}
Matrix * = Matrix4X4 . CreateTranslation ( positionToAlignTo ) ;
Children . Add ( item . Clone ( ) ) ;
}
2018-08-13 13:48:10 -07:00
[ShowAsList]
[DisplayName("Anchor")]
public ChildrenSelector AnchorObjectSelector { get ; set ; } = new ChildrenSelector ( ) ;
2018-04-12 09:54:31 -07:00
public bool Advanced { get ; set ; } = false ;
2018-03-19 09:27:15 -07:00
[DisplayName("X")]
2018-03-26 16:29:23 -07:00
[Icons(new string[] { "424.png" , "align_left.png" , "align_center_x.png" , "align_right.png" , "align_origin.png" } ) ]
2018-03-19 09:27:15 -07:00
public Align XAlign { get ; set ; } = Align . None ;
[DisplayName("Start X")]
2018-03-26 16:29:23 -07:00
[Icons(new string[] { "424.png" , "align_to_left.png" , "align_to_center_x.png" , "align_to_right.png" , "" } ) ]
2018-03-19 09:27:15 -07:00
public Align XAlignTo { get ; set ; } = Align . None ;
[DisplayName("Offset X")]
public double XOffset { get ; set ; } = 0 ;
[DisplayName("Y")]
2018-08-19 18:10:28 -07:00
[Icons(new string[] { "424.png" , "align_bottom.png" , "align_center_y.png" , "align_Top.png" , "align_origin.png" } ) ]
2018-03-19 09:27:15 -07:00
public Align YAlign { get ; set ; } = Align . None ;
[DisplayName("Start Y")]
2018-03-26 16:29:23 -07:00
[Icons(new string[] { "424.png" , "align_to_bottom.png" , "align_to_center_y.png" , "align_to_top.png" , "" } ) ]
2018-03-19 09:27:15 -07:00
public Align YAlignTo { get ; set ; } = Align . None ;
[DisplayName("Offset Y")]
public double YOffset { get ; set ; } = 0 ;
[DisplayName("Z")]
2018-08-19 18:10:28 -07:00
[Icons(new string[] { "424.png" , "align_bottom.png" , "align_center_y.png" , "align_Top.png" , "align_origin.png" } ) ]
2018-03-19 09:27:15 -07:00
public Align ZAlign { get ; set ; } = Align . None ;
[DisplayName("Start Z")]
2018-03-26 16:29:23 -07:00
[Icons(new string[] { "424.png" , "align_to_bottom.png" , "align_to_center_y.png" , "align_to_top.png" , "" } ) ]
2018-03-19 09:27:15 -07:00
public Align ZAlignTo { get ; set ; } = Align . None ;
[DisplayName("Offset Z")]
public double ZOffset { get ; set ; } = 0 ;
2018-05-02 14:34:44 -07:00
public override bool CanApply = > true ;
2018-03-19 09:27:15 -07:00
private List < Aabb > CurrentChildrenBounds
{
get
{
2018-08-08 13:59:34 -07:00
var currentChildrenBounds = new List < Aabb > ( ) ;
2018-03-19 09:27:15 -07:00
this . Children . Modify ( list = >
{
foreach ( var child in list )
{
currentChildrenBounds . Add ( child . GetAxisAlignedBoundingBox ( ) ) ;
}
} ) ;
return currentChildrenBounds ;
}
}
2018-08-13 13:48:10 -07:00
[JsonIgnore]
private IObject3D AnchorObject
{
get
{
if ( AnchorObjectSelector . Count = = 1 )
{
return this . Children . Where ( c = > c . ID = = AnchorObjectSelector [ 0 ] ) . FirstOrDefault ( ) ;
}
return null ;
}
}
[JsonIgnore]
private int AnchorObjectIndex
{
get
{
int index = 0 ;
foreach ( var child in this . Children )
{
if ( child . ID = = AnchorObjectSelector [ 0 ] )
{
return index ;
}
index + + ;
}
return - 1 ;
}
}
2018-06-02 22:29:56 -07:00
public static Vector3 GetPositionToAlignTo ( IObject3D objectToAlignTo , FaceAlign boundingFacesToAlignTo , Vector3 extraOffset )
2018-01-29 13:50:55 -08:00
{
Vector3 positionToAlignTo = new Vector3 ( ) ;
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlignTo , FaceAlign . Left , FaceAlign . Right ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . X = objectToAlignTo . GetAxisAlignedBoundingBox ( ) . minXYZ . X ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlignTo , FaceAlign . Right , FaceAlign . Left ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . X = objectToAlignTo . GetAxisAlignedBoundingBox ( ) . maxXYZ . X ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlignTo , FaceAlign . Front , FaceAlign . Back ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . Y = objectToAlignTo . GetAxisAlignedBoundingBox ( ) . minXYZ . Y ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlignTo , FaceAlign . Back , FaceAlign . Front ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . Y = objectToAlignTo . GetAxisAlignedBoundingBox ( ) . maxXYZ . Y ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlignTo , FaceAlign . Bottom , FaceAlign . Top ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . Z = objectToAlignTo . GetAxisAlignedBoundingBox ( ) . minXYZ . Z ;
}
2018-06-02 22:29:56 -07:00
if ( IsSet ( boundingFacesToAlignTo , FaceAlign . Top , FaceAlign . Bottom ) )
2018-01-29 13:50:55 -08:00
{
positionToAlignTo . Z = objectToAlignTo . GetAxisAlignedBoundingBox ( ) . maxXYZ . Z ;
}
return positionToAlignTo + extraOffset ;
}
2018-05-22 16:17:13 -07:00
public override void OnInvalidate ( InvalidateArgs invalidateType )
2018-05-04 13:47:16 -07:00
{
2018-06-08 12:08:48 -07:00
if ( ( invalidateType . InvalidateType = = InvalidateType . Content
| | invalidateType . InvalidateType = = InvalidateType . Matrix
| | invalidateType . InvalidateType = = InvalidateType . Mesh )
2018-05-22 16:17:13 -07:00
& & invalidateType . Source ! = this
2018-06-20 17:16:38 -07:00
& & ! RebuildLocked )
{
Rebuild ( null ) ;
}
else if ( invalidateType . InvalidateType = = InvalidateType . Properties
& & invalidateType . Source = = this )
2018-05-04 13:47:16 -07:00
{
Rebuild ( null ) ;
}
2018-05-29 17:46:59 -07:00
else
{
base . OnInvalidate ( invalidateType ) ;
}
2018-05-04 13:47:16 -07:00
}
2018-06-20 17:16:38 -07:00
private void Rebuild ( UndoBuffer undoBuffer )
2018-01-29 13:50:55 -08:00
{
2018-05-29 17:46:59 -07:00
this . DebugDepth ( "Rebuild" ) ;
2018-08-13 13:48:10 -07:00
var childrenIds = Children . Select ( c = > c . ID ) . ToArray ( ) ;
if ( childrenIds . Length = = 0 )
{
AnchorObjectSelector . Clear ( ) ;
}
else if ( AnchorObjectSelector . Count ! = 1
| | ! AnchorObjectSelector . Where ( i = > childrenIds . Contains ( i ) ) . Any ( ) )
{
AnchorObjectSelector . Clear ( ) ;
AnchorObjectSelector . Add ( childrenIds [ 0 ] ) ;
}
// if the count of our children changed clear our cache of the bounds
if ( Children . Count ! = OriginalChildrenBounds . Count )
{
OriginalChildrenBounds . Clear ( ) ;
}
2018-06-20 08:09:35 -07:00
using ( RebuildLock ( ) )
2018-01-29 13:50:55 -08:00
{
2018-06-20 08:09:35 -07:00
var aabb = this . GetAxisAlignedBoundingBox ( ) ;
2018-01-29 13:50:55 -08:00
2018-06-20 08:09:35 -07:00
// TODO: check if the has code for the children
if ( OriginalChildrenBounds . Count = = 0 )
2018-05-04 13:47:16 -07:00
{
2018-06-20 08:09:35 -07:00
this . Children . Modify ( list = >
{
foreach ( var child in list )
{
OriginalChildrenBounds . Add ( child . GetAxisAlignedBoundingBox ( ) ) ;
}
} ) ;
2018-05-04 13:47:16 -07:00
}
2018-06-20 08:09:35 -07:00
this . Children . Modify ( list = >
2018-03-19 09:27:15 -07:00
{
2018-06-20 08:09:35 -07:00
if ( list . Count = = 0 )
{
return ;
}
2018-08-13 13:48:10 -07:00
int anchorIndex = AnchorObjectIndex ;
var anchorBounds = CurrentChildrenBounds [ anchorIndex ] ;
2018-06-20 08:09:35 -07:00
int i = 0 ;
2018-08-13 13:48:10 -07:00
// first align the anchor object
2018-06-20 08:09:35 -07:00
foreach ( var child in list )
2018-03-19 09:27:15 -07:00
{
2018-08-13 13:48:10 -07:00
if ( XAlign = = Align . None
| | i = = anchorIndex )
{
if ( i < OriginalChildrenBounds . Count )
{
// make sure it is where it started
AlignAxis ( 0 , Align . Min , OriginalChildrenBounds [ i ] . minXYZ . X , 0 , child ) ;
}
}
if ( YAlign = = Align . None
| | i = = anchorIndex )
2018-03-19 09:27:15 -07:00
{
2018-08-13 13:48:10 -07:00
if ( i < OriginalChildrenBounds . Count )
2018-05-09 09:29:54 -07:00
{
2018-08-13 13:48:10 -07:00
AlignAxis ( 1 , Align . Min , OriginalChildrenBounds [ i ] . minXYZ . Y , 0 , child ) ;
}
}
if ( ZAlign = = Align . None
| | i = = anchorIndex )
{
if ( i < OriginalChildrenBounds . Count )
{
AlignAxis ( 2 , Align . Min , OriginalChildrenBounds [ i ] . minXYZ . Z , 0 , child ) ;
}
}
i + + ;
}
// the align all the objects to it
i = 0 ;
foreach ( var child in list )
{
if ( XAlign ! = Align . None
& & i ! = anchorIndex )
{
if ( XAlign = = Align . Origin )
{
// find the origin in world space of the child
var firstOrigin = Vector3 . Transform ( Vector3 . Zero , AnchorObject . WorldMatrix ( ) ) ;
var childOrigin = Vector3 . Transform ( Vector3 . Zero , child . WorldMatrix ( ) ) ;
child . Translate ( new Vector3 ( - ( childOrigin - firstOrigin ) . X + ( Advanced ? XOffset : 0 ) , 0 , 0 ) ) ;
2018-05-09 09:29:54 -07:00
}
2018-06-20 08:09:35 -07:00
else
2018-03-26 16:29:23 -07:00
{
2018-08-13 13:48:10 -07:00
AlignAxis ( 0 , XAlign , GetAlignToOffset ( CurrentChildrenBounds , 0 , ( ! Advanced | | XAlignTo = = Align . None ) ? XAlign : XAlignTo ) , XOffset , child ) ;
2018-03-26 16:29:23 -07:00
}
2018-08-13 13:48:10 -07:00
}
if ( YAlign ! = Align . None
& & i ! = anchorIndex )
{
if ( YAlign = = Align . Origin )
2018-03-26 16:29:23 -07:00
{
2018-08-13 13:48:10 -07:00
// find the origin in world space of the child
var firstOrigin = Vector3 . Transform ( Vector3 . Zero , AnchorObject . WorldMatrix ( ) ) ;
var childOrigin = Vector3 . Transform ( Vector3 . Zero , child . WorldMatrix ( ) ) ;
child . Translate ( new Vector3 ( 0 , - ( childOrigin - firstOrigin ) . Y + ( Advanced ? YOffset : 0 ) , 0 ) ) ;
2018-03-26 16:29:23 -07:00
}
2018-06-20 08:09:35 -07:00
else
2018-03-26 16:29:23 -07:00
{
2018-08-13 13:48:10 -07:00
AlignAxis ( 1 , YAlign , GetAlignToOffset ( CurrentChildrenBounds , 1 , ( ! Advanced | | YAlignTo = = Align . None ) ? YAlign : YAlignTo ) , YOffset , child ) ;
2018-03-26 16:29:23 -07:00
}
2018-08-13 13:48:10 -07:00
}
if ( ZAlign ! = Align . None
& & i ! = anchorIndex )
{
if ( ZAlign = = Align . Origin )
2018-05-09 09:29:54 -07:00
{
2018-08-13 13:48:10 -07:00
// find the origin in world space of the child
var firstOrigin = Vector3 . Transform ( Vector3 . Zero , AnchorObject . WorldMatrix ( ) ) ;
var childOrigin = Vector3 . Transform ( Vector3 . Zero , child . WorldMatrix ( ) ) ;
child . Translate ( new Vector3 ( 0 , 0 , - ( childOrigin - firstOrigin ) . Z + ( Advanced ? ZOffset : 0 ) ) ) ;
2018-05-09 09:29:54 -07:00
}
2018-06-20 08:09:35 -07:00
else
2018-03-26 16:29:23 -07:00
{
2018-08-13 13:48:10 -07:00
AlignAxis ( 2 , ZAlign , GetAlignToOffset ( CurrentChildrenBounds , 2 , ( ! Advanced | | ZAlignTo = = Align . None ) ? ZAlign : ZAlignTo ) , ZOffset , child ) ;
2018-03-26 16:29:23 -07:00
}
2018-03-19 09:27:15 -07:00
}
2018-06-20 08:09:35 -07:00
i + + ;
2018-03-19 09:27:15 -07:00
}
2018-06-20 08:09:35 -07:00
} ) ;
}
2018-05-04 13:47:16 -07:00
2018-06-20 08:09:35 -07:00
Invalidate ( new InvalidateArgs ( this , InvalidateType . Matrix , null ) ) ;
2018-03-13 17:17:28 -07:00
}
2018-05-02 14:34:44 -07:00
public override void Remove ( UndoBuffer undoBuffer )
2018-03-13 17:17:28 -07:00
{
2018-06-20 08:09:35 -07:00
using ( RebuildLock ( ) )
2018-03-13 17:17:28 -07:00
{
2018-06-20 08:09:35 -07:00
// put everything back to where it was before the arrange started
if ( OriginalChildrenBounds . Count = = Children . Count )
2018-03-19 09:27:15 -07:00
{
2018-06-20 08:09:35 -07:00
int i = 0 ;
foreach ( var child in Children )
{
// Where you are minus where you started to get back to where you started
child . Translate ( - ( child . GetAxisAlignedBoundingBox ( ) . minXYZ - OriginalChildrenBounds [ i ] . minXYZ ) ) ;
i + + ;
}
2018-03-19 09:27:15 -07:00
}
2018-03-13 17:17:28 -07:00
2018-06-20 08:09:35 -07:00
base . Remove ( undoBuffer ) ;
}
2018-06-01 17:44:46 -07:00
Invalidate ( new InvalidateArgs ( this , InvalidateType . Content ) ) ;
2018-03-13 17:17:28 -07:00
}
2018-07-06 17:11:33 -07:00
public void UpdateControls ( PublicPropertyChange change )
2018-03-13 17:17:28 -07:00
{
2018-08-01 18:05:04 -07:00
var editRow = change . Context . GetEditRow ( nameof ( XAlignTo ) ) ;
if ( editRow ! = null ) editRow . Visible = Advanced & & XAlign ! = Align . Origin ;
editRow = change . Context . GetEditRow ( nameof ( XOffset ) ) ;
if ( editRow ! = null ) editRow . Visible = Advanced ;
editRow = change . Context . GetEditRow ( nameof ( YAlignTo ) ) ;
if ( editRow ! = null ) editRow . Visible = Advanced & & YAlign ! = Align . Origin ;
editRow = change . Context . GetEditRow ( nameof ( YOffset ) ) ;
if ( editRow ! = null ) editRow . Visible = Advanced ;
editRow = change . Context . GetEditRow ( nameof ( ZAlignTo ) ) ;
if ( editRow ! = null ) editRow . Visible = Advanced & & ZAlign ! = Align . Origin ;
editRow = change . Context . GetEditRow ( nameof ( ZOffset ) ) ;
if ( editRow ! = null ) editRow . Visible = Advanced ;
2018-03-13 17:17:28 -07:00
}
2018-06-02 22:29:56 -07:00
private static bool IsSet ( FaceAlign variableToCheck , FaceAlign faceToCheckFor , FaceAlign faceToAssertNot )
2018-03-13 17:17:28 -07:00
{
2018-03-19 09:27:15 -07:00
if ( ( variableToCheck & faceToCheckFor ) ! = 0 )
2018-03-13 17:17:28 -07:00
{
2018-03-19 09:27:15 -07:00
if ( ( variableToCheck & faceToAssertNot ) ! = 0 )
{
throw new Exception ( "You cannot have both " + faceToCheckFor . ToString ( ) + " and " + faceToAssertNot . ToString ( ) + " set when calling Align. The are mutually exclusive." ) ;
}
return true ;
2018-03-13 17:17:28 -07:00
}
2018-03-19 09:27:15 -07:00
return false ;
2018-03-13 17:17:28 -07:00
}
2018-03-26 16:29:23 -07:00
private void AlignAxis ( int axis , Align align , double alignTo , double offset , IObject3D item )
2018-03-13 17:17:28 -07:00
{
2018-03-19 09:27:15 -07:00
var aabb = item . GetAxisAlignedBoundingBox ( ) ;
var translate = Vector3 . Zero ;
switch ( align )
2018-03-13 17:17:28 -07:00
{
2018-03-19 09:27:15 -07:00
case Align . Min :
translate [ axis ] = alignTo - aabb . minXYZ [ axis ] + offset ;
break ;
case Align . Center :
translate [ axis ] = alignTo - aabb . Center [ axis ] + offset ;
break ;
case Align . Max :
translate [ axis ] = alignTo - aabb . maxXYZ [ axis ] + offset ;
break ;
2018-03-13 17:17:28 -07:00
}
2018-03-19 09:27:15 -07:00
item . Translate ( translate ) ;
2018-03-13 17:17:28 -07:00
}
2018-03-19 09:27:15 -07:00
private double GetAlignToOffset ( List < Aabb > currentChildrenBounds , int axis , Align alignTo )
2018-03-13 17:17:28 -07:00
{
2018-03-19 09:27:15 -07:00
switch ( alignTo )
2018-03-13 17:17:28 -07:00
{
2018-03-19 09:27:15 -07:00
case Align . Min :
2018-08-13 13:48:10 -07:00
return currentChildrenBounds [ AnchorObjectIndex ] . minXYZ [ axis ] ;
2018-03-13 17:17:28 -07:00
2018-03-19 09:27:15 -07:00
case Align . Center :
2018-08-13 13:48:10 -07:00
return currentChildrenBounds [ AnchorObjectIndex ] . Center [ axis ] ;
2018-03-19 09:27:15 -07:00
case Align . Max :
2018-08-13 13:48:10 -07:00
return currentChildrenBounds [ AnchorObjectIndex ] . maxXYZ [ axis ] ;
2018-03-19 09:27:15 -07:00
default :
throw new NotImplementedException ( ) ;
}
2018-03-13 17:17:28 -07:00
}
}
2018-01-29 13:50:55 -08:00
}