Open CASCADE--Buile Bottle

1.Building the Profile

1.1 Defining Support Points

在Open CASCADE中定义三维笛卡尔坐标系的有两种不同的类:

原始集合gp_Pnt类(生存周期有限,在使用完后被自动销毁)

由句柄控制的Geom_CartesianPoint类(具有较长的生存周期)

两者之间的定义和使用的区别:

gp_Pnt aPnt1(0,0,0);
Handle(Geom_Cartesian_Point) aPnt2=new Geom_CartesianPoint(0,0,0);

Standard_Real xValue=aPnt1.x();
Standard_Real xValue=qPnt2->x();

定义如下四个点:

Standard_Real myHeight = 70, myWidth = 50, myThickness = 30;
	//初始化五个点,由gp_Pnt类型定义。
	gp_Pnt aPnt1(-myWidth / 2., 0, 0); 
	gp_Pnt aPnt2(-myWidth / 2., -myThickness/4., 0);
	gp_Pnt aPnt3(0,-myThickness / 2., 0);
	gp_Pnt aPnt4(myWidth / 2., -myThickness / 4., 0);
	gp_Pnt aPnt5(myWidth / 2., 0, 0);

1.2 Defining the Geometry

定义几何体:由上面定义的五个点来实现:由两个线段和一段弧组成

要创建这样的实体,需要一个特定的数据结构,它实现了3D集合对象。上述结构可以在OCC的Geom包(包是一组提供相关功能的类)中找到。Geom包实现了3D几何对象:提供了基本的曲线和曲面以及更复杂的曲线(Bezier和BSpline)。 Geom_line and Geom_Circle.

但是,Geom包仅仅提供了几何实体的数据结构,可以通过直接实例化类来使用,但可以用更加容易技术基本曲线和曲面的GC包,因为GC提供两个我们所需要的算法:

GC_MakeSegment class:to create a segment。

GC_MakeArcOfCircle class:to create an arc of a circle 。

上述两个类的返回值都是Geom_TrimmedCurve类型的句柄。

//将五个点连接为几何体
Handle(Geom_TrimmedCurve) aArcOfCircle = GC_MakeArcOfCircle(aPnt2, aPnt3, aPnt4);
Handle(Geom_TrimmedCurve) aSegment1 = GC_MakeSegment(aPnt1, aPnt2);
Handle(Geom_TrimmedCurve) aSegment2 = GC_MakeSegment(aPnt4, aPnt5);


//附:所有的GC类都提供了一种类型转换方法,可以通过类似函数调用自动获取结果:IsDone和Value方法:

GC_MakeSegment mkSeg(aPnt1,aPnt2);
Handle(Geom_TrimmedCurve) aSegment1;
if(mkSeg.IsDone())
{
    aSegment1=mkSeg.Value();
    ....
}

1.3 Defining the Topology

1.2中创建了轮廓的一部分几何支撑,但这些曲线是独立的,彼此之间没有关系。为了简化模型,将这三条曲线作为一个整体来操作。通过OCCT中的ToopoDS包的数据结构来实现:他定义了几何实体之间的关系,这些几何实体可以间接在一起来表示复杂的形状,TopoDS包中的每个对象都继承自TopoDS_Shape类,它们所描述的拓扑形状如下所示:

shapeOpen CASCADE ClassDescription
VertexTopoDS_Vertex与几何中的一点相对应的0维形状
EdgeTopoDS_Edge与曲线相对应的一维形状,每个顶点(Vertex)上都有一个端点(extremity)
WireTopoDS_Wire由点(Vertex)连接的按序排好的边。
FaceTopoDS_Face以闭合导线(closed wire)为界的表名的一部分
ShellTopoDS_Shell由边连接的一组面
SolidTopoDS_Solid由shell包围的三维空间的一部分
CompSolidTopoDS_CompSolid由表名连接的Solid的集合
CompoundTopoDS_Compound上面描述的任何其他形状的集合

参考上表,我们可以创建:

          先前计算的曲线三条边(edge)。

           One Wire with these edges.

然而,TopoDS包仅提供拓扑实体的数据结构,可用于计算标准拓扑对象的算法类可以在BRepBuilderAPI包中找到。要创建一天边可以使用BRepBuilderAPI_MakeEdge类和先前计算了的曲线。连接这些边可以使用BRepBuilderAPI_MakeWire类

//定义其拓扑结构
TopoDS_Edge aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1);
TopoDS_Edge aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle);
TopoDS_Edge aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2);
//连接上述三条边
TopoDS_Wire aWire=BRepBuilderAPI_MakeWire(aEdge1,aEdge2,aEdge3);

1.4 Completing the Profile

一旦创建了连接的第一部分,就需要计算完整的概要文件。一种简单的方法是:通过放射(镜像)现有线路来创建新的线路

要对形状(包括导线)转换,首先需要使用gp_Trsf类定义3D几何转换的属性(平移、旋转、缩放、反射或这些的组合)。本例子中,我们需要定于关于坐标系x轴的反射。用gp_Ax1类定义的轴是由点和向量构成的:

方法一:

gp_Pnt aOrigin (0,0,0);//x轴坐落于点(0,0,0)
gp_Dir xDir(1,0,0);//方向向量
gp_Ax1 xAxis(aOrigin,xDir);//x轴

方法二:使用gp包中定义的几何常数(坐标系的原点、主方向和轴),要得到x轴,只需调用gp::OX()

gp_Ax1 xAxis=gp::OX();

在上诉对称轴确定后,需要使用gp_Tfsf类来进行3D几何转换。使用SetMirror方法来确定镜像的对称轴:

gp_Trsf aTrsf;
aTrsf.SetMirror(xAxis);

在完成所有数据的存储后,使用BRepBuilderAPI_Transform类来进行转换。

BRepBuilderAPI_Transform aBRepTrsf(aWire,aTrsf);

BRepBuilderAPI_Transform不会修改形状的性质:镜像的线依然是线。但是BRepBuilderAPI_Transform::Shape方法返回一个TopoDS_Shape对象。接着,通过TopoDS的全局函数将镜像结果的形状转换为导线,使用TopoDS::Wire方法。

TopoDS_Shape aMirrorShape=aBRepTrsf.Shape();//转换为TopoDS_Shape类型
TopoDS_Wire aMirrorWire=TopoDS::Wire(aMirrorShape);

到目前为止已经创建了两个导线:aWire和aMirrorWire.现在需要将这两个导线连接起来计算单个的形状:

首先创建BRepBuilderAPI_MakeWire实例,然后将这两个线通过Add方法加到这个实例中。

BRepBuilderAPI_MakeWire mkWire;
mkWire.Add(aWire);
mkWire.Add(aMirrorWire);
TopoDS_Wire myWireProfile=mkWire.Wire();

2.Building the Body

2.1 Prism the Profile

创建瓶子的主体,可以通过以前创建的概要文件(profile)沿着某一方向进行扫描。利用BRepBuilderAPI_MakeFace类来创建面(面是由闭合曲线包围的表面边界的一部分)

TopoDS_Face myFaceProfile=BRepBuilderAPI_MakeFace(myWireProfile);

利用BRepPrimAPI包提供的BRepPrimAPI_MakePrism类进行扫描,创建几何实体:

gp_Vec aPrismVec(0,0,myHeight);//有向向量:方向和距离
TopoDS_Shape myBody=BRepPrimAPI_MakePrism(myFaceProfile,aPrismVec);//创建实体

2.2 Applying Fillets (倒圆角)

将2.1中的棱柱进行倒圆角操作:应用于所有边、半径为厚度的1/2.

要在棱柱边缘使用Fillet(倒圆角),可以使用BRepFilletAPI_MakeFillet类:

1.在BRepFilletAPI_MakeFillet构造函数中指定要填充的形状

BRepFilletAPI_MakeFillet mkFillet(myBody);

2.使用其Add方法添加fillet的边和半径(可以根据需要添加任意多的边)

而在添加倒角边的时候,需要提前知道所有的边:通过TopExp_Explorer类提供的功能,选取TopoDS_Shape中描述的数据结构,提取指定的子形状。

TopExp_Explorer anEdgeExplorer(myBody,TopAbs_EDGE);//TopAbs_ShapeEnum::TopAbs_EDGE

注:the type of sub-shapes to be found.由TopAbs_ShapeEnum枚举给出。

在所得到的anEdgeExplorer实例中包含三个主要方法:More():是否还存在更多子形状

                                                                                       Current():当前子形状,只有More()为true是可用。

                                                                                       Next():下一个子形状。

While(anEdgeExplorer.More())
{
    TopoDS_Edge anEdge=TopoDS::Edge(anEdgeExplorer.Current));
    mkFillet.Add(myThickness/12.,anEdge);
    anEdge.Next();
}

3. 得到倒角后的瓶身

myBody=mkFillet.Shape();

2.3 Adding the Neck

创建瓶子的颈部,需要先创建一个圆柱体,将其与瓶身融合,圆柱体放置在瓶身的顶部表名,半径为myThickness、4,高度为myHeight/10。

myBody=BRepAlgoAPI_Fuse(myBody,myNeck);

对于该圆柱体的定位,需要一个坐标系。gp_Ax2类从一点和两个方向定义坐标系(主轴z方向和x方向,y方向从这两个方向计算)。法线在z轴上,代码定义如下:

gp_Pnt neckLocation(0,0,myHeight);
gp_Dir neckAxis=gp::DZ();
gp_Ax2 neckAx2(neckLocation,neckAxis)

用BRepPrimAPI_MakeCylinder类来创建圆柱体:

Standard_Real myNeckRadius = myThickness/4.;
Standard_Real myNeckHeight = myHeight/10.;
BRepPrimAPI_MakeCylinder MKCylinder(neckAx2,myNeckRadius,myNeckHeight);
TopoDS_Shape myNeck=MKCylinder.Shape();

到此为止,有两个独立的几何实体:一个瓶身主体,一个需要融合的颈部。可使用BRepAlgoAPI包挺的布尔操作来实现:包括布尔交叉、布尔减法、布尔联合。使用BRepAlgoAPI_Fuse来进行布尔联合操作:

3.4 Creating a Hollowed Solid

将上述的实体瓶子变为空心瓶子

从顶部创造一个中空的实体,BRepOffsetAPI_MakeThickSolid类计算实体厚度

    TopoDS_Face faceToRemove;//选择一个面作为基础几何面
	Standard_Real zMax = -1;//瓶子的最高坐标,后面进行比较替换
//对瓶子的所有面的特征进行迭代。
	for (TopExp_Explorer aFaceExplorer(myBody, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next())
	{
		TopoDS_Face aFace = TopoDS::Face(aFaceExplorer.Current());
		//检查aface是否是瓶子的颈部最上面
		Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace);//对于检测到的面,你需要访问形状的几何属性,为此使用BRep_Tool类
		if (aSurface->DynamicType() == STANDARD_TYPE(Geom_Plane))//类型检测
		{
            //将Geom_Surface类型转换为Geom_Plane类型。
			Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurface);
			gp_Pnt aPnt = aPlane->Location();//获取当前平面坐标点
			Standard_Real aZ = aPnt.Z();
			if (aZ > zMax)
			{
				zMax = aZ;
				faceToRemove = aFace;
			}
		}
	}
    //BRepOffsetAPI_MakeThickSolid以一个面列表为参数,所以使用TopTools_ListOfShape::Append()添加面参数。
	TopTools_ListOfShape facesToRemove;
	facesToRemove.Append(facesToRemove);
	BRepOffsetAPI_MakeThickSolid BodyMaker;
	BodyMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3);
	myBody = BodyMaker.Shape();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值