Sun, 09/30/2018 - 10:18
I need to read a *.stl file,then display the shape in my program. But the *.stl is so big, there are more than 10000 triangles in it. So if using the followed code to display.
......
while(...)
{ // Will cycle >10000 times.
......// Read data from a stl file.
gp_Pnt aPnt1(vX1, vY1, vZ1);
gp_Pnt aPnt2(vX2, vY2, vZ2);
gp_Pnt aPnt3(vX3, vY3, vZ3);
if( !aPnt1.IsEqual(aPnt2, 1.0e-06) && !aPnt1.IsEqual(aPnt3, 1.0e-06) && !aPnt3.IsEqual(aPnt2, 1.0e-06) ){
TopoDS_Vertex Vertex1 = BRepBuilderAPI_MakeVertex(aPnt1);
TopoDS_Vertex Vertex2 = BRepBuilderAPI_MakeVertex(aPnt2);
TopoDS_Vertex Vertex3 = BRepBuilderAPI_MakeVertex(aPnt3);
TopoDS_Wire AktWire = BRepBuilderAPI_MakePolygon(Vertex1, Vertex2, Vertex3, Standard_True);
if(!AktWire.IsNull()){
TopoDS_Face AktFace = BRepBuilderAPI_MakeFace(AktWire);
if( !AktFace.IsNull() ){
myBuilder.Add( STLShowShape, AktFace );
}
}
}
Handle(AIS_Shape) showObj = new AIS_Shape(STLShowShape);
myAISContext()->SetColor(showObj, Quantity_NOC_WHITE);
myAISContext()->SetMaterial(showObj,Graphic3d_NOM_DEFAULT);
myAISContext()->SetDisplayMode(showObj,1,Standard_True);
myAISContext()->Display(showObj);
......
The above codes are working OK. But TOO slow. I think perhaps because the AIS_Shape is too big(Or other reason?), and I don't need those triangle shapes' BREP information. So I want to use OpenGL directly to show those Triangles. My InitView() function is copied from OCCT Sample as follow,
bool InitViewer(System::IntPtr theWnd)
{
Handle(Aspect_DisplayConnection) aDisplayConnection;
myGraphicDriver() = new OpenGl_GraphicDriver (aDisplayConnection);
myViewer() = new V3d_Viewer (myGraphicDriver());
myViewer()->SetDefaultLights();
myViewer()->SetLightOn();
myView() = myViewer()->CreateView();
Handle(WNT_Window) aWNTWindow = new WNT_Window (reinterpret_cast<HWND> (theWnd.ToPointer()));
myView()->SetWindow(aWNTWindow);
myView()->ZBufferTriedronSetup(......);
myView()->TriedronDisplay(......);
myAISContext() = new AIS_InteractiveContext( myViewer() );
myAISContext()->UpdateCurrentViewer();
myView()->Redraw();
myView()->MustBeResized();
return true;
}
During trying to find a way to solve this problem, I find the STLViewer.exe load and show the *.stl very very quickly. It based on only OpenGL. Can anyone give me some suggestions about how to use OpenGL in OCC or improving the codes' running speed? Thanks a lot!
Sun, 09/30/2018 - 10:57
You don't need creating a BRep from STL with each triangle becoming a Face - this is indeed slow and inefficient.
Just use Poly_Triangulation returned by RWStl::ReadFile() - see readstl Draw Harness command.
Mon, 10/01/2018 - 07:24
Have a look at AIS_Triangulation. You can simply create Poly_Triangulation from stl data and use it for presentations computing.
Fri, 10/05/2018 - 05:01
Thank for Anton Shabalin and Kirill Gavrilov's reply.
I use AIS_Triangulation and Poly_Triangulation can display those triangles very quick. My sample code like followed:
......
TColgp_Array1OfPnt myTriNodes(1, 6);
Poly_Array1OfTriangle myTriangles(1, 2);
myTriNodes(1).SetCoord(0,0,0);
myTriNodes(2).SetCoord(0,1,0);
myTriNodes(3).SetCoord(0,0,1);
myTriNodes(4).SetCoord(0,0,0);
myTriNodes(5).SetCoord(-1,0,1);
myTriNodes(6).SetCoord(-1,0,0);
myTriangles(1).Set(1,2,3);
myTriangles(2).Set(4,5,6);
Handle(Poly_Triangulation) myPoly = new Poly_Triangulation(myTriNodes, myTriangles);
Handle(AIS_Triangulation) myAISTria = new AIS_Triangulation(myPoly);
myAISContext()->SetColor(myAISTria, Quantity_NOC_WHITE);
myAISContext()->Display(myAISTria);
......
But I have two more questions.
1. Why the SetColor(myAISTria, Quantity_NOC_WHITE) takes no effects? It always brown color. How can I set those triangles color? Further more, I want to know how to use different color to show the triangles' front and back color.
2. I read the source about StlAPI_Reader.cxx. When it read a stl file, it read the file twice. The first time, it counts the number of the "facet..." structure to decide the the parameters NUM1 and NUM2 in TColgp_Array1OfPnt nNodes(1, NUM1) and Poly_Array1OfTriangle nTriangles(1, NUM2). The second time it read the data one by one. My question is CAN I find a way like using std::vector in OCCT to instead TColgp_Array1OfPnt and Poly_Array1OfTriangle to modify the array's length and add new element later?
Fri, 10/05/2018 - 06:28
You don't need AIS_Triangulation for displaying STL triangulation.
Just use normal AIS_Shape presentation and adjust its attributes in the way you need (including back-face/front-face materials).
You are looking into very old nonsense code - it is better upgrading OCCT to an up-to-date state with improved STL reader.
Implementing RWStl_Reader interface would allow reading STL content into application-specific structures,
but in this case you'll have to implement AIS presentation on your own.
Fri, 10/05/2018 - 18:31
Thank you very much!!!
I find a way to change the color using AIS_Triangulation. Codes like followed:
......
Standard_Integer aColorRedInt = 255;
Standard_Integer aColorGreenInt = 255<<8;
Standard_Integer aColorBlueInt = 255<<16;
Handle(TColStd_HArray1OfInteger) aColorArray = new TColStd_HArray1OfInteger (1, 6);
aColorArray->SetValue(1,aColorRedInt);
aColorArray->SetValue(2,aColorRedInt);
aColorArray->SetValue(3,aColorRedInt);
aColorArray->SetValue(4,aColorGreenInt);
aColorArray->SetValue(5,aColorGreenInt);
aColorArray->SetValue(6,aColorGreenInt);// Or aColorArray->SetValue(6,aColorBlueInt )
myAISTria->SetColors (aColorArray);
myAISContext()->Display(myAISTria);
......
If one triangle's three nodes are the same color, this triangle will be the color as nodes are. If the three color are NOT the same color, this triangle will be a coloful face.
After reading your reply, I still don't know how to use AIS_Shape to show those triangles. I need to show more than 10000 triangles, Is AIS_Shape too big? How can I get Handle(AIS_Shape) from Poly_Triangulation and show them quickly? Could you give me some sample codes?
And how to set back-face/front-face materials?Could you give me some functions' name?Thanks!
Now I'm working with OCC 6.3.0 and 7.1.0 (Sure, 6.3.0 is a terrible prehistoric code, but the legacy is based on it. ), so I need to rewrite some algorithm to override the old codes.
Fri, 10/05/2018 - 22:28
OCCT 6.3.0 does not provide any efficient way for displaying middle-sized data arrays.
STL reader has been rewritten in OCCT 7.2.0 (as well as several bug-fixes and improvements for displaying triangulation-only faces using AIS_Shape) - check Release Notes.
Fri, 10/05/2018 - 11:41
Hi,
I have the same problem. I am starting to understand how to display in a fast way a lot of triangles.
Can you share your test so we can proceed together to solve this ?
Marco
Fri, 10/05/2018 - 17:19
I have get the below snippet of code from ReadStl of XSDRAWSTLVRML.cxx file , but the face cannot be displayed.
It seems that in draw the subsequent "DBRep::Set(theArgv[1], aFace);" made the necessary job.
Have any one a method to read in a faster way a stl file or a poly_Triangulation and display them ?
Fri, 10/05/2018 - 22:27
The face is displayed using normal command vdisplay creating an AIS_Shape within Draw Harness tests.
Most likely you will find Wireframe presentation not very useful for triangulation (in contrast to BRep model there will be no isolines).
Tue, 10/09/2018 - 19:27
Hi Kirill,
I have implemented the display of the triangles with BRep_Builder.makeface and I can create an AIS_InteractiveObject and display it with shading.
But, I also need a visualization through an AIS_Triangulation because I have to set the colors of the vertex of the triangles.
I can do the visualization, but I cannot shade the surface. I get a compact coloured shape. Using the SetDisplayMode(AIS_Shaded) of the context I get no shape visualization.
How can I render a AIS_Triangulation object ?
Or can I set the color of some vertexes of the face builded with BRep-Builder ?
Tue, 10/09/2018 - 20:21
Hi Kirill,
I have solved.
I have set the normals of the Poly_Triangulation object and then I can see a shaded shape.