본문으로 건너뛰기

Cryun's WIKI

FCutWorkingInfo.InsertEdgeVertices()

FCutWorkingInfo.AddSegments()를 통해 분류된 교체 세그먼트들 중에서 엣지 위에 있는 교차 세그먼트를 처리한다.


center

AB엣지상에 있는 교차 세그먼트 P를 기준으로 AP, PB 2개의 엣지로 분할한다.
P의 위치는 엣지 위의 매개변수 t(0~1 범위)로 계산되어 FDynamicMesh3::SplitEdge()를 통해 분할된다.



의사 코드


while ( EdgeVertices.Num() > 0 )
{
    // 엣지 하나 선택
    {
        const auto EIDToPtIdxItr = EdgeVertices.CreateConstIterator();
        EID   = EIDToPtIdxItr.Key();
        PtIdx = EIDToPtIdxItr.Value();
    }
 
    // 같은 엣지에 있는 모든 점 찾기
    TArray< int > PtIndices;
    EdgeVertices.MultiFind( EID, PtIndices );
 
    // 매개변수 t 계산 (0~1 범위)
    FPtOnMesh& Pt = IntersectionVerts[ PtIdx ];
    Mesh->GetEdgeV( EID, EA, EB );
    FSegment3d Seg( EA, EB );
    double SplitParam = Seg.ProjectUnitRange( Pt.Pos );
 
    // SplitEdge 실행 (1개 엣지 → 2개 엣지)
    DynamicMeshInfo::FEdgeSplitInfo SplitInfo;
    Mesh->SplitEdge( EID, SplitInfo, SplitParam );
 
    // 새 정점 위치를 정확한 교차점으로 설정
    Mesh->SetVertex( SplitInfo.NewVertex, Pt.Pos );
 
    // 점 정보 업데이트
    Pt.ElemID = SplitInfo.NewVertex;
    Pt.Type = EVertexType::Vertex;
 
    // 처리 완료된 엣지 제거
    EdgeVertices.Remove( EID );
    FIndex2i SplitEdges{ SplitInfo.OriginalEdge, SplitInfo.NewEdges.A };
 
    // 같은 엣지의 다른 점들 재배치
    if ( PtIndices.Num() > 1 )
    {
        for ( int RelocatePtIdx : PtIndices )
        {
            if ( PtIdx == RelocatePtIdx ) // 이미 처리한 점은 건너뛰기
                continue;
 
            FPtOnMesh& RelocatePt = IntersectionVerts[ RelocatePtIdx ];
 
            // Split으로 생성된 2개 엣지 중 어디에 속하는지 판단
            UpdateFromSplit( RelocatePt, SplitInfo.NewVertex, SplitEdges );
 
            // 재분류된 타입에 따라 해당 컨테이너에 추가
            if ( RelocatePt.Type == EVertexType::Edge )
            {
                EdgeVertices.Add( RelocatePt.ElemID, RelocatePtIdx );
            }
        }
    }
}