2020-11-11 12:24:31 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "SubdividePolyTool.h"
# include "ToolBuilderUtil.h"
# include "InteractiveToolManager.h"
# include "GroupTopology.h"
# include "MeshDescriptionToDynamicMesh.h"
# include "DynamicMeshToMeshDescription.h"
# include "ToolSetupUtil.h"
# include "Util/ColorConstants.h"
2021-06-13 00:36:02 -04:00
# include "DynamicMesh/MeshNormals.h"
2021-06-12 14:30:22 -04:00
# include "Components/DynamicMeshComponent.h"
2020-11-11 12:24:31 -04:00
# include "Drawing/PreviewGeometryActor.h"
2021-03-24 11:11:02 -04:00
# include "TargetInterfaces/MaterialProvider.h"
# include "TargetInterfaces/PrimitiveComponentBackedTarget.h"
2021-12-06 12:42:19 -05:00
# include "ModelingToolTargetUtil.h"
2021-03-24 11:11:02 -04:00
2021-03-09 19:33:56 -04:00
using namespace UE : : Geometry ;
2020-11-11 12:24:31 -04:00
# define LOCTEXT_NAMESPACE "USubdividePolyTool"
class SubdivPostProcessor : public IRenderMeshPostProcessor
{
public :
SubdivPostProcessor ( int InSubdivisionLevel ,
2020-11-24 16:01:01 -04:00
ESubdivisionScheme InSubdivisionScheme ,
2020-11-11 12:24:31 -04:00
ESubdivisionOutputNormals InNormalComputationMethod ,
2021-12-02 12:21:36 -05:00
ESubdivisionOutputUVs InUVComputationMethod ,
bool bInNewPolyGroups ) :
2020-11-11 12:24:31 -04:00
SubdivisionLevel ( InSubdivisionLevel ) ,
2020-11-24 16:01:01 -04:00
SubdivisionScheme ( InSubdivisionScheme ) ,
2020-11-11 12:24:31 -04:00
NormalComputationMethod ( InNormalComputationMethod ) ,
2021-12-02 12:21:36 -05:00
UVComputationMethod ( InUVComputationMethod ) ,
bNewPolyGroups ( bInNewPolyGroups )
2020-11-11 12:24:31 -04:00
{ }
int SubdivisionLevel = 3 ;
2020-11-24 16:01:01 -04:00
ESubdivisionScheme SubdivisionScheme = ESubdivisionScheme : : CatmullClark ;
2020-11-11 12:24:31 -04:00
ESubdivisionOutputNormals NormalComputationMethod = ESubdivisionOutputNormals : : Generated ;
ESubdivisionOutputUVs UVComputationMethod = ESubdivisionOutputUVs : : Interpolated ;
2021-12-02 12:21:36 -05:00
bool bNewPolyGroups = false ;
2020-11-11 12:24:31 -04:00
void ProcessMesh ( const FDynamicMesh3 & Mesh , FDynamicMesh3 & OutRenderMesh ) final
{
2021-12-09 15:02:36 -05:00
if ( Mesh . TriangleCount ( ) = = 0 | | Mesh . VertexCount ( ) = = 0 )
{
return ;
}
2020-11-11 12:24:31 -04:00
constexpr bool bAutoCompute = true ;
FGroupTopology Topo ( & Mesh , bAutoCompute ) ;
FSubdividePoly Subd ( Topo , Mesh , SubdivisionLevel ) ;
2020-11-24 16:01:01 -04:00
Subd . SubdivisionScheme = SubdivisionScheme ;
2020-11-11 12:24:31 -04:00
Subd . NormalComputationMethod = NormalComputationMethod ;
Subd . UVComputationMethod = UVComputationMethod ;
2021-12-02 12:21:36 -05:00
Subd . bNewPolyGroups = bNewPolyGroups ;
2020-11-11 12:24:31 -04:00
ensure ( Subd . ComputeTopologySubdivision ( ) ) ;
ensure ( Subd . ComputeSubdividedMesh ( OutRenderMesh ) ) ;
}
} ;
// Tool builder
2021-03-24 11:11:02 -04:00
USingleSelectionMeshEditingTool * USubdividePolyToolBuilder : : CreateNewTool ( const FToolBuilderState & SceneState ) const
2020-11-11 12:24:31 -04:00
{
2021-03-24 11:11:02 -04:00
return NewObject < USubdividePolyTool > ( SceneState . ToolManager ) ;
2020-11-11 12:24:31 -04:00
}
2020-12-02 12:25:59 -04:00
bool USubdividePolyTool : : CheckGroupTopology ( FText & Message )
{
FGroupTopology Topo ( OriginalMesh . Get ( ) , true ) ;
2021-09-17 00:33:56 -04:00
FSubdividePoly TempSubD ( Topo , * OriginalMesh , 1 ) ;
FSubdividePoly : : ETopologyCheckResult CheckResult = TempSubD . ValidateTopology ( ) ;
2020-12-02 12:25:59 -04:00
2021-09-17 00:33:56 -04:00
if ( CheckResult = = FSubdividePoly : : ETopologyCheckResult : : NoGroups )
2020-12-02 12:25:59 -04:00
{
Message = LOCTEXT ( " NoGroupsWarning " ,
" This object has no PolyGroups. \n Use the PolyGroups or Select Tool to assign PolyGroups. \n Tool will be limited to Loop subdivision scheme. " ) ;
return false ;
}
2021-09-17 00:33:56 -04:00
if ( CheckResult = = FSubdividePoly : : ETopologyCheckResult : : InsufficientGroups )
2020-12-02 12:25:59 -04:00
{
Message = LOCTEXT ( " SingleGroupsWarning " ,
" This object has only one PolyGroup. \n Use the PolyGroups or Select Tool to assign PolyGroups. \n Tool will be limited to Loop subdivision scheme. " ) ;
return false ;
}
2021-09-17 00:33:56 -04:00
if ( CheckResult = = FSubdividePoly : : ETopologyCheckResult : : UnboundedPolygroup )
2020-12-02 12:25:59 -04:00
{
2021-09-17 00:33:56 -04:00
Message = LOCTEXT ( " NoGroupBoundaryWarning " ,
" Found a PolyGroup with no boundaries. \n Use the PolyGroups or Select Tool to assign PolyGroups. \n Tool will be limited to Loop subdivision scheme. " ) ;
return false ;
}
2020-12-02 12:25:59 -04:00
2021-09-17 00:33:56 -04:00
if ( CheckResult = = FSubdividePoly : : ETopologyCheckResult : : MultiBoundaryPolygroup )
{
Message = LOCTEXT ( " MultipleGroupBoundaryWarning " ,
" Found a PolyGroup with multiple boundaries, which is not supported. \n Use the PolyGroups or Select Tool to assign PolyGroups. \n Tool will be limited to Loop subdivision scheme. " ) ;
return false ;
}
2020-12-02 12:25:59 -04:00
2021-09-17 00:33:56 -04:00
if ( CheckResult = = FSubdividePoly : : ETopologyCheckResult : : DegeneratePolygroup )
{
Message = LOCTEXT ( " DegenerateGroupPolygon " ,
" One PolyGroup has fewer than three boundary edges. \n Use the PolyGroups or Select Tool to assign/fix PolyGroups. \n Tool will be limited to Loop subdivision scheme. " ) ;
return false ;
2020-12-02 12:25:59 -04:00
}
return true ;
}
2020-11-11 12:24:31 -04:00
2021-01-13 12:43:27 -04:00
void USubdividePolyTool : : CapSubdivisionLevel ( ESubdivisionScheme Scheme , int DesiredLevel )
{
// Stolen from UDisplaceMeshTool::ValidateSubdivisions
constexpr int MaxFaces = 3000000 ;
int NumOriginalFaces = MaxFaces ;
if ( Scheme = = ESubdivisionScheme : : Loop )
{
NumOriginalFaces = OriginalMesh - > TriangleCount ( ) ;
}
else
{
constexpr bool bAutoCompute = true ;
FGroupTopology Topo ( OriginalMesh . Get ( ) , bAutoCompute ) ;
NumOriginalFaces = Topo . Groups . Num ( ) ;
}
2021-12-09 15:02:36 -05:00
int MaxLevel = ( int ) floor ( log2 ( MaxFaces / ( NumOriginalFaces + 1 ) ) / 2.0 ) ;
2021-01-13 12:43:27 -04:00
if ( DesiredLevel > MaxLevel )
{
FText WarningText = FText : : Format ( LOCTEXT ( " SubdivisionLevelTooHigh " , " Subdivision level clamped: desired subdivision level ({0}) exceeds maximum level ({1}) for a mesh with this number of faces. " ) ,
FText : : AsNumber ( DesiredLevel ) ,
FText : : AsNumber ( MaxLevel ) ) ;
GetToolManager ( ) - > DisplayMessage ( WarningText , EToolMessageLevel : : UserWarning ) ;
Properties - > SubdivisionLevel = MaxLevel ;
Properties - > SilentUpdateWatched ( ) ; // Don't trigger this function again due to setting SubdivisionLevel above
}
else
{
// Clear possible lingering warning message
GetToolManager ( ) - > DisplayMessage ( FText ( ) , EToolMessageLevel : : UserWarning ) ;
}
}
2020-11-11 12:24:31 -04:00
void USubdividePolyTool : : Setup ( )
{
UInteractiveTool : : Setup ( ) ;
2021-02-08 17:02:09 -04:00
SetToolDisplayName ( LOCTEXT ( " ToolName " , " Subdivide " ) ) ;
2020-11-11 12:24:31 -04:00
2021-03-24 11:11:02 -04:00
if ( ! Target )
2020-11-11 12:24:31 -04:00
{
return ;
}
bool bWantVertexNormals = false ;
2021-02-17 11:50:23 -04:00
OriginalMesh = MakeShared < FDynamicMesh3 , ESPMode : : ThreadSafe > ( bWantVertexNormals , false , false , false ) ;
2020-11-11 12:24:31 -04:00
FMeshDescriptionToDynamicMesh Converter ;
2021-12-06 12:42:19 -05:00
Converter . Convert ( UE : : ToolTarget : : GetMeshDescription ( Target ) , * OriginalMesh ) ;
2020-11-11 12:24:31 -04:00
2020-12-02 12:25:59 -04:00
FText ErrorMessage ;
bool bCatmullClarkOK = CheckGroupTopology ( ErrorMessage ) ;
2020-11-11 12:24:31 -04:00
2020-12-02 12:25:59 -04:00
if ( bCatmullClarkOK )
2020-11-11 12:24:31 -04:00
{
2020-12-02 12:25:59 -04:00
GetToolManager ( ) - > DisplayMessage ( LOCTEXT ( " SubdividePolyToolMessage " ,
" Set the subdivision level and hit Accept to create a new subdivided mesh " ) ,
EToolMessageLevel : : UserNotification ) ;
2020-11-11 12:24:31 -04:00
}
2020-12-02 12:25:59 -04:00
else
2020-11-11 12:24:31 -04:00
{
2020-12-02 12:25:59 -04:00
GetToolManager ( ) - > DisplayMessage ( ErrorMessage , EToolMessageLevel : : UserWarning ) ;
2020-11-11 12:24:31 -04:00
}
Properties = NewObject < USubdividePolyToolProperties > ( this , TEXT ( " Subdivide Mesh Tool Settings " ) ) ;
Properties - > RestoreProperties ( this ) ;
2020-12-02 12:25:59 -04:00
Properties - > bCatmullClarkOK = bCatmullClarkOK ;
if ( ! bCatmullClarkOK )
{
Properties - > SubdivisionScheme = ESubdivisionScheme : : Loop ;
}
2020-11-11 12:24:31 -04:00
AddToolPropertySource ( Properties ) ;
SetToolPropertySourceEnabled ( Properties , true ) ;
2021-03-24 11:11:02 -04:00
IPrimitiveComponentBackedTarget * TargetComponent = Cast < IPrimitiveComponentBackedTarget > ( Target ) ;
2020-11-17 15:49:38 -04:00
PreviewMesh = NewObject < UPreviewMesh > ( this ) ;
if ( PreviewMesh = = nullptr )
{
return ;
}
2022-01-28 10:18:10 -05:00
PreviewMesh - > CreateInWorld ( GetTargetWorld ( ) , FTransform : : Identity ) ;
2021-10-07 22:25:54 -04:00
ToolSetupUtil : : ApplyRenderingConfigurationToPreview ( PreviewMesh , nullptr ) ;
2020-11-11 12:24:31 -04:00
2021-03-24 11:11:02 -04:00
PreviewMesh - > SetTransform ( TargetComponent - > GetWorldTransform ( ) ) ;
2020-11-17 15:49:38 -04:00
PreviewMesh - > UpdatePreview ( OriginalMesh . Get ( ) ) ;
2020-11-11 12:24:31 -04:00
2021-06-12 14:30:22 -04:00
UDynamicMeshComponent * PreviewDynamicMeshComponent = ( UDynamicMeshComponent * ) PreviewMesh - > GetRootComponent ( ) ;
2020-11-12 23:01:08 -04:00
if ( PreviewDynamicMeshComponent = = nullptr )
{
return ;
}
2020-11-17 15:49:38 -04:00
2020-11-24 16:01:01 -04:00
check ( Properties - > SubdivisionLevel > = 1 ) ; // Should be enforced by UPROPERTY meta tags
2021-01-13 12:43:27 -04:00
CapSubdivisionLevel ( Properties - > SubdivisionScheme , Properties - > SubdivisionLevel ) ;
2020-11-11 12:24:31 -04:00
PreviewDynamicMeshComponent - > SetRenderMeshPostProcessor ( MakeUnique < SubdivPostProcessor > ( Properties - > SubdivisionLevel ,
2020-11-24 16:01:01 -04:00
Properties - > SubdivisionScheme ,
Properties - > NormalComputationMethod ,
2021-12-02 12:21:36 -05:00
Properties - > UVComputationMethod ,
Properties - > bNewPolyGroups ) ) ;
2020-11-11 12:24:31 -04:00
// Use the input mesh's material on the preview
FComponentMaterialSet MaterialSet ;
2021-03-24 11:11:02 -04:00
Cast < IMaterialProvider > ( Target ) - > GetMaterialSet ( MaterialSet ) ;
2020-11-11 12:24:31 -04:00
for ( int k = 0 ; k < MaterialSet . Materials . Num ( ) ; + + k )
{
2020-11-17 15:49:38 -04:00
PreviewMesh - > SetMaterial ( k , MaterialSet . Materials [ k ] ) ;
2020-11-11 12:24:31 -04:00
}
// configure secondary render material
UMaterialInterface * SelectionMaterial = ToolSetupUtil : : GetSelectionMaterial ( FLinearColor ( 0.8f , 0.75f , 0.0f ) , GetToolManager ( ) ) ;
if ( SelectionMaterial ! = nullptr )
{
2020-11-17 15:49:38 -04:00
PreviewMesh - > SetSecondaryRenderMaterial ( SelectionMaterial ) ;
2020-11-11 12:24:31 -04:00
}
// dynamic mesh configuration settings
auto RebuildMeshPostProcessor = [ this ] ( )
{
2021-06-12 14:30:22 -04:00
UDynamicMeshComponent * PreviewDynamicMeshComponent = ( UDynamicMeshComponent * ) PreviewMesh - > GetRootComponent ( ) ;
2020-11-12 23:01:08 -04:00
PreviewDynamicMeshComponent - > SetRenderMeshPostProcessor ( MakeUnique < SubdivPostProcessor > ( Properties - > SubdivisionLevel ,
2020-11-24 16:01:01 -04:00
Properties - > SubdivisionScheme ,
Properties - > NormalComputationMethod ,
2021-12-02 12:21:36 -05:00
Properties - > UVComputationMethod ,
Properties - > bNewPolyGroups ) ) ;
2020-11-12 23:01:08 -04:00
PreviewDynamicMeshComponent - > NotifyMeshUpdated ( ) ;
2020-11-11 12:24:31 -04:00
} ;
// Watch for property changes
2021-01-13 12:43:27 -04:00
Properties - > WatchProperty ( Properties - > SubdivisionLevel , [ this , RebuildMeshPostProcessor ] ( int NewSubdLevel )
2020-11-11 12:24:31 -04:00
{
2021-01-13 12:43:27 -04:00
CapSubdivisionLevel ( Properties - > SubdivisionScheme , NewSubdLevel ) ;
2020-11-11 12:24:31 -04:00
RebuildMeshPostProcessor ( ) ;
} ) ;
2021-01-13 12:43:27 -04:00
Properties - > WatchProperty ( Properties - > SubdivisionScheme , [ this , RebuildMeshPostProcessor ] ( ESubdivisionScheme NewScheme )
2020-11-24 16:01:01 -04:00
{
2021-01-13 12:43:27 -04:00
CapSubdivisionLevel ( NewScheme , Properties - > SubdivisionLevel ) ;
2020-11-24 16:01:01 -04:00
RebuildMeshPostProcessor ( ) ;
bPreviewGeometryNeedsUpdate = true ; // Switch from rendering poly cage to all triangle edges
} ) ;
2021-01-13 12:43:27 -04:00
2020-11-11 12:24:31 -04:00
Properties - > WatchProperty ( Properties - > NormalComputationMethod , [ this , RebuildMeshPostProcessor ] ( ESubdivisionOutputNormals )
{
RebuildMeshPostProcessor ( ) ;
} ) ;
Properties - > WatchProperty ( Properties - > UVComputationMethod , [ this , RebuildMeshPostProcessor ] ( ESubdivisionOutputUVs )
{
RebuildMeshPostProcessor ( ) ;
} ) ;
2021-12-02 12:21:36 -05:00
Properties - > WatchProperty ( Properties - > bNewPolyGroups , [ this , RebuildMeshPostProcessor ] ( bool )
{
RebuildMeshPostProcessor ( ) ;
} ) ;
2020-11-11 12:24:31 -04:00
auto RenderGroupsChanged = [ this ] ( bool bNewRenderGroups )
{
2020-11-12 23:01:08 -04:00
if ( bNewRenderGroups )
2020-11-11 12:24:31 -04:00
{
2020-11-17 15:49:38 -04:00
PreviewMesh - > SetOverrideRenderMaterial ( ToolSetupUtil : : GetSelectionMaterial ( GetToolManager ( ) ) ) ;
PreviewMesh - > SetTriangleColorFunction ( [ ] ( const FDynamicMesh3 * Mesh , int TriangleID )
2020-11-11 12:24:31 -04:00
{
2020-11-12 23:01:08 -04:00
return LinearColors : : SelectFColor ( Mesh - > GetTriangleGroup ( TriangleID ) ) ;
2020-12-03 17:40:22 -04:00
} , UPreviewMesh : : ERenderUpdateMode : : FullUpdate ) ;
2020-11-11 12:24:31 -04:00
}
2020-11-12 23:01:08 -04:00
else
{
2020-11-17 15:49:38 -04:00
PreviewMesh - > SetOverrideRenderMaterial ( nullptr ) ;
2020-12-03 17:40:22 -04:00
PreviewMesh - > SetTriangleColorFunction ( nullptr , UPreviewMesh : : ERenderUpdateMode : : FullUpdate ) ;
2020-11-12 23:01:08 -04:00
}
2020-11-11 12:24:31 -04:00
} ;
Properties - > WatchProperty ( Properties - > bRenderGroups , RenderGroupsChanged ) ;
// Render with polygroup colors
RenderGroupsChanged ( Properties - > bRenderGroups ) ;
2020-11-24 16:01:01 -04:00
Properties - > WatchProperty ( Properties - > bRenderCage , [ this ] ( bool bNewRenderCage )
{
bPreviewGeometryNeedsUpdate = true ;
} ) ;
2020-11-11 12:24:31 -04:00
PreviewGeometry = NewObject < UPreviewGeometry > ( this ) ;
2021-03-24 11:11:02 -04:00
PreviewGeometry - > CreateInWorld ( TargetComponent - > GetOwnerActor ( ) - > GetWorld ( ) , TargetComponent - > GetWorldTransform ( ) ) ;
2020-11-11 12:24:31 -04:00
CreateOrUpdatePreviewGeometry ( ) ;
// regenerate preview geo if mesh changes due to undo/redo/etc
PreviewDynamicMeshComponent - > OnMeshChanged . AddLambda ( [ this ] ( ) { bPreviewGeometryNeedsUpdate = true ; } ) ;
2020-11-17 15:49:38 -04:00
2021-03-24 11:11:02 -04:00
TargetComponent - > SetOwnerVisibility ( false ) ;
2020-11-17 15:49:38 -04:00
PreviewMesh - > SetVisible ( true ) ;
2020-11-11 12:24:31 -04:00
}
void USubdividePolyTool : : CreateOrUpdatePreviewGeometry ( )
{
2020-11-24 16:01:01 -04:00
if ( ! Properties - > bRenderCage )
2020-11-11 12:24:31 -04:00
{
2020-11-24 16:01:01 -04:00
PreviewGeometry - > RemoveLineSet ( TEXT ( " TopologyEdges " ) ) ;
PreviewGeometry - > RemoveLineSet ( TEXT ( " AllEdges " ) ) ;
return ;
}
2020-11-11 12:24:31 -04:00
2020-11-24 16:01:01 -04:00
if ( Properties - > SubdivisionScheme = = ESubdivisionScheme : : Loop )
{
int NumEdges = OriginalMesh - > EdgeCount ( ) ;
PreviewGeometry - > RemoveLineSet ( TEXT ( " TopologyEdges " ) ) ;
PreviewGeometry - > CreateOrUpdateLineSet ( TEXT ( " AllEdges " ) ,
NumEdges ,
[ this ] ( int32 Index , TArray < FRenderableLine > & LinesOut )
2020-11-11 12:24:31 -04:00
{
2020-11-24 16:01:01 -04:00
FIndex2i EdgeVertices = OriginalMesh - > GetEdgeV ( Index ) ;
2020-11-11 12:24:31 -04:00
2020-11-24 16:01:01 -04:00
if ( EdgeVertices [ 0 ] = = FDynamicMesh3 : : InvalidID | | EdgeVertices [ 1 ] = = FDynamicMesh3 : : InvalidID )
{
return ;
}
FVector A = ( FVector ) OriginalMesh - > GetVertex ( EdgeVertices [ 0 ] ) ;
FVector B = ( FVector ) OriginalMesh - > GetVertex ( EdgeVertices [ 1 ] ) ;
const float TopologyLineThickness = 4.0f ;
const FColor TopologyLineColor ( 255 , 0 , 0 ) ;
LinesOut . Add ( FRenderableLine ( A , B , TopologyLineColor , TopologyLineThickness ) ) ;
} ) ;
}
else
{
FGroupTopology Topology ( OriginalMesh . Get ( ) , true ) ;
int NumEdges = Topology . Edges . Num ( ) ;
2020-11-11 12:24:31 -04:00
2020-11-24 16:01:01 -04:00
PreviewGeometry - > RemoveLineSet ( TEXT ( " AllEdges " ) ) ;
PreviewGeometry - > CreateOrUpdateLineSet ( TEXT ( " TopologyEdges " ) ,
NumEdges ,
[ & Topology , this ] ( int32 Index , TArray < FRenderableLine > & LinesOut )
{
const FGroupTopology : : FGroupEdge & Edge = Topology . Edges [ Index ] ;
FIndex2i EdgeCorners = Edge . EndpointCorners ;
if ( EdgeCorners [ 0 ] = = FDynamicMesh3 : : InvalidID | | EdgeCorners [ 1 ] = = FDynamicMesh3 : : InvalidID )
{
return ;
}
FIndex2i EdgeVertices { Topology . Corners [ EdgeCorners [ 0 ] ] . VertexID ,
Topology . Corners [ EdgeCorners [ 1 ] ] . VertexID } ;
FVector A = ( FVector ) OriginalMesh - > GetVertex ( EdgeVertices [ 0 ] ) ;
FVector B = ( FVector ) OriginalMesh - > GetVertex ( EdgeVertices [ 1 ] ) ;
const float TopologyLineThickness = 4.0f ;
const FColor TopologyLineColor ( 255 , 0 , 0 ) ;
LinesOut . Add ( FRenderableLine ( A , B , TopologyLineColor , TopologyLineThickness ) ) ;
} ) ;
}
2020-11-11 12:24:31 -04:00
}
2022-01-28 18:40:54 -05:00
void USubdividePolyTool : : OnShutdown ( EToolShutdownType ShutdownType )
2020-11-11 12:24:31 -04:00
{
if ( Properties )
{
Properties - > SaveProperties ( this ) ;
}
2020-11-12 23:01:08 -04:00
if ( PreviewGeometry )
{
PreviewGeometry - > Disconnect ( ) ;
}
2021-03-11 21:27:23 -04:00
2021-03-24 11:11:02 -04:00
Cast < IPrimitiveComponentBackedTarget > ( Target ) - > SetOwnerVisibility ( true ) ;
2020-11-11 12:24:31 -04:00
2020-11-17 15:49:38 -04:00
if ( PreviewMesh )
2020-11-11 12:24:31 -04:00
{
if ( ShutdownType = = EToolShutdownType : : Accept )
{
GetToolManager ( ) - > BeginUndoTransaction ( LOCTEXT ( " USubdividePolyTool " , " Subdivide Mesh " ) ) ;
2021-06-12 14:30:22 -04:00
UDynamicMeshComponent * PreviewDynamicMeshComponent = ( UDynamicMeshComponent * ) PreviewMesh - > GetRootComponent ( ) ;
2020-11-11 12:24:31 -04:00
FDynamicMesh3 * DynamicMeshResult = PreviewDynamicMeshComponent - > GetRenderMesh ( ) ;
2021-12-06 12:42:19 -05:00
UE : : ToolTarget : : CommitMeshDescriptionUpdateViaDynamicMesh ( Target , * DynamicMeshResult , true ) ;
2020-11-11 12:24:31 -04:00
GetToolManager ( ) - > EndUndoTransaction ( ) ;
}
2020-11-17 15:49:38 -04:00
PreviewMesh - > Disconnect ( ) ;
PreviewMesh = nullptr ;
2020-11-11 12:24:31 -04:00
}
}
bool USubdividePolyTool : : CanAccept ( ) const
{
2020-11-17 15:49:38 -04:00
return PreviewMesh ! = nullptr ;
2020-11-11 12:24:31 -04:00
}
void USubdividePolyTool : : OnTick ( float DeltaTime )
{
if ( bPreviewGeometryNeedsUpdate )
{
CreateOrUpdatePreviewGeometry ( ) ;
bPreviewGeometryNeedsUpdate = false ;
}
}
# undef LOCTEXT_NAMESPACE