2021-03-05 19:27:14 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
2021-04-08 14:32:07 -04:00
# include "DatasmithSketchUpMaterial.h"
2021-03-05 19:27:14 -04:00
2021-04-08 14:32:07 -04:00
# include "DatasmithSketchUpCommon.h"
2021-03-05 19:27:14 -04:00
# include "DatasmithSketchUpComponent.h"
# include "DatasmithSketchUpExportContext.h"
2021-05-11 01:10:20 -04:00
# include "DatasmithSketchUpMetadata.h"
2021-03-05 19:27:14 -04:00
# include "DatasmithSketchUpMesh.h"
# include "DatasmithSketchUpString.h"
# include "DatasmithSketchUpSummary.h"
# include "DatasmithSketchUpTexture.h"
# include "DatasmithSketchUpUtils.h"
// SketchUp SDK.
# include "DatasmithSketchUpSDKBegins.h"
# include "SketchUpAPI/model/component_instance.h"
# include "SketchUpAPI/model/drawing_element.h"
# include "SketchUpAPI/model/entity.h"
# include "SketchUpAPI/model/model.h"
# include "SketchUpAPI/model/texture.h"
2021-09-06 12:23:53 -04:00
# include "SketchUpAPI/model/typed_value.h"
# include "SketchUpAPI/model/rendering_options.h"
2021-03-05 19:27:14 -04:00
# include "DatasmithSketchUpSDKCeases.h"
// Datasmith SDK.
# include "Containers/Array.h"
# include "DatasmithSceneFactory.h"
# include "DatasmithUtils.h"
# include "DatasmithMaterialsUtils.h"
# include "Misc/Paths.h"
# include "Misc/SecureHash.h"
using namespace DatasmithSketchUp ;
// Structure that holds extracted data from SketchUp material during export process
class FExtractedMaterial
{
public :
FExtractedMaterial (
FExportContext & Context ,
SUMaterialRef InSMaterialDefinitionRef // source SketchUp material definition
) ;
// Source SketchUp material referecene
SUMaterialRef SourceMaterialRef ;
// Extracted from SketchUp
// Source SketchUp material ID.
FEntityIDType SketchupSourceID ;
// Source SketchUp material name.
FString SketchupSourceName ;
// Source SketchUp material type: SUMaterialType_Colored, SUMaterialType_Textured or SUMaterialType_ColorizedTexture.
SUMaterialType SourceType ;
// Source SketchUp material color.
SUColor SourceColor ;
// Whether or not the source SketchUp color alpha values are used.
bool bSourceColorAlphaUsed ;
SUTextureRef TextureRef = SU_INVALID ;
FString LocalizedMaterialName ;
FString InheritedMaterialName ;
private :
// Make the material names sanitized for Datasmith.
void InitMaterialNames ( ) ;
} ;
FExtractedMaterial : : FExtractedMaterial (
FExportContext & Context ,
SUMaterialRef InSMaterialDefinitionRef )
: SourceMaterialRef ( InSMaterialDefinitionRef )
, SourceColor ( { 128 , 128 , 128 , 255 } ) // default RGBA: sRGB opaque middle gray
{
SUResult SResult = SU_ERROR_NONE ;
// Get the material ID of the SketckUp material.
SketchupSourceID = DatasmithSketchUpUtils : : GetMaterialID ( SourceMaterialRef ) ;
// Retrieve the SketchUp material name.
SketchupSourceName = SuGetString ( SUMaterialGetName , SourceMaterialRef ) ;
// Remove any name encasing "[]".
SketchupSourceName . RemoveFromStart ( TEXT ( " [ " ) ) ;
SketchupSourceName . RemoveFromEnd ( TEXT ( " ] " ) ) ;
// Get the SketchUp material type.
SUMaterialGetType ( SourceMaterialRef , & SourceType ) ; // we can ignore the returned SU_RESULT
// Get the SketchUp material color.
SUColor SMaterialColor ;
SResult = SUMaterialGetColor ( SourceMaterialRef , & SMaterialColor ) ;
// Keep the default opaque middle gray when the material does not have a color value (SU_ERROR_NO_DATA).
if ( SResult = = SU_ERROR_NONE )
{
SourceColor = SMaterialColor ;
}
// Get the flag indicating whether or not the SketchUp color alpha values are used.
SUMaterialGetUseOpacity ( SourceMaterialRef , & bSourceColorAlphaUsed ) ; // we can ignore the returned SU_RESULT
// Retrieve the SketchUp material texture.
SResult = SUMaterialGetTexture ( SourceMaterialRef , & TextureRef ) ;
// Make the material names sanitized for Datasmith.
InitMaterialNames ( ) ;
}
void FExtractedMaterial : : InitMaterialNames ( )
{
FString SanitizedName = FDatasmithUtils : : SanitizeObjectName ( SketchupSourceName ) ;
FString HashedName = FMD5 : : HashAnsiString ( * SketchupSourceName ) ;
LocalizedMaterialName = FString : : Printf ( TEXT ( " %ls-L%ls " ) , * SanitizedName , * HashedName ) ;
InheritedMaterialName = FString : : Printf ( TEXT ( " %ls-I%ls " ) , * SanitizedName , * HashedName ) ;
}
FMaterialIDType const FMaterial : : DEFAULT_MATERIAL_ID ;
FMaterialIDType const FMaterial : : INHERITED_MATERIAL_ID ;
namespace DatasmithSketchUp
{
TSharedPtr < IDatasmithBaseMaterialElement > CreateMaterialElement (
FExportContext & Context ,
FExtractedMaterial & InMaterial ,
TCHAR const * InMaterialName ,
2021-06-07 20:09:45 -04:00
FTexture * Texture ,
bool bInScaleTexture
2021-03-05 19:27:14 -04:00
)
{
// Create a Datasmith material element for the material definition.
TSharedRef < IDatasmithUEPbrMaterialElement > DatasmithMaterialElementPtr = FDatasmithSceneFactory : : CreateUEPbrMaterial ( InMaterialName ) ;
// Set the material element label used in the Unreal UI.
FString MaterialLabel = FDatasmithUtils : : SanitizeObjectName ( InMaterial . SketchupSourceName ) ;
DatasmithMaterialElementPtr - > SetLabel ( * MaterialLabel ) ;
2021-11-07 23:43:01 -05:00
2021-09-06 12:23:53 -04:00
FLinearColor LinearColor = FMaterial : : ConvertColor ( InMaterial . SourceColor , InMaterial . bSourceColorAlphaUsed ) ;
2021-03-05 19:27:14 -04:00
DatasmithMaterialElementPtr - > SetTwoSided ( false ) ; // todo: consider this
bool bTranslucent = InMaterial . bSourceColorAlphaUsed ;
2021-06-07 20:09:45 -04:00
if ( Texture )
2021-03-05 19:27:14 -04:00
{
2021-05-11 01:10:20 -04:00
IDatasmithMaterialExpressionTexture * ExpressionTexture = DatasmithMaterialElementPtr - > AddMaterialExpression < IDatasmithMaterialExpressionTexture > ( ) ;
ExpressionTexture - > SetName ( TEXT ( " Texture " ) ) ;
ExpressionTexture - > SetTexturePathName ( Texture - > GetDatasmithElementName ( ) ) ;
// Apply texture scaling
if ( bInScaleTexture & & ! Texture - > TextureScale . Equals ( FVector2D : : UnitVector ) )
2021-03-05 19:27:14 -04:00
{
2021-05-11 01:10:20 -04:00
IDatasmithMaterialExpressionFunctionCall * UVEditExpression = DatasmithMaterialElementPtr - > AddMaterialExpression < IDatasmithMaterialExpressionFunctionCall > ( ) ;
UVEditExpression - > SetFunctionPathName ( TEXT ( " /DatasmithContent/Materials/UVEdit.UVEdit " ) ) ;
UVEditExpression - > ConnectExpression ( ExpressionTexture - > GetInputCoordinate ( ) ) ;
// Tiling
IDatasmithMaterialExpressionColor * TilingValue = DatasmithMaterialElementPtr - > AddMaterialExpression < IDatasmithMaterialExpressionColor > ( ) ;
TilingValue - > SetName ( TEXT ( " UV Tiling " ) ) ;
TilingValue - > GetColor ( ) = FLinearColor ( Texture - > TextureScale . X , Texture - > TextureScale . Y , 0.f ) ;
TilingValue - > ConnectExpression ( * UVEditExpression - > GetInput ( 2 ) ) ;
//IDatasmithMaterialExpressionColor* OffsetValue = MaterialElement->AddMaterialExpression< IDatasmithMaterialExpressionColor >();
//OffsetValue->SetName(TEXT("UV Offset"));
//OffsetValue->GetColor() = FLinearColor(0.f, 0.f, 0.f);
//OffsetValue->ConnectExpression(*UVEditExpression->GetInput(7));
IDatasmithMaterialExpressionTextureCoordinate * TextureCoordinateExpression = DatasmithMaterialElementPtr - > AddMaterialExpression < IDatasmithMaterialExpressionTextureCoordinate > ( ) ;
TextureCoordinateExpression - > SetCoordinateIndex ( 0 ) ;
TextureCoordinateExpression - > ConnectExpression ( * UVEditExpression - > GetInput ( 0 ) ) ;
2021-03-05 19:27:14 -04:00
}
ExpressionTexture - > ConnectExpression ( DatasmithMaterialElementPtr - > GetBaseColor ( ) ) ;
bTranslucent = bTranslucent | | Texture - > GetTextureUseAlphaChannel ( ) ;
2021-05-25 02:43:26 -04:00
// Set the Datasmith material element opacity.
if ( Texture - > GetTextureUseAlphaChannel ( ) )
{
// Invert texture translarency to get Unreal opacity
IDatasmithMaterialExpressionGeneric * ExpressionOpacity = DatasmithMaterialElementPtr - > AddMaterialExpression < IDatasmithMaterialExpressionGeneric > ( ) ;
ExpressionOpacity - > SetExpressionName ( TEXT ( " OneMinus " ) ) ;
ExpressionTexture - > ConnectExpression ( * ExpressionOpacity - > GetInput ( 0 ) , 3 ) ;
ExpressionOpacity - > ConnectExpression ( DatasmithMaterialElementPtr - > GetOpacity ( ) ) ;
}
2021-03-05 19:27:14 -04:00
}
2021-05-25 02:43:26 -04:00
else
{
IDatasmithMaterialExpressionColor * ExpressionColor = DatasmithMaterialElementPtr - > AddMaterialExpression < IDatasmithMaterialExpressionColor > ( ) ;
ExpressionColor - > SetName ( TEXT ( " Base Color " ) ) ;
ExpressionColor - > GetColor ( ) = LinearColor ;
ExpressionColor - > ConnectExpression ( DatasmithMaterialElementPtr - > GetBaseColor ( ) ) ;
// Set the Datasmith material element opacity.
if ( InMaterial . bSourceColorAlphaUsed )
{
IDatasmithMaterialExpressionScalar * ExpressionOpacity = DatasmithMaterialElementPtr - > AddMaterialExpression < IDatasmithMaterialExpressionScalar > ( ) ;
ExpressionOpacity - > SetName ( TEXT ( " Opacity " ) ) ;
ExpressionOpacity - > GetScalar ( ) = float ( InMaterial . SourceColor . alpha ) / float ( 255 ) ;
ExpressionOpacity - > ConnectExpression ( DatasmithMaterialElementPtr - > GetOpacity ( ) ) ;
}
}
2021-03-05 19:27:14 -04:00
if ( bTranslucent )
{
DatasmithMaterialElementPtr - > SetBlendMode ( /*EBlendMode::BLEND_Translucent*/ 2 ) ;
}
Context . DatasmithScene - > AddMaterial ( DatasmithMaterialElementPtr ) ;
// Return the Datasmith material element.
return DatasmithMaterialElementPtr ;
}
}
FMaterial : : FMaterial ( SUMaterialRef InMaterialRef )
: MaterialRef ( InMaterialRef )
2021-09-06 12:23:53 -04:00
, bInvalidated ( true )
2021-03-05 19:27:14 -04:00
{ }
TSharedPtr < FMaterial > FMaterial : : Create ( FExportContext & Context , SUMaterialRef InMaterialRef )
{
TSharedPtr < FMaterial > Material = MakeShared < FMaterial > ( InMaterialRef ) ;
return Material ;
}
2021-11-07 23:43:01 -05:00
void FMaterial : : Invalidate ( )
2021-09-06 12:23:53 -04:00
{
bInvalidated = true ;
}
FLinearColor FMaterial : : ConvertColor ( const SUColor & C , bool bAlphaUsed )
{
FColor SRGBColor ( C . red , C . green , C . blue , bAlphaUsed ? C . alpha : 255 ) ;
return FLinearColor ( SRGBColor ) ;
}
TSharedRef < IDatasmithBaseMaterialElement > FMaterial : : CreateDefaultMaterialElement ( FExportContext & Context )
2021-03-05 19:27:14 -04:00
{
TSharedRef < IDatasmithUEPbrMaterialElement > DatasmithMaterialElementPtr = FDatasmithSceneFactory : : CreateUEPbrMaterial ( TEXT ( " Default " ) ) ;
FLinearColor LinearColor ( 0.5 , 0.5 , 0.5 , 1 ) ;
2021-09-06 12:23:53 -04:00
// Retrieve Front Face color current Style - Styles api doesn't have a way to access it, using RenderingOptions instead
SURenderingOptionsRef RenderingOptionsRef = SU_INVALID ;
if ( SUModelGetRenderingOptions ( Context . ModelRef , & RenderingOptionsRef ) = = SU_ERROR_NONE )
{
SUTypedValueRef ColorTypedValue = SU_INVALID ;
SUTypedValueCreate ( & ColorTypedValue ) ;
if ( SURenderingOptionsGetValue ( RenderingOptionsRef , " FaceFrontColor " , & ColorTypedValue ) = = SU_ERROR_NONE )
{
SUColor Color ;
if ( SUTypedValueGetColor ( ColorTypedValue , & Color ) = = SU_ERROR_NONE )
{
LinearColor = ConvertColor ( Color ) ;
}
}
SUTypedValueRelease ( & ColorTypedValue ) ;
}
2021-03-05 19:27:14 -04:00
DatasmithMaterialElementPtr - > SetTwoSided ( false ) ; // todo: consider this
IDatasmithMaterialExpressionColor * ExpressionColor = DatasmithMaterialElementPtr - > AddMaterialExpression < IDatasmithMaterialExpressionColor > ( ) ;
ExpressionColor - > SetName ( TEXT ( " Base Color " ) ) ;
ExpressionColor - > GetColor ( ) = LinearColor ;
ExpressionColor - > ConnectExpression ( DatasmithMaterialElementPtr - > GetBaseColor ( ) ) ;
Context . DatasmithScene - > AddMaterial ( DatasmithMaterialElementPtr ) ;
2021-09-06 12:23:53 -04:00
return DatasmithMaterialElementPtr ;
2021-03-05 19:27:14 -04:00
}
2021-04-08 14:32:07 -04:00
void FMaterial : : Remove ( FExportContext & Context )
{
2021-11-07 23:43:01 -05:00
MaterialDirectlyAppliedToMeshes . RemoveDatasmithElement ( Context ) ;
2021-12-10 17:50:05 -05:00
// Expecting that SketchUp removes material from geometry/instances prior to removing it from the scene, but in case it doesn't...
if ( ! ensure ( MaterialDirectlyAppliedToMeshes . MeshesMaterialDirectlyAppliedTo . IsEmpty ( ) ) )
{
for ( FEntitiesGeometry * Geom : MaterialDirectlyAppliedToMeshes . MeshesMaterialDirectlyAppliedTo . Array ( ) )
{
UnregisterGeometry ( Context , Geom ) ;
}
}
2021-11-07 23:43:01 -05:00
MaterialInheritedByNodes . RemoveDatasmithElement ( Context ) ;
2021-04-08 14:32:07 -04:00
2021-12-10 17:50:05 -05:00
// Expecting that SketchUp removes material from geometry/instances prior to removing it from the scene, but in case it doesn't...
if ( ! ensure ( MaterialInheritedByNodes . NodesMaterialInheritedBy . IsEmpty ( ) ) )
{
for ( FNodeOccurence * Node : MaterialDirectlyAppliedToMeshes . NodesMaterialInheritedBy . Array ( ) )
{
UnregisterInstance ( Context , Node ) ;
}
}
2021-06-07 20:09:45 -04:00
Context . Textures . UnregisterMaterial ( this ) ;
2021-04-08 14:32:07 -04:00
}
2021-03-05 19:27:14 -04:00
2021-09-06 12:23:53 -04:00
void FMaterial : : UpdateTexturesUsage ( FExportContext & Context )
2021-03-05 19:27:14 -04:00
{
2021-09-06 12:23:53 -04:00
if ( ! bInvalidated )
{
return ;
}
2021-04-08 14:32:07 -04:00
2021-06-07 20:09:45 -04:00
if ( Texture )
{
Context . Textures . UnregisterMaterial ( this ) ;
Texture = nullptr ;
}
2021-09-06 12:23:53 -04:00
// todo: extract once(another usage in Update)
FExtractedMaterial ExtractedMaterial ( Context , MaterialRef ) ;
2021-06-07 20:09:45 -04:00
if ( SUIsValid ( ExtractedMaterial . TextureRef ) )
{
Texture = ( ExtractedMaterial . SourceType = = SUMaterialType : : SUMaterialType_ColorizedTexture )
? Context . Textures . AddColorizedTexture ( ExtractedMaterial . TextureRef , ExtractedMaterial . SketchupSourceName )
: Context . Textures . AddTexture ( ExtractedMaterial . TextureRef , ExtractedMaterial . SketchupSourceName ) ;
Context . Textures . RegisterMaterial ( this ) ;
}
2021-09-06 12:23:53 -04:00
}
2021-04-08 14:32:07 -04:00
2021-09-06 12:23:53 -04:00
void FMaterial : : Update ( FExportContext & Context )
2021-11-07 23:43:01 -05:00
{
2021-09-06 12:23:53 -04:00
if ( ! bInvalidated )
{
return ;
}
FExtractedMaterial ExtractedMaterial ( Context , MaterialRef ) ;
EntityId = ExtractedMaterial . SketchupSourceID . EntityID ;
2021-04-08 14:32:07 -04:00
2021-11-07 23:43:01 -05:00
MaterialDirectlyAppliedToMeshes . RemoveDatasmithElement ( Context ) ;
if ( MaterialDirectlyAppliedToMeshes . HasUsers ( ) )
2021-04-08 14:32:07 -04:00
{
2021-11-07 23:43:01 -05:00
MaterialDirectlyAppliedToMeshes . DatasmithElement = CreateMaterialElement ( Context , ExtractedMaterial , * ExtractedMaterial . LocalizedMaterialName , Texture , false ) ;
2021-09-06 12:23:53 -04:00
}
2021-11-07 23:43:01 -05:00
MaterialInheritedByNodes . RemoveDatasmithElement ( Context ) ;
if ( MaterialInheritedByNodes . HasUsers ( ) )
2021-09-06 12:23:53 -04:00
{
2021-11-07 23:43:01 -05:00
MaterialInheritedByNodes . DatasmithElement = CreateMaterialElement ( Context , ExtractedMaterial , * ExtractedMaterial . InheritedMaterialName , Texture , true ) ;
2021-04-08 14:32:07 -04:00
}
2021-11-07 23:43:01 -05:00
FMaterialIDType MaterialId = DatasmithSketchUpUtils : : GetMaterialID ( MaterialRef ) ;
MaterialDirectlyAppliedToMeshes . Apply ( MaterialId ) ;
MaterialInheritedByNodes . Apply ( MaterialId ) ;
2021-03-05 19:27:14 -04:00
2021-09-06 12:23:53 -04:00
bInvalidated = false ;
}
2021-04-08 14:32:07 -04:00
2021-03-05 19:27:14 -04:00
FMaterialOccurrence & FMaterial : : RegisterGeometry ( FEntitiesGeometry * Geom )
{
2021-11-07 23:43:01 -05:00
MaterialDirectlyAppliedToMeshes . RegisterGeometry ( Geom ) ;
if ( MaterialDirectlyAppliedToMeshes . IsInvalidated ( ) )
2021-09-06 12:23:53 -04:00
{
2021-11-07 23:43:01 -05:00
Invalidate ( ) ; // Invalidate material if occurrence is not built
2021-09-06 12:23:53 -04:00
}
2021-11-07 23:43:01 -05:00
return MaterialDirectlyAppliedToMeshes ;
2021-03-05 19:27:14 -04:00
}
2021-11-07 23:43:01 -05:00
void FMaterial : : UnregisterGeometry ( FExportContext & Context , FEntitiesGeometry * Geom )
2021-03-05 19:27:14 -04:00
{
2021-11-07 23:43:01 -05:00
MaterialDirectlyAppliedToMeshes . UnregisterGeometry ( Context , Geom ) ;
2021-03-05 19:27:14 -04:00
}
FMaterialOccurrence & FMaterial : : RegisterInstance ( FNodeOccurence * NodeOccurrence )
{
2021-11-07 23:43:01 -05:00
MaterialInheritedByNodes . RegisterInstance ( NodeOccurrence ) ;
if ( MaterialInheritedByNodes . IsInvalidated ( ) )
2021-09-06 12:23:53 -04:00
{
2021-11-07 23:43:01 -05:00
Invalidate ( ) ; // Invalidate material if occurrence is not built
2021-09-06 12:23:53 -04:00
}
2021-11-07 23:43:01 -05:00
2021-09-27 19:54:25 -04:00
NodeOccurrence - > MaterialOverride = this ;
2021-11-07 23:43:01 -05:00
return MaterialInheritedByNodes ;
2021-03-05 19:27:14 -04:00
}
2021-11-07 23:43:01 -05:00
void FMaterial : : UnregisterInstance ( FExportContext & Context , FNodeOccurence * NodeOccurrence )
2021-09-27 19:54:25 -04:00
{
2021-11-07 23:43:01 -05:00
MaterialInheritedByNodes . UnregisterInstance ( Context , NodeOccurrence ) ;
2021-09-27 19:54:25 -04:00
NodeOccurrence - > MaterialOverride = nullptr ;
}
2021-03-05 19:27:14 -04:00
const TCHAR * FMaterialOccurrence : : GetName ( )
{
2021-09-06 12:23:53 -04:00
if ( ! DatasmithElement )
{
return nullptr ;
}
2021-03-05 19:27:14 -04:00
return DatasmithElement - > GetName ( ) ;
}
2021-11-07 23:43:01 -05:00
void FMaterialOccurrence : : Apply ( FMaterialIDType MaterialId )
{
// Apply material to meshes
for ( FEntitiesGeometry * Geometry : MeshesMaterialDirectlyAppliedTo )
{
//Geometry->SetMaterialElementName(DatasmithSketchUpUtils::GetMaterialID(MaterialRef), MaterialDirectlyAppliedToMeshes->GetName());
for ( const TSharedPtr < FDatasmithInstantiatedMesh > & Mesh : Geometry - > Meshes )
{
if ( int32 * SlotIdPtr = Mesh - > SlotIdForMaterialID . Find ( MaterialId ) )
{
Mesh - > DatasmithMesh - > SetMaterial ( GetName ( ) , * SlotIdPtr ) ;
}
}
}
// Apply material to mesh actors
for ( FNodeOccurence * NodePtr : NodesMaterialInheritedBy )
{
FNodeOccurence & Node = * NodePtr ;
FDefinition * EntityDefinition = Node . Entity . GetDefinition ( ) ;
DatasmithSketchUp : : FEntitiesGeometry & EntitiesGeometry = * EntityDefinition - > GetEntities ( ) . EntitiesGeometry ;
for ( int32 MeshIndex = 0 ; MeshIndex < Node . MeshActors . Num ( ) ; + + MeshIndex )
{
// Update Override(Inherited) Material
// todo: set inherited material only on mesh actors that have faces with default material, right now setting on every mesh, hot harmful but excessive
if ( EntitiesGeometry . IsMeshUsingInheritedMaterial ( MeshIndex ) )
{
const TSharedPtr < IDatasmithMeshActorElement > & MeshActor = Node . MeshActors [ MeshIndex ] ;
// SketchUp has 'material override' only for single('Default') material.
// So we reset overrides on the actor to remove this single override(if it was set) and re-add new override
MeshActor - > ResetMaterialOverrides ( ) ; // Clear previous override if was set
MeshActor - > AddMaterialOverride ( GetName ( ) , EntitiesGeometry . GetInheritedMaterialOverrideSlotId ( ) ) ;
}
}
}
}
2021-09-06 12:23:53 -04:00
void FMaterialOccurrence : : RemoveDatasmithElement ( FExportContext & Context )
{
if ( ! DatasmithElement )
{
return ;
}
Context . DatasmithScene - > RemoveMaterial ( DatasmithElement ) ;
2021-11-07 23:43:01 -05:00
DatasmithElement . Reset ( ) ;
}
bool FMaterialOccurrence : : RemoveUser ( FExportContext & Context )
{
if ( ! ensure ( UserCount ! = 0 ) )
{
return true ;
}
UserCount - - ;
if ( UserCount ! = 0 )
{
return false ;
}
RemoveDatasmithElement ( Context ) ;
return true ;
}
void FMaterialOccurrence : : RegisterGeometry ( FEntitiesGeometry * Geom )
{
if ( ! MeshesMaterialDirectlyAppliedTo . Contains ( Geom ) )
{
MeshesMaterialDirectlyAppliedTo . Add ( Geom ) ;
AddUser ( ) ;
}
}
void FMaterialOccurrence : : UnregisterGeometry ( FExportContext & Context , FEntitiesGeometry * Geom )
{
if ( ! MeshesMaterialDirectlyAppliedTo . Contains ( Geom ) )
{
return ;
}
MeshesMaterialDirectlyAppliedTo . Remove ( Geom ) ;
RemoveUser ( Context ) ;
}
void FMaterialOccurrence : : RegisterInstance ( FNodeOccurence * NodeOccurrence )
{
NodesMaterialInheritedBy . Add ( NodeOccurrence ) ;
AddUser ( ) ;
}
void FMaterialOccurrence : : UnregisterInstance ( FExportContext & Context , FNodeOccurence * NodeOccurrence )
{
NodesMaterialInheritedBy . Remove ( NodeOccurrence ) ;
RemoveUser ( Context ) ;
}
void FMaterialCollection : : Update ( )
{
2021-12-10 17:50:05 -05:00
// Update usage of materials and textures by materials before updating textures(to only update used textures)
TArray < FMaterialIDType > UnusedMaterials ;
2021-11-07 23:43:01 -05:00
for ( TPair < FMaterialIDType , TSharedPtr < DatasmithSketchUp : : FMaterial > > IdAndMaterial : MaterialDefinitionMap )
{
FMaterial & Material = * IdAndMaterial . Value ;
if ( Material . IsUsed ( ) )
{
Material . UpdateTexturesUsage ( Context ) ;
}
2021-12-10 17:50:05 -05:00
else
{
UnusedMaterials . Add ( IdAndMaterial . Key ) ;
}
}
// Remove unused materials(SketchUp material removal notification is unusable but we need to remove unused materials)
for ( FMaterialIDType MaterialId : UnusedMaterials )
{
RemoveMaterial ( MaterialId ) ;
2021-11-07 23:43:01 -05:00
}
Context . Textures . Update ( ) ;
// Update materials after textures are updated - some materials might end up using shared texture(in case it has same contents, which is determined in Textures Update)
for ( TPair < FMaterialIDType , TSharedPtr < FMaterial > > IdAndMaterial : MaterialDefinitionMap )
{
FMaterial & Material = * IdAndMaterial . Value ;
if ( Material . IsUsed ( ) )
{
Material . Update ( Context ) ;
}
}
if ( DefaultMaterial . IsInvalidated ( ) & & DefaultMaterial . HasUsers ( ) )
{
DefaultMaterial . DatasmithElement = FMaterial : : CreateDefaultMaterialElement ( Context ) ;
DefaultMaterial . Apply ( FMaterial : : INHERITED_MATERIAL_ID ) ;
}
}
const TCHAR * FMaterialCollection : : GetDefaultMaterialName ( )
{
return DefaultMaterial . GetName ( ) ;
2021-09-06 12:23:53 -04:00
}