Open CASCADE基础介绍(2)
一些OCC的基础知识,愿与各位OCC爱好者共同学习;mail:<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />tongabcd@yeah.net
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
一:关于体的类
BRepBuilderAPI_MakeVertex类
创建点;
BRepBuilderAPI_MakeEdge类
此类用来创建边;
比如,由直线生成边:
gp_Lin line(gp_Ax1(gp_Pnt(10,10,10),gp_Dir(1,0,0)));
WhiteEdge = BRepBuilderAPI_MakeEdge(line,-20,10);
下面为生成四分之一园边:
gp_Elips Elips(gp_Ax2(gp_Pnt(10,0,0),gp_Dir(1,1,1)),60,30);
RedEdge = BRepBuilderAPI_MakeEdge(Elips,0,PI/2);
下面是由曲线生成边:
Handle (Geom_BezierCurve) curve = new Geom_BezierCurve(array);
BRepBuilderAPI_MakeEdge ME (curve);
GreenEdge = ME;
V3 = ME.Vertex1();
V4 = ME.Vertex2();
BRepBuilderAPI_MakeWire类
用来创建一个Wire类;
用一个Wire和一个边来生成一个新的Wire:
ExistingWire = BRepBuilderAPI_MakeWire(Edge2);
Edge3 = BRepBuilderAPI_MakeEdge(gp_Pnt(-300,0,-80),gp_Pnt(-90,20,-30));
BRepBuilderAPI_MakeWire MW1(ExistingWire,Edge3);
if (MW1.IsDone()) {YellowWire = MW1;}
用一个Wire和添加边的方法来生成Wire:
BRepBuilderAPI_MakeWire MW;
MW.Add(ExistingWire2);
MW.Add(Edge5);
MW.Add(Edge6);
MW.Add(Edge7);
if (MW.IsDone()) {
WhiteWire = MW.Wire();
LastEdge = MW.Edge();
LastVertex = MW.Vertex();
}
BRepBuilderAPI_MakeFace类
生成一个面;有多种生成面的方法;
--通过一个封闭曲线生成面:
BRepBuilderAPI_MakeFace(curve);
--通过一个Wire生成面:
BrownFace = BRepBuilderAPI_MakeFace(YellowWire);
Bnd_Box2d类:
定义一个二维空间的边界盒,可以得出边界盒各个点的值,有时,在某个方向是无限大,这种情况下,称为在此方向上是开放的;
示例:
Bnd_Box2d aCBox;
Geom2dAdaptor_Curve GACC (C);
BndLib_Add2dCurve::Add (GACC,Precision::Approximation(),aCBox);
Bnd_Box类:
定义一个三维空间的边界盒,可以扩大或缩小边界盒,也可以合并两个轴对齐边界盒;
BRepPrimAPI_MakeBox类
用来生成一个立方体;
构造一个立方体可以是两个对角点,一个角点及三个方向长度,可以是非轴对称的:
TopoDS_Shape B2 = BRepPrimAPI_MakeBox (gp_Ax2(gp_Pnt(-200.,-80.,-70.), gp_Dir(1.,2.,1.)), 80.,90.,120.);
使用方法
TopoDS_Face& BottomFace() ;.可以得到立方体的底面;同样,用其它类似的方法可以获得顶面等;
方法TopoDS_Solid& Solid() ;可以将box转化为一个Solid;
方法TopoDS_Shell& Shell() ;可以将box转化为一个shell;
BRepPrimAPI_MakeCylinder类
用来生成一个园柱体或园柱体的一部分;
比如:
TopoDS_Shape C2 = BRepPrimAPI_MakeCylinder (gp_Ax2(gp_Pnt(200.,0.,200.), gp_Dir(0.,1.,0.)),40.,110.,210.*PI180);
BRepPrimAPI_MakeCone类
生成一个园锥或园锥的一部分;
BRepPrimAPI_MakeSphere类
生成球体或球体的一部分,可以是U方向切一部分或V方向切一部分;
BRepPrimAPI_MakeTorus类
生成环或环的一部分;
BRepPrimAPI_MakeWedge类
生成一个楔块或楔块的一部分;
BRepPrimAPI_MakePrism类
生成一个线性的swept,称为Prisms;它的基类是BRepPrimAPI_MakeSweep类;BRepPrimAPI_MakeSweep类的基类是
BRepBuilderAPI_MakeShape类
注意,原始基本图形不可以包含任何实体:
应用此类时:
--顶点“推移”成边:
TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(gp_Pnt(-200.,-200.,0.));
Handle(AIS_Shape) ais1 = new AIS_Shape(V1);
TopoDS_Shape S1 = BRepPrimAPI_MakePrism(V1,gp_Vec(0.,0.,100.));
Handle(AIS_Shape) ais2 = new AIS_Shape(S1);
--边“推移”成面:.
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(gp_Pnt(-150.,-150,0.), gp_Pnt(-50.,-50,0.));
Handle(AIS_Shape) ais3 = new AIS_Shape(E);
myAISContext->Display(ais3,Standard_False);
TopoDS_Shape S2 = BRepPrimAPI_MakePrism(E,gp_Vec(0.,0.,100.));
--Wires “推移”成Shells.
TopoDS_Edge E1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0.,0.,0.), gp_Pnt(50.,0.,0.));
TopoDS_Edge E2 = BRepBuilderAPI_MakeEdge(gp_Pnt(50.,0.,0.), gp_Pnt(50.,50.,0.));
TopoDS_Edge E3 = BRepBuilderAPI_MakeEdge(gp_Pnt(50.,50.,0.), gp_Pnt(0.,0.,0.));
TopoDS_Wire W = BRepBuilderAPI_MakeWire(E1,E2,E3);
TopoDS_Shape S3 = BRepPrimAPI_MakePrism(W,gp_Vec(0.,0.,100.));
--Faces “推移”成Solids.
TopoDS_Face F = BRepBuilderAPI_MakeFace(gp_Pln(gp::XOY()),Wc);
Handle(AIS_Shape) ais7 = new AIS_Shape(F);
myAISContext->Display(ais7,Standard_False);
TopoDS_Shape S4 = BRepPrimAPI_MakePrism(F,gp_Vec(0.,0.,100.));
--Shells “推移”成复合实体
BRepPrimAPI_MakeRevol类
一个回转sweep体;
类继承关系和前面类似:BRepBuilderAPI_MakeShape--〉BRepPrimAPI_MakeSweep-->BRepPrimAPI_MakeRevol
,对于角度而言,范围是[0,2PI],默认值是2PI,生成规则:
- Vertex -> Edge.
- Edge -> Face.
- Wire -> Shell.
- Face-> Solid.
- Shell-> CompSolid.
BRepOffsetAPI_MakePipe类
可以生成一个管道
类继承关系是:BRepBuilderAPI_MakeShape--〉BRepPrimAPI_MakeSweep-->BRepOffsetAPI_MakePipe
以下为生成一个管道的示例过程:
--利用生成一个WIRE,作为管道的路径:
Handle(Geom_BezierCurve) curve = new Geom_BezierCurve(CurvePoles);
TopoDS_Edge E = BRepBuilderAPI_MakeEdge(curve);
TopoDS_Wire W = BRepBuilderAPI_MakeWire(E);
--生成一个面,作为生成管道的截面:
gp_Circ c = gp_Circ(gp_Ax2(gp_Pnt(0.,0.,0.),gp_Dir(0.,1.,0.)),10.);
TopoDS_Edge Ec = BRepBuilderAPI_MakeEdge(c);
TopoDS_Wire Wc = BRepBuilderAPI_MakeWire(Ec);
TopoDS_Face F = BRepBuilderAPI_MakeFace(gp_Pln(gp::ZOX()),Wc);
--利用前两步生成的路径和截面来生成pipe:
TopoDS_Shape S = BRepOffsetAPI_MakePipe(W,F);
Handle(AIS_Shape) ais2 = new AIS_Shape(S);
BRepOffsetAPI_ThruSections类
此类继承自BRepBuilderAPI_MakeShape:创建一个loft,通过一组给定的sections,生成一个shell或一个solid;通常,section是wire;但是第一个和最后一个section可以是
vertices;
比如:
BRepOffsetAPI_ThruSections generator(Standard_False,Standard_True);
generator.AddWire(W1);
generator.AddWire(W2);
generator.AddWire(W3);
generator.AddWire(W4);
generator.Build();
TopoDS_Shape S1 = generator.Shape();
Handle(AIS_Shape) ais1 = new AIS_Shape(S1);
BRepBuilderAPI_MakePolygon类
创建一个polygonal wires,可以通过一组点或向量生成,也可以先生成一个空的对象,再添加点。
示例1:
BRepBuilderAPI_MakePolygon P;
P.Add(gp_Pnt(0.,0.,0.));
P.Add(gp_Pnt(200.,0.,0.));
P.Add(gp_Pnt(200.,200.,0.));
P.Add(gp_Pnt(0.,200.,0.));
P.Add(gp_Pnt(0.,0.,0.));
TopoDS_Wire W = P.Wire();
示例2:
TopoDS_Wire wprof = BRepBuilderAPI_MakePolygon(gp_Pnt(0.,0.,0.),gp_Pnt(-60.,-60.,-200.));
BRepOffsetAPI_MakeEvolved类
创建一个可展图形,它是通过一个planar spine (face or wire)和一个rofile (wire)来生成的,它是一个非循环的sweep (pipe),用profile沿着spline;自相交点将被移除;
比如:
--沿着一个spline,sweep一个profile;
Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spine,const TopoDS_Wire& Profil,const GeomAbs_JoinType Join = GeomAbs_Arc,const Standard_Boolean
AxeProf = Standard_True,const Standard_Boolean Solid = Standard_False,const Standard_Boolean ProfOnSpine = Standard_False,const Standard_Real Tol = 0.0000001);
AxeProf参数如果为true,R是0,X,Y,Z;如果solid为真,结果为一个solid或复合的solids;
示例:
TopoDS_Shape
S = BRepOffsetAPI_MakeEvolved(W,wprof,GeomAbs_Arc,Standard_True,Standard_False,Standard_True,0.0001);
BRepBuilderAPI_ModifyShape类
当使用BRepTools来创建一个修改类,主要有以下派生类:
--BRepBuilderAPI_Copy:处理一个图形的拷贝;
--BRepBuilderAPI_Transform 和BRepBuilderAPI_GTransform:用来对一个图形应用几何变形;
--BRepBuilderAPI_NurbsConvert:用来将一个图形转化为NURBS几何体;
--BRepOffsetAPI_DraftAngle:创建一个tapered图形;
BRepOffsetAPI_DraftAngle类
创建一个tapered图形;一般过程是:
--初始化构造算法;
--输入要taper的特征面;
--实现算法;
--生成结果;
示例:
TopoDS_Shape S = BRepPrimAPI_MakeBox(200.,300.,150.);
BRepOffsetAPI_DraftAngle adraft(S);
TopExp_Explorer Ex;
for (Ex.Init(S,TopAbs_FACE); Ex.More(); Ex.Next()) {
TopoDS_Face F = TopoDS::Face(Ex.Current());
Handle(Geom_Plane) surf = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(F));
gp_Pln apln = surf->Pln();
gp_Dir dirF = apln.Axis().Direction();
if (dirF.IsNormal(gp_Dir(0.,0.,1.),Precision::Angular()))
adraft.Add(F, gp_Dir(0.,0.,1.), 15.*PI180, gp_Pln(gp::XOY()));
}
ais1->Set(adraft.Shape());
二:关于布尔等实体修改操作相关
BRepAlgoAPI_BooleanOperation类
此类的基类是BRepBuilderAPI_MakeShape类,它是一个抽象类;
可以应用的操作有:BOP_SECTION 、BOP_COMMON、BOP_FUSE、BOP_CUT、BOP_CUT21
有时会产生错误,无法达到想要的结果,根据返回值,可以得到错误信息,含义是:
0:OK
1: 对象创建完成,但结果为空;
2:源图形为空;
3:参数类型检查错误;
4:不能为DSFiller分配内存;
5:此种类型参数的Builder无法工作;
6:不允许的操作;
7:不能为Builder分配内存;
>100 参见Builder错误信息;
相关的方法介绍:
--TopTools_ListOfShape& SectionEdges()方法:返回一组截面的边,它们在布尔操作过程中生成;
--Standard_Boolean HasDeleted()方法:如果至少一个图形对象被删除了,返回为真;
--Standard_Boolean HasGenerated()方法:如果至少生成了一个图形,返回为真;
--Standard_Boolean HasModified()方法:如果至少一个图形被修改了,返回为真;
--TopTools_ListOfShape& Generated(const TopoDS_Shape& S) 方法:返回生成以后的图形的集合;
--TopTools_ListOfShape& Modified2(const TopoDS_Shape& aS)方法:返回修改后的图形的集合;
--Standard_Boolean IsDeleted(const TopoDS_Shape& aS)方法:如果图形S已经被删除,返回为真,即结果图形中不包括图形S;
-BOP_Operation Operation()方法:返回布尔操作的类型;
布尔操作类
包括有BRepAlgoAPI_Cut类, BRepAlgoAPI_Fuse类,BRepAlgoAPI_Common类:布尔交集;
BRepAlgoAPI_Section类
计算两个图形或几何体的截面,几何对象可以是平面的表面,转化为face.
示例:
给定两个图形S1和S2,计算在S1和S2上的边,在新曲线上生成近似值,结果在第一部分上而不在第二部分上:
Standard_Boolean PerformNow = Standard_False;
BRepBoolAPI_Section S(S1,S2,PerformNow);
S.ComputePCurveOn1(Standard_True);
S.Approximation(Standard_True);
S.Build();
TopoDS_Shape R = S.Shape();
如果结果为空,调用NotDone();
常见方法:
--BRepAlgoAPI_Section(const Handle(Geom_Surface)& Sf1,const Handle(Geom_Surface)& Sf2,const Standard_Boolean
PerformNow = Standard_True);
用来生成线:
--两个图形SH1和SH2;
--图形SH和平面P1;
--表面SF和图形SH;
--两个表面SF1和SF2;
参数PerformNow如果为真,将直接计算结果,如果为假,表示后面将通过Build()这个函数来计算结果;
生成后的图形是由方法Shape()得出的;
这些相交的边是独立的,不在一个链表上,也不在一个wire上,如果不存在一个相交边,返回结果为空;
示例:
--计算相交的基本边--利用这些基本边创建一个相交线--决定相交线在两个图形的哪个图形的参数空间;
TopoDS_Shape S1 = ... , S2 = ... ;
Standard_Boolean PerformNow = Standard_False;
BRepAlgoAPI_Section S ( S1, S2, PerformNow );
S.ComputePCurveOn1 (Standard_True);
S.Approximation (Standard_True);
S.Build();
TopoDS_Shape R = S.Shape();
BRepFilletAPI_LocalOperation类
基类是BRepBuilderAPI_MakeShape;
构造在一个shell的边的园角;常用方法有
--void Add(const TopoDS_Edge& E) = 0;在builder上添加一个轮廓线;
--void ResetContour(const Standard_Integer IC) = 0;重置索引为IC的轮廓线;
--Standard_Integer NbContours() const = 0;返回轮廓线的数目;
--Standard_Integer Contour(const TopoDS_Edge& E) const = 0;返回边E的轮廓线的索引,如果边E不在轮廓线内,返回为O;
--Standard_Integer NbEdges(const Standard_Integer I) const = 0;返回在轮廓线I中的边数;
--void Remove(const TopoDS_Edge& E) = 0;移除一个边;
--Standard_Real Length(const Standard_Integer IC) const = 0;得到某个轮廓线的长度;
--TopoDS_Vertex FirstVertex(const Standard_Integer IC) const = 0;返回某个轮廓线的第一个顶点;LastVertex方法返回最后一个顶点;
--Abscissa方法,返回某个顶点的横坐标;
--Standard_Boolean ClosedAndTangent(const Standard_Integer IC) const如果某个轮廓线是封闭切线,返回为真;
--Standard_Boolean Closed(const Standard_Integer IC) const = 0;如果某个轮廓线是封闭,返回为真;
--Reset() = 0;重置所有;
BRepFilletAPI_MakeFillet类
创建一个园角;
示例一:
对一个BOX园角:
BRepFilletAPI_MakeFillet fillet(Box);
for (TopExp_Explorer ex(Box,TopAbs_EDGE); ex.More(); ex.Next()) {
TopoDS_Edge Edge =TopoDS::Edge(ex.Current());
fillet.Add(20,Edge);
}
示例二:
两个BOX,合并后园角;
TopoDS_Shape fusedShape = BRepAlgoAPI_Fuse(S1,S2);
BRepFilletAPI_MakeFillet fill(fusedShape);
for (TopExp_Explorer ex1(fusedShape,TopAbs_EDGE); ex1.More(); ex1.Next()) {
TopoDS_Edge E =TopoDS::Edge(ex1.Current());
fill.Add(E);
}
for (Standard_Integer i = 1;i<=fill.NbContours();i++) {
Standard_Real longueur(fill.Length(i));
Standard_Real Rad(0.15*longueur);
fill.SetRadius(Rad,i, 1);
}
TopoDS_Shape blendedFusedSolids = fill.Shape();
Handle(AIS_Shape) aBlend = new AIS_Shape(blendedFusedSolids);
示例三:
只园角其中一条边:
BRepFilletAPI_MakeFillet Rake(theBox);
TopExp_Explorer ex(theBox,TopAbs_EDGE);
ex.Next();
ex.Next();
ex.Next();
ex.Next();
Rake.Add(8,50,TopoDS::Edge(ex.Current()));
Rake.Build();
if (Rake.IsDone() ){
TopoDS_Shape evolvedBox = Rake.Shape();
ais1->Set(evolvedBox);
}
示例四:
园角一个园柱:
BRepFilletAPI_MakeFillet fillet(theCylinder);
TColgp_Array1OfPnt2d TabPoint2(1,20);
for (Standard_Integer i=0; i<=19; i++) {
gp_Pnt2d Point2d(i*2*PI/19,60*cos(i*PI/19-PI/2)+10);
TabPoint2.SetValue(i+1,Point2d);
}
TopExp_Explorer exp2(theCylinder,TopAbs_EDGE);
fillet.Add(TabPoint2,TopoDS::Edge(exp2.Current()));
fillet.Build();
if (fillet.IsDone() ){
TopoDS_Shape LawEvolvedCylinder = fillet.Shape();
ais3->Set(LawEvolvedCylinder);
myAISContext->Redisplay(ais3,Standard_False);
myAISContext->SetCurrentObject(ais3,Standard_False);
}
BRepFilletAPI_MakeChamfer类
创建一个倒角;
基类:BRepFilletAPI_LocalOperation;
可以设置相关参数,比如倒角两个距离,角度等参数;
示例:
BRepFilletAPI_MakeChamfer MC(theBox);
// add all the edges to chamfer
TopTools_IndexedDataMapOfShapeListOfShape M;
TopExp::MapShapesAndAncestors(theBox,TopAbs_EDGE,TopAbs_FACE,M);
for (Standard_Integer i = 1;i<=M.Extent();i++) {
TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First());
MC.Add(5,5,E,F);
}
BRepBuilderAPI_MakeShell类
生成一个表面的外壳,注意,一个图形的外壳,不是一个由表面和厚度定义的实体模型,如果想要创建这种壳,需要使用BRepOffsetAPI_MakeOffsetShape,一个外壳是由一系列相互通过普通的边连接起来的面;如果表面是C2连续的,外壳将只有一个面;如果表面不是C2连续的,将把一些面细分成所有的面都是C2连续的,结果是外壳包含所有这些面;通过一个非C2连续的表面来生成一个外壳,一般过程是:--构造一个外壳对象--实现算法--生成结果;
注意:表面分解的这些C2面并没有缝合在一起,需要使用BRepOffsetAPI_Sewing,如果想实现带厚度的外壳,需要使用BRepOffsetAPI_MakeOffsetShape类;