2020-01-08 17:11:23 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-10-16 14:27:19 -04:00
# include "RemoveOccludedTrianglesTool.h"
# include "InteractiveToolManager.h"
# include "ToolBuilderUtil.h"
2019-10-24 16:45:51 -04:00
# include "ToolSetupUtil.h"
2019-10-16 14:27:19 -04:00
2021-06-13 00:35:22 -04:00
# include "DynamicMesh/DynamicMesh3.h"
2021-01-13 16:19:10 -04:00
# include "Polygroups/PolygroupUtil.h"
2019-10-16 14:27:19 -04:00
# include "BaseBehaviors/MultiClickSequenceInputBehavior.h"
# include "Selection/SelectClickedAction.h"
# include "MeshDescriptionToDynamicMesh.h"
# include "DynamicMeshToMeshDescription.h"
# include "InteractiveGizmoManager.h"
2021-02-05 16:33:02 -04:00
# include "Misc/MessageDialog.h"
2019-10-16 14:27:19 -04:00
# if WITH_EDITOR
# include "Misc/ScopedSlowTask.h"
# endif
2021-03-11 11:40:03 -04:00
# include "TargetInterfaces/MaterialProvider.h"
# include "TargetInterfaces/MeshDescriptionCommitter.h"
# include "TargetInterfaces/MeshDescriptionProvider.h"
# include "TargetInterfaces/PrimitiveComponentBackedTarget.h"
# include "ToolTargetManager.h"
2021-03-09 19:33:56 -04:00
# include "ExplicitUseGeometryMathTypes.h" // using UE::Geometry::(math types)
using namespace UE : : Geometry ;
2019-10-16 14:27:19 -04:00
# define LOCTEXT_NAMESPACE "URemoveOccludedTrianglesTool"
/*
* ToolBuilder
*/
2021-03-11 11:40:03 -04:00
const FToolTargetTypeRequirements & URemoveOccludedTrianglesToolBuilder : : GetTargetRequirements ( ) const
{
static FToolTargetTypeRequirements TypeRequirements ( {
UMaterialProvider : : StaticClass ( ) ,
UMeshDescriptionCommitter : : StaticClass ( ) ,
UMeshDescriptionProvider : : StaticClass ( ) ,
2021-06-22 11:54:55 -04:00
UPrimitiveComponentBackedTarget : : StaticClass ( )
2021-03-11 11:40:03 -04:00
} ) ;
return TypeRequirements ;
}
2019-10-16 14:27:19 -04:00
bool URemoveOccludedTrianglesToolBuilder : : CanBuildTool ( const FToolBuilderState & SceneState ) const
{
2021-03-11 11:40:03 -04:00
return SceneState . TargetManager - > CountSelectedAndTargetable ( SceneState , GetTargetRequirements ( ) ) > 0 ;
2019-10-16 14:27:19 -04:00
}
UInteractiveTool * URemoveOccludedTrianglesToolBuilder : : BuildTool ( const FToolBuilderState & SceneState ) const
{
URemoveOccludedTrianglesTool * NewTool = NewObject < URemoveOccludedTrianglesTool > ( SceneState . ToolManager ) ;
2021-03-11 11:40:03 -04:00
TArray < TObjectPtr < UToolTarget > > Targets = SceneState . TargetManager - > BuildAllSelectedTargetable ( SceneState , GetTargetRequirements ( ) ) ;
NewTool - > SetTargets ( MoveTemp ( Targets ) ) ;
2019-10-16 14:27:19 -04:00
NewTool - > SetWorld ( SceneState . World ) ;
return NewTool ;
}
/*
* Tool
*/
URemoveOccludedTrianglesToolProperties : : URemoveOccludedTrianglesToolProperties ( )
{
}
URemoveOccludedTrianglesAdvancedProperties : : URemoveOccludedTrianglesAdvancedProperties ( )
{
}
URemoveOccludedTrianglesTool : : URemoveOccludedTrianglesTool ( )
{
2021-02-08 17:02:09 -04:00
SetToolDisplayName ( LOCTEXT ( " ProjectToTargetToolName " , " Jacket " ) ) ;
2019-10-16 14:27:19 -04:00
}
void URemoveOccludedTrianglesTool : : SetWorld ( UWorld * World )
{
this - > TargetWorld = World ;
}
void URemoveOccludedTrianglesTool : : Setup ( )
{
UInteractiveTool : : Setup ( ) ;
// hide input StaticMeshComponent
2021-03-11 11:40:03 -04:00
for ( int Idx = 0 ; Idx < Targets . Num ( ) ; Idx + + )
2019-10-16 14:27:19 -04:00
{
2021-03-11 11:40:03 -04:00
TargetComponentInterface ( Idx ) - > SetOwnerVisibility ( false ) ;
2019-10-16 14:27:19 -04:00
}
2021-03-11 11:40:03 -04:00
2020-01-27 20:11:15 -05:00
// find components with the same source asset
2021-03-11 11:40:03 -04:00
TArray < int32 > MapToFirstOccurrences ;
bool bAnyHasSameSource = GetMapToSharedSourceData ( MapToFirstOccurrences ) ;
TargetToPreviewIdx . SetNum ( Targets . Num ( ) ) ;
2020-01-27 20:11:15 -05:00
PreviewToTargetIdx . Reset ( ) ;
2021-03-11 11:40:03 -04:00
for ( int32 ComponentIdx = 0 ; ComponentIdx < MapToFirstOccurrences . Num ( ) ; ComponentIdx + + )
2020-01-27 20:11:15 -05:00
{
2021-03-11 11:40:03 -04:00
if ( MapToFirstOccurrences [ ComponentIdx ] = = ComponentIdx )
2020-01-27 20:11:15 -05:00
{
2021-03-11 11:40:03 -04:00
int32 NumPreviews = PreviewToTargetIdx . Num ( ) ;
PreviewToTargetIdx . Add ( ComponentIdx ) ;
TargetToPreviewIdx [ ComponentIdx ] = NumPreviews ;
2020-01-27 20:11:15 -05:00
}
2021-03-11 11:40:03 -04:00
else
2020-01-27 20:11:15 -05:00
{
2021-03-11 11:40:03 -04:00
TargetToPreviewIdx [ ComponentIdx ] = TargetToPreviewIdx [ MapToFirstOccurrences [ ComponentIdx ] ] ;
2020-01-27 20:11:15 -05:00
}
}
if ( bAnyHasSameSource )
{
GetToolManager ( ) - > DisplayMessage (
LOCTEXT ( " JacketingMultipleAssetWithSameSource " , " WARNING: Multiple meshes in your selection use the same source asset! Triangles will be conservatively removed from these meshes only when they are occluded in every selected instance. " ) ,
EToolMessageLevel : : UserWarning ) ;
}
2021-01-13 16:19:10 -04:00
// initialize the PreviewMesh+BackgroundCompute object
SetupPreviews ( ) ;
2019-10-16 14:27:19 -04:00
BasicProperties = NewObject < URemoveOccludedTrianglesToolProperties > ( this , TEXT ( " Remove Occluded Triangle Settings " ) ) ;
AdvancedProperties = NewObject < URemoveOccludedTrianglesAdvancedProperties > ( this , TEXT ( " Advanced Settings " ) ) ;
2021-01-13 16:19:10 -04:00
MakePolygroupLayerProperties ( ) ;
BasicProperties - > WatchProperty ( BasicProperties - > Action ,
[ this ] ( EOccludedAction Action ) { SetToolPropertySourceEnabled ( PolygroupLayersProperties , Action = = EOccludedAction : : SetNewGroup ) ; }
) ;
2019-10-16 14:27:19 -04:00
// initialize our properties
AddToolPropertySource ( BasicProperties ) ;
2021-01-13 16:19:10 -04:00
AddToolPropertySource ( PolygroupLayersProperties ) ;
2019-10-16 14:27:19 -04:00
AddToolPropertySource ( AdvancedProperties ) ;
2021-01-13 16:19:10 -04:00
for ( UMeshOpPreviewWithBackgroundCompute * Preview : Previews )
{
Preview - > InvalidateResult ( ) ;
}
2020-09-24 00:43:27 -04:00
GetToolManager ( ) - > DisplayMessage (
2020-10-22 19:19:16 -04:00
LOCTEXT ( " RemoveOccludedTrianglesToolDescription " , " Remove triangles that are fully contained within the selected Meshes, and hence cannot be visible with opaque shading. " ) ,
2020-09-24 00:43:27 -04:00
EToolMessageLevel : : UserNotification ) ;
2019-10-16 14:27:19 -04:00
}
2021-01-13 16:19:10 -04:00
void URemoveOccludedTrianglesTool : : MakePolygroupLayerProperties ( )
{
PolygroupLayersProperties = NewObject < UPolygroupLayersProperties > ( this , TEXT ( " Polygroup Layer " ) ) ;
auto GetGroupLayerNames = [ ] ( const FDynamicMesh3 & Mesh )
{
TSet < FName > Names ;
if ( Mesh . Attributes ( ) )
{
for ( int32 LayerIdx = 0 ; LayerIdx < Mesh . Attributes ( ) - > NumPolygroupLayers ( ) ; LayerIdx + + )
{
FName Name = Mesh . Attributes ( ) - > GetPolygroupLayer ( LayerIdx ) - > GetName ( ) ;
Names . Add ( Name ) ;
}
}
return Names ;
} ;
check ( OriginalDynamicMeshes . Num ( ) > 0 ) ;
TSet < FName > CommonLayerNames = GetGroupLayerNames ( * OriginalDynamicMeshes [ 0 ] ) ;
for ( int32 Idx = 1 ; Idx < OriginalDynamicMeshes . Num ( ) ; Idx + + )
{
CommonLayerNames = CommonLayerNames . Intersect ( GetGroupLayerNames ( * OriginalDynamicMeshes [ Idx ] ) ) ;
}
PolygroupLayersProperties - > InitializeGroupLayers ( CommonLayerNames ) ;
}
2019-10-16 14:27:19 -04:00
void URemoveOccludedTrianglesTool : : SetupPreviews ( )
{
2021-03-11 11:40:03 -04:00
int32 NumTargets = Targets . Num ( ) ;
2020-01-27 20:11:15 -05:00
int32 NumPreviews = PreviewToTargetIdx . Num ( ) ;
2019-10-16 14:27:19 -04:00
# if WITH_EDITOR
static const FText SlowTaskText = LOCTEXT ( " RemoveOccludedTrianglesInit " , " Building mesh occlusion data... " ) ;
2020-01-27 20:11:15 -05:00
FScopedSlowTask SlowTask ( NumTargets , SlowTaskText ) ;
2019-10-16 14:27:19 -04:00
SlowTask . MakeDialog ( ) ;
// Declare progress shortcut lambdas
auto EnterProgressFrame = [ & SlowTask ] ( float Progress )
{
SlowTask . EnterProgressFrame ( Progress ) ;
} ;
# else
auto EnterProgressFrame = [ ] ( float Progress ) { } ;
# endif
2021-01-13 16:19:10 -04:00
// create a "magic pink" secondary material to mark occluded faces (to be used if we are setting a new triangle group instead of removing faces)
UMaterialInterface * OccludedMaterial = ToolSetupUtil : : GetSelectionMaterial ( FLinearColor ( 0.9f , 0.1f , 0.9f ) , GetToolManager ( ) ) ;
OccludedGroupIDs . Init ( - 1 , NumPreviews ) ;
OccludedGroupLayers . Init ( - 1 , NumPreviews ) ;
2021-03-01 17:01:16 -04:00
OccluderTrees . SetNum ( NumTargets ) ;
OccluderWindings . SetNum ( NumTargets ) ;
OccluderTransforms . SetNum ( NumTargets ) ;
2020-01-27 20:11:15 -05:00
OriginalDynamicMeshes . SetNum ( NumPreviews ) ;
PreviewToCopyIdx . Reset ( ) ; PreviewToCopyIdx . SetNum ( NumPreviews ) ;
for ( int32 TargetIdx = 0 ; TargetIdx < NumTargets ; TargetIdx + + )
2019-10-16 14:27:19 -04:00
{
2020-01-27 20:11:15 -05:00
EnterProgressFrame ( 1 ) ;
int PreviewIdx = TargetToPreviewIdx [ TargetIdx ] ;
2019-10-16 14:27:19 -04:00
2021-01-13 16:19:10 -04:00
// used to choose which triangles need to use the special "OccludedMaterial" secondary material, when the Occluded Action == SetNewGroup
auto IsOccludedGroupFn = [ this , PreviewIdx ] ( const FDynamicMesh3 * Mesh , int32 TriangleID )
{
int GroupID = OccludedGroupIDs [ PreviewIdx ] ;
if ( GroupID > = 0 )
{
int LayerIndex = OccludedGroupLayers [ PreviewIdx ] ;
if ( LayerIndex < 0 )
{
return Mesh - > GetTriangleGroup ( TriangleID ) = = GroupID ;
}
else
{
check ( Mesh - > HasAttributes ( ) & & Mesh - > Attributes ( ) - > NumPolygroupLayers ( ) > LayerIndex ) ;
return Mesh - > Attributes ( ) - > GetPolygroupLayer ( LayerIndex ) - > GetValue ( TriangleID ) = = GroupID ;
}
}
return false ;
} ;
2020-01-27 20:11:15 -05:00
bool bHasConverted = OriginalDynamicMeshes [ PreviewIdx ] . IsValid ( ) ;
2019-10-16 14:27:19 -04:00
2020-01-27 20:11:15 -05:00
if ( ! bHasConverted )
{
URemoveOccludedTrianglesOperatorFactory * OpFactory = NewObject < URemoveOccludedTrianglesOperatorFactory > ( ) ;
OpFactory - > Tool = this ;
OpFactory - > PreviewIdx = PreviewIdx ;
2021-02-17 11:50:23 -04:00
OriginalDynamicMeshes [ PreviewIdx ] = MakeShared < FDynamicMesh3 , ESPMode : : ThreadSafe > ( ) ;
2020-01-27 20:11:15 -05:00
FMeshDescriptionToDynamicMesh Converter ;
2021-03-11 11:40:03 -04:00
Converter . Convert ( TargetMeshProviderInterface ( TargetIdx ) - > GetMeshDescription ( ) , * OriginalDynamicMeshes [ PreviewIdx ] ) ;
2019-10-16 14:27:19 -04:00
2020-01-27 20:11:15 -05:00
UMeshOpPreviewWithBackgroundCompute * Preview = Previews . Add_GetRef ( NewObject < UMeshOpPreviewWithBackgroundCompute > ( OpFactory , " Preview " ) ) ;
Preview - > Setup ( this - > TargetWorld , OpFactory ) ;
2021-06-11 22:39:18 -04:00
Preview - > PreviewMesh - > SetTangentsMode ( EDynamicMeshComponentTangentsMode : : AutoCalculated ) ;
2019-12-19 18:07:47 -05:00
2020-01-27 20:11:15 -05:00
FComponentMaterialSet MaterialSet ;
2021-03-11 11:40:03 -04:00
TargetMaterialInterface ( TargetIdx ) - > GetMaterialSet ( MaterialSet ) ;
2020-01-27 20:11:15 -05:00
Preview - > ConfigureMaterials ( MaterialSet . Materials ,
ToolSetupUtil : : GetDefaultWorkingMaterial ( GetToolManager ( ) )
) ;
2019-12-19 18:07:47 -05:00
2021-03-11 11:40:03 -04:00
Preview - > PreviewMesh - > SetTransform ( TargetComponentInterface ( TargetIdx ) - > GetWorldTransform ( ) ) ;
2020-01-27 20:11:15 -05:00
Preview - > PreviewMesh - > UpdatePreview ( OriginalDynamicMeshes [ PreviewIdx ] . Get ( ) ) ;
Preview - > SetVisibility ( true ) ;
2021-01-13 16:19:10 -04:00
2021-03-01 17:01:16 -04:00
OccluderTrees [ TargetIdx ] = MakeShared < FDynamicMeshAABBTree3 , ESPMode : : ThreadSafe > ( OriginalDynamicMeshes [ PreviewIdx ] . Get ( ) ) ;
OccluderWindings [ TargetIdx ] = MakeShared < TFastWindingTree < FDynamicMesh3 > , ESPMode : : ThreadSafe > ( OccluderTrees [ TargetIdx ] . Get ( ) ) ;
2021-03-18 12:46:27 -04:00
OccluderTransforms [ TargetIdx ] = ( UE : : Geometry : : FTransform3d ) TargetComponentInterface ( TargetIdx ) - > GetWorldTransform ( ) ;
2021-03-01 17:01:16 -04:00
2021-01-13 16:19:10 -04:00
// configure secondary render material
Preview - > SecondaryMaterial = OccludedMaterial ;
// Set occluded layer index and group IDs
Previews [ PreviewIdx ] - > OnOpCompleted . AddLambda ( [ this , PreviewIdx ] ( const FDynamicMeshOperator * UncastOp ) {
const FRemoveOccludedTrianglesOp * Op = static_cast < const FRemoveOccludedTrianglesOp * > ( UncastOp ) ;
OccludedGroupIDs [ PreviewIdx ] = Op - > CreatedGroupID ;
OccludedGroupLayers [ PreviewIdx ] = Op - > CreatedGroupLayerIndex ;
} ) ;
// enable secondary triangle buffers
Preview - > PreviewMesh - > EnableSecondaryTriangleBuffers ( MoveTemp ( IsOccludedGroupFn ) ) ;
2020-01-27 20:11:15 -05:00
}
else
{
// already did the conversion for a full UMeshOpPreviewWithBackgroundCompute -- just make a light version of that and hook it up to copy the other's work
int CopyIdx = PreviewCopies . Num ( ) ;
UPreviewMesh * PreviewMesh = PreviewCopies . Add_GetRef ( NewObject < UPreviewMesh > ( this ) ) ;
2021-03-11 11:40:03 -04:00
PreviewMesh - > CreateInWorld ( this - > TargetWorld , TargetComponentInterface ( TargetIdx ) - > GetWorldTransform ( ) ) ;
2019-10-16 14:27:19 -04:00
2020-01-27 20:11:15 -05:00
PreviewToCopyIdx [ PreviewIdx ] . Add ( CopyIdx ) ;
PreviewMesh - > UpdatePreview ( OriginalDynamicMeshes [ PreviewIdx ] . Get ( ) ) ;
FComponentMaterialSet MaterialSet ;
2021-03-11 11:40:03 -04:00
TargetMaterialInterface ( TargetIdx ) - > GetMaterialSet ( MaterialSet ) ;
2020-01-27 20:11:15 -05:00
PreviewMesh - > SetMaterials ( MaterialSet . Materials ) ;
PreviewMesh - > SetVisible ( true ) ;
2021-03-01 17:01:16 -04:00
OccluderTrees [ TargetIdx ] = OccluderTrees [ PreviewToTargetIdx [ PreviewIdx ] ] ;
OccluderWindings [ TargetIdx ] = OccluderWindings [ PreviewToTargetIdx [ PreviewIdx ] ] ;
2021-03-18 12:46:27 -04:00
OccluderTransforms [ TargetIdx ] = ( UE : : Geometry : : FTransform3d ) TargetComponentInterface ( TargetIdx ) - > GetWorldTransform ( ) ;
2021-03-01 17:01:16 -04:00
2021-01-13 16:19:10 -04:00
PreviewMesh - > SetSecondaryRenderMaterial ( OccludedMaterial ) ;
PreviewMesh - > EnableSecondaryTriangleBuffers ( MoveTemp ( IsOccludedGroupFn ) ) ;
2020-01-27 20:11:15 -05:00
Previews [ PreviewIdx ] - > OnMeshUpdated . AddLambda ( [ this , CopyIdx ] ( UMeshOpPreviewWithBackgroundCompute * Compute ) {
PreviewCopies [ CopyIdx ] - > UpdatePreview ( Compute - > PreviewMesh - > GetPreviewDynamicMesh ( ) ) ;
} ) ;
}
2019-10-16 14:27:19 -04:00
}
}
void URemoveOccludedTrianglesTool : : Shutdown ( EToolShutdownType ShutdownType )
{
2020-11-24 18:42:39 -04:00
if ( ShutdownType = = EToolShutdownType : : Accept & & AreAllTargetsValid ( ) = = false )
{
UE_LOG ( LogTemp , Error , TEXT ( " Tool Target has become Invalid (possibly it has been Force Deleted). Aborting Tool. " ) ) ;
ShutdownType = EToolShutdownType : : Cancel ;
}
2019-10-16 14:27:19 -04:00
// Restore (unhide) the source meshes
2021-03-11 11:40:03 -04:00
for ( int ComponentIdx = 0 ; ComponentIdx < Targets . Num ( ) ; ComponentIdx + + )
2019-10-16 14:27:19 -04:00
{
2021-03-11 11:40:03 -04:00
TargetComponentInterface ( ComponentIdx ) - > SetOwnerVisibility ( true ) ;
2019-10-16 14:27:19 -04:00
}
2020-01-27 20:11:15 -05:00
// clear all the preview copies
for ( UPreviewMesh * PreviewMesh : PreviewCopies )
{
PreviewMesh - > SetVisible ( false ) ;
PreviewMesh - > Disconnect ( ) ;
PreviewMesh = nullptr ;
}
PreviewCopies . Empty ( ) ;
2019-10-16 14:27:19 -04:00
TArray < FDynamicMeshOpResult > Results ;
for ( UMeshOpPreviewWithBackgroundCompute * Preview : Previews )
{
Results . Add ( Preview - > Shutdown ( ) ) ;
}
if ( ShutdownType = = EToolShutdownType : : Accept )
{
GenerateAsset ( Results ) ;
}
}
TUniquePtr < FDynamicMeshOperator > URemoveOccludedTrianglesOperatorFactory : : MakeNewOperator ( )
{
TUniquePtr < FRemoveOccludedTrianglesOp > Op = MakeUnique < FRemoveOccludedTrianglesOp > ( ) ;
Op - > NormalOffset = Tool - > AdvancedProperties - > NormalOffset ;
2021-01-13 16:19:10 -04:00
Op - > bSetTriangleGroupInsteadOfRemoving = Tool - > BasicProperties - > Action = = EOccludedAction : : SetNewGroup ;
Op - > ActiveGroupLayer = Tool - > PolygroupLayersProperties - > ActiveGroupLayer ;
Op - > bActiveGroupLayerIsDefault = ! Tool - > PolygroupLayersProperties - > HasSelectedPolygroup ( ) ;
2019-10-16 14:27:19 -04:00
switch ( Tool - > BasicProperties - > OcclusionTestMethod )
{
case EOcclusionCalculationUIMode : : GeneralizedWindingNumber :
Op - > InsideMode = EOcclusionCalculationMode : : FastWindingNumber ;
break ;
case EOcclusionCalculationUIMode : : RaycastOcclusionSamples :
Op - > InsideMode = EOcclusionCalculationMode : : SimpleOcclusionTest ;
break ;
default :
ensure ( false ) ; // all cases should be handled
}
switch ( Tool - > BasicProperties - > TriangleSampling )
{
case EOcclusionTriangleSamplingUIMode : : Vertices :
Op - > TriangleSamplingMethod = EOcclusionTriangleSampling : : Vertices ;
break ;
// Centroids sampling not exposed in UI for now
// case EOcclusionTriangleSamplingUIMode::Centroids:
// Op->TriangleSamplingMethod = EOcclusionTriangleSampling::Centroids;
// break;
case EOcclusionTriangleSamplingUIMode : : VerticesAndCentroids :
Op - > TriangleSamplingMethod = EOcclusionTriangleSampling : : VerticesAndCentroids ;
break ;
default :
ensure ( false ) ;
}
Op - > WindingIsoValue = Tool - > BasicProperties - > WindingIsoValue ;
2020-01-27 20:11:15 -05:00
int ComponentIndex = Tool - > PreviewToTargetIdx [ PreviewIdx ] ;
2021-03-11 11:40:03 -04:00
FTransform LocalToWorld = Tool - > TargetComponentInterface ( ComponentIndex ) - > GetWorldTransform ( ) ;
2020-01-27 20:11:15 -05:00
Op - > OriginalMesh = Tool - > OriginalDynamicMeshes [ PreviewIdx ] ;
2019-10-16 14:27:19 -04:00
2021-03-01 17:01:16 -04:00
if ( Tool - > BasicProperties - > bOnlySelfOcclude )
{
int32 TargetIdx = Tool - > PreviewToTargetIdx [ PreviewIdx ] ;
Op - > OccluderTrees . Add ( Tool - > OccluderTrees [ TargetIdx ] ) ;
Op - > OccluderWindings . Add ( Tool - > OccluderWindings [ TargetIdx ] ) ;
2021-03-18 12:46:27 -04:00
Op - > OccluderTransforms . Add ( UE : : Geometry : : FTransform3d : : Identity ( ) ) ;
2021-03-01 17:01:16 -04:00
}
else
{
Op - > OccluderTrees = Tool - > OccluderTrees ;
Op - > OccluderWindings = Tool - > OccluderWindings ;
Op - > OccluderTransforms = Tool - > OccluderTransforms ;
}
2019-10-16 14:27:19 -04:00
Op - > AddRandomRays = Tool - > BasicProperties - > AddRandomRays ;
2019-10-24 17:07:23 -04:00
Op - > AddTriangleSamples = Tool - > BasicProperties - > AddTriangleSamples ;
2020-11-10 17:04:15 -04:00
2021-01-04 16:55:56 -04:00
Op - > ShrinkRemoval = Tool - > BasicProperties - > ShrinkRemoval ;
2020-11-10 17:04:15 -04:00
Op - > MinAreaConnectedComponent = Tool - > BasicProperties - > MinAreaIsland ;
Op - > MinTriCountConnectedComponent = Tool - > BasicProperties - > MinTriCountIsland ;
2019-10-16 14:27:19 -04:00
Op - > SetTransform ( LocalToWorld ) ;
2021-03-18 12:46:27 -04:00
Op - > MeshTransforms . Add ( ( UE : : Geometry : : FTransform3d ) LocalToWorld ) ;
2020-01-27 20:11:15 -05:00
for ( int32 CopyIdx : Tool - > PreviewToCopyIdx [ PreviewIdx ] )
{
2021-03-18 12:46:27 -04:00
Op - > MeshTransforms . Add ( ( UE : : Geometry : : FTransform3d ) Tool - > PreviewCopies [ CopyIdx ] - > GetTransform ( ) ) ;
2020-01-27 20:11:15 -05:00
}
2019-10-16 14:27:19 -04:00
return Op ;
}
2020-04-18 18:42:59 -04:00
void URemoveOccludedTrianglesTool : : OnTick ( float DeltaTime )
2019-10-16 14:27:19 -04:00
{
for ( UMeshOpPreviewWithBackgroundCompute * Preview : Previews )
{
Preview - > Tick ( DeltaTime ) ;
}
2020-01-27 20:11:15 -05:00
// copy working material state to corresponding copies
for ( int PreviewIdx = 0 ; PreviewIdx < Previews . Num ( ) ; PreviewIdx + + )
{
UMeshOpPreviewWithBackgroundCompute * Preview = Previews [ PreviewIdx ] ;
bool bIsWorking = Preview - > IsUsingWorkingMaterial ( ) ;
for ( int CopyIdx : PreviewToCopyIdx [ PreviewIdx ] )
{
if ( bIsWorking )
2021-01-13 16:19:10 -04:00
{
2020-01-27 20:11:15 -05:00
PreviewCopies [ CopyIdx ] - > SetOverrideRenderMaterial ( Preview - > WorkingMaterial ) ;
2021-01-13 16:19:10 -04:00
PreviewCopies [ CopyIdx ] - > ClearSecondaryRenderMaterial ( ) ;
2020-01-27 20:11:15 -05:00
}
else
{
PreviewCopies [ CopyIdx ] - > ClearOverrideRenderMaterial ( ) ;
2021-01-13 16:19:10 -04:00
PreviewCopies [ CopyIdx ] - > SetSecondaryRenderMaterial ( Preview - > SecondaryMaterial ) ;
2020-01-27 20:11:15 -05:00
}
}
}
2019-10-16 14:27:19 -04:00
}
# if WITH_EDITOR
void URemoveOccludedTrianglesTool : : PostEditChangeProperty ( FPropertyChangedEvent & PropertyChangedEvent )
{
for ( UMeshOpPreviewWithBackgroundCompute * Preview : Previews )
{
Preview - > InvalidateResult ( ) ;
}
}
# endif
2020-01-07 15:54:23 -05:00
void URemoveOccludedTrianglesTool : : OnPropertyModified ( UObject * PropertySet , FProperty * Property )
2019-10-16 14:27:19 -04:00
{
for ( UMeshOpPreviewWithBackgroundCompute * Preview : Previews )
{
Preview - > InvalidateResult ( ) ;
}
}
bool URemoveOccludedTrianglesTool : : CanAccept ( ) const
{
for ( UMeshOpPreviewWithBackgroundCompute * Preview : Previews )
{
if ( ! Preview - > HaveValidResult ( ) )
{
return false ;
}
}
2020-11-24 18:42:39 -04:00
return Super : : CanAccept ( ) ;
2019-10-16 14:27:19 -04:00
}
void URemoveOccludedTrianglesTool : : GenerateAsset ( const TArray < FDynamicMeshOpResult > & Results )
{
GetToolManager ( ) - > BeginUndoTransaction ( LOCTEXT ( " RemoveOccludedTrianglesToolTransactionName " , " Remove Occluded Triangles " ) ) ;
2020-01-27 20:11:15 -05:00
check ( Results . Num ( ) = = Previews . Num ( ) ) ;
2021-02-05 16:33:02 -04:00
// check if we entirely remove away any meshes
bool bWantDestroy = false ;
for ( int32 PreviewIdx = 0 ; PreviewIdx < Previews . Num ( ) ; PreviewIdx + + )
{
bWantDestroy = bWantDestroy | | ( Results [ PreviewIdx ] . Mesh . Get ( ) - > TriangleCount ( ) = = 0 ) ;
}
// if so ask user what to do
if ( bWantDestroy )
{
FText Title = LOCTEXT ( " RemoveOccludedDestroyTitle " , " Delete mesh components? " ) ;
EAppReturnType : : Type Ret = FMessageDialog : : Open ( EAppMsgType : : YesNo ,
LOCTEXT ( " RemoveOccludedDestroyQuestion " , " Jacketing has removed all triangles from some meshes. Actually destroy these mesh components? " ) , & Title ) ;
if ( Ret = = EAppReturnType : : No )
{
bWantDestroy = false ;
}
}
2019-10-16 14:27:19 -04:00
2020-01-27 20:11:15 -05:00
for ( int32 PreviewIdx = 0 ; PreviewIdx < Previews . Num ( ) ; PreviewIdx + + )
2019-10-16 14:27:19 -04:00
{
2020-01-27 20:11:15 -05:00
check ( Results [ PreviewIdx ] . Mesh . Get ( ) ! = nullptr ) ;
int ComponentIdx = PreviewToTargetIdx [ PreviewIdx ] ;
2021-02-05 16:33:02 -04:00
if ( Results [ PreviewIdx ] . Mesh . Get ( ) - > TriangleCount ( ) = = 0 )
{
if ( bWantDestroy )
{
2021-03-11 11:40:03 -04:00
for ( int TargetIdx = 0 ; TargetIdx < Targets . Num ( ) ; TargetIdx + + )
2021-02-05 16:33:02 -04:00
{
if ( TargetToPreviewIdx [ TargetIdx ] = = PreviewIdx )
{
2021-03-11 11:40:03 -04:00
TargetComponentInterface ( TargetIdx ) - > GetOwnerComponent ( ) - > DestroyComponent ( ) ;
2021-02-05 16:33:02 -04:00
}
}
}
continue ;
}
2021-03-11 11:40:03 -04:00
TargetMeshCommitterInterface ( ComponentIdx ) - > CommitMeshDescription ( [ & Results , & PreviewIdx , this ] ( const IMeshDescriptionCommitter : : FCommitterParams & CommitParams )
2019-10-16 14:27:19 -04:00
{
FDynamicMeshToMeshDescription Converter ;
2021-03-11 11:40:03 -04:00
Converter . Convert ( Results [ PreviewIdx ] . Mesh . Get ( ) , * CommitParams . MeshDescriptionOut ) ;
2019-10-16 14:27:19 -04:00
} ) ;
}
GetToolManager ( ) - > EndUndoTransaction ( ) ;
}
# undef LOCTEXT_NAMESPACE