2019-12-27 07:44:07 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2017-03-29 13:37:42 -04:00
# include "InsertEdgeLoop.h"
# include "IMeshEditorModeEditingContract.h"
# include "IMeshEditorModeUIContract.h"
2018-02-14 14:13:42 -05:00
# include "Framework/Commands/UICommandInfo.h"
2017-03-29 13:37:42 -04:00
# include "EditableMesh.h"
# include "MeshElement.h"
2018-02-14 14:13:42 -05:00
# include "Framework/MultiBox/MultiBoxBuilder.h"
# include "Framework/Commands/UICommandList.h"
2017-03-29 13:37:42 -04:00
# define LOCTEXT_NAMESPACE "MeshEditorMode"
void UInsertEdgeLoopCommand : : RegisterUICommand ( FBindingContext * BindingContext )
{
2017-06-26 14:00:48 -04:00
UI_COMMAND_EXT ( BindingContext , /* Out */ UICommandInfo , " InsertEdgeLoop " , " Insert Edge Loop " , " Inserts a loop of edges at a specific location along the selected edge as you click and drag. If a valid loop cannot be determined, no edges will be inserted. " , EUserInterfaceActionType : : RadioButton , FInputChord ( ) ) ;
2017-03-29 13:37:42 -04:00
}
2017-03-30 16:00:43 -04:00
void UInsertEdgeLoopCommand : : ApplyDuringDrag ( IMeshEditorModeEditingContract & MeshEditorMode , UViewportInteractor * ViewportInteractor )
2017-03-29 13:37:42 -04:00
{
// Insert edge loop
static TMap < UEditableMesh * , TArray < FMeshElement > > SelectedMeshesAndEdges ;
MeshEditorMode . GetSelectedMeshesAndEdges ( /* Out */ SelectedMeshesAndEdges ) ;
if ( SelectedMeshesAndEdges . Num ( ) > 0 )
{
// Deselect the edges first, since they'll be deleted or split up while inserting the edge loop,
// and we want them to be re-selected after undo
2017-03-30 16:00:43 -04:00
MeshEditorMode . DeselectAllMeshElements ( ) ;
2017-03-29 13:37:42 -04:00
2017-03-30 16:00:43 -04:00
static TArray < FMeshElement > MeshElementsToSelect ;
MeshElementsToSelect . Reset ( ) ;
2017-03-29 13:37:42 -04:00
for ( auto & MeshAndEdges : SelectedMeshesAndEdges )
{
UEditableMesh * EditableMesh = MeshAndEdges . Key ;
verify ( ! EditableMesh - > AnyChangesToUndo ( ) ) ;
const TArray < FMeshElement > & EdgeElements = MeshAndEdges . Value ;
// Figure out where to add the loop along the edge
2017-05-08 15:03:23 -04:00
FEdgeID ClosestEdgeID = FEdgeID : : Invalid ;
float Split = 0.0f ;
const bool bFoundSplit = MeshEditorMode . FindEdgeSplitUnderInteractor ( MeshEditorMode . GetActiveActionInteractor ( ) , EditableMesh , EdgeElements , /* Out */ ClosestEdgeID , /* Out */ Split ) ;
2017-03-29 13:37:42 -04:00
// Insert the edge loop
2017-05-08 15:03:23 -04:00
if ( bFoundSplit )
2017-03-29 13:37:42 -04:00
{
for ( const FMeshElement & EdgeMeshElement : EdgeElements )
{
const FEdgeID EdgeID ( EdgeMeshElement . ElementAddress . ElementID ) ;
static TArray < FEdgeID > NewEdgeIDs ;
NewEdgeIDs . Reset ( ) ;
2017-05-08 15:03:23 -04:00
static TArray < float > Splits ; // @todo mesheditor edgeloop: Add support for inserting multiple splits at once!
Splits . Reset ( ) ;
Splits . Add ( Split ) ;
2017-03-29 13:37:42 -04:00
EditableMesh - > InsertEdgeLoop ( EdgeID , Splits , /* Out */ NewEdgeIDs ) ;
// Select all of the new edges that were created by inserting the loop
if ( NewEdgeIDs . Num ( ) > 0 )
{
for ( const FEdgeID NewEdgeID : NewEdgeIDs )
{
FMeshElement MeshElementToSelect ;
{
MeshElementToSelect . Component = EdgeMeshElement . Component ;
MeshElementToSelect . ElementAddress . SubMeshAddress = EdgeMeshElement . ElementAddress . SubMeshAddress ;
MeshElementToSelect . ElementAddress . ElementType = EEditableMeshElementType : : Edge ;
MeshElementToSelect . ElementAddress . ElementID = NewEdgeID ;
}
// Queue selection of this new element. We don't want it to be part of the current action.
2017-03-30 16:00:43 -04:00
MeshElementsToSelect . Add ( MeshElementToSelect ) ;
2017-03-29 13:37:42 -04:00
}
}
}
MeshEditorMode . TrackUndo ( EditableMesh , EditableMesh - > MakeUndo ( ) ) ;
}
}
2017-03-30 16:00:43 -04:00
MeshEditorMode . SelectMeshElements ( MeshElementsToSelect ) ;
2017-03-29 13:37:42 -04:00
}
}
void UInsertEdgeLoopCommand : : AddToVRRadialMenuActionsMenu ( IMeshEditorModeUIContract & MeshEditorMode , FMenuBuilder & MenuBuilder , TSharedPtr < FUICommandList > CommandList , const FName TEMPHACK_StyleSetName , class UVREditorMode * VRMode )
{
if ( MeshEditorMode . GetMeshElementSelectionMode ( ) = = EEditableMeshElementType : : Edge )
{
MenuBuilder . AddMenuEntry (
2017-03-30 10:05:26 -04:00
LOCTEXT ( " VRInsertEdgeLoop " , " Insert Loop " ) ,
2017-03-29 13:37:42 -04:00
FText ( ) ,
FSlateIcon ( TEMPHACK_StyleSetName , " MeshEditorMode.EdgeInsert " ) , // @todo mesheditor extensibility: TEMPHACK for style; Need PolygonModelingStyle, probably. Or we're just cool with exporting MeshEditorModeStyle, since we're all the same plugin after all.
MakeUIAction ( MeshEditorMode ) ,
NAME_None ,
EUserInterfaceActionType : : ToggleButton
) ;
}
}
# undef LOCTEXT_NAMESPACE