這幾周真心把我給累到了,突如其來一下子要接收消化那麼多新的知識,工作上面要用到的還有我自己感興趣研究的,基本上周末都沒得休息
。不過努力就有收獲,這幾周沒白忙活,工作上面對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)檢測。
有了這些類,那麼封裝拉伸功能基本上可以完成的了!