FCutWorkingInfo.AddSegments()를 통해 분류된 교체 세그먼트들 중에서 삼각형 내부에 있는 교차 세그먼트를 처리한다.

처리는 삼각형 내부의 점 P를 기준으로 하나의 삼각형을 3개의 삼각형으로 분할한다.
P는 무게 중심 좌표로 계산되어 FDynamicMesh3::PokeTriangle()을 통해 분할된다.
하나의 삼각형에 여러개의 교차 세그먼트가 있는 경우
- 첫 번째 점으로
PokeTriangle수행 (1개 → 3개 분할) - 나머지 점들을 새로 생성된 3개 삼각형 중 어디에 속하는지 재분류
UpdateFromPoke를 통해 각 점의 타입(Edge/Face) 재결정- 재분류된 타입에 따라 EdgeVertices 또는 FaceVertices에 다시 추가
의 과정을 거쳐서 처리된다.
의사 코드
while ( FaceVertices.Num() > 0 )
{
// 삼각형 하나 선택
{
const auto TIDToPtIdxItr = FaceVertices.CreateConstIterator();
TID = TIDToPtIdxItr.Key();
PtIdx = TIDToPtIdxItr.Value();
}
// 같은 삼각형에 있는 모든 점 찾기
TArray< int > PtIndices;
FaceVertices.MultiFind( TID, PtIndices );
// 무게중심 좌표 계산
FPtOnMesh& Pt = IntersectionVerts[ PtIdx ];
Mesh->GetTriVertices( TID, Tri.V[ 0 ], Tri.V[ 1 ], Tri.V[ 2 ] );
FVector3d BaryCoords = VectorUtil::BarycentricCoords( Pt.Pos, Tri.V[ 0 ], Tri.V[ 1 ], Tri.V[ 2 ] );
// PokeTriangle 실행 (1개 삼각형 → 3개 삼각형)
DynamicMeshInfo::FPokeTriangleInfo PokeInfo;
Mesh->PokeTriangle( TID, BaryCoords, PokeInfo );
// 새 정점 위치를 정확한 교차점으로 설정
int PokeVID = PokeInfo.NewVertex;
Mesh->SetVertex( PokeVID, Pt.Pos );
// 점 정보 업데이트
Pt.ElemID = PokeVID;
Pt.Type = EVertexType::Vertex;
// 처리 완료된 삼각형 제거
FaceVertices.Remove( TID );
FIndex3i PokeTriangles( TID, PokeInfo.NewTriangles.A, PokeInfo.NewTriangles.B );
// 같은 삼각형의 다른 점들 재배치
if ( PtIndices.Num() > 1 )
{
for ( int RelocatePtIdx : PtIndices )
{
if ( PtIdx == RelocatePtIdx ) // 이미 처리한 점은 건너뛰기
continue;
FPtOnMesh& RelocatePt = IntersectionVerts[ RelocatePtIdx ];
// Poke로 생성된 3개 삼각형 중 어디에 속하는지 판단
UpdateFromPoke( RelocatePt, PokeInfo.NewVertex, PokeInfo.NewEdges, PokeTriangles );
// 재분류된 타입에 따라 해당 컨테이너에 추가
if ( RelocatePt.Type == EVertexType::Edge )
{
EdgeVertices.Add( RelocatePt.ElemID, RelocatePtIdx );
}
else if ( RelocatePt.Type == EVertexType::Face )
{
FaceVertices.Add( RelocatePt.ElemID, RelocatePtIdx );
}
}
}
}