본문으로 바로가기

OCC의 BRepBuilderAPI_Copy는 B-Rep 형상을 복사할 때 기본적으로 형상의 Topology와 Geometry를 완전히 복사함. 하지만 텐셀레이션 정보(Poly_Triangulation)와 에지 정보(PolygonOnTriangulation)에 대해서는 다음과 복사해야 함.

void CopyTriangulationAndEdgePolygons(const TopoDS_Shape& shape, TopoDS_Shape& copied_shape) 
{
    BRep_Builder builder;

    // Face 일치 쌍 목록 생성
    std::vector<std::pair<TopoDS_Face, TopoDS_Face>> face_pairs;
    {
        TopExp_Explorer expSrc(shape, TopAbs_FACE);
        TopExp_Explorer expDst(copied_shape, TopAbs_FACE);
        for (; expSrc.More() && expDst.More(); expSrc.Next(), expDst.Next()) {
            TopoDS_Face srcFace = TopoDS::Face(expSrc.Current());
            TopoDS_Face dstFace = TopoDS::Face(expDst.Current());
            face_pairs.push_back({srcFace, dstFace});
            // Triangulation 복사 (사실상 BRepBuilderAPI_Copy에서도 복사됨)
            TopLoc_Location srcLoc = srcFace.Location();
            Handle(Poly_Triangulation) srcTri = BRep_Tool::Triangulation(srcFace, srcLoc);
            if (!srcTri.IsNull()) {
                Handle(Poly_Triangulation) dstTri = Handle(Poly_Triangulation)::DownCast(srcTri->Copy());
                builder.UpdateFace(dstFace, dstTri);
            }
        }
    }

    // Edge 매핑 (원본 <--> 복사본)
    TopTools_IndexedMapOfShape srcEdges, dstEdges;
    TopExp::MapShapes(shape, TopAbs_EDGE, srcEdges);
    TopExp::MapShapes(copied_shape, TopAbs_EDGE, dstEdges);

    // Face별로 Edge에 대해서만 PolygonOnTriangulation 복사
    for (size_t i = 0; i < face_pairs.size(); ++i) {
        const TopoDS_Face& srcFace = face_pairs[i].first;
        const TopoDS_Face& dstFace = face_pairs[i].second;

        TopLoc_Location srcLoc = srcFace.Location();
        TopLoc_Location dstLoc = dstFace.Location();
        Handle(Poly_Triangulation) srcTri = BRep_Tool::Triangulation(srcFace, srcLoc);
        Handle(Poly_Triangulation) dstTri = BRep_Tool::Triangulation(dstFace, dstLoc);

        if (srcTri.IsNull() || dstTri.IsNull()) continue;

        for (TopExp_Explorer expEdge(srcFace, TopAbs_EDGE); expEdge.More(); expEdge.Next()) {
            TopoDS_Edge srcEdge = TopoDS::Edge(expEdge.Current());
            int edgeIdx = srcEdges.FindIndex(srcEdge);
            if (edgeIdx < 1 || edgeIdx > dstEdges.Extent()) continue;
            TopoDS_Edge dstEdge = TopoDS::Edge(dstEdges(edgeIdx));

            Handle(Poly_PolygonOnTriangulation) srcPoly = BRep_Tool::PolygonOnTriangulation(srcEdge, srcTri, srcLoc);
            if (!srcPoly.IsNull()) {
                Handle(Poly_PolygonOnTriangulation) dstPoly = Handle(Poly_PolygonOnTriangulation)::DownCast(srcPoly->Copy());
                builder.UpdateEdge(dstEdge, dstPoly, dstTri, dstLoc);
            }
        }
    }
}

'블로그 (Blog) > 개발로그 (Devlogs)' 카테고리의 다른 글

qCompress를 이용한 스트링 압축/해제  (0) 2025.07.09
Qt + Tk  (0) 2025.07.05
Crow  (0) 2025.07.01
PySide6용 컬러 선택 위젯  (0) 2025.06.30
업무 정리 위키 프로그램  (0) 2025.06.24