Concurrent AIS display

Hello,

    I'm trying to concurrently display many custom AIS objects but I get crash at some point in AIS_InteractiveContext::Display() at line 491 "myObjects.Bind(theIObj, aStatus);" because this method doesn't seem to be thread-safe.

    What's the correct way to run concurrent computation of the 3D graphics with AIS_InteractiveContext ?

Kirill Gavrilov's picture

I get crash at some point in AIS_InteractiveContext::Display()
...
because this method doesn't see to be thread-safe.

The class or method should never be considered thread-safe, as long as it is not explicitly documented to be so (which is pretty unusual).
Mutex at application level should be used for concurrent access to AIS_InteractiveContext instance and calling any of it's methods.

What's the correct way to run concurrent computation of the 3D graphics with AIS_InteractiveContext ?

If your AIS_InteractiveObject::Compute() is computationally intensive - try moving out presentation computation to dedicated method (which would flush result into object itself).

You may also consider improving AIS_InteractiveContext itself by adding a method displaying the list of interactive objects with (optional) multi-threaded compute, which would care about concurrent access to things like AIS_InteractiveContext::myObjects and others in scope of a single function - which would more clear, robust and efficient than trying to make the whole AIS thing thread-safe for every other method.

Hugues Delorme's picture

Hello Kirill,

    Thanks very much for helping, what do you mean by "try moving out presentation computation to dedicated method" ?

    About the second solution is there any plan to have this multi-threaded version of the AIS_InteractiveContext::Display() function ?

Kirill Gavrilov's picture

what do you mean by "try moving out presentation computation to dedicated method" ?

In case of displaying TopoDS_Shape, generation of triangulation takes most of the time, so that this step can be performed by application before displaying.
In case of a custom presentation - you may profile what takes most of the time and consider moving this outside of ::Compute(), so that this method will only fill presentation strutures, and not perform any expensive algorithms.

Alternatively, when custom ::Compute() does expensive algorithm on big data, the parallelization can be put directly to your ::Compute().
This will be likely less efficient than parallelization for a big number of small objects, but still can be profitable (most optimal balancing depends on data structures).
For instance, StdPrs_WFShape::Add() has IsParallel flag for computing IsoLines in parallel for different Faces in the Shape.

is there any plan to have this multi-threaded version of the AIS_InteractiveContext::Display() function ?

This is currently not within the closest plans. You may contribute to OCCT project, or consider using Open Cascade support services:

https://www.opencascade.com/content/technology-support

Hugues Delorme's picture

Hello Kirill,

I applied what you suggested about preparing graphics outside Compute(). It works well, this "preparation" step is done concurrently and then the Compute() function just adds the "pre-created" graphics entities to a Graphic3d_Group object.

What I found error-prone with this solution though is that anytime graphics have to be recomputed/redisplayed you have to make sure to execute first that "preparation" step before any call to eg AIS_InteractiveObject::Redisplay().

Anyway thanks for your help, it solved the problem.