개요
엣지를 분할하여 새로운 정점을 추가하고 새로 추가된 정점에 대해 토폴로지를 재구성한다.

Input
| 타입 | 매개변수 | 설명 |
|---|---|---|
| int | eab | 분할할 엣지 ID |
| double | SplitT | 분할 위치 (0.0=정점A, 0.5=중간, 1.0=정점B) |
엣지 ID와 분할 위치를 입력받는다.
Output
| 타입 | 매개변수 | 설명 |
|---|---|---|
| FEdgeSplitInfo& | SplitInfo | 분할 결과 정보 |
엣지를 분할, FEdgeSplitInfo를 반환한다.
알고리즘
유효성 검사
if ( !IsEdge( eab ) )
{
return EMeshResult::Failed_NotAnEdge;
}
const FEdge Edge = Edges[ eab ];
int a = Edge.Vert[ 0 ], b = Edge.Vert[ 1 ];
int t0 = Edge.Tri[ 0 ];
// 정점 방향 보정 (a,b 순서가 뒤바뀐 경우)
if ( a != Edge.Vert[ 0 ] )
{
split_t = 1.0 - split_t; // t 값 반전
}엣지 ID가 유효한지 확인하고, 정점 순서를 보정한다.
새 정점 생성 및 속성 보간
// 위치 보간
FVector3d vNew = Lerp( GetVertex( a ), GetVertex( b ), split_t );
int f = AppendVertex( vNew );
// 노말 보간 (정규화 필수!)
if ( HasVertexNormals() )
{
SetVertexNormal( f, Normalized( Lerp( GetVertexNormal( a ), GetVertexNormal( b ), (float)split_t ) ) );
}
// 컬러 보간
if ( HasVertexColors() )
{
SetVertexColor( f, Lerp( GetVertexColor( a ), GetVertexColor( b ), (float)split_t ) );
}
// UV 보간
if ( HasVertexUVs() )
{
SetVertexUV( f, Lerp( GetVertexUV( a ), GetVertexUV( b ), (float)split_t ) );
}엣지 상의 위치에 새 정점을 생성하고, 모든 속성을 선형 보간한다. 노말은 정규화가 필수다.
경계 엣지 분할
경계 엣지는 한쪽에만 삼각형이 있는 엣지다.
삼각형 재구성
// 기존 삼각형 수정: t0 = (A, B, C) → (A, F, C)
ReplaceTriangleVertex( t0, b, f );
// 새 삼각형 추가: t2 = (F, B, C)
int t2 = AddTriangleInternal( f, b, c, InvalidID, InvalidID, InvalidID );엣지 재구성
// 원본 엣지를 A-F로 변경
int eaf = eab;
ReplaceEdgeVertex( eaf, b, f );
// 새 엣지 생성
int efb = AddEdgeInternal( f, b, t2 ); // F-B 엣지
int efc = AddEdgeInternal( f, c, t0, t2 ); // F-C 엣지 (t0와 t2 공유)
// 기존 B-C 엣지를 t2에 연결
ReplaceEdgeTriangle( ebc, t0, t2 );내부 엣지 분할
내부 엣지는 양쪽에 삼각형이 있으므로 경계 엣지보다 복잡하다.
반대편 삼각형 정보 가져오기
int t1 = Edges[ eab ].Tri[ 1 ];
FIndex3i T1tv = GetTriangle( t1 );
int d = IndexUtil::FindTriOtherVtx( a, b, T1tv ); // 반대편 정점 D삼각형 재구성
// 기존 삼각형 수정
ReplaceTriangleVertex( t0, b, f ); // t0: (A, B, C) → (A, F, C)
ReplaceTriangleVertex( t1, b, f ); // t1: (B, A, D) → (F, A, D)
// 새 삼각형 추가
int t2 = AddTriangleInternal( f, b, c, ... ); // (F, B, C)
int t3 = AddTriangleInternal( f, d, b, ... ); // (F, D, B)엣지 재구성
// 원본 엣지를 A-F로 변경
int eaf = eab;
ReplaceEdgeVertex( eaf, b, f );
// 새 엣지 생성
int efb = AddEdgeInternal( f, b, t2, t3 ); // F-B (t2와 t3 공유)
int efc = AddEdgeInternal( f, c, t0, t2 ); // F-C (t0와 t2 공유)
int edf = AddEdgeInternal( d, f, t1, t3 ); // D-F (t1과 t3 공유)
// 기존 엣지들의 삼각형 연결 업데이트
ReplaceEdgeTriangle( ebc, t0, t2 ); // B-C는 이제 t2에 속함
ReplaceEdgeTriangle( edb, t1, t3 ); // D-B는 이제 t3에 속함어트리뷰트 업데이트 & 완료
// UV, 노멀 등 오버레이 어트리뷰트 업데이트
if ( HasAttributes() )
{
Attributes()->OnSplitEdge( SplitInfo );
}
// 메시 변경 스탬프 업데이트
UpdateChangeStamps( true, true );
return EMeshResult::Ok;