AIS_Shape Dynamic Hilight line width does not work


I would like to change the attributes of Edge presentation in DynamicHilightAttributes. But it does not work.

Handle(AIS_InteractiveContext) ctx = ...; 
TopoDS_Shape shape = MakeBox(20, 20, 20); 
Handle(AIS_Shape) prs = new AIS_Shape(shape); 
prs->SetDynamicHilightAttributes(new Prs3d_Drawer()); 
prs->DynamicHilightAttributes()->SetLineAspect(new Prs3d_LineAspect(Quantity_NOC_RED, Aspect_TOL_SOLID, 10.0)); 
ctx->Display(prs, false); 
ctx->SetDisplayMode(prs, AIS_Shaded, false); 
ctx->Activate(prs, AIS_Shape::SelectionMode(TopAbs_EDGE)); 

At this point i can detect the edges of the presentation. But i would like to override the default graphical representation of a detected Edge. Increase the line width and change the color. I thought this was the role of DynamicHilightAttributes()->LineAspect();

I think there is something i am missing.

Thank you for your help, Aurelien

Kirill Gavrilov's picture

Highlighting of AIS_Shape reuses the same presentation for a normal display, so that DynamicHilightAttributes() affects only color and a couple of other attributes, but not fine-grained attributes like number of isolines to compute or width of wires. See also a comment for method AIS_InteractiveContext::HighlightStyle():

Tip: although highlighting style is defined by Prs3d_Drawer, only a small set of properties derived from it's base class Graphic3d_PresentationAttributes will be actually used in most cases.

You will need modifying behavior of AIS_Shape if you really need highlighting to have different presentation - like making a dedicated display mode or customizing SelectMgr_EntityOwner::HilightWithColor() within subclasses.

Alternatively, Graphic3d_PresentationAttributes might be extended within OCCT itself to allow overriding line width (as a multiplier, for instance) for highlighting.

Aurélien Schmit's picture

So one of the best solutions for specific highlighting behaviour is probably to create a new presentation that better suits the needs.

Now without talking about highlighting, only taking into account the presentation. For an AIS_Shape, in theory we could change the width of the face boundaries with the SetWidth() method.

When we look at the source code of AIS_Shape.cxx, the SetWidth() method modifies the FaceBoundary aspect. Note that SetFaceBoundaryDraw(Standard_True).

bool AIS_Shape::setWidth (const Handle(Prs3d_Drawer)& theDrawer,
                          const Standard_Real theLineWidth) const
  bool toRecompute = theDrawer->SetOwnLineAspects();

  // override width
  theDrawer->LineAspect()->SetWidth (theLineWidth);
  theDrawer->WireAspect()->SetWidth (theLineWidth);
  theDrawer->FreeBoundaryAspect()->SetWidth (theLineWidth);
  theDrawer->UnFreeBoundaryAspect()->SetWidth (theLineWidth);
  theDrawer->SeenLineAspect()->SetWidth (theLineWidth);
  theDrawer->FaceBoundaryAspect()->SetWidth (theLineWidth);
  return toRecompute;

Then: AIS_Shape::Compute() - StdPrs_ShadedShape::Add(thePrs, myShape, myDrawer, ...)

  if (theDrawer->FaceBoundaryDraw())
    if (Handle(Graphic3d_ArrayOfSegments) aBndSegments = fillFaceBoundaries (theShape, theDrawer->FaceBoundaryUpperContinuity()))
      Handle(Graphic3d_Group) aPrsGrp = thePrs->NewGroup();
      aPrsGrp->SetGroupPrimitivesAspect (theDrawer->FaceBoundaryAspect()->Aspect());
      aPrsGrp->AddPrimitiveArray (aBndSegments);

We can see that for the display of face boudaries, the aspect taken into account is FaceBoudaryAspect whose Width we modified just before.

The problem is that nothing has changed visually. Face boundaries still have the default width.

Kirill Gavrilov's picture

Which OpenGL setup are you running on (Core or Compatible profile / direct or virtual environment)? Does it support thick lines at all?