I am using OCAF and I am creating documents with attributes of our own types and our own presentation drivers. Some of these presentations are very costly to compute. Hiding attributes is implemented here as getting the TPrsStd_AISPresentation attribute that is related to the particular attribute and calling its Erase() method with Standard_False as argument.
Now it may happen that the user modifies something that invalidates the visualization. For example he might change visualization options. I have reacted on that by calling the presentation's Update() method to trigger visualization recomputation. But actually this is too eager. Why recompute the visualization if it is hidden anyway???
So I have tried to improve that. Finally I have found a solution, but the solution is absolutely weird (see item 3 in the list below). The reason might be that I do not understand how TPrsStd_AISPresentations work. But it might also be that the OCCT methods are badly documented or not correctly implemented. I do not know what is the case, so I would like to describe my tries. Could someone tell me why they did not work? Otherwise I would register several issues in the bug tracker.
1. Attempt: Remove the Presentation from the Interactive Context
To get rid of the old visualization, I have called TPrsStd_AISPresentations::Erase(Standard_True) on the respective presentation. Strangely this method does nothing, if the presentation is not displayed (check code of TPrsStd_AISPresentation::Erase). Why? After erasing the presentation I could decide to remove it!!! As a workaround for doing that I have to call TPrsStd_AISPresentation::SetDisplayed(Standard_True) first. Anyway, I did that, but it didn't change anything. I have not been able to figure out the difference between erasing and removing a presentation. The documentation of AIS_InteractiveContext::Remove() states that it will remove the object from every viewer. Still if I call TPrsStd_AISPresentations::Display(Standard_False) later (when the user decides to show the attribute and I do not know anymore that there has arisen a need to update the presentation), then the OLD visualization is displayed.
To do: TPrsStd_AISPresentation::Erase should remove the presentation even if it is not displayed. If there is really no big difference between erasing and removing presentations, then one of these functionalities should be marked deprecated and removed.
2. Attempt: Set to Update
The interactive object stored in the presentation attribute has a method SetToUpdate() which it inherits from PrsMgr_PresentableObject. This looks tempting. I had expected TPrsStd_AISPresentation::Display() to check whether the interactive object has been set like that and then to update the visualization. Unfortunately it doesn't do that.
To do: Shouldn't TPrsStd_AISPresentation::Display() check whether its interactive object needs to be updated before displaying it the next time?
3. Attempt: Nullify the Presentation's Interactive Object
By chance I have found a way to do exactly what I want. If I call TPrsStd_AISPresentation::Restore(presentation), then the internal interactive object is nullified. I don't have to remember that an update is necessary. The next time someone calls TPrsStd_AISPresentation::Display(), the visualization will be recomputed. So this is a perfect way of doing a lazy presentation update. Unfortunately misusing the Restore() method is a dirty hack.
To do: If this is really the best way to do lazy presentation updates then add a method TPrsStd_AISPresentation::NullifyAIS() and write to the method's documentation that this can be used for invalidating the current visualization.
I am extremely excited about your comments.