a lot of edges

hi,

i need to display a thousands of linear edges. scene has to be updated after each added one.
i used TopoDS_Edge object and displayed that as an AIS_Shape, but showing of each new edge was slower and slower.

is there some trick how to make this faster?

best regards,
adrian

Patrik Mueller's picture

Hi Adrian,

how about adding the edges to a TopoDS_Compound and Display this with an AIS_Shape?

Best regards,

Patrik

a-helcman's picture

hi patrik,

i need to refresh the display for rach new edge.

best regards,
adrian

Patrik Mueller's picture

Hm...

what about building your own AIS_InteractiveObject(s)? Depending on your needs it could be sufficient just drawing the lines for the edges? So you could save some initialization and refreshing times from AIS_Shape?

Patrik

a-helcman's picture

yes, i wanted to go around this, but i am forced to do it in such way.

adrian

a-helcman's picture

hello patrik,

i created my own ais object:

ISession_Abscissa::ISession_Abscissa()
{
bPrepared = false;
}

ISession_Abscissa::ISession_Abscissa (gp_Pnt &o_Pts, gp_Pnt &o_Pte)
{
oPts = o_Pts;
oPte = o_Pte;

bPrepared = true;
}

void ISession_Abscissa::Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
const Handle(Prs3d_Presentation)& aPresentation,
const Standard_Integer aMode)
{
Handle(Geom_Line) po_line = new Geom_Line(oPts, gp_Vec(oPts, oPte));
GeomAdaptor_Curve o_curve_adaptor (po_line);

StdPrs_Curve::Add (aPresentation, o_curve_adaptor, 0, 1, 1, 0);
}

void ISession_Abscissa::Compute (const Handle(Prs3d_Projector)& aProjector,
const Handle(Prs3d_Presentation)& aPresentation)
{
}

void ISession_Abscissa::ComputeSelection (const Handle(SelectMgr_Selection)& aSelection,
const Standard_Integer aMode)
{
}

but the situation is the same. is there some way how to speed up this object?

best regards,
adrian

Patrik Mueller's picture

Hi Adrian,

here is one of my methods:

the idea is to avoid creating new liness as you do. So I just create the topology outside AIS and only do a simple drawing with Graphic3d primitives!!

void Im_AISMesh::ComputeVertexNormals(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager, const Handle(Prs3d_Presentation)& aPresentation, const Handle(Prs3d_Drawer)& aDrawer)
{
if (!m_Mesh.IsNull())
{
Handle_Graphic3d_Structure theStructure = Handle_Graphic3d_Structure::DownCast(aPresentation);
Handle_Graphic3d_Group theGroup= new Graphic3d_Group(theStructure);

theGroup->SetGroupPrimitivesAspect(new Graphic3d_AspectLine3d(m_VertexColor,Aspect_TOL_SOLID,1.0));
theGroup->BeginPrimitives();

Standard_Integer vertexCount = m_Mesh->NbVertices();
for (Standard_Integer i = 0; i < vertexCount; i++)
{
Im_Vertex tmpVertex;
Standard_Boolean result = m_Mesh->GetVertex(i, tmpVertex);
if (result)
{
gp_Pnt tmpPnt = tmpVertex.GetPosition();
gp_Pnt tmpNormal = tmpPnt.Translated(tmpVertex.GetNormal());

Graphic3d_Vertex gV(tmpPnt.X(), tmpPnt.Y(), tmpPnt.Z());
Graphic3d_Vertex gN(tmpNormal.X(), tmpNormal.Y(), tmpNormal.Z());

theGroup->Polyline(gV, gN);
}
}
theGroup->EndPrimitives();
}
}

HTH,

Patrik

a-helcman's picture

patrik,

thank you for your solution. it is 15% faster than my one.

i use the new ais mesh like this:

if (po_mesh.IsNull())
{
po_mesh = new ISession_Mesh;
poOCAISContext->Display (po_mesh, false);

po_mesh->oaMesh.Add (o_first_pos);
}

po_mesh->oaMesh.Add (o_next_pos);

poOCAISContext->Redisplay (po_mesh);

for each new position the ComputeVertexNormals is called. in the loop inside there are processed all added positions. this is a time consuming for the huge amounts of points. is it not possible to perform just the body of the loop for each new position?

best regards,
adrian

Patrik Mueller's picture

Hi Adrian,

ComputeVertexNormals was just a hint how to solve such a problem. I think storing and displaying the Graphic3d_Vertices for the points and normals could help?
How about just displaying the vertices and normals without building a group? Could give some more speed?

Best regards,

Patrik

a-helcman's picture

hello patrik,

the new enhanced version doesn't recompute all group for each new line segment.
it is more than 3times(!!!) faster than the previous code.
but the stability is so so. it crashes sometimes in TKOpenGL (no stack available).
why is this solution dangerous?
i had problem to set the color for the segments. i have to do that for each new element.

> How about just displaying the vertices and normals without building a group?

how can i do that?

best regards,
adrian

==========================================================================
====== ISESSION_MESH =====================================================

void ISession_Mesh::SetMyColor (Quantity_NameOfColor o_Color)
{
if (o_Color != oColor)
{
poLineAspect.Nullify();

poLineAspect = new Graphic3d_AspectLine3d (o_Color,Aspect_TOL_SOLID,1.0);
oColor = o_Color;
}
}

void ISession_Mesh::ComputeVertexNormals(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager, const Handle(Prs3d_Presentation)& aPresentation, const Handle(Prs3d_Drawer)& aDrawer)
{
if (poGroup.IsNull())
{
Handle_Graphic3d_Structure po_structure = Handle_Graphic3d_Structure::DownCast(aPresentation);

poGroup = new Graphic3d_Group(po_structure);

}

poGroup->BeginPrimitives();

Graphic3d_Vertex gV(oNewPt1.X(),oNewPt1.Y(),oNewPt1.Z());
Graphic3d_Vertex gN(oNewPt2.X(),oNewPt2.Y(),oNewPt2.Z());

poGroup->Polyline(gV, gN);

poGroup->EndPrimitives();

poGroup->SetPrimitivesAspect (poLineAspect);
}

==========================================================================
====== USAGE =============================================================

bool b_init;

if (poAISPathMesh.IsNull())
{
poAISPathMesh = new ISession_Mesh;
poAISPathMesh->SetColor (Quantity_NOC_YELLOW);
b_init = true;
}
else
b_init = false;

poAISPathMesh->oNewPt1 = o_Segment_Pts;
poAISPathMesh->oNewPt2 = o_Segment_Pte;

if (b_init)
poOCAISContext->Display (poAISPathMesh, !bShowTool);
else
poOCAISContext->Redisplay (poAISPathMesh, !bShowTool);

Patrik Mueller's picture

Hi Adrian,

if I read it correctly you create a Graphic3d_Group for every polyline! I think this could procduce the OpenGL stack errors with too much DisplayLists or VBOs (depends on OCC)!!!
And for storing the the elements: just use 2x std::vector< Graphic3d_Vertex> for caching the points and normals.

Perhaps this helps,

Patrik

a-helcman's picture

patrik,

i create just one group per mesh.

==============
if (poGroup.IsNull()) //<== CREATE JUST ONCE WHEN THE HANDLE IS EMPTY
{
Handle_Graphic3d_Structure po_structure = Handle_Graphic3d_Structure::DownCast(aPresentation);

poGroup = new Graphic3d_Group(po_structure);

}
========

poGroup is a member variable of the ISession_Mesh class.

best regards,
adrian

Patrik Mueller's picture

Oops,

my failure:

poGroup->BeginPrimitives();

Graphic3d_Vertex gV(oNewPt1.X(),oNewPt1.Y(),oNewPt1.Z());
Graphic3d_Vertex gN(oNewPt2.X(),oNewPt2.Y(),oNewPt2.Z());

poGroup->Polyline(gV, gN);

poGroup->EndPrimitives();

try to minimize the calls of BeginPrimitives() and EndPrimitives() in a group! As far as I know there could be some limitations in OpenGL!!

Patrik

a-helcman's picture

patrik,

i commented lines of BeginPrimitives() and EndPrimitives(). it didn't influence the behaviour of the mesh object!
so ISession_Mesh works with or without these calls in the same way.
stability stood the same too. crashes from time to time.
i suspect the poGroup->SetPrimitivesAspect (poLineAspect); line for making problems. without that the color of the segments is white, stability seems to be ok (no crash still). i need just one color for complete mesh. i tryied some ways to solve that but without success.

best regards,
adrian

Patrik Mueller's picture

Adrian,

have your checked poLineAspect.IsNull() ?
Perhaps this can give you a hint where to search for the error.
If not I have no idea at the moment...

Greets,

Patrik

a-helcman's picture

patrik,

i initialize poLineAspect in the ISession_Mesh constructor by calling SetMyColor:

ISession_Mesh::ISession_Mesh()
{
SetMyColor (Quantity_NOC_YELLOW);
}

so there is no danger from this side.

crashes appeared between 1000 - 5000 displayed segments.
never at the same place. in many cases (80%) the testing code runs successfully.

thank you very much for your assistance. your advices were very helpfull for me.

best regards,
adrian

Patrik Mueller's picture

....

glad I could help a little bit!

Patrik

a-helcman's picture

hello patrik,

the solution, which you have helped me to find has one small defect.
it is impossible to select the endpoints of the edges. i can not find the coordinates of the points by a mouse clicking.
is this a tax for the fast solution? or is there a way how to solve this without the slowing down a performance?

best regards,
adrian

Patrik Mueller's picture

Hi Adrian,

you have to implement "ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, const Standard_Integer aMode)" for the Interactive Object.

Greets,

Patrik

a-helcman's picture

hi patrik,

i used a tens of tricks but i can not force the oc to show vertex-selection ring around edges end-points.
- local context is open
- ActivateStandardMode (TopAbs_VERTEX).
is it possible? i can see this vertex selection just in AIS_Shape.

best regards,
adrian

a-helcman's picture

...it crashes also without the SetPrimitivesAspect line when it runs out of debugger...