这几周真心把我给累到了,突如其来一下子要接收消化那么多新的知识,工作上面要用到的还有我自己感兴趣研究的,基本上周末都没得休息
。不过努力就有收获,这几周没白忙活,工作上面对OCCT的使用已经摸出了点门道。
AutoCAD中的拉伸功能有这几个限制:待拉伸的模型不可以是自相交的(self-intersecting),拉伸出来的模型也不可是自相交的。AutoCAD在基于这两个限制上可对线段,多段线以及面进行拉伸。拉伸可以沿方向(Direction),路径(Path)和锥角(Taper Angle)进行。而在OCCT中它并没有针对拉伸等这些业务层级别的功能进行封装实现,要实现沿方向,路径和锥角进行拉伸,需要用到BRepPrimAPI_MakePrism(沿方向拉伸),BRepOffsetAPI_MakePipe(沿路径拉伸)和BRepOffsetAPI_DraftAngle(根据锥角使模型产生形变)。由于OCCT所有实现的功能都是功能级别上的,这几个类所实现的拉伸的效果是没有AutoCAD中的这几个限制的。下面贴出这几个类的使用示例:
BRepPrimAPI_MakePrism(沿方向拉伸):
TopoDS_Shape makeExtrude(const TopoDS_Shape& oriShape, const gp_Vec& dir)
{
TopoDS_Shape rstShape;
try
{
TopoDS_Shape oriShape1 = oriShape;
if (oriShape1.ShapeType() == TopAbs_WIRE)
oriShape1 = BRepBuilderAPI_MakeFace(TopoDS::Wire(oriShape1));
rstShape = BRepPrimAPI_MakePrism(oriShape1, dir);
}
catch (const Standard_Failure& err)
{
std::cout<<"\nStandard_Failure: "<<err.GetMessageString();
}
catch (...)
{
std::cout<<"\nBRepPrimAPI_MakePrism some unknown errors occur";
}
return rstShape;
}
BRepOffsetAPI_MakePipe(沿路径拉伸):
TopoDS_Shape makeExtrude(const TopoDS_Shape& oriShape)
{
Handle(Geom_TrimmedCurve) arc = GC_MakeArcOfCircle(gp_Pnt(0, 0, 0), gp_Pnt(10, 10, 0), gp_Pnt(0, 20, 0));
Handle(Geom_TrimmedCurve) arc2 = GC_MakeArcOfCircle(gp_Pnt(0, 20, 0), gp_Pnt(-10, 30, 0), gp_Pnt(0, 40, 0));
Handle(Geom_TrimmedCurve) seg = GC_MakeSegment(gp_Pnt(0, 40, 0), gp_Pnt(20, 40, 0));
Handle(Geom_TrimmedCurve) seg1 = GC_MakeSegment(gp_Pnt(20, 40, 0), gp_Pnt(20, 60, 0));
TopoDS_Edge arcEdge = BRepBuilderAPI_MakeEdge(arc);
TopoDS_Edge arcEdge1 = BRepBuilderAPI_MakeEdge(arc2);
TopoDS_Edge segEdge = BRepBuilderAPI_MakeEdge(seg);
TopoDS_Edge segEdge1 = BRepBuilderAPI_MakeEdge(seg1);
TopoDS_Wire arcWire = BRepBuilderAPI_MakeWire(arcEdge, arcEdge1, segEdge/*, segEdge1*/); //return arcWire;
TopoDS_Shape rstShape;
try
{
rstShape = BRepOffsetAPI_MakePipe(arcWire, oriShape);
}
catch (const Standard_Failure& err)
{
std::cout<<"\nStandard_Failure: "<<err.GetMessageString();
}
catch (...)
{
std::cout<<"\nBRepOffsetAPI_MakePipe some unknown error occur";
}
return rstShape;
}
其中这两个类的拉伸规则如下:
还有一个类BRepOffsetAPI_MakePipeShell只能对线框以下的模型进行拉伸,即它最高只能拉伸出shell,而它相对于BRepOffsetAPI_MakePipe有一个较灵活的地方是:它提供了几个方法:
BRepOffsetAPI_MakePipeShell::Add
BRepOffsetAPI_MakePipeShell::SetMode
void BRepOffsetAPI_MakePipeShell::Add ( const TopoDS_Shape & Profile,
const Standard_Boolean WithContact = Standard_False,
const Standard_Boolean WithCorrection = Standard_False
)
void BRepOffsetAPI_MakePipeShell::SetMode ( const gp_Dir & BiNormal )
第一个方法里面有一个参数WithCorrection,当为true时,那么它在做拉伸时,拉伸的面的法向会校正为拉伸路径曲线的切线方向,当为false时,拉伸的面的法向会保持原有的法向不变;第二个方法是设置拉伸面的固定法向,也就是说在拉伸的过程中拉伸面的法向始终保持BiNormal不变。这两个方法不能同时使用!
而BRepOffsetAPI_MakePipe在拉伸的过程是是保持原有的拉伸面的法向不变,这个特征满足AutoCAD中拉伸功能的特征!
还有一个BRepOffsetAPI_DraftAngle(根据锥角使模型产生形变)的示例:
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.*M_PI/180, gp_Pln(gp::XOY()));
}
TopoDS_Shape resultShape = adraft.Shape();
我接下来还要做的一件事就是将它们进行封装,封装成业务层的拉伸功能,下周又是攻坚的一站
,不过这周是真的得好好休息了。。
在执行拉伸功能的时候检测待拉伸的模型是否合法,拉伸后的模型是否合法可使用BRepAlgoAPI_Check,这个类可以检测自干涉(self-interference),也就是自相交(self-intersection)检测。
有了这些类,那么封装拉伸功能基本上可以完成的了!