2017-03-31 14:31:36 -04:00
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
# include "RemoveEdge.h"
# include "IMeshEditorModeEditingContract.h"
# include "IMeshEditorModeUIContract.h"
# include "UICommandInfo.h"
# include "EditableMesh.h"
# include "MeshElement.h"
# define LOCTEXT_NAMESPACE "MeshEditorMode"
void URemoveEdgeCommand : : RegisterUICommand ( FBindingContext * BindingContext )
{
UI_COMMAND_EXT ( BindingContext , /* Out */ UICommandInfo , " RemoveEdge " , " Remove Edge " , " Attempts to remove the selected edge and merge adjacent polygons. " , EUserInterfaceActionType : : Button , FInputChord ( EKeys : : BackSpace ) ) ;
}
void URemoveEdgeCommand : : Execute ( IMeshEditorModeEditingContract & MeshEditorMode )
{
if ( MeshEditorMode . GetActiveAction ( ) ! = NAME_None )
{
return ;
}
static TMap < UEditableMesh * , TArray < FMeshElement > > MeshesWithEdgesToRemove ;
MeshEditorMode . GetSelectedMeshesAndEdges ( MeshesWithEdgesToRemove ) ;
// @todo mesheditor: Only if one edge is selected, for now. It gets a bit confusing when performing this operation
// with more than one edge selected. However, it can be very useful when collapsing away edges that don't share any
// common polygons, so we should try to support it.
if ( MeshesWithEdgesToRemove . Num ( ) ! = 1 )
{
const auto & FirstMeshWithEdges = MeshesWithEdgesToRemove . CreateConstIterator ( ) ;
if ( FirstMeshWithEdges - > Get < 1 > ( ) . Num ( ) ! = 1 )
{
return ;
}
}
FScopedTransaction Transaction ( LOCTEXT ( " UndoRemoveEdge " , " Remove Edge " ) ) ;
MeshEditorMode . CommitSelectedMeshes ( ) ;
// Refresh selection (committing may have created a new mesh instance)
MeshEditorMode . GetSelectedMeshesAndEdges ( MeshesWithEdgesToRemove ) ;
MeshEditorMode . DeselectMeshElements ( MeshesWithEdgesToRemove ) ;
TArray < FMeshElement > MeshElementsToSelect ;
for ( const auto & MeshAndElements : MeshesWithEdgesToRemove )
{
UEditableMesh * EditableMesh = MeshAndElements . Key ;
EditableMesh - > StartModification ( EMeshModificationType : : Final , EMeshTopologyChange : : TopologyChange ) ;
const TArray < FMeshElement > & EdgeElementsToRemove = MeshAndElements . Value ;
for ( const FMeshElement & EdgeElementToRemove : EdgeElementsToRemove )
{
const FEdgeID EdgeID ( EdgeElementToRemove . ElementAddress . ElementID ) ;
{
bool bWasEdgeRemoved = false ;
FPolygonRef NewPolygonRef ;
EditableMesh - > TryToRemovePolygonEdge ( EdgeID , /* Out */ bWasEdgeRemoved , /* Out */ NewPolygonRef ) ;
if ( bWasEdgeRemoved )
{
// Select the new polygon
FMeshElement NewPolygonMeshElement ;
{
NewPolygonMeshElement . Component = EdgeElementToRemove . Component ;
NewPolygonMeshElement . ElementAddress = EdgeElementToRemove . ElementAddress ;
NewPolygonMeshElement . ElementAddress . ElementType = EEditableMeshElementType : : Polygon ;
NewPolygonMeshElement . ElementAddress . SectionID = NewPolygonRef . SectionID ;
NewPolygonMeshElement . ElementAddress . ElementID = NewPolygonRef . PolygonID ;
}
MeshElementsToSelect . Add ( NewPolygonMeshElement ) ;
}
else
{
// Couldn't remove the edge
// @todo mesheditor: Needs good user feedback when this happens
}
}
}
EditableMesh - > EndModification ( ) ;
MeshEditorMode . TrackUndo ( EditableMesh , EditableMesh - > MakeUndo ( ) ) ;
}
2017-04-10 16:45:27 -04:00
// Select the polygon leftover after removing the edge
MeshEditorMode . SelectMeshElements ( MeshElementsToSelect ) ;
2017-03-31 14:31:36 -04:00
}
void URemoveEdgeCommand : : AddToVRRadialMenuActionsMenu ( IMeshEditorModeUIContract & MeshEditorMode , FMenuBuilder & MenuBuilder , TSharedPtr < FUICommandList > CommandList , const FName TEMPHACK_StyleSetName , class UVREditorMode * VRMode )
{
if ( MeshEditorMode . GetMeshElementSelectionMode ( ) = = EEditableMeshElementType : : Edge )
{
MenuBuilder . AddMenuEntry (
LOCTEXT ( " VRRemoveEdge " , " Remove " ) ,
FText ( ) ,
FSlateIcon ( TEMPHACK_StyleSetName , " MeshEditorMode.EdgeRemove " ) ,
MakeUIAction ( MeshEditorMode ) ,
NAME_None ,
EUserInterfaceActionType : : CollapsedButton
) ;
}
}
# undef LOCTEXT_NAMESPACE