Hide AIS_InteractiveContext::Erase does not work the first time

Initially after loading CAD files (using STEPCAFControl_Reader for example), if I hide that object using AIS_InteractiveContext::Erase, it does not hide. When I then make if visible again with Display and then Erase it again, it finally becomes invisible and it works as it is supposed to. So why is it not hiding on the very first time ??? Some kind of initialisation missing ???

Luc Wens's picture
Luc Wens's picture

Adding is done with RecurseAdd:

void RecurseAdd(const Handle(AIS_InteractiveContext)& theAIScontext, const Handle(AIS_InteractiveObject)& rShape, bool bShow)
{
    if (rShape.IsNull())
        return;

    for (PrsMgr_ListOfPresentableObjectsIter anIt(rShape->Children()); anIt.More(); anIt.Next())
    {
        if (Handle(AIS_InteractiveObject) aShape = Handle(AIS_InteractiveObject)::DownCast(anIt.Value()))
        {
            RecurseAdd(theAIScontext, aShape, bShow);
        }
    }
    if (!rShape->HasColor())
        rShape->SetColor(Quantity_NOC_ROYALBLUE);
    if (!rShape->HasMaterial())
        rShape->SetMaterial(Graphic3d_NOM_BRONZE);

    AIS_DisplayStatus DisplayStatus = (bShow ? AIS_DS_Displayed : AIS_DS_Erased);
    int DisplayMode = rShape->DisplayMode();
    int HighLightMode = rShape->HilightMode();

    theAIScontext->Display(rShape, DisplayMode, -1, Standard_False, DisplayStatus);
}

When I put DisplayMode fix to 1, then it does hide from the first time, but then my STL meshes are not shown proper anymore.

theAIScontext->Display(rShape, 1, -1, Standard_False, DisplayStatus);

show/hide is done with RecurseShowHide

void RecurseShowHide(const Handle(AIS_InteractiveContext)& rInteractiveContext, Handle(AIS_InteractiveObject)& theIObj, bool ibShow, bool bShowTrihedron, bool bRedraw)
{
    if (theIObj.IsNull())
        return;
    bool bShow = ibShow;
    Handle(AIS_CtrackTrihedron) hTrihedron = Handle(AIS_CtrackTrihedron)::DownCast(theIObj);
    if (!hTrihedron.IsNull())
        bShow = bShowTrihedron && ibShow;
    if (bShow)
        rInteractiveContext->Display(theIObj, bRedraw);
    else
        rInteractiveContext->Erase(theIObj, bRedraw);
    for (PrsMgr_ListOfPresentableObjectsIter aPrsIter(theIObj->Children()); aPrsIter.More(); aPrsIter.Next())
    {
        Handle(AIS_InteractiveObject) hChildInteractiveObject = Handle(AIS_InteractiveObject)::DownCast(aPrsIter.Value());
        if (!hChildInteractiveObject.IsNull())
            RecurseShowHide(rInteractiveContext, hChildInteractiveObject, bShow, bShowTrihedron, bRedraw);
    }
}
Luc Wens's picture

Here is the source file

Attachments: 
Luc Wens's picture

I'm wondering if this is a bug, so the next line

theAIScontext->Display(rShape, 1/* rShape->DisplayMode()*/, 0, Standard_False, DisplayStatus);

makes that AIScontext->Display and AIScontext->Erase work like expected. 

The next line, having the AIS_Object using its own displaymode, and in practice returning 0 for Shaded, makes Display and Erase behave differently:

theAIScontext->Display(rShape, rShape->DisplayMode(), 0, Standard_False, DisplayStatus);

Makes no sense to me ......

Kirill Gavrilov's picture

Your code relies on Parent/Children relationship logic between AIS_InteractiveObject presentations. This API is currently somewhat incomplete and not well defined - in particular behavior with inconsistent display modes used for children and parents.

Fill free to report bugs and suggest patches to mentioned functionality if you found it useful for your application. Current development snapshot of OCCT 7.6.0dev also includes one bugfix in Parent/Children visibility logic, though I cannot say if it affects the problem described in this topic anyhow.

Otherwise, I would suggest avoiding Parent/Children relationships between AIS_InteractiveObject's and implement logic propagating necessary attributes (transformations / visibility / etc.) from tree-like structure to a plain list of AIS_InteractiveObject basing on application requirements.

Luc Wens's picture

It does indeed relate to Parent/Children relationship.
I have a small demo project that shows the problem and will add this to a bug report.
I'll need to rethink the hierarchy in my current main project.

Tnx

Luc Wens's picture

Still a question: would using OCAF make a difference? The hierarchy is inherent to my application: a 6DOF coordinate system to which CAD files can attached and that is positioned by input of dynamic optical 6DOF measurements. I guess OCAF would allow me to retain this hierarchy, but I'm not sure if OCAF would suffer from the same bug

Kirill Gavrilov's picture

I don't see how OCAF could make any difference. OCAF is focused on data model storage, not on visualization - so that it is up to application to decide how to replicate hierarchy in OCAF document within the AIS viewer.

Usually, the main thing to reproduce in the viewer from the tree structure in the document is proper part transformation, inheriting transformation of all parents. This doesn't require creation of AIS_InteractiveObject with parents and children - you may define local local transformation (TopLoc_Location/gp_Trsf) of each AIS_InteractiveObject as a final transformation with all parents premultiplied, and take care to update object location AIS_InteractiveContext::SetLocation() on update of any parent.