2021-03-22 08:32:17 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "CutMeshWithMeshTool.h"
# include "CompositionOps/BooleanMeshesOp.h"
# include "ToolSetupUtil.h"
2021-05-20 16:39:39 -04:00
# include "BaseGizmos/TransformGizmoUtil.h"
2021-03-22 08:32:17 -04:00
# include "Selection/ToolSelectionUtil.h"
2021-06-02 15:58:00 -04:00
# include "ModelingObjectsCreationAPI.h"
2021-06-13 00:36:02 -04:00
# include "DynamicMesh/DynamicMesh3.h"
# include "DynamicMesh/MeshTransforms.h"
2021-03-22 08:32:17 -04:00
# include "MeshDescriptionToDynamicMesh.h"
# include "DynamicMeshToMeshDescription.h"
# include "Async/Async.h"
2021-03-22 11:13:15 -04:00
# include "TargetInterfaces/MaterialProvider.h"
# include "TargetInterfaces/MeshDescriptionCommitter.h"
# include "TargetInterfaces/MeshDescriptionProvider.h"
# include "TargetInterfaces/PrimitiveComponentBackedTarget.h"
2021-03-23 14:51:49 -04:00
# include "TargetInterfaces/AssetBackedTarget.h"
ModelingTools: add support for creating Volumes directly from DrawPolygon, DrawRevolve, DrawPolyPath, and AddPrimitive, CombineMeshes, CutMeshWithMesh, PlaneCut, BaseCreateFromSelected Tools. Improve support for Editing volumes, eg handling mesh/volume interactions, and add configurable auto-simplification for volumes to avoid painful Editor hangs.
- Move ToolTarget implementations, DynamicMeshToVolume to ModelingComponentsEditorOnly module
- move VolumeToDynamicMesh, DynamicMeshProvider/Commiter interfaces to ModelingComponents module
- Add UCreateMeshObjectTypeProperties property set to expose mesh/volume options
- Add FCreateMeshObjectParams::TypeHintClass to allow AVolume type (or other UClass hints) to be passed to creation APIs
- Add UE::ToolTarget::ConfigureCreateMeshObjectParams() util function in ModelingToolTargetUtil, tries to determine output type in a FCreateMeshObjectParams based on input ToolTarget
- Add UEditorModelingObjectsCreationAPI::CreateVolume() implementation
- Add UEditorModelingObjectsCreationAPI::FilterMaterials() that strips out any internal materials and replaces with WorldGridMaterial. This occurs when (eg) subtracting a Volume from a StaticMesh, because the temporary volume mesh gets assigned internal materials, but the Tools don't know this. Use in EditorModelingObjectsCreationAPI when creating new objects. UStaticMeshComponentToolTarget also does this filtering in ::CommitMaterialSetUpdate().
- Add ::ComponentTypeSupportsCollision() function to ComponentCollisionUtil, use to avoid checks/ensures for Volume targets
- Add support for automatic mesh simplification in DynamicMeshToVolume. Add CVar to VolumeDynamicMeshToolTarget.h to control max triangle count (default 500). Apply auto-simplify when creating or updating an AVolume. This prevents the Editor from blocking for long periods on meshes that are too high-res for volumes (even 500 is quite high).
- DynamicMeshToVolume now emits polygroup-faces that contain holes (ie multiple boundary loops) as a set of triangles, rather than emitting separate overlapping faces for each boundary loop
#rb none
#rnx
#jira none
#preflight 60ba50632c42ea0001cb54c5
[CL 16561742 by Ryan Schmidt in ue5-main branch]
2021-06-04 16:04:03 -04:00
# include "ModelingToolTargetUtil.h"
2021-03-22 11:13:15 -04:00
2022-09-28 01:06:15 -04:00
# include UE_INLINE_GENERATED_CPP_BY_NAME(CutMeshWithMeshTool)
2021-03-22 11:13:15 -04:00
using namespace UE : : Geometry ;
2021-03-22 08:32:17 -04:00
namespace
{
// probably should be something defined for the whole tool framework...
# if WITH_EDITOR
static EAsyncExecution CutMeshWithMeshToolAsyncExecTarget = EAsyncExecution : : LargeThreadPool ;
# else
static EAsyncExecution CutMeshWithMeshToolAsyncExecTarget = EAsyncExecution : : ThreadPool ;
# endif
}
# define LOCTEXT_NAMESPACE "UCutMeshWithMeshTool"
void UCutMeshWithMeshTool : : SetupProperties ( )
{
Super : : SetupProperties ( ) ;
CutProperties = NewObject < UCutMeshWithMeshToolProperties > ( this ) ;
CutProperties - > RestoreProperties ( this ) ;
AddToolPropertySource ( CutProperties ) ;
SetToolDisplayName ( LOCTEXT ( " CutMeshWithMeshToolName " , " Cut With Mesh " ) ) ;
GetToolManager ( ) - > DisplayMessage (
2021-11-16 12:19:22 -05:00
LOCTEXT ( " OnStartTool " , " Cut the first input mesh with the second input mesh. Use the transform gizmos to modify the position and orientation of the input objects. " ) ,
2021-03-22 08:32:17 -04:00
EToolMessageLevel : : UserNotification ) ;
// create intersection preview mesh object
IntersectPreviewMesh = NewObject < UPreviewMesh > ( this ) ;
2022-01-28 10:18:10 -05:00
IntersectPreviewMesh - > CreateInWorld ( GetTargetWorld ( ) , FTransform : : Identity ) ;
2021-10-07 22:25:54 -04:00
ToolSetupUtil : : ApplyRenderingConfigurationToPreview ( IntersectPreviewMesh , nullptr ) ;
2021-03-22 08:32:17 -04:00
IntersectPreviewMesh - > SetVisible ( true ) ;
IntersectPreviewMesh - > SetMaterial ( ToolSetupUtil : : GetDefaultBrushVolumeMaterial ( GetToolManager ( ) ) ) ;
}
void UCutMeshWithMeshTool : : SaveProperties ( )
{
Super : : SaveProperties ( ) ;
CutProperties - > SaveProperties ( this ) ;
IntersectPreviewMesh - > Disconnect ( ) ;
}
void UCutMeshWithMeshTool : : ConvertInputsAndSetPreviewMaterials ( bool bSetPreviewMesh )
{
// disable output options
// (this property set is not registered yet in SetupProperties() above)
SetToolPropertySourceEnabled ( HandleSourcesProperties , false ) ;
2022-08-24 16:14:52 -04:00
SetToolPropertySourceEnabled ( OutputTypeProperties , false ) ;
2021-03-22 08:32:17 -04:00
FComponentMaterialSet AllMaterialSet ;
2021-03-22 11:13:15 -04:00
TArray < TArray < int > > MaterialRemap ; MaterialRemap . SetNum ( Targets . Num ( ) ) ;
2021-03-22 08:32:17 -04:00
2021-11-16 12:19:22 -05:00
if ( ! CutProperties - > bUseFirstMeshMaterials )
2021-03-22 08:32:17 -04:00
{
2021-11-16 12:19:22 -05:00
TMap < UMaterialInterface * , int > KnownMaterials ;
2021-03-22 11:13:15 -04:00
for ( int ComponentIdx = 0 ; ComponentIdx < Targets . Num ( ) ; ComponentIdx + + )
2021-03-22 08:32:17 -04:00
{
2021-11-23 09:42:40 -05:00
const FComponentMaterialSet ComponentMaterialSet = UE : : ToolTarget : : GetMaterialSet ( Targets [ ComponentIdx ] ) ;
2021-03-22 08:32:17 -04:00
for ( UMaterialInterface * Mat : ComponentMaterialSet . Materials )
{
int * FoundMatIdx = KnownMaterials . Find ( Mat ) ;
int MatIdx ;
if ( FoundMatIdx )
{
MatIdx = * FoundMatIdx ;
}
else
{
MatIdx = AllMaterialSet . Materials . Add ( Mat ) ;
KnownMaterials . Add ( Mat , MatIdx ) ;
}
MaterialRemap [ ComponentIdx ] . Add ( MatIdx ) ;
}
}
}
else
{
2021-11-23 09:42:40 -05:00
AllMaterialSet = UE : : ToolTarget : : GetMaterialSet ( Targets [ 0 ] ) ;
2021-03-22 08:32:17 -04:00
for ( int MatIdx = 0 ; MatIdx < AllMaterialSet . Materials . Num ( ) ; MatIdx + + )
{
MaterialRemap [ 0 ] . Add ( MatIdx ) ;
}
2021-03-22 11:13:15 -04:00
for ( int ComponentIdx = 1 ; ComponentIdx < Targets . Num ( ) ; ComponentIdx + + )
2021-03-22 08:32:17 -04:00
{
2021-11-23 09:42:40 -05:00
MaterialRemap [ ComponentIdx ] . Init ( 0 , Cast < IMaterialProvider > ( Targets [ ComponentIdx ] ) - > GetNumMaterials ( ) ) ;
2021-03-22 08:32:17 -04:00
}
}
2021-03-22 11:13:15 -04:00
for ( int ComponentIdx = 0 ; ComponentIdx < Targets . Num ( ) ; ComponentIdx + + )
2021-03-22 08:32:17 -04:00
{
TSharedPtr < FDynamicMesh3 , ESPMode : : ThreadSafe > Mesh = MakeShared < FDynamicMesh3 , ESPMode : : ThreadSafe > ( ) ;
FMeshDescriptionToDynamicMesh Converter ;
2021-11-23 09:42:40 -05:00
Converter . Convert ( UE : : ToolTarget : : GetMeshDescription ( Targets [ ComponentIdx ] ) , * Mesh ) ;
2021-03-22 08:32:17 -04:00
// ensure materials and attributes are always enabled
Mesh - > EnableAttributes ( ) ;
Mesh - > Attributes ( ) - > EnableMaterialID ( ) ;
FDynamicMeshMaterialAttribute * MaterialIDs = Mesh - > Attributes ( ) - > GetMaterialID ( ) ;
for ( int TID : Mesh - > TriangleIndicesItr ( ) )
{
MaterialIDs - > SetValue ( TID , MaterialRemap [ ComponentIdx ] [ MaterialIDs - > GetValue ( TID ) ] ) ;
}
if ( ComponentIdx = = 0 )
{
OriginalTargetMesh = Mesh ;
}
else
{
OriginalCuttingMesh = Mesh ;
}
}
Preview - > ConfigureMaterials ( AllMaterialSet . Materials , ToolSetupUtil : : GetDefaultWorkingMaterial ( GetToolManager ( ) ) ) ;
// check if we have the same mesh on both inputs
ModelingTools: add support for creating Volumes directly from DrawPolygon, DrawRevolve, DrawPolyPath, and AddPrimitive, CombineMeshes, CutMeshWithMesh, PlaneCut, BaseCreateFromSelected Tools. Improve support for Editing volumes, eg handling mesh/volume interactions, and add configurable auto-simplification for volumes to avoid painful Editor hangs.
- Move ToolTarget implementations, DynamicMeshToVolume to ModelingComponentsEditorOnly module
- move VolumeToDynamicMesh, DynamicMeshProvider/Commiter interfaces to ModelingComponents module
- Add UCreateMeshObjectTypeProperties property set to expose mesh/volume options
- Add FCreateMeshObjectParams::TypeHintClass to allow AVolume type (or other UClass hints) to be passed to creation APIs
- Add UE::ToolTarget::ConfigureCreateMeshObjectParams() util function in ModelingToolTargetUtil, tries to determine output type in a FCreateMeshObjectParams based on input ToolTarget
- Add UEditorModelingObjectsCreationAPI::CreateVolume() implementation
- Add UEditorModelingObjectsCreationAPI::FilterMaterials() that strips out any internal materials and replaces with WorldGridMaterial. This occurs when (eg) subtracting a Volume from a StaticMesh, because the temporary volume mesh gets assigned internal materials, but the Tools don't know this. Use in EditorModelingObjectsCreationAPI when creating new objects. UStaticMeshComponentToolTarget also does this filtering in ::CommitMaterialSetUpdate().
- Add ::ComponentTypeSupportsCollision() function to ComponentCollisionUtil, use to avoid checks/ensures for Volume targets
- Add support for automatic mesh simplification in DynamicMeshToVolume. Add CVar to VolumeDynamicMeshToolTarget.h to control max triangle count (default 500). Apply auto-simplify when creating or updating an AVolume. This prevents the Editor from blocking for long periods on meshes that are too high-res for volumes (even 500 is quite high).
- DynamicMeshToVolume now emits polygroup-faces that contain holes (ie multiple boundary loops) as a set of triangles, rather than emitting separate overlapping faces for each boundary loop
#rb none
#rnx
#jira none
#preflight 60ba50632c42ea0001cb54c5
[CL 16561742 by Ryan Schmidt in ue5-main branch]
2021-06-04 16:04:03 -04:00
if ( Cast < IAssetBackedTarget > ( Targets [ 0 ] ) ! = nullptr & & Cast < IAssetBackedTarget > ( Targets [ 0 ] ) - > HasSameSourceData ( Targets [ 1 ] ) )
2021-03-23 14:51:49 -04:00
{
GetToolManager ( ) - > DisplayMessage (
2021-11-16 12:19:22 -05:00
LOCTEXT ( " SameSourceError " , " WARNING: Both input meshes have the same Asset; both inputs will be affected. " ) ,
2021-03-23 14:51:49 -04:00
EToolMessageLevel : : UserWarning ) ;
}
2021-03-22 08:32:17 -04:00
}
class FCutMeshWithMeshOp : public FDynamicMeshOperator
{
public :
virtual ~ FCutMeshWithMeshOp ( ) { }
TSharedPtr < const FDynamicMesh3 , ESPMode : : ThreadSafe > TargetMesh ;
FTransform TargetMeshTransform ;
TSharedPtr < const FDynamicMesh3 , ESPMode : : ThreadSafe > CuttingMesh ;
FTransform CuttingMeshTransform ;
bool bAttemptToFixHoles = true ;
bool bCollapseExtraEdges = true ;
2021-09-08 17:43:40 -04:00
double WindingThreshold = 0.5 ;
2021-03-22 08:32:17 -04:00
2021-11-16 12:19:22 -05:00
virtual void CalculateResult ( FProgressCancel * Progress ) override
2021-03-22 08:32:17 -04:00
{
TUniquePtr < FBooleanMeshesOp > SubtractOp = MakeUnique < FBooleanMeshesOp > ( ) ;
SubtractOp - > CSGOperation = ECSGOperation : : DifferenceAB ;
SubtractOp - > bAttemptFixHoles = bAttemptToFixHoles ;
SubtractOp - > bTryCollapseExtraEdges = bCollapseExtraEdges ;
2021-09-08 17:43:40 -04:00
SubtractOp - > WindingThreshold = WindingThreshold ;
2021-03-22 08:32:17 -04:00
SubtractOp - > Meshes . Add ( TargetMesh ) ;
SubtractOp - > Transforms . Add ( TargetMeshTransform ) ;
SubtractOp - > Meshes . Add ( CuttingMesh ) ;
SubtractOp - > Transforms . Add ( CuttingMeshTransform ) ;
TUniquePtr < FBooleanMeshesOp > IntersectOp = MakeUnique < FBooleanMeshesOp > ( ) ;
IntersectOp - > CSGOperation = ECSGOperation : : Intersect ;
IntersectOp - > bAttemptFixHoles = bAttemptToFixHoles ;
IntersectOp - > bTryCollapseExtraEdges = bCollapseExtraEdges ;
2021-09-08 17:43:40 -04:00
IntersectOp - > WindingThreshold = WindingThreshold ;
2021-03-22 08:32:17 -04:00
IntersectOp - > Meshes . Add ( TargetMesh ) ;
IntersectOp - > Transforms . Add ( TargetMeshTransform ) ;
IntersectOp - > Meshes . Add ( CuttingMesh ) ;
IntersectOp - > Transforms . Add ( CuttingMeshTransform ) ;
TFuture < void > SubtractFuture = Async ( CutMeshWithMeshToolAsyncExecTarget , [ & ] ( )
{
SubtractOp - > CalculateResult ( Progress ) ;
} ) ;
TFuture < void > IntersectFuture = Async ( CutMeshWithMeshToolAsyncExecTarget , [ & ] ( )
{
IntersectOp - > CalculateResult ( Progress ) ;
} ) ;
SubtractFuture . Wait ( ) ;
IntersectFuture . Wait ( ) ;
this - > ResultMesh = SubtractOp - > ExtractResult ( ) ;
SetResultTransform ( SubtractOp - > GetResultTransform ( ) ) ;
IntersectMesh = IntersectOp - > ExtractResult ( ) ;
CreatedSubtractBoundaryEdges = SubtractOp - > GetCreatedBoundaryEdges ( ) ;
CreatedIntersectBoundaryEdges = IntersectOp - > GetCreatedBoundaryEdges ( ) ;
}
TUniquePtr < FDynamicMesh3 > IntersectMesh ;
TArray < int > CreatedSubtractBoundaryEdges ;
TArray < int > CreatedIntersectBoundaryEdges ;
} ;
void UCutMeshWithMeshTool : : SetPreviewCallbacks ( )
{
DrawnLineSet = NewObject < ULineSetComponent > ( Preview - > PreviewMesh - > GetRootComponent ( ) ) ;
DrawnLineSet - > SetupAttachment ( Preview - > PreviewMesh - > GetRootComponent ( ) ) ;
DrawnLineSet - > SetLineMaterial ( ToolSetupUtil : : GetDefaultLineComponentMaterial ( GetToolManager ( ) ) ) ;
DrawnLineSet - > RegisterComponent ( ) ;
Preview - > OnOpCompleted . AddLambda (
[ this ] ( const FDynamicMeshOperator * Op )
{
const FCutMeshWithMeshOp * CuttingOp = ( const FCutMeshWithMeshOp * ) ( Op ) ;
CreatedSubtractBoundaryEdges = CuttingOp - > CreatedSubtractBoundaryEdges ;
CreatedIntersectBoundaryEdges = CuttingOp - > CreatedIntersectBoundaryEdges ;
IntersectionMesh = * CuttingOp - > IntersectMesh ; // cannot steal this here because it is const...
IntersectPreviewMesh - > UpdatePreview ( & IntersectionMesh ) ;
IntersectPreviewMesh - > SetTransform ( ( FTransform ) Op - > GetResultTransform ( ) ) ;
}
) ;
Preview - > OnMeshUpdated . AddLambda (
[ this ] ( const UMeshOpPreviewWithBackgroundCompute * )
{
GetToolManager ( ) - > PostInvalidation ( ) ;
UpdateVisualization ( ) ;
}
) ;
}
void UCutMeshWithMeshTool : : UpdateVisualization ( )
{
2021-11-16 12:19:22 -05:00
constexpr FColor BoundaryEdgeColor ( 240 , 15 , 15 ) ;
constexpr float BoundaryEdgeThickness = 2.0 ;
constexpr float BoundaryEdgeDepthBias = 2.0f ;
2021-03-22 08:32:17 -04:00
DrawnLineSet - > Clear ( ) ;
2021-11-16 12:19:22 -05:00
if ( CutProperties - > bShowNewBoundaries )
2021-03-22 08:32:17 -04:00
{
const FDynamicMesh3 * TargetMesh = Preview - > PreviewMesh - > GetPreviewDynamicMesh ( ) ;
FVector3d A , B ;
for ( int EID : CreatedSubtractBoundaryEdges )
{
TargetMesh - > GetEdgeV ( EID , A , B ) ;
DrawnLineSet - > AddLine ( ( FVector ) A , ( FVector ) B , BoundaryEdgeColor , BoundaryEdgeThickness , BoundaryEdgeDepthBias ) ;
}
for ( int EID : CreatedIntersectBoundaryEdges )
{
IntersectionMesh . GetEdgeV ( EID , A , B ) ;
DrawnLineSet - > AddLine ( ( FVector ) A , ( FVector ) B , BoundaryEdgeColor , BoundaryEdgeThickness , BoundaryEdgeDepthBias ) ;
}
}
}
TUniquePtr < FDynamicMeshOperator > UCutMeshWithMeshTool : : MakeNewOperator ( )
{
TUniquePtr < FCutMeshWithMeshOp > CuttingOp = MakeUnique < FCutMeshWithMeshOp > ( ) ;
CuttingOp - > TargetMesh = OriginalTargetMesh ;
CuttingOp - > TargetMeshTransform = TransformProxies [ 0 ] - > GetTransform ( ) ;
2021-03-22 11:13:15 -04:00
2021-03-22 08:32:17 -04:00
CuttingOp - > CuttingMesh = OriginalCuttingMesh ;
CuttingOp - > CuttingMeshTransform = TransformProxies [ 1 ] - > GetTransform ( ) ;
2021-03-22 11:13:15 -04:00
2021-11-16 12:19:22 -05:00
CuttingOp - > bAttemptToFixHoles = CutProperties - > bTryFixHoles ;
CuttingOp - > bCollapseExtraEdges = CutProperties - > bTryCollapseEdges ;
2021-09-08 17:43:40 -04:00
CuttingOp - > WindingThreshold = CutProperties - > WindingThreshold ;
2021-03-22 08:32:17 -04:00
return CuttingOp ;
}
void UCutMeshWithMeshTool : : OnPropertyModified ( UObject * PropertySet , FProperty * Property )
{
2021-11-16 12:19:22 -05:00
if ( Property & & ( Property - > GetFName ( ) = = GET_MEMBER_NAME_CHECKED ( UCutMeshWithMeshToolProperties , bUseFirstMeshMaterials ) ) )
2021-03-22 08:32:17 -04:00
{
if ( ! AreAllTargetsValid ( ) )
{
2021-11-16 12:19:22 -05:00
GetToolManager ( ) - > DisplayMessage ( LOCTEXT ( " InvalidTargets " , " Input meshes are no longer valid " ) , EToolMessageLevel : : UserWarning ) ;
2021-03-22 08:32:17 -04:00
return ;
}
ConvertInputsAndSetPreviewMaterials ( false ) ;
Preview - > InvalidateResult ( ) ;
}
2021-11-16 12:19:22 -05:00
else if ( Property & & ( Property - > GetFName ( ) = = GET_MEMBER_NAME_CHECKED ( UCutMeshWithMeshToolProperties , bShowNewBoundaries ) ) )
2021-03-22 08:32:17 -04:00
{
GetToolManager ( ) - > PostInvalidation ( ) ;
UpdateVisualization ( ) ;
}
else
{
Super : : OnPropertyModified ( PropertySet , Property ) ;
}
}
FString UCutMeshWithMeshTool : : GetCreatedAssetName ( ) const
{
return TEXT ( " Boolean " ) ;
}
FText UCutMeshWithMeshTool : : GetActionName ( ) const
{
2021-11-16 12:19:22 -05:00
return LOCTEXT ( " CutMeshWithMeshActionName " , " Cut Mesh " ) ;
2021-03-22 08:32:17 -04:00
}
2022-01-28 18:40:54 -05:00
void UCutMeshWithMeshTool : : OnShutdown ( EToolShutdownType ShutdownType )
2021-03-22 08:32:17 -04:00
{
SaveProperties ( ) ;
HandleSourcesProperties - > SaveProperties ( this ) ;
TransformProperties - > SaveProperties ( this ) ;
2021-06-02 15:58:00 -04:00
FDynamicMeshOpResult OpResult = Preview - > Shutdown ( ) ;
2021-03-22 08:32:17 -04:00
// Restore (unhide) the source meshes
2021-03-22 11:13:15 -04:00
for ( int32 ci = 0 ; ci < Targets . Num ( ) ; + + ci )
2021-03-22 08:32:17 -04:00
{
2021-11-23 09:42:40 -05:00
UE : : ToolTarget : : ShowSourceObject ( Targets [ ci ] ) ;
2021-03-22 08:32:17 -04:00
}
if ( ShutdownType = = EToolShutdownType : : Accept )
{
GetToolManager ( ) - > BeginUndoTransaction ( GetActionName ( ) ) ;
TArray < AActor * > SelectActors ;
FComponentMaterialSet MaterialSet ;
MaterialSet . Materials = GetOutputMaterials ( ) ;
// update subtract asset
2021-11-23 09:42:40 -05:00
FTransform3d TargetToWorld = UE : : ToolTarget : : GetLocalToWorldTransform ( Targets [ 0 ] ) ;
2021-03-22 08:32:17 -04:00
{
2021-06-02 15:58:00 -04:00
if ( OpResult . Mesh - > TriangleCount ( ) > 0 )
2021-03-22 08:32:17 -04:00
{
2022-08-30 14:40:56 -04:00
MeshTransforms : : ApplyTransform ( * OpResult . Mesh , OpResult . Transform , true ) ;
MeshTransforms : : ApplyTransformInverse ( * OpResult . Mesh , TargetToWorld , true ) ;
2021-12-06 12:42:19 -05:00
UE : : ToolTarget : : CommitMeshDescriptionUpdateViaDynamicMesh ( Targets [ 0 ] , * OpResult . Mesh , true ) ;
2021-11-23 09:42:40 -05:00
Cast < IMaterialProvider > ( Targets [ 0 ] ) - > CommitMaterialSetUpdate ( MaterialSet , true ) ;
2021-03-22 08:32:17 -04:00
}
}
2021-11-23 09:42:40 -05:00
SelectActors . Add ( UE : : ToolTarget : : GetTargetActor ( Targets [ 0 ] ) ) ;
2021-03-22 08:32:17 -04:00
// create intersection asset
if ( IntersectionMesh . TriangleCount ( ) > 0 )
{
2022-08-30 14:40:56 -04:00
MeshTransforms : : ApplyTransform ( IntersectionMesh , OpResult . Transform , true ) ;
MeshTransforms : : ApplyTransformInverse ( IntersectionMesh , TargetToWorld , true ) ;
2021-03-22 08:32:17 -04:00
FTransform3d NewTransform = TargetToWorld ;
2021-11-23 09:42:40 -05:00
FString CurName = UE : : Modeling : : GetComponentAssetBaseName ( UE : : ToolTarget : : GetTargetComponent ( Targets [ 0 ] ) ) ;
2021-03-22 08:32:17 -04:00
FString UseBaseName = FString : : Printf ( TEXT ( " %s_%s " ) , * CurName , TEXT ( " CutPart " ) ) ;
2021-06-02 15:58:00 -04:00
FCreateMeshObjectParams NewMeshObjectParams ;
2022-01-28 10:18:10 -05:00
NewMeshObjectParams . TargetWorld = GetTargetWorld ( ) ;
2021-06-02 15:58:00 -04:00
NewMeshObjectParams . Transform = ( FTransform ) NewTransform ;
NewMeshObjectParams . BaseName = UseBaseName ;
NewMeshObjectParams . Materials = GetOutputMaterials ( ) ;
NewMeshObjectParams . SetMesh ( & IntersectionMesh ) ;
2022-08-24 16:14:52 -04:00
// note: CutMeshWithMeshTool does not support converting types currently
ModelingTools: add support for creating Volumes directly from DrawPolygon, DrawRevolve, DrawPolyPath, and AddPrimitive, CombineMeshes, CutMeshWithMesh, PlaneCut, BaseCreateFromSelected Tools. Improve support for Editing volumes, eg handling mesh/volume interactions, and add configurable auto-simplification for volumes to avoid painful Editor hangs.
- Move ToolTarget implementations, DynamicMeshToVolume to ModelingComponentsEditorOnly module
- move VolumeToDynamicMesh, DynamicMeshProvider/Commiter interfaces to ModelingComponents module
- Add UCreateMeshObjectTypeProperties property set to expose mesh/volume options
- Add FCreateMeshObjectParams::TypeHintClass to allow AVolume type (or other UClass hints) to be passed to creation APIs
- Add UE::ToolTarget::ConfigureCreateMeshObjectParams() util function in ModelingToolTargetUtil, tries to determine output type in a FCreateMeshObjectParams based on input ToolTarget
- Add UEditorModelingObjectsCreationAPI::CreateVolume() implementation
- Add UEditorModelingObjectsCreationAPI::FilterMaterials() that strips out any internal materials and replaces with WorldGridMaterial. This occurs when (eg) subtracting a Volume from a StaticMesh, because the temporary volume mesh gets assigned internal materials, but the Tools don't know this. Use in EditorModelingObjectsCreationAPI when creating new objects. UStaticMeshComponentToolTarget also does this filtering in ::CommitMaterialSetUpdate().
- Add ::ComponentTypeSupportsCollision() function to ComponentCollisionUtil, use to avoid checks/ensures for Volume targets
- Add support for automatic mesh simplification in DynamicMeshToVolume. Add CVar to VolumeDynamicMeshToolTarget.h to control max triangle count (default 500). Apply auto-simplify when creating or updating an AVolume. This prevents the Editor from blocking for long periods on meshes that are too high-res for volumes (even 500 is quite high).
- DynamicMeshToVolume now emits polygroup-faces that contain holes (ie multiple boundary loops) as a set of triangles, rather than emitting separate overlapping faces for each boundary loop
#rb none
#rnx
#jira none
#preflight 60ba50632c42ea0001cb54c5
[CL 16561742 by Ryan Schmidt in ue5-main branch]
2021-06-04 16:04:03 -04:00
UE : : ToolTarget : : ConfigureCreateMeshObjectParams ( Targets [ 0 ] , NewMeshObjectParams ) ;
2021-06-02 15:58:00 -04:00
FCreateMeshObjectResult Result = UE : : Modeling : : CreateMeshObject ( GetToolManager ( ) , MoveTemp ( NewMeshObjectParams ) ) ;
if ( Result . IsOK ( ) & & Result . NewActor ! = nullptr )
2021-03-22 08:32:17 -04:00
{
2021-06-02 15:58:00 -04:00
SelectActors . Add ( Result . NewActor ) ;
2021-03-22 08:32:17 -04:00
}
}
ToolSelectionUtil : : SetNewActorSelection ( GetToolManager ( ) , SelectActors ) ;
GetToolManager ( ) - > EndUndoTransaction ( ) ;
}
UInteractiveGizmoManager * GizmoManager = GetToolManager ( ) - > GetPairedGizmoManager ( ) ;
GizmoManager - > DestroyAllGizmosByOwner ( this ) ;
}
# undef LOCTEXT_NAMESPACE
2022-09-28 01:06:15 -04:00