2020-12-03 02:35:44 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# pragma once
# include "MathUtil.h"
2021-06-13 00:35:22 -04:00
# include "DynamicMesh/DynamicMesh3.h"
# include "DynamicMesh/DynamicMeshAttributeSet.h"
2020-12-03 02:35:44 -04:00
namespace UE
{
namespace Geometry
{
2021-09-15 12:50:27 -04:00
/**
* FPolygroupLayer represents a polygroup set on a FDynamicMesh3 , which supports a " default "
* group set stored on the mesh , and then N extended group layers stored in the mesh AttributeSet .
* This struct can represent either .
*/
struct DYNAMICMESH_API FPolygroupLayer
{
/** If true, layer is the default FDynamicMesh3 triangle groups layer */
bool bIsDefaultLayer = true ;
/** If bIsDefaultLayer is false, this is the index of the AttributeSet Polygroup Layer */
int32 LayerIndex = - 1 ;
/** Construct a FPolygroupLayer for the default layer */
static FPolygroupLayer Default ( ) { return FPolygroupLayer { true , - 1 } ; }
/** Construct a FPolygroupLayer for an extended layer */
static FPolygroupLayer Layer ( int32 Index ) { return FPolygroupLayer { false , Index } ; }
2021-09-17 00:33:33 -04:00
bool operator = = ( const FPolygroupLayer & OtherLayer ) const
{
if ( bIsDefaultLayer | | OtherLayer . bIsDefaultLayer )
{
return bIsDefaultLayer & & OtherLayer . bIsDefaultLayer ;
}
else
{
return LayerIndex = = OtherLayer . LayerIndex ;
}
}
2021-09-15 12:50:27 -04:00
/** @return true if the specified layer (default or extended) exist and is initialized on the given Mesh */
bool CheckExists ( const FDynamicMesh3 * Mesh ) ;
} ;
2020-12-03 02:35:44 -04:00
/**
* Polygroup sets can be stored in multiple places . The default location is in the per - triangle group integer stored
* directly on a FDynamicMesh3 . Additional layers may be stored in the FDynamicMeshAttributeSet . Future iterations
* could store packed polygroups in other places , store them in separate arrays , and so on .
* FPolygroupSet can be used to abstract these different cases , by providing a standard Polygroup Get / Set API .
*
* To support unique Polygroup ID allocation , FPolygroupSet calculates the maximum GroupID on creation , and
* updates this maximum across SetGroup ( ) calls . AllocateNewGroupID ( ) can be used to provide new unused GroupIDs .
2021-01-12 17:35:51 -04:00
* For consistency with FDynamicMesh3 , MaxGroupID is set such that all GroupIDs are less than MaxGroupID
2020-12-03 02:35:44 -04:00
*
*/
struct DYNAMICMESH_API FPolygroupSet
{
2021-06-25 01:40:46 -04:00
const FDynamicMesh3 * Mesh = nullptr ;
const FDynamicMeshPolygroupAttribute * PolygroupAttrib = nullptr ;
2020-12-03 02:35:44 -04:00
int32 GroupLayerIndex = - 1 ;
2021-01-12 17:35:51 -04:00
int32 MaxGroupID = 0 ; // Note: all group IDs are less than MaxGroupID
2020-12-03 02:35:44 -04:00
/** Initialize a PolygroupSet for the given Mesh, and standard triangle group layer */
2021-06-25 01:40:46 -04:00
explicit FPolygroupSet ( const FDynamicMesh3 * MeshIn ) ;
2020-12-03 02:35:44 -04:00
2021-09-15 12:50:27 -04:00
/** Initialize a PolygroupSet for the given Mesh, and standard triangle group layer */
explicit FPolygroupSet ( const FDynamicMesh3 * MeshIn , FPolygroupLayer GroupLayer ) ;
2020-12-03 02:35:44 -04:00
/** Initialize a PolygroupSet for given Mesh and specific Polygroup attribute layer */
2021-06-25 01:40:46 -04:00
explicit FPolygroupSet ( const FDynamicMesh3 * MeshIn , const FDynamicMeshPolygroupAttribute * PolygroupAttribIn ) ;
2020-12-03 02:35:44 -04:00
/** Initialize a PolygroupSet for given Mesh and specific Polygroup attribute layer, found by index. If not valid, fall back to standard triangle group layer. */
2021-06-25 01:40:46 -04:00
explicit FPolygroupSet ( const FDynamicMesh3 * MeshIn , int32 PolygroupLayerIndex ) ;
2020-12-03 02:35:44 -04:00
/** Initialize a PolygroupSet for given Mesh and specific Polygroup attribute layer, found by name. If not valid, fall back to standard triangle group layer. */
2021-06-25 01:40:46 -04:00
explicit FPolygroupSet ( const FDynamicMesh3 * MeshIn , FName AttribName ) ;
2020-12-03 02:35:44 -04:00
/** Initialize a PolygroupSet by copying an existing PolygroupSet */
explicit FPolygroupSet ( const FPolygroupSet * CopyIn ) ;
/** @return Mesh this PolygroupSet references */
2021-06-25 01:40:46 -04:00
const FDynamicMesh3 * GetMesh ( ) { return Mesh ; }
2020-12-03 02:35:44 -04:00
/** @return PolygroupAttribute this PolygroupSet references, or null if no PolygroupAttribute is in use */
2021-06-25 01:40:46 -04:00
const FDynamicMeshPolygroupAttribute * GetPolygroup ( ) { return PolygroupAttrib ; }
2020-12-03 02:35:44 -04:00
/** @return index of current PolygroupAttribute into Mesh AttributeSet, or -1 if this information does not exist */
int32 GetPolygroupIndex ( ) const { return GroupLayerIndex ; }
/**
* @ return PolygroupID for a TriangleID
*/
2021-06-25 01:40:46 -04:00
int32 GetGroup ( int32 TriangleID ) const
2020-12-03 02:35:44 -04:00
{
return ( PolygroupAttrib ) ? PolygroupAttrib - > GetValue ( TriangleID ) : Mesh - > GetTriangleGroup ( TriangleID ) ;
}
2021-06-20 16:57:02 -04:00
/**
* @ return PolygroupID for a TriangleID
*/
2021-06-25 01:40:46 -04:00
int32 GetTriangleGroup ( int32 TriangleID ) const
2021-06-20 16:57:02 -04:00
{
return ( PolygroupAttrib ) ? PolygroupAttrib - > GetValue ( TriangleID ) : Mesh - > GetTriangleGroup ( TriangleID ) ;
}
2020-12-03 02:35:44 -04:00
/**
* Set the PolygroupID for a TriangleID
*/
2021-06-25 01:40:46 -04:00
void SetGroup ( int32 TriangleID , int32 NewGroupID , FDynamicMesh3 & WritableMesh )
2020-12-03 02:35:44 -04:00
{
2021-06-25 01:40:46 -04:00
checkSlow ( & WritableMesh = = this - > Mesh ) ; // require the same mesh
if ( WritableMesh . IsTriangle ( TriangleID ) )
2020-12-03 02:35:44 -04:00
{
if ( PolygroupAttrib )
{
2021-06-25 01:40:46 -04:00
FDynamicMeshPolygroupAttribute * WritableGroupAttrib = WritableMesh . Attributes ( ) - > GetPolygroupLayer ( GroupLayerIndex ) ;
checkSlow ( WritableGroupAttrib = = PolygroupAttrib )
WritableGroupAttrib - > SetValue ( TriangleID , NewGroupID ) ;
2020-12-03 02:35:44 -04:00
}
else
{
2021-06-25 01:40:46 -04:00
WritableMesh . SetTriangleGroup ( TriangleID , NewGroupID ) ;
2020-12-03 02:35:44 -04:00
}
}
2021-01-12 17:35:51 -04:00
MaxGroupID = FMath : : Max ( MaxGroupID , NewGroupID + 1 ) ;
2020-12-03 02:35:44 -04:00
}
/**
* Calculate the current maximum PolygroupID used in the active set and store in MaxGroupID member
*/
void RecalculateMaxGroupID ( ) ;
/**
* Allocate a new unused PolygroupID by incrementing the MaxGroupID member
*/
int32 AllocateNewGroupID ( )
{
2021-01-12 17:35:51 -04:00
return MaxGroupID + + ;
2020-12-03 02:35:44 -04:00
}
} ;
} // end namespace Geometry
} // end namespace UE