天天看點

OpenCascade 入門須知API

Tutorial簡述

gp_XXX
Standard_XXX
Geom_XXX
GC_MakeXXX
TopoDS_XXX
BRepBuilderAPI_XXX
BRepPrimAPI_XXX
BRepFilletAPI_XXX
TopExp_Explorer
TopAbs_ShapeEnum
BRepAlgoAPI_XXX
BRep_Tool與 Standard_Transient
TopTools_XXX
BRepOffsetAPI_XXX
           

Tutorial簡述

Tutorial用一個繪制Bottle的例子描述了OCC模組化的基本步驟。這裡涉及了一些概念和類的用法,不細心看做筆記是很容易忘掉的。

gp_XXX

gp_Pnt 是最簡單的“點”;此外對應的有還有許多這樣的簡單結構,這些類從其類名就可以知道它可能有哪些參數,沒錯,這些類包含了點、線、面、軸以及各種曲面等,其中的參數都是建構這些幾何結構必須的參數,我們可以稱gp_Pnt這一類的類為基本幾何類。

- gp_Ax2 
- gp_Ax2d 
- gp_Ax3 
- gp_Ax3d 
- gp_Ax22 
- gp_Ax22d 
- gp_Circ 
- gp_Circ2d 
- gp_Cone 
- gp_Cylinder 
- gp_Dir 
- gp_Dir2d 
- gp_Elips 
- gp_Elips2d 
- gp_EulerSequence 
- gp_GTrsf 
- gp_GTrsf2d 
- gp_Hypr 
- gp_Hypr2d 
- gp_Lin 
- gp_Lin2d 
- gp_Mat 
- gp_Mat2d 
- gp_Parab 
- gp_Parab2d 
- gp_Pln 
- gp_Pnt2d 
- gp_Quaternion 
- gp_QuaternionNLerp 
- gp_QuaternionSLerp 
- gp_Sphere 
- gp_Torus 
- gp_Trsf 
- gp_Trsf2d 
- gp_TrsfForm 
- gp_TrsfNLerp 
- gp_Vec 
- gp_Vec2d 
- gp_VectorWithNullMagnitude 
- gp_XY 
- gp_XYZ
           

Geom_XXX

Geom定義了幾何資料結構,但也僅此而已,并不包含什麼算法,可以說它是由gp_XXX建構而成的資料結構,比gp_XXX進階一些。我們可以稱其為建構幾何類。

Geom_Axis1Placement 
Geom_Axis2Placement 
Geom_AxisPlacement 
Geom_BezierCurve 
Geom_BezierSurface 
Geom_BoundedCurve 
Geom_BoundedSurface 
Geom_BSplineCurve 
Geom_BSplineSurface 
Geom_CartesianPoint 
Geom_Circle 
Geom_Conic 
……
           

Standard_XXX

Standard_XXX類型的類是OCC的類型定義、宏定義的資料結構,與我們常用的C++沒有差別的,我們可以稱其為OCC定義數值類型。

#define Standard_False false
#define Standard_True  true
typedef int           Standard_Integer;
typedef double        Standard_Real;
typedef bool          Standard_Boolean;
typedef float         Standard_ShortReal;
typedef char          Standard_Character;
typedef unsigned char Standard_Byte;
typedef void*         Standard_Address;
typedef size_t        Standard_Size;
typedef std::time_t   Standard_Time;
 
// Unicode primitives, char16_t, char32_t
typedef char          Standard_Utf8Char;     //!< signed   UTF-8 char
typedef unsigned char Standard_Utf8UChar;    //!< unsigned UTF-8 char
           

Geom_XXX

Geom定義了幾何資料結構,但也僅此而已,并不包含什麼算法,可以說它是由gp_XXX建構而成的資料結構,比gp_XXX進階一些。我們可以稱其為建構幾何類。

Geom_Axis1Placement 
Geom_Axis2Placement 
Geom_AxisPlacement 
Geom_BezierCurve 
Geom_BezierSurface 
Geom_BoundedCurve 
Geom_BoundedSurface 
Geom_BSplineCurve 
Geom_BSplineSurface 
Geom_CartesianPoint 
Geom_Circle 
Geom_Conic 
……
           

GC_MakeXXX

GC_MakeXXX由簡單的幾何資料結構建構複雜的、常見的、帶參數的幾何結構Geom_XXX,它主要包含的就是建構算法,我們可以稱其為幾何形狀建構包,建構的結果是指向Geom_XXX的指針。

GC_MakeArcOfCircle 
GC_MakeArcOfEllipse 
GC_MakeArcOfHyperbola 
GC_MakeArcOfParabola 
GC_MakeCircle 
GC_MakeConicalSurface 
GC_MakeCylindricalSurface 
GC_MakeEllipse 
GC_MakeHyperbola. 
GC_MakeLine 
GC_MakeMirror 
GC_MakePlane 
GC_MakeRotation 
GC_MakeScale 
GC_MakeSegment 
GC_MakeTranslation 
GC_MakeTrimmedCone 
GC_MakeTrimmedCylinder 
GC_Root
 
Handle(Geom_TrimmedCurve) aArcOfCircle = GC_MakeArcOfCircle(aPnt2,aPnt3,aPnt4);
           

TopoDS_XXX

TopoDS_XXX比Geom_XXX再高一級,是多個Geom_XXX的一種組合。每一個TopoDS_XXX類都繼承至TopoDS_Shape。我們可以稱這一層為幾何拓撲結構。包含了拓撲點、線、面、體等簡單的、複雜的幾何拓撲結構。注意:這層也隻是資料結構,并不包含算法。

TopoDS_AlertWithShape 
TopoDS_Builder 
TopoDS_Compound 
TopoDS_CompSolid 
TopoDS_Edge 
TopoDS_Face 
TopoDS_FrozenShape 
TopoDS_HShape 
TopoDS_Iterator 
TopoDS_ListIteratorOfListOfShape 
TopoDS_ListOfShape 
TopoDS_LockedShape 
TopoDS_Shape 
TopoDS_Shell 
TopoDS_Solid 
TopoDS_TCompound 
TopoDS_TCompSolid 
TopoDS_TEdge 
TopoDS_TFace 
TopoDS_TShape 
TopoDS_TShell 
TopoDS_TSolid 
TopoDS_TVertex 
TopoDS_TWire 
TopoDS_UnCompatibleShapes 
TopoDS_Vertex 
TopoDS_Wire
           

BRepBuilderAPI_XXX

前邊說了TopoDS_XXX隻是資料結構,那麼如何由Geom_XXX建構TopoDS_XXX呢,這就是BRepBuilderAPI_XXX的工作了。我們可以稱這一層為拓撲結構建構包。它的傳回值直接就是TopoDS_XXX。

此外這一部分有好多需要注意的事項:

通過矩陣變換擷取拓撲結構

通過向下轉型(TopoDS::XXX)擷取拓撲結構

通過TopoDS的組合擷取TopoDS結構

也就是說:這一步驟相當于使用一個CAD、SolidWorks等的造型軟體。熟悉造型的功能,想必更熟悉這部分要完成的工作。

BRepBuilderAPI_BndBoxTreeSelector 
BRepBuilderAPI_CellFilter 
BRepBuilderAPI_Collect 
BRepBuilderAPI_Command 
BRepBuilderAPI_Copy 
BRepBuilderAPI_EdgeError 
BRepBuilderAPI_FaceError 
BRepBuilderAPI_FastSewing 
BRepBuilderAPI_FindPlane 
BRepBuilderAPI_GTransform 
BRepBuilderAPI_MakeEdge 
BRepBuilderAPI_MakeEdge2d 
BRepBuilderAPI_MakeFace 
BRepBuilderAPI_MakePolygon 
BRepBuilderAPI_MakeShape 
BRepBuilderAPI_MakeShell 
BRepBuilderAPI_MakeSolid 
BRepBuilderAPI_MakeVertex 
BRepBuilderAPI_MakeWire 
BRepBuilderAPI_ModifyShape 
BRepBuilderAPI_NurbsConvert 
BRepBuilderAPI_PipeError 
BRepBuilderAPI_Sewing 
BRepBuilderAPI_ShapeModification 
BRepBuilderAPI_ShellError 
BRepBuilderAPI_Transform 
BRepBuilderAPI_TransitionMode 
BRepBuilderAPI_VertexInspector 
BRepBuilderAPI_WireError
 
TopoDS_Edge aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1); 
TopoDS_Edge aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle); 
TopoDS_Edge aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2);
           

BRepPrimAPI_XXX

這一層包的功能是把之前的拓撲結建構立成實體,它們建構的結果當然也是拓撲結果的TopoDS_XXX。我們可以稱這一層為實體建構包,拓撲建構滿足以下的規律:

OpenCascade 入門須知API
BRepPrimAPI_MakeBox 
BRepPrimAPI_MakeCone 
BRepPrimAPI_MakeCylinder 
BRepPrimAPI_MakeHalfSpace 
BRepPrimAPI_MakeOneAxis 
BRepPrimAPI_MakePrism 
BRepPrimAPI_MakeRevol 
BRepPrimAPI_MakeRevolution 
BRepPrimAPI_MakeSphere 
BRepPrimAPI_MakeSweep 
BRepPrimAPI_MakeTorus 
BRepPrimAPI_MakeWedge
           

BRepFilletAPI_XXX

倒角包:計算倒角。

BRepFilletAPI_LocalOperation 
BRepFilletAPI_MakeChamfer 
BRepFilletAPI_MakeFillet 
BRepFilletAPI_MakeFillet2d
           

TopExp_Explorer

這個類比較特殊,專門用于TopoDS_XXX的解析的,就是将已知實體(拓撲結構)解析為邊組合、面組合等等。我們可以稱其為拓撲解析包。

for(TopExp_Explorer aFaceExplorer(myBody, TopAbs_FACE) ; aFaceExplorer.More() ; aFaceExplorer.Next())
{ 
    TopoDS_Face aFace = TopoDS::Face(aFaceExplorer.Current()); 
}
           

TopAbs_ShapeEnum

這也是一個特殊的結構,類似一個拓撲結構的數組,具有.More().Next().Current()三個重要的方法,我們可以稱其為拓撲解析結果集。

BRepAlgoAPI_XXX

這個是核心算法包,專門用于Shape的交common(Boolean intersection)、差cut(Boolean subtraction)、和fuse(Boolean union)的計算。底層采用的是布爾操作。我們可以稱其為幾何算法包。

BRepAlgoAPI_Algo 
BRepAlgoAPI_BooleanOperation 
BRepAlgoAPI_BuilderAlgo 
BRepAlgoAPI_Check 
BRepAlgoAPI_Common 
BRepAlgoAPI_Cut 
BRepAlgoAPI_Defeaturing 
BRepAlgoAPI_Fuse 
BRepAlgoAPI_Section 
BRepAlgoAPI_Splitter
           

**BRep_Tool **

這個BRep_Tool類主要有三個方法,用于從TopoDS_XXX向Geom_XXX轉換。

TopoDS_Face -> Geom_Surface 
TopoDS_Edge -> Geom_Curve 
TopoDS_Vertex -> Geom_Point 
           

Standard_Transient

主要有兩個用途。:

DynamicType 函數用來擷取 Handle(Geom_Surface)的真實類型,因為Geom_Surface有可能是任何一種面。

IsKind 用來判斷該類型是否是某個類的子類。

Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace);
 
if(aSurface->DynamicType() == STANDARD_TYPE(Geom_Plane))
{ 
    Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurface);
    //
}
           

TopTools_XXX

組。List,Array,Sequence等。

TopTools_Array1OfListOfShape 
TopTools_Array1OfShape 
TopTools_Array2OfShape 
TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape 
TopTools_DataMapIteratorOfDataMapOfIntegerShape 
……
           

BRepOffsetAPI_XXX

非常有用的包,通俗點講它的功能:如果你的線框模型可以生成實體,模型,那麼它可以……裡邊是一個複雜而漫長的過程……我可以稱他形體生成包

BRepOffsetAPI_ThruSections aTool(Standard_True); 
aTool.AddWire(threadingWire1); 
aTool.AddWire(threadingWire2); 
aTool.CheckCompatibility(Standard_False); 
TopoDS_Shape myThreading = aTool.Shape();
           

Tutorial源代碼

TopoDS_Shape MakeBottle(const Standard_Real myWidth, const Standard_Real myHeight, const Standard_Real myThickness) 
{ 
    // Profile : Define Support Points 
    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);
    // Profile : Define the Geometry 
    Handle(Geom_TrimmedCurve) aSegment1 = GC_MakeSegment(aPnt1, aPnt2); 
    Handle(Geom_TrimmedCurve) aSegment2 = GC_MakeSegment(aPnt4, aPnt5);
    // Profile : Define the Topology 
    TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(aSegment1); 
    TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge(aSegment2); 
    TopoDS_Wire aWire = BRepBuilderAPI_MakeWire(anEdge1, anEdge2, anEdge3);
    // Complete Profile 
    gp_Ax1 xAxis = gp::OX(); 
    gp_Trsf aTrsf;
    aTrsf.SetMirror(xAxis); 
    BRepBuilderAPI_Transform aBRepTrsf(aWire, aTrsf); 
    TopoDS_Wire aMirroredWire = TopoDS::Wire(aMirroredShape);
    BRepBuilderAPI_MakeWire mkWire; 
    mkWire.Add(aMirroredWire); 
    TopoDS_Wire myWireProfile = mkWire.Wire();
    // Body : Prism the Profile 
    TopoDS_Face myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile); 
    gp_Vec aPrismVec(0, 0, myHeight); 
    TopoDS_Shape myBody = BRepPrimAPI_MakePrism(myFaceProfile, aPrismVec);
    // Body : Apply Fillets 
    BRepFilletAPI_MakeFillet mkFillet(myBody); 
    TopExp_Explorer anEdgeExplorer(myBody, TopAbs_EDGE); 
    while(anEdgeExplorer.More())
    { 
        TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExplorer.Current()); //Add edge to fillet algorithm 
        mkFillet.Add(myThickness / 12., anEdge); 
        anEdgeExplorer.Next(); 
    }
    myBody = mkFillet.Shape();
    // Body : Add the Neck 
    gp_Pnt neckLocation(0, 0, myHeight); 
    gp_Dir neckAxis = gp::DZ(); 
    gp_Ax2 neckAx2(neckLocation, neckAxis);
    Standard_Real myNeckRadius = myThickness / 4.; 
    Standard_Real myNeckHeight = myHeight / 10.;
    BRepPrimAPI_MakeCylinder MKCylinder(neckAx2, myNeckRadius, myNeckHeight); 
    TopoDS_Shape myNeck = MKCylinder.Shape();
    myBody = BRepAlgoAPI_Fuse(myBody, myNeck);
    // Body : Create a Hollowed Solid 
    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()); // Check if <aFace> is the top face of the bottle’s neck 
        Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace); 
        if(aSurface->DynamicType() == STANDARD_TYPE(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; 
            }
        }
    }
    TopTools_ListOfShape facesToRemove; 
    facesToRemove.Append(faceToRemove); 
    BRepOffsetAPI_MakeThickSolid BodyMaker; 
    BodyMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3); 
    myBody = BodyMaker.Shape(); 
    // Threading : Create Surfaces 
    Handle(Geom_CylindricalSurface) aCyl1 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 0.99); 
    Handle(Geom_CylindricalSurface) aCyl2 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 1.05);
    // Threading : Define 2D Curves 
    gp_Pnt2d aPnt(2. * M_PI, myNeckHeight / 2.); 
    gp_Dir2d aDir(2. * M_PI, myNeckHeight / 4.); 
    gp_Ax2d anAx2d(aPnt, aDir);
    Standard_Real aMajor = 2. * M_PI; 
    Standard_Real aMinor = myNeckHeight / 10;
    Handle(Geom2d_Ellipse) anEllipse1 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor); 
    Handle(Geom2d_Ellipse) anEllipse2 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor / 4); 
    Handle(Geom2d_TrimmedCurve) anArc1 = new Geom2d_TrimmedCurve(anEllipse1, 0, M_PI); 
    Handle(Geom2d_TrimmedCurve) anArc2 = new Geom2d_TrimmedCurve(anEllipse2, 0, M_PI); 
    gp_Pnt2d anEllipsePnt1 = anEllipse1->Value(0); 
    gp_Pnt2d anEllipsePnt2 = anEllipse1->Value(M_PI);
    Handle(Geom2d_TrimmedCurve) aSegment = GCE2d_MakeSegment(anEllipsePnt1, anEllipsePnt2); 
    // Threading : Build Edges and Wires 
    TopoDS_Edge anEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(anArc1, aCyl1); 
    TopoDS_Edge anEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment, aCyl1); 
    TopoDS_Edge anEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(anArc2, aCyl2); 
    TopoDS_Edge anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment, aCyl2); 
    TopoDS_Wire threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1, anEdge2OnSurf1); 
    TopoDS_Wire threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2, anEdge2OnSurf2); 
    BRepLib::BuildCurves3d(threadingWire1); 
    BRepLib::BuildCurves3d(threadingWire2);
    // Create Threading 
    BRepOffsetAPI_ThruSections aTool(Standard_True); 
    aTool.AddWire(threadingWire1); 
    aTool.AddWire(threadingWire2); 
    aTool.CheckCompatibility(Standard_False);
    TopoDS_Shape myThreading = aTool.Shape();
    // Building the Resulting Compound 
    TopoDS_Compound aRes; 
    BRep_Builder aBuilder; 
    aBuilder.MakeCompound (aRes); 
    aBuilder.Add (aRes, myBody); 
    aBuilder.Add (aRes, myThreading);
    return aRes;
}
           

繼續閱讀