개요


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


center



Input


타입매개변수설명
inteab분할할 엣지 ID
doubleSplitT분할 위치 (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;