Open Cascade 采用自顶向下方式创建Box

OpenCASCADE Make Primitives-Box - opencascade - 博客园OpenCASCADE Make Primitives-Box OpenCASCADE Make Primitives-Box - opencascade - 博客园

这篇文章中,作者采用自底向上的方式创建了一个Box,即先从叶子结点出发,逐步回到根结点,即先构造出顶点、边、Wire、Shell、最后到实体。

在学习作者源码基础上,本文尝试采用相反的方式创建了一个Box,即首先创建Solid,然后是Shell、Face、Wire、Edge、Vertex。结果证明本文创建的box.brep与原文作者创建的Box完全相同。

代码附上:

MyMakeBox.h

#pragma once

#include <gp_Pln.hxx>

#include <ElCLib.hxx>
#include <ElSLib.hxx>

#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <Geom2d_Line.hxx>

#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shell.hxx>

#include <BRep_Builder.hxx>
#include <BRepTools.hxx>

#include <vector>

void InitializeGeometryData(double x, double y, double z);

void AddEdgeVertexs();

void SetEdgesPCurve();

void AddWireEdges();

void AddFaceWires();

void AddShellFaces();

TopoDS_Shape MyMakeBox(double x, double y, double z); 

MyMakeBox.cpp

#include "MyMakeBox.h"

//geometry data
gp_Pnt aPoints[8];
gp_Lin aLines[12];
gp_Pln aPlanes[6];

//topology data
TopoDS_Vertex aVertices[8];
TopoDS_Edge aEdges[12];
TopoDS_Wire aWires[6];
TopoDS_Face aFaces[6];
TopoDS_Shell aShell;
TopoDS_Solid aSolid;

//BRep_Builder
BRep_Builder aBuilder;

void InitializeGeometryData(double x, double y, double z)
{
    aPoints[0] = gp_Pnt(0.0, 0.0, 0.0);
    aPoints[1] = gp_Pnt(x, 0.0, 0.0);
    aPoints[2] = gp_Pnt(x, y, 0.0);
    aPoints[3] = gp_Pnt(0.0, y, 0.0);
    aPoints[4] = gp_Pnt(0.0, 0.0, z);
    aPoints[5] = gp_Pnt(x, 0.0, z);
    aPoints[6] = gp_Pnt(x, y, z);
    aPoints[7] = gp_Pnt(0.0, y, z);


    aLines[0] = gp_Lin(aPoints[0], gp::DX());
    aLines[1] = gp_Lin(aPoints[1], gp::DY());
    aLines[2] = gp_Lin(aPoints[3], gp::DX());
    aLines[3] = gp_Lin(aPoints[0], gp::DY());
    aLines[4] = gp_Lin(aPoints[4], gp::DX());
    aLines[5] = gp_Lin(aPoints[5], gp::DY());
    aLines[6] = gp_Lin(aPoints[7], gp::DX());
    aLines[7] = gp_Lin(aPoints[4], gp::DY());
    aLines[8] = gp_Lin(aPoints[0], gp::DZ());
    aLines[9] = gp_Lin(aPoints[1], gp::DZ());
    aLines[10] = gp_Lin(aPoints[2], gp::DZ());
    aLines[11] = gp_Lin(aPoints[3], gp::DZ());


    aPlanes[0] = gp_Pln(aPoints[0], gp::DZ()); // bottom
    aPlanes[1] = gp_Pln(aPoints[4], gp::DZ()); // top
    aPlanes[2] = gp_Pln(aPoints[0], gp::DY()); // front
    aPlanes[3] = gp_Pln(aPoints[3], gp::DY()); // back
    aPlanes[4] = gp_Pln(aPoints[0], gp::DX()); // left
    aPlanes[5] = gp_Pln(aPoints[1], gp::DX());  // right

    return;
}

void AddEdgeVertexs()
{
    aBuilder.MakeVertex(aVertices[0], aPoints[0], Precision::Confusion());
    aBuilder.MakeVertex(aVertices[1], aPoints[1], Precision::Confusion());
    aBuilder.MakeVertex(aVertices[2], aPoints[2], Precision::Confusion());
    aBuilder.MakeVertex(aVertices[3], aPoints[3], Precision::Confusion());
    aBuilder.MakeVertex(aVertices[4], aPoints[4], Precision::Confusion());
    aBuilder.MakeVertex(aVertices[5], aPoints[5], Precision::Confusion());
    aBuilder.MakeVertex(aVertices[6], aPoints[6], Precision::Confusion());
    aBuilder.MakeVertex(aVertices[7], aPoints[7], Precision::Confusion());

    // set the vertex info of the edges.
// edge 0:
    {
        TopoDS_Vertex V1 = aVertices[0];
        TopoDS_Vertex V2 = aVertices[1];

        V2.Reverse();
        //顶点的朝向(orientation)属性,没有直接的几何意义,但是根据约定,若顶点的朝向属性值为TopAbs_FORWARD,
        //它就必须与表示边的曲线的参数值小的端部匹配。相应地,TopAbs_REVERSED的顶点与参数值大的端部匹配

        aBuilder.Add(aEdges[0], V1);
        aBuilder.Add(aEdges[0], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[0], aPoints[0]), aEdges[0], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[0], aPoints[1]), aEdges[0], Precision::Confusion());
        //ElCLib::Parameter : Computes the parameter value of the point P on the given curve.

        BRepTools::Update(aEdges[0]);//Update an edge, compute 2d bounding boxes.
    }

    // edge 1:
    {
        TopoDS_Vertex V1 = aVertices[1];
        TopoDS_Vertex V2 = aVertices[2];

        V2.Reverse();

        aBuilder.Add(aEdges[1], V1);
        aBuilder.Add(aEdges[1], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[1], aPoints[1]), aEdges[1], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[1], aPoints[2]), aEdges[1], Precision::Confusion());

        BRepTools::Update(aEdges[1]);
    }

    // edge 2:
    {
        TopoDS_Vertex V1 = aVertices[3];
        TopoDS_Vertex V2 = aVertices[2];

        V2.Reverse();

        aBuilder.Add(aEdges[2], V1);
        aBuilder.Add(aEdges[2], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[2], aPoints[3]), aEdges[2], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[2], aPoints[2]), aEdges[2], Precision::Confusion());

        BRepTools::Update(aEdges[2]);
    }

    // edge 3:
    {
        TopoDS_Vertex V1 = aVertices[0];
        TopoDS_Vertex V2 = aVertices[3];

        V2.Reverse();

        aBuilder.Add(aEdges[3], V1);
        aBuilder.Add(aEdges[3], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[3], aPoints[0]), aEdges[3], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[3], aPoints[3]), aEdges[3], Precision::Confusion());

        BRepTools::Update(aEdges[3]);
    }

    // edge 4:
    {
        TopoDS_Vertex V1 = aVertices[4];
        TopoDS_Vertex V2 = aVertices[5];

        V2.Reverse();

        aBuilder.Add(aEdges[4], V1);
        aBuilder.Add(aEdges[4], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[4], aPoints[4]), aEdges[4], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[4], aPoints[5]), aEdges[4], Precision::Confusion());

        BRepTools::Update(aEdges[4]);
    }

    // edge 5:
    {
        TopoDS_Vertex V1 = aVertices[5];
        TopoDS_Vertex V2 = aVertices[6];

        V2.Reverse();

        aBuilder.Add(aEdges[5], V1);
        aBuilder.Add(aEdges[5], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[5], aPoints[5]), aEdges[5], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[5], aPoints[6]), aEdges[5], Precision::Confusion());

        BRepTools::Update(aEdges[5]);
    }

    // edge 6:
    {
        TopoDS_Vertex V1 = aVertices[7];
        TopoDS_Vertex V2 = aVertices[6];

        V2.Reverse();

        aBuilder.Add(aEdges[6], V1);
        aBuilder.Add(aEdges[6], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[6], aPoints[7]), aEdges[6], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[6], aPoints[6]), aEdges[6], Precision::Confusion());

        BRepTools::Update(aEdges[6]);
    }

    // edge 7:
    {
        TopoDS_Vertex V1 = aVertices[4];
        TopoDS_Vertex V2 = aVertices[7];

        V2.Reverse();

        aBuilder.Add(aEdges[7], V1);
        aBuilder.Add(aEdges[7], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[7], aPoints[4]), aEdges[7], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[7], aPoints[7]), aEdges[7], Precision::Confusion());

        BRepTools::Update(aEdges[7]);
    }

    // edge 8:
    {
        TopoDS_Vertex V1 = aVertices[0];
        TopoDS_Vertex V2 = aVertices[4];

        V2.Reverse();

        aBuilder.Add(aEdges[8], V1);
        aBuilder.Add(aEdges[8], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[8], aPoints[0]), aEdges[8], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[8], aPoints[4]), aEdges[8], Precision::Confusion());

        BRepTools::Update(aEdges[8]);
    }

    // edge 9:
    {
        TopoDS_Vertex V1 = aVertices[1];
        TopoDS_Vertex V2 = aVertices[5];

        V2.Reverse();

        aBuilder.Add(aEdges[9], V1);
        aBuilder.Add(aEdges[9], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[9], aPoints[1]), aEdges[9], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[9], aPoints[5]), aEdges[9], Precision::Confusion());

        BRepTools::Update(aEdges[9]);
    }

    // edge 10:
    {
        TopoDS_Vertex V1 = aVertices[2];
        TopoDS_Vertex V2 = aVertices[6];

        V2.Reverse();

        aBuilder.Add(aEdges[10], V1);
        aBuilder.Add(aEdges[10], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[10], aPoints[2]), aEdges[10], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[10], aPoints[6]), aEdges[10], Precision::Confusion());

        BRepTools::Update(aEdges[10]);
    }

    // edge 11:
    {
        TopoDS_Vertex V1 = aVertices[3];
        TopoDS_Vertex V2 = aVertices[7];

        V2.Reverse();

        aBuilder.Add(aEdges[11], V1);
        aBuilder.Add(aEdges[11], V2);

        aBuilder.UpdateVertex(V1, ElCLib::Parameter(aLines[11], aPoints[3]), aEdges[11], Precision::Confusion());
        aBuilder.UpdateVertex(V2, ElCLib::Parameter(aLines[11], aPoints[7]), aEdges[11], Precision::Confusion());

        BRepTools::Update(aEdges[11]);
    }
    return;
}

void SetEdgesPCurve()
{
    // set bottom pcurve info of between the edge and surface.
    {
        // pcurve 0:
        double u = 0.0;
        double v = 0.0;
        double du = 0.0;
        double dv = 0.0;

        gp_Dir DX = aPlanes[0].XAxis().Direction();
        gp_Dir DY = aPlanes[0].YAxis().Direction();

        ElSLib::Parameters(aPlanes[0], aLines[0].Location(), u, v);
        //ElSLib::Parameters:求第二个参数点P在第一个参数gp_Pln上的u、v参数。
        //parametrization P (U, V) = Pl.Location() + U * Pl.XDirection() + V * Pl.YDirection()

        du = aLines[0].Direction() * DX;//向量点乘,线的方向向量点乘X轴方向向量
        dv = aLines[0].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[0], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[0], Precision::Confusion());
        //UpdateEdge:Sets a pcurve for the edge on the face. 
        //Geom2d_Line (const gp_Pnt2d &P, const gp_Dir2d &V):Constructs a line passing through point P and parallel to 
        //  vector V (P and V are, respectively, the origin and the unit vector of the positioning axis of the line).



        // pcurve 1:
        ElSLib::Parameters(aPlanes[0], aLines[1].Location(), u, v);
        du = aLines[1].Direction() * DX;
        dv = aLines[1].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[1], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[0], Precision::Confusion());

        // pcurve 2:
        ElSLib::Parameters(aPlanes[0], aLines[2].Location(), u, v);
        du = aLines[2].Direction() * DX;
        dv = aLines[2].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[2], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[0], Precision::Confusion());

        // pcurve 3:
        ElSLib::Parameters(aPlanes[0], aLines[3].Location(), u, v);
        du = aLines[3].Direction() * DX;
        dv = aLines[3].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[3], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[0], Precision::Confusion());
    }

    // set top pcurve info of between the edge and surface.
    {
        // pcurve 0:
        double u = 0.0;
        double v = 0.0;
        double du = 0.0;
        double dv = 0.0;

        gp_Dir DX = aPlanes[1].XAxis().Direction();
        gp_Dir DY = aPlanes[1].YAxis().Direction();

        ElSLib::Parameters(aPlanes[1], aLines[4].Location(), u, v);
        du = aLines[4].Direction() * DX;
        dv = aLines[4].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[4], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[1], Precision::Confusion());

        // pcurve 1:
        ElSLib::Parameters(aPlanes[1], aLines[5].Location(), u, v);
        du = aLines[5].Direction() * DX;
        dv = aLines[5].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[5], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[1], Precision::Confusion());

        // pcurve 2:
        ElSLib::Parameters(aPlanes[1], aLines[6].Location(), u, v);
        du = aLines[6].Direction() * DX;
        dv = aLines[6].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[6], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[1], Precision::Confusion());

        // pcurve 3:
        ElSLib::Parameters(aPlanes[1], aLines[7].Location(), u, v);
        du = aLines[7].Direction() * DX;
        dv = aLines[7].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[7], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[1], Precision::Confusion());
    }

    // set front pcurve info of between the edge and surface.
    {
        // pcurve 0:
        double u = 0.0;
        double v = 0.0;
        double du = 0.0;
        double dv = 0.0;

        gp_Dir DX = aPlanes[2].XAxis().Direction();
        gp_Dir DY = aPlanes[2].YAxis().Direction();

        ElSLib::Parameters(aPlanes[2], aLines[0].Location(), u, v);
        du = aLines[0].Direction() * DX;
        dv = aLines[0].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[0], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[2], Precision::Confusion());

        // pcurve 1:
        ElSLib::Parameters(aPlanes[2], aLines[9].Location(), u, v);
        du = aLines[9].Direction() * DX;
        dv = aLines[9].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[9], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[2], Precision::Confusion());

        // pcurve 2:
        ElSLib::Parameters(aPlanes[2], aLines[4].Location(), u, v);
        du = aLines[4].Direction() * DX;
        dv = aLines[4].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[4], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[2], Precision::Confusion());

        // pcurve 3:
        ElSLib::Parameters(aPlanes[2], aLines[8].Location(), u, v);
        du = aLines[8].Direction() * DX;
        dv = aLines[8].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[8], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[2], Precision::Confusion());
    }

    // set back pcurve info of between the edge and surface.
    {
        // pcurve 0:
        double u = 0.0;
        double v = 0.0;
        double du = 0.0;
        double dv = 0.0;

        gp_Dir DX = aPlanes[3].XAxis().Direction();
        gp_Dir DY = aPlanes[3].YAxis().Direction();

        ElSLib::Parameters(aPlanes[3], aLines[2].Location(), u, v);
        du = aLines[2].Direction() * DX;
        dv = aLines[2].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[2], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[3], Precision::Confusion());

        // pcurve 1:
        ElSLib::Parameters(aPlanes[3], aLines[10].Location(), u, v);
        du = aLines[10].Direction() * DX;
        dv = aLines[10].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[10], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[3], Precision::Confusion());

        // pcurve 2:
        ElSLib::Parameters(aPlanes[3], aLines[6].Location(), u, v);
        du = aLines[6].Direction() * DX;
        dv = aLines[6].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[6], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[3], Precision::Confusion());

        // pcurve 3:
        ElSLib::Parameters(aPlanes[3], aLines[11].Location(), u, v);
        du = aLines[11].Direction() * DX;
        dv = aLines[11].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[11], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[3], Precision::Confusion());
    }

    // set left pcurve info of between the edge and surface.
    {
        // pcurve 0:
        double u = 0.0;
        double v = 0.0;
        double du = 0.0;
        double dv = 0.0;

        gp_Dir DX = aPlanes[4].XAxis().Direction();
        gp_Dir DY = aPlanes[4].YAxis().Direction();

        ElSLib::Parameters(aPlanes[4], aLines[3].Location(), u, v);
        du = aLines[3].Direction() * DX;
        dv = aLines[3].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[3], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[4], Precision::Confusion());

        // pcurve 1:
        ElSLib::Parameters(aPlanes[4], aLines[11].Location(), u, v);
        du = aLines[11].Direction() * DX;
        dv = aLines[11].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[11], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[4], Precision::Confusion());

        // pcurve 2:
        ElSLib::Parameters(aPlanes[4], aLines[7].Location(), u, v);
        du = aLines[7].Direction() * DX;
        dv = aLines[7].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[7], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[4], Precision::Confusion());

        // pcurve 3:
        ElSLib::Parameters(aPlanes[4], aLines[8].Location(), u, v);
        du = aLines[8].Direction() * DX;
        dv = aLines[8].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[8], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[4], Precision::Confusion());
    }

    // set right pcurve info of between the edge and surface.
    {
        // pcurve 0:
        double u = 0.0;
        double v = 0.0;
        double du = 0.0;
        double dv = 0.0;

        gp_Dir DX = aPlanes[5].XAxis().Direction();
        gp_Dir DY = aPlanes[5].YAxis().Direction();

        ElSLib::Parameters(aPlanes[5], aLines[1].Location(), u, v);
        du = aLines[1].Direction() * DX;
        dv = aLines[1].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[1], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[5], Precision::Confusion());

        // pcurve 1:
        ElSLib::Parameters(aPlanes[5], aLines[10].Location(), u, v);
        du = aLines[10].Direction() * DX;
        dv = aLines[10].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[10], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[5], Precision::Confusion());

        // pcurve 2:
        ElSLib::Parameters(aPlanes[5], aLines[5].Location(), u, v);
        du = aLines[5].Direction() * DX;
        dv = aLines[5].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[5], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[5], Precision::Confusion());

        // pcurve 3:
        ElSLib::Parameters(aPlanes[5], aLines[9].Location(), u, v);
        du = aLines[9].Direction() * DX;
        dv = aLines[9].Direction() * DY;

        aBuilder.UpdateEdge(aEdges[9], new Geom2d_Line(gp_Lin2d(gp_Pnt2d(u, v), gp_Dir2d(du, dv))), aFaces[5], Precision::Confusion());
    }

    return;
}

void AddWireEdges()
{
    aBuilder.MakeEdge(aEdges[0], new Geom_Line(aLines[0]), Precision::Confusion());
    aBuilder.MakeEdge(aEdges[1], new Geom_Line(aLines[1]), Precision::Confusion());
    aBuilder.MakeEdge(aEdges[2], new Geom_Line(aLines[2]), Precision::Confusion());
    aBuilder.MakeEdge(aEdges[3], new Geom_Line(aLines[3]), Precision::Confusion());

    aBuilder.MakeEdge(aEdges[4], new Geom_Line(aLines[4]), Precision::Confusion());
    aBuilder.MakeEdge(aEdges[5], new Geom_Line(aLines[5]), Precision::Confusion());
    aBuilder.MakeEdge(aEdges[6], new Geom_Line(aLines[6]), Precision::Confusion());
    aBuilder.MakeEdge(aEdges[7], new Geom_Line(aLines[7]), Precision::Confusion());

    aBuilder.MakeEdge(aEdges[8], new Geom_Line(aLines[8]), Precision::Confusion());
    aBuilder.MakeEdge(aEdges[9], new Geom_Line(aLines[9]), Precision::Confusion());
    aBuilder.MakeEdge(aEdges[10], new Geom_Line(aLines[10]), Precision::Confusion());
    aBuilder.MakeEdge(aEdges[11], new Geom_Line(aLines[11]), Precision::Confusion());

    SetEdgesPCurve();

    AddEdgeVertexs();

    //add edge to the wire.
    // wire 1: bottom
    {
        TopoDS_Edge E1 = aEdges[0];
        TopoDS_Edge E2 = aEdges[1];
        TopoDS_Edge E3 = aEdges[2];
        TopoDS_Edge E4 = aEdges[3];

        E3.Reverse();
        E4.Reverse();

        aBuilder.Add(aWires[0], E1);
        aBuilder.Add(aWires[0], E2);
        aBuilder.Add(aWires[0], E3);
        aBuilder.Add(aWires[0], E4);

        BRepTools::Update(aWires[0]);//Update a wire (nothing is done)
    }

    // wire 2: top
    {
        TopoDS_Edge E1 = aEdges[4];
        TopoDS_Edge E2 = aEdges[5];
        TopoDS_Edge E3 = aEdges[6];
        TopoDS_Edge E4 = aEdges[7];

        E3.Reverse();
        E4.Reverse();

        aBuilder.Add(aWires[1], E1);
        aBuilder.Add(aWires[1], E2);
        aBuilder.Add(aWires[1], E3);
        aBuilder.Add(aWires[1], E4);

        BRepTools::Update(aWires[1]);
    }

    // wire 3: front
    {
        TopoDS_Edge E1 = aEdges[0];
        TopoDS_Edge E2 = aEdges[9];
        TopoDS_Edge E3 = aEdges[4];
        TopoDS_Edge E4 = aEdges[8];

        E1.Reverse();
        E2.Reverse();

        aBuilder.Add(aWires[2], E1);
        aBuilder.Add(aWires[2], E2);
        aBuilder.Add(aWires[2], E3);
        aBuilder.Add(aWires[2], E4);

        BRepTools::Update(aWires[2]);
    }

    // wire 4: back
    {
        TopoDS_Edge E1 = aEdges[2];
        TopoDS_Edge E2 = aEdges[10];
        TopoDS_Edge E3 = aEdges[6];
        TopoDS_Edge E4 = aEdges[11];

        E1.Reverse();
        E2.Reverse();

        aBuilder.Add(aWires[3], E1);
        aBuilder.Add(aWires[3], E2);
        aBuilder.Add(aWires[3], E3);
        aBuilder.Add(aWires[3], E4);

        BRepTools::Update(aWires[3]);
    }

    // wire 5: left
    {
        TopoDS_Edge E1 = aEdges[3];
        TopoDS_Edge E2 = aEdges[11];
        TopoDS_Edge E3 = aEdges[7];
        TopoDS_Edge E4 = aEdges[8];

        E3.Reverse();
        E4.Reverse();

        aBuilder.Add(aWires[4], E1);
        aBuilder.Add(aWires[4], E2);
        aBuilder.Add(aWires[4], E3);
        aBuilder.Add(aWires[4], E4);

        BRepTools::Update(aWires[4]);
    }

    // wire 6: right
    {
        TopoDS_Edge E1 = aEdges[1];
        TopoDS_Edge E2 = aEdges[10];
        TopoDS_Edge E3 = aEdges[5];
        TopoDS_Edge E4 = aEdges[9];

        E3.Reverse();
        E4.Reverse();

        aBuilder.Add(aWires[5], E1);
        aBuilder.Add(aWires[5], E2);
        aBuilder.Add(aWires[5], E3);
        aBuilder.Add(aWires[5], E4);

        BRepTools::Update(aWires[5]);
    }


    return;
}

void AddFaceWires()
{
    aBuilder.MakeWire(aWires[0]);
    aBuilder.MakeWire(aWires[1]);
    aBuilder.MakeWire(aWires[2]);
    aBuilder.MakeWire(aWires[3]);
    aBuilder.MakeWire(aWires[4]);
    aBuilder.MakeWire(aWires[5]);

    AddWireEdges();

    //add wires to the face.
    aBuilder.Add(aFaces[0], aWires[0]);
    aBuilder.Add(aFaces[1], aWires[1]);
    aBuilder.Add(aFaces[2], aWires[2]);
    aBuilder.Add(aFaces[3], aWires[3]);
    aBuilder.Add(aFaces[4], aWires[4]);
    aBuilder.Add(aFaces[5], aWires[5]);

    return;
}

void AddShellFaces()
{
    aBuilder.MakeFace(aFaces[0], new Geom_Plane(aPlanes[0]), Precision::Confusion());
    aBuilder.MakeFace(aFaces[1], new Geom_Plane(aPlanes[1]), Precision::Confusion());
    aBuilder.MakeFace(aFaces[2], new Geom_Plane(aPlanes[2]), Precision::Confusion());
    aBuilder.MakeFace(aFaces[3], new Geom_Plane(aPlanes[3]), Precision::Confusion());
    aBuilder.MakeFace(aFaces[4], new Geom_Plane(aPlanes[4]), Precision::Confusion());
    aBuilder.MakeFace(aFaces[5], new Geom_Plane(aPlanes[5]), Precision::Confusion());

    AddFaceWires();

    // add faces to the shell.
    {
        TopoDS_Face F1 = aFaces[0];
        TopoDS_Face F2 = aFaces[1];
        TopoDS_Face F3 = aFaces[2];
        TopoDS_Face F4 = aFaces[3];
        TopoDS_Face F5 = aFaces[4];
        TopoDS_Face F6 = aFaces[5];

        F1.Reverse();
        F3.Reverse();
        F5.Reverse();

        aBuilder.Add(aShell, F1);
        aBuilder.Add(aShell, F2);
        aBuilder.Add(aShell, F3);
        aBuilder.Add(aShell, F4);
        aBuilder.Add(aShell, F5);
        aBuilder.Add(aShell, F6);
    }

    aShell.Closed(BRep_Tool::IsClosed(aShell));//Sets the closedness flag.
    BRepTools::Update(aShell);//Update a shell (nothing is done)

    return;
}

TopoDS_Shape MyMakeBox(double x, double y, double z)
{
    //1. geomrtry data
    InitializeGeometryData(x,y,z);

    //TopoDS_Solid
    aBuilder.MakeSolid(aSolid);

    //TopoDS_Shell
    aBuilder.MakeShell(aShell);

    AddShellFaces();

    //std::cout << "aShell is Free ? " << aShell.Free() << std::endl;
    aBuilder.Add(aSolid, aShell);
    //std::cout << "aShell is Free ? " << aShell.Free() << std::endl;

    return aSolid;
}

main.cpp

#include <iostream>
#include "MyMakeBox.h"

#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepCheck_Analyzer.hxx>

int main()
{
    TopoDS_Shape aBox = MakeBox(1.0, 2.0, 3.0);

    TopoDS_Shape myBox = MyMakeBox(1.0, 2.0, 3.0);

    //BRepCheck
    //BRepCheck_Analyzer analyzer(aBox);
    //std::cout << "analyzer.IsValid() = " << analyzer.IsValid() << std::endl;

    BRepCheck_Analyzer analyzer(myBox);
    std::cout << "analyzer.IsValid() = " << analyzer.IsValid() << std::endl;

    BRepTools::Dump(myBox, std::cout);
    BRepTools::Write(myBox, "D:\\myBox.brep");

    return 0;
}

需要说明的是,BRep_Builder的Add(TopoDS_Shape &S, const TopoDS_Shape &C) 方法执行后,Shape C就会 not Free,即变为FrozenShape,不再可以添加TopoDS_Shape,采用本文所述方式进行构建,可以规避这个问题。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值