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,采用本文所述方式进行构建,可以规避这个问题。