OCCT 建模,VTK显示
2019/6/21
在OCCT中visualization中有現(xiàn)成的VTK接口 從Topo::DS_Shape到Mapper的接口如下所示:
IVtkOCC_Shape::Handle aShapeImpl = new IVtkOCC_Shape(MakeBottle(20,30,8));vtkSmartPointer<IVtkTools_ShapeDataSource> DS = vtkSmartPointer<IVtkTools_ShapeDataSource>::New();DS->SetShape(aShapeImpl);vtkSmartPointer<vtkPolyDataMapper> Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();Mapper->SetInputConnection(DS->GetOutputPort());畫(huà)圖的例子采用的是OCCT官方教程中的二鍋頭的例子 圖形的類(lèi)型為T(mén)opo::DS_Shape
另外還有一個(gè)球的生成作為測(cè)試 圖形的類(lèi)型為T(mén)opo::DS_Face
#include <vtkAutoInit.h> //avoid error:0xC0000005 VTK_MODULE_INIT(vtkRenderingOpenGL); VTK_MODULE_INIT(vtkInteractionStyle);//Libs from OCCT #pragma comment(lib, "TKernel.lib") #pragma comment(lib, "TKMath.lib") #pragma comment(lib, "TKBRep.lib") #pragma comment(lib, "TKMesh.lib") #pragma comment(lib, "TKTopAlgo.lib")#include <TCollection_AsciiString.hxx> #include <TopoDS.hxx> #include <TopoDS_Shape.hxx> #include <TopoDS_Edge.hxx> #include <TopoDS_Wire.hxx> #include <TopoDS_Face.hxx> #include <gp_Circ.hxx> #include <gp_Elips.hxx> #include <gp_Sphere.hxx> #include <gp_Pnt.hxx> #include <Geom_Line.hxx> #include <Geom_Circle.hxx> #include <Geom_Plane.hxx> #include <Geom_CylindricalSurface.hxx> #include <Geom2d_Ellipse.hxx> #include <Geom2d_TrimmedCurve.hxx> #include <GC_MakeArcOfCircle.hxx> #include <GC_MakeSegment.hxx> #include <Poly_Polygon3D.hxx> #include <Poly_Triangulation.hxx> #include <BRep_Builder.hxx> #include <BRepBuilderAPI.hxx> #include <BRepBuilderAPI_MakeEdge.hxx> #include <BRepBuilderAPI_MakeWire.hxx> #include <BRepBuilderAPI_MakeFace.hxx> #include <BRepPrimAPI_MakePrism.hxx> #include <BRepprimAPI_MakeCylinder.hxx> #include <BRepBuilderAPI_Transform.hxx> #include <BRepAlgoAPI_Fuse.hxx> #include <BRep_Tool.hxx> #include <BRepMesh.hxx> #include <BRepMesh_IncrementalMesh.hxx> #include <BRepFilletAPI_MakeFillet.hxx> #include <BRepOffsetAPI_MakeThickSolid.hxx> #include <BRepLib.hxx> #include <TopExp_Explorer.hxx> #include <GCE2d_MakeSegment.hxx> #include <BRepOffsetAPI_ThruSections.hxx> #include <IVtkOCC_Shape.hxx> #include <IVtkTools_ShapeDataSource.hxx>//Libs from VTK #include <vtkSmartPointer.h> #include <vtkPoints.h> #include <vtkPolyData.h> #include <vtkCellArray.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderWindow.h> #include <vtkRenderer.h> #include <vtkRenderWindowInteractor.h> #include <vtkProperty.h> #include <vtkLine.h> #include <vtkTriangle.h> #include <vtkPolyDataWriter.h> #include <vtkVertexGlyphFilter.h>//OCC shape //standard 基本類(lèi)型 TopoDS_Shape MakeBottle(const Standard_Real myWidth, const Standard_Real myHeight,const Standard_Real myThickness) {// Profile : Define Support Points//gp:幾何元素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);// Profile : Define the Geometry//geom構(gòu)建幾何類(lèi)型 Handle為智能指針Handle(Geom_TrimmedCurve) anArcOfCircle = GC_MakeArcOfCircle(aPnt2, aPnt3, aPnt4);Handle(Geom_TrimmedCurve) aSegment1 = GC_MakeSegment(aPnt1, aPnt2);Handle(Geom_TrimmedCurve) aSegment2 = GC_MakeSegment(aPnt4, aPnt5);// Profile : Define the Topology//topods幾何拓?fù)浣Y(jié)構(gòu) 包含幾何信息 方向 位置//brepbuilderapi 使用幾何類(lèi)型構(gòu)造幾何拓?fù)浣Y(jié)構(gòu)TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(aSegment1);TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge(anArcOfCircle);TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge(aSegment2);TopoDS_Wire aWire = BRepBuilderAPI_MakeWire(anEdge1, anEdge2, anEdge3);// Complete Profilegp_Ax1 xAxis = gp::OX();gp_Trsf aTrsf;aTrsf.SetMirror(xAxis);BRepBuilderAPI_Transform aBRepTrsf(aWire, aTrsf);TopoDS_Shape aMirroredShape = aBRepTrsf.Shape();TopoDS_Wire aMirroredWire = TopoDS::Wire(aMirroredShape);BRepBuilderAPI_MakeWire mkWire;mkWire.Add(aWire);mkWire.Add(aMirroredWire);TopoDS_Wire myWireProfile = mkWire.Wire();// Body : Prism the Profile// brepprimapi掃描構(gòu)建幾何體TopoDS_Face myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile);gp_Vec aPrismVec(0, 0, myHeight);TopoDS_Shape myBody = BRepPrimAPI_MakePrism(myFaceProfile, aPrismVec);// Body : Apply Fillets//brepfilletapi倒角 圓角等//topexp——explorer用于遍歷元素 for循環(huán)BRepFilletAPI_MakeFillet mkFillet(myBody);TopExp_Explorer anEdgeExplorer(myBody, TopAbs_EDGE);while (anEdgeExplorer.More()){TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExplorer.Current());//Add edge to fillet algorithmmkFillet.Add(myThickness / 12., anEdge);anEdgeExplorer.Next();}myBody = mkFillet.Shape();// Body : Add the Neck//brepalgo 算法包 布爾運(yùn)算 裁剪等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 SolidTopoDS_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 數(shù)據(jù)結(jié)構(gòu)類(lèi)型 表 樹(shù)等TopTools_ListOfShape facesToRemove;facesToRemove.Append(faceToRemove);//brepoffsetapi 通過(guò)偏移來(lái)生成實(shí)體BRepOffsetAPI_MakeThickSolid BodyMaker;BodyMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3);myBody = BodyMaker.Shape();// Threading : Create SurfacesHandle(Geom_CylindricalSurface) aCyl1 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 0.99);Handle(Geom_CylindricalSurface) aCyl2 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 1.05);// Threading : Define 2D Curvesgp_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 WiresTopoDS_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; }//Mesh&Data transmission void BuildMesh(vtkRenderer* render, const TopoDS_Face& face, double deflection = 0.1) {TopLoc_Location location;BRepMesh_IncrementalMesh(face, deflection);Handle_Poly_Triangulation triFace = BRep_Tool::Triangulation(face, location);Standard_Integer nTriangles = triFace->NbTriangles();gp_Pnt vertex1;gp_Pnt vertex2;gp_Pnt vertex3;Standard_Integer nVertexIndex1 = 0;Standard_Integer nVertexIndex2 = 0;Standard_Integer nVertexIndex3 = 0;TColgp_Array1OfPnt nodes(1, triFace->NbNodes());Poly_Array1OfTriangle triangles(1, triFace->NbTriangles());nodes = triFace->Nodes();triangles = triFace->Triangles();vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();vtkSmartPointer<vtkPolyData> pointData = vtkSmartPointer<vtkPolyData>::New();vtkSmartPointer<vtkPolyData> lineData = vtkSmartPointer<vtkPolyData>::New();vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();points->Allocate(nTriangles * 3);cells->Allocate(nTriangles);int id = 0;for (Standard_Integer i = 1; i <= nTriangles; i++){Poly_Triangle aTriangle = triangles.Value(i);aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);vertex1 = nodes.Value(nVertexIndex1).Transformed(location.Transformation());vertex2 = nodes.Value(nVertexIndex2).Transformed(location.Transformation());vertex3 = nodes.Value(nVertexIndex3).Transformed(location.Transformation());points->InsertNextPoint(vertex1.X(), vertex1.Y(), vertex1.Z());points->InsertNextPoint(vertex2.X(), vertex2.Y(), vertex2.Z());points->InsertNextPoint(vertex3.X(), vertex3.Y(), vertex3.Z());vtkSmartPointer<vtkLine> line0 = vtkSmartPointer<vtkLine>::New();line0->GetPointIds()->SetId(0, id * 3);line0->GetPointIds()->SetId(1, id * 3 + 1);vtkSmartPointer<vtkLine> line1 = vtkSmartPointer<vtkLine>::New();line1->GetPointIds()->SetId(0, id * 3 + 1);line1->GetPointIds()->SetId(1, id * 3 + 2);vtkSmartPointer<vtkLine> line2 = vtkSmartPointer<vtkLine>::New();line2->GetPointIds()->SetId(0, id * 3 + 2);line2->GetPointIds()->SetId(1, id * 3);vtkSmartPointer<vtkTriangle> triangle = vtkSmartPointer<vtkTriangle>::New();triangle->GetPointIds()->SetId(0, id * 3);triangle->GetPointIds()->SetId(1, id * 3 + 1);triangle->GetPointIds()->SetId(2, id * 3 + 2);// Add the triangle to a cell arraylines->InsertNextCell(line0);lines->InsertNextCell(line1);lines->InsertNextCell(line2);cells->InsertNextCell(triangle);id++;}pointData->SetPoints(points);vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter =vtkSmartPointer<vtkVertexGlyphFilter>::New();glyphFilter->SetInputData(pointData);glyphFilter->Update();lineData->SetPoints(points);lineData->SetLines(lines);polyData->SetPoints(points);polyData->SetPolys(cells);/*vtkSmartPointer<vtkPolyDataWriter> writer = vtkSmartPointer<vtkPolyDataWriter>::New();writer->SetFileName("Mesh.vtk");writer->SetInputData(polyData);writer->Write();*/vtkSmartPointer<vtkPolyDataMapper> pointMapper = vtkSmartPointer<vtkPolyDataMapper>::New();pointMapper->SetInputData(glyphFilter->GetOutput());vtkSmartPointer<vtkPolyDataMapper> lineMapper = vtkSmartPointer<vtkPolyDataMapper>::New();pointMapper->SetInputData(lineData);vtkSmartPointer<vtkPolyDataMapper> faceMapper = vtkSmartPointer<vtkPolyDataMapper>::New();faceMapper->SetInputData(polyData);vtkSmartPointer<vtkActor> pointActor = vtkSmartPointer<vtkActor>::New();pointActor->SetMapper(pointMapper);pointActor->GetProperty()->SetPointSize(3);pointActor->GetProperty()->SetColor(1, 1, 1);pointActor->GetProperty()->SetOpacity(1); vtkSmartPointer<vtkActor> lineActor = vtkSmartPointer<vtkActor>::New();lineActor->SetMapper(lineMapper);lineActor->GetProperty()->SetLineWidth(3);lineActor->GetProperty()->SetColor(1, 0, 0);vtkSmartPointer<vtkActor> faceActor = vtkSmartPointer<vtkActor>::New();faceActor->SetMapper(faceMapper);faceActor->GetProperty()->SetColor(1, 0, 0);render->AddActor(pointActor);render->AddActor(lineActor);render->AddActor(faceActor); }void TestScene(vtkRenderer* render) {gp_Ax2 axis;axis.SetAxis(gp::OX());axis.SetLocation(gp_Pnt(0.0, 0.0, 0.0));TopoDS_Face sphereFace1 = BRepBuilderAPI_MakeFace(gp_Sphere(axis, 8.0));BuildMesh(render, sphereFace1); }void BuildScene(vtkRenderer* render, TopoDS_Shape model,double deflection) {for (TopExp_Explorer aFaceExplorer(model, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next()){TopoDS_Face aFace = TopoDS::Face(aFaceExplorer.Current());BuildMesh(render, aFace,deflection);} }int main(int argc, char* argv[]) {// Create a renderer, render window, and interactorvtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();renderWindow->SetSize(1200, 900);renderWindow->AddRenderer(renderer);vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();renderWindowInteractor->SetRenderWindow(renderWindow);//build meshBuildScene(renderer, MakeBottle(20,30,8),0.01);TestScene(renderer);renderer->SetBackground(0, 0.2, 0.8);// Render and interactrenderWindow->Render();renderWindowInteractor->Start();return 0; }顯示效果圖:
VTK的管線(xiàn)配置還是比較簡(jiǎn)單的 建立相應(yīng)的數(shù)據(jù)結(jié)構(gòu) 將對(duì)應(yīng)的數(shù)據(jù)傳過(guò)去就行
比較麻煩的地方:
1.類(lèi)型 TopoDS_Shape和TopoDS_Face的問(wèn)題 即類(lèi)型層次和轉(zhuǎn)換的問(wèn)題
2.三角剖分相關(guān)的源碼
源碼中間三角剖分最終都成為了Topo::DS_TFace中間的Trianglation 之后就沒(méi)有辦法看了
一層一層嵌套很難受
參考資料之后 覺(jué)得還是要從BRep_FastDiscretFace.cxx里面看
3.如何生成體網(wǎng)格
目前僅能實(shí)現(xiàn)一條參數(shù)軸(U)的離散
即僅能通過(guò)暴力方法 生成旋轉(zhuǎn)和拉伸生成實(shí)體的面網(wǎng)格
總結(jié)
以上是生活随笔為你收集整理的OCCT 建模,VTK显示的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python按模板生成html_使用Py
- 下一篇: linux 下载工具