CustomAspects: a subshape made hidden is selectable

Hello forum,
please see the attached document.

I loaded into a viewer two cubes, two AIS_ColoredShape (Fig. 1)
I created a composite solid, one single AIS_ColoredShape (the previous are removed from the display) (Fig. 2)
I hid one of the cubes of the composite solid, acting on the AIS_ColoredDrawer (->setHidden(true)) (Fig. 3)
I called context Redisplay onto the interactive shape, since I don't want the hidden cube is selectable
Unfortunately the hidden cube is selectable (Fig. 4)
Could you please help me?
Grazie
Giovanni

P.S. OpenCascade 7.3.0, Windows10

Attachments: 
gkv311 n's picture

Could you prepare some code snippet reproducing the issue? This logic should work, if I understand description correctly.

Giovanni Bettega's picture

void occWidget::hideSelectedBodies()
{
// check if the selected body is a main shape
for(occContext->InitSelected(); occContext->MoreSelected(); occContext->NextSelected())
{
const occHandle(AIS_ColoredShape)& curAISShape =
occHandle(AIS_ColoredShape)::DownCast(occContext->SelectedOwner()->Selectable());

occHandle(SelectMgr_EntityOwner) so = occContext->SelectedOwner();
occHandle(StdSelect_BRepOwner) bro = occHandle(StdSelect_BRepOwner)::DownCast(so);
const TopoDS_Shape& shape = bro->Shape();

if(curAISShape->Shape().ShapeType()==TopAbs_COMPSOLID && shape.ShapeType()==TopAbs_SOLID)
{
occContext->Unhilight(curAISShape,false);
curAISShape->CustomAspects(shape)->SetHidden(true);
occContext->Redisplay(curAISShape,false,true);
continue;
}
// the current selected shape is a "main" shape
occContext->Unhilight(curAISShape,false);
occContext->Erase(curAISShape,false);

}

occContext->ClearSelected(false);
occContext->UpdateCurrentViewer();
}

gkv311 n's picture

Is it done with enabled local selection for TopoDS_Solid?

Giovanni Bettega's picture

Selection mode is arbitrary. It is established by the buttons shown in the picture.
If a composite solid X is shown, and a face has been selected, X is hidden
If a composite solid X is shown, and one of its solids has been selected, only the selected solid is hidden
Giovanni

Attachments: 
gkv311 n's picture

Tip: use insert code or Markdown syntax for better forgetting in the forum.

Giovanni Bettega's picture

Hello, I would like to underline that is, obviously, possible to hide a set of faces (see picture), acting on custom aspects, and to make the hidden faces as not selectable by calling ::Redisplay.

Code (here a previous graphic selection of faces has been performed):

//! ----------------------------------------------------------
//! set the hidden state for the drawer of each selected face
//! ----------------------------------------------------------
for(occContext->InitSelected(); occContext->MoreSelected(); occContext->NextSelected())
{
    const occHandle(AIS_ColoredShape)& AISShape = occHandle(AIS_ColoredShape)::DownCast(occContext->SelectedOwner()->Selectable());
    const occHandle(StdSelect_BRepOwner)& bro = occHandle(StdSelect_BRepOwner)::DownCast(occContext->SelectedOwner());
    const TopoDS_Shape& selectedFace = bro->Shape();
    const occHandle(AIS_ColoredDrawer)& aDrawer = AISShape->CustomAspects(selectedFace);
    aDrawer->SetHidden(true);
}

//! ----------
//! redisplay
//! ----------
for(occContext->InitSelected(); occContext->MoreSelected(); occContext->NextSelected())
{
    const occHandle(AIS_ColoredShape)& AISShape = occHandle(AIS_ColoredShape)::DownCast(occContext->SelectedOwner()->Selectable());
    occContext->Redisplay(AISShape,false);
}
occContext->ClearSelected(true);

Redisplay is in separated for cycle only for clarity Ciao Giovanni

Attachments: 
gkv311 n's picture

I'm unable reproducing the issue with the given code snippet neither on OCCT 7.3.0 not on the latest release. So it is better expanding sample with more elaborated reproducible scenario.

pload MODELING VISUALIZATION
box b1 1 2 3
box b2 3 0 0 2 1 3
compound b1 b2 c
vinit View1
vdisplay -dispMode 1 c
vfit
vaspects c -subshape b1 -setcolor RED
vselmode c 6 1
vaspects c -subshape b2 -setvisibility 0
#mytest; # or via code snippet after selection

Redisplay is in separated for cycle only for clarity

That should be done not for clarity but rather for a proper workflow. Changing objects while iterating over selection is fragile, and moreover - suboptimal in case, when more than one subshape is selected (the same object will be redisplayed multiple times). The proper way would be collecting the list of modified presentations (into NCollection_IndexedMap<Handle(AIS_ColoredShape)> or something like this) and redisplaying them afterwards.

const occHandle(AIS_ColoredShape)& AISShape = occHandle(AIS_ColoredShape)::DownCast()

...

const occHandle(AIS_ColoredDrawer)& aDrawer = AISShape->CustomAspects(selectedFace);

In these cases, compilers would handle this safely, but it is better not storing a temporary object by reference. Always check what method returns, these methods return copies of Handle() objects.

Giovanni Bettega's picture

Thank you gkv,
also with the suggested changes, a face selection can be hidden and becomes not selectable,
while a selection of solids of a composite solid can be made hidden, but not unselectable by calling Redisplay.
Per me rimane un piccolo mistero.
Ciao
Giovanni

gkv311 n's picture

Could you share some composite solid model?

Giovanni Bettega's picture

of course just for info I built the composite solid in attachment using something like that:

BOPAlgo_Builder builder;
builder.SetGlue(BOPAlgo_GlueShift);
builder.AddArgument(cube1);
builder.AddArgument(cube2);
builder.Perform();
TopoDS_Shape compositeSolid = builder.Shape();
BRepTools::Write(resultingShape,"D://compsolid.brep");

Grazie ciao Giovanni

Attachments: 
gkv311 n's picture

OK, I see now that the problem happens specifically while picking shared Faces.

pload MODELING VISUALIZATION
box b1  0  0   0 100 100 100
box b2 50 50 100 100 100 100
bclear
baddobjects b1 b2
bapisplit c
explode c So
vinit View1
vdisplay -dispMode 1 c
vfit
vaspects c -subshape c_2 -setvisibility 0
vselmode c 6 1
vmoveto 200 200

Giovanni Bettega's picture

Thank you gkv for yout comment.
Nice to know that someone works up to 8 p.m.!
The AIS_Shape->Shape() is a composite solid.
The "problem" is that when hiding one of the two solids
by setting its custom drawer as hidden, and then calling
redisplay onto the AIS_Shape, the hidden solid can be
selected, and it is also detected when moving mouse
Buona serata e grazie
ciao
Giovanni

Sathiya nathan's picture

Hi Giovanni,
I think while setting the sub shape hidden it removes only presentation, To avoid selection you may need reconstruct the TopoDs_shape by removing the selected faces. In another way override ComputeSelection function and skip adding the faces which are not visible to selection structure.
It may have performance impact but this is what i found.

void MyAIS_Object::ComputeSelection(const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer theMode)
{

for (exp.Init(shape, TopAbs_FACE); exp.More(); exp.Next())
{
TopoDS_Face aFace = TopoDS::Face(exp.Current()));
// Check the AISColoredDrawer of this face is visible or not here
bool shapeVisible = true;
if(shapeVisible)
{
switch (theMode)
{
case 0: StdSelect_BRepSelectionTool::Load (theSelection, this, aFace , TopAbs_SHAPE, 0, 0); break;
case 1: StdSelect_BRepSelectionTool::Load (theSelection, this, aFace , TopAbs_VERTEX, 0, 0); break;
case 2: StdSelect_BRepSelectionTool::Load (theSelection, this, aFace , TopAbs_EDGE, 0, 0); break;
case 3: StdSelect_BRepSelectionTool::Load (theSelection, this, aFace , TopAbs_WIRE, 0, 0); break;
case 4: StdSelect_BRepSelectionTool::Load (theSelection, this, aFace , TopAbs_FACE, 0, 0); break;
}
}
}
}

Giovanni Bettega's picture

Thank you for your hint. What actually I would like to say is that hide/show of a face of an AIS_ColoredShape works very well. Indeed, when I hide a face of a solid and then I call AIS_InteractiveContext::Redisplay on that AIS_ColoredShape, the hidden face cannot be selected (and highlighted) anymore. This because AIS_InteractiveContext::Redisplay does exactly what you're saying:

void AIS_InteractiveContext::Redisplay (const Handle(AIS_InteractiveObject)& theIObj, const Standard_Boolean theToUpdateViewer, const Standard_Boolean theAllModes) { RecomputePrsOnly (theIObj, theToUpdateViewer, theAllModes); RecomputeSelectionOnly (theIObj); }

The problem is actually that when I hide a TopoDS_Solid "child" or (or subshape of) a TopoDS_Compsolid, and I call Redisplay, the hidden solid remains selectable. Grazie e buona serata Giovanni

Giovanni Bettega's picture

At the end a workaround