DiscussionsIssue archiveVisualization and 3D Viewer

Archived discussion

CustomAspects: a subshape made hidden is selectable

Visualization and 3D ViewerMon, 01/23/2023 - 21:3315 replies

Browse this forum
QuestionAuthor

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
Author

P.S. OpenCascade 7.3.0, Windows10

Discussion

15 archived replies

Posts are displayed in their archived order.

01Commenter-1

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

02Author

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();
}

03Commenter-1

Is it done with enabled local selection for TopoDS_Solid?

04Author

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
Author

05Commenter-1

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

06Author

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 Author

07Commenter-1

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.

08Author

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
Author

09Commenter-1

Could you share some composite solid model?

10Author

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 Author

11Commenter-1

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

Archived image: external image

12Author

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
Author

13Commenter-2

Hi Author,
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;
}
}
}
}

14Author

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 Author

15Author

At the end a workaround