새로운 엣지 단순화
엣지 단순화 옵션
if ( bSimplifyAlongNewEdges )
{
SimplifyAlongNewEdges( NumMeshesToProcess, CutMesh, CutBoundaryEdges, AllVIDMatches );
}부울 연산으로 생성된 새로운 엣지를 따라 불필요한 정점들을 제거하여 메시를 단순화한다. bSimplifyAlongNewEdges 프로퍼티가 활성화된 경우에만 실행된다.
Difference 연산 처리
삼각형 방향 반전
if ( Operation == EBooleanOp::Difference )
{
// 두 번째 메시의 모든 삼각형을 뒤집기
TArray< int > AllTID;
for ( int TID : CutMesh[ 1 ]->TriangleIndicesItr() )
{
AllTID.Add( TID );
}
FDynamicMeshEditor FlipEditor( CutMesh[ 1 ] );
FlipEditor.ReverseTriangleOrientations( AllTID, true );
}Difference 연산 ( A - B )에서는 B 메시의 내부를 외부로 만들어야 하므로 모든 삼각형의 방향을 뒤집는다.
| 연산 타입 | 처리 | 이유 |
|---|---|---|
| Union, Intersection | 방향 유지 | 두 메시의 방향이 동일 |
| Difference | B 메시 방향 반전 | B의 내부가 외부가 되어야 함 |
두 메시 병합
메시 병합 및 인덱스 매핑
if ( NumMeshesToProcess > 1 )
{
FDynamicMeshEditor Editor( Result );
FMeshIndexMappings IndexMaps;
Editor.AppendMesh( CutMesh[ 1 ], IndexMaps ); // 두 번째 메시를 결과에 추가
if ( bPopulateSecondMeshGroupMap )
{
SecondMeshGroupMap = IndexMaps.GetGroupMap(); // 그룹 매핑 저장
}
}첫 번째 메시 ( CutMesh[ 0 ] )는 이미 Result에 있으므로 두 번째 메시 ( CutMesh[ 1 ] )를 추가로 병합한다.
데이터 구조 설명
| 변수 | 타입 | 설명 |
|---|---|---|
IndexMaps | FMeshIndexMappings | 원래 인덱스와 새 인덱스 간의 매핑 |
SecondMeshGroupMap | 그룹 매핑 | 두 번째 메시의 그룹 정보 매핑 |
엣지 용접 또는 경계 엣지 추적
1. 용접 모드
if ( bWeldSharedEdges )
{
bool bWeldSuccess = MergeEdges( IndexMaps, CutMesh, CutBoundaryEdges, AllVIDMatches );
bSuccess = bSuccess && bWeldSuccess;
}두 메시의 공유 엣지를 하나로 합쳐 물리적으로 연결한다.
2. 비용접 모드
else
{
CreatedBoundaryEdges = CutBoundaryEdges[ 0 ]; // 첫 번째 메시의 경계 엣지
// 두 번째 메시의 경계 엣지를 새 인덱스로 매핑
for ( int OldMeshEID : CutBoundaryEdges[ 1 ] )
{
FIndex2i OtherEV = CutMesh[ 1 ]->GetEdgeV( OldMeshEID ); // 원래 정점 인덱스
int MappedEID = Result->FindEdge
(
IndexMaps.GetNewVertex( OtherEV.A ), // 새 정점 인덱스
IndexMaps.GetNewVertex( OtherEV.B )
);
CreatedBoundaryEdges.Add( MappedEID );
}
}용접하지 않는 경우 경계 엣지를 추적하여 나중에 사용할 수 있도록 저장한다.
처리 모드 비교
| 모드 | 동작 | 용도 |
|---|---|---|
| 용접 모드 | 공유 엣지를 하나로 병합 | 완전히 연결된 단일 메시 생성 |
| 비용접 모드 | 경계 엣지 추적 및 저장 | 경계 정보 유지 필요시 |
특수 연산 처리
NewGroup 연산 경계 엣지 처리
else if ( Operation != EBooleanOp::NewGroupInside &&
Operation != EBooleanOp::NewGroupOutside )
{
CreatedBoundaryEdges = CutBoundaryEdges[ 0 ];
}NewGroupInside / NewGroupOutside 연산은 경계 엣지를 생성하지 않으므로 별도 처리가 필요없다.
새 엣지 추적
생성된 엣지 기록
if ( bTrackAllNewEdges )
{
for ( int32 eid : CreatedBoundaryEdges )
{
AllNewEdges.Add( eid );
}
}부울 연산으로 생성된 모든 새 엣지를 추적한다. bTrackAllNewEdges 프로퍼티가 활성화된 경우에만 실행된다.
공간 변환 복원
원래 좌표계로 복원
if ( bPutResultInInputSpace )
{
MeshTransforms::ApplyTransform( *Result, ResultTransform );
ResultTransform = FTransformSRT3d::Identity();
}계산은 정규화된 좌표계에서 수행되었으므로 결과를 원래 입력 공간으로 다시 변환한다.
| 단계 | 좌표계 | 설명 |
|---|---|---|
| 입력 | 원래 좌표계 | 사용자가 제공한 메시의 좌표계 |
| 처리 | 정규화 좌표계 | 수치 안정성을 위한 정규화된 좌표계 |
| 출력 | 원래 좌표계 | 입력과 동일한 좌표계로 복원 |