How to use OpenGL directly in OCC?

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!

Kirill Gavrilov's picture

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.

Anton Shabalin's picture

Have a look at AIS_Triangulation. You can simply create Poly_Triangulation from stl data and use it for presentations computing.

X F's picture

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?

Kirill Gavrilov's picture

1. Why the SetColor(myAISTria, Quantity_NOC_WHITE)  takes no effects?

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).

2. I read the source about StlAPI_Reader.cxx. When it read a stl file, it read the file twice.

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.

X F's picture

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. 

Kirill Gavrilov's picture

Now I'm working with OCC 6.3.0 and 7.1.0

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.

Marco Balen's picture

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

Marco Balen's picture

I have get the below snippet of code from ReadStl of XSDRAWSTLVRML.cxx file , but the face cannot be displayed.

Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile(aFile);
 TopoDS_Face aFace;
 BRep_Builder aB;
 aB.MakeFace(aFace);
 aB.UpdateFace(aFace, aSTLMesh);

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 ?

Kirill Gavrilov's picture

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).

pload ALL
readstl m [locate_data_file bearing.stl]
vinit View1
vdisplay -dispMode 1 m
vfit
Marco Balen's picture

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 ?

Marco Balen's picture

Hi Kirill,

I have solved.

I have set the normals of the Poly_Triangulation object and then I can see a shaded shape.