How to set edge color & width of a shape (read from STEP) before storing it as thumbnail

kiiu.rib

Looking around for some CAD
Hello together,

I am struggeling now since days. Doing research, reading, trying to find working code & understanding the found code.
Thing is, I am complete new to OCCT (and also C++).

I am using pythonocc. I can read STEP and also creating a thumbnail of it with help of pythonocc (with reset face colors).
But I want to increase the line width of all edges as well, also I'd like to control the edge color.
(the code is basically copy & paste from around the internet)

Here is a part of my python code for creating the thumbnail. The shape was read from a .stp file with STEPCAFControl_Reader and XCAFDoc_DocumentTool.

Python:
    def __init__(self, request_id: str, file: str) -> None:
        self.doc = TDocStd_Document(TCollection_ExtendedString("_output"))
        self.file = file

        self.request_id = request_id

        self.thumbnail_dir = f"./tmp_thumbnail/{request_id}"
        os.makedirs(self.thumbnail_dir, exist_ok=True)

        self.thumbnail_display: Viewer3d = self.__create_display()
        self.thumbnail_context: AIS_InteractiveContext = self.thumbnail_display.Context
        self.thumbnail_drawer: Prs3d_Drawer = self.thumbnail_display.Context.DefaultDrawer()
 
[...]
  
    def __create_thumbnail(self, shape: TopoDS_Shape, image_filename: str) -> None:
        face_color = Quantity_Color(Quantity_NOC_TOMATO)
        black = Quantity_Color(Quantity_NOC_BLACK)
      
        # I want to change how edges get rendererd
        aspect = Graphic3d_AspectFillArea3d()
        aspect.SetEdgeOn()
        aspect.SetEdgeColor(black)
        aspect.SetEdgeWidth(2)

        # I reuse the display for other shapes as well. This is why clearing it is important.
        self.thumbnail_context.RemoveAll(True)
      
        # FIXME This doesn't work as expected ... I guess I have wrong expectations and I am doing something wrong here
        self.thumbnail_drawer.ShadingAspect().SetAspect(aspect)

        # displaying shape and exporting to image works as expected
        self.thumbnail_display.DisplayShape(shape, color=face_color, update=True)
        self.thumbnail_display.ExportToImage(image_filename)


For sure I am doing something wrong.
Very likely "changing" edges just works differently. I don't even know if I can just create such an aspect from out of nowhere and assign it. Also even if, I don't know where to assign it.
Until now I didn't find any piece of documentation that explains how the pieces are put together correctly...

Any hints, suggestions, corrections, help? Thanks very much!

Btw. setting width via FaceBoundaryAspect BEFORE adding the shape helps already with the edge width. But the same "trick" (that I don't understand) doesn't work for the color...

Python:
        ...
        self.thumbnail_drawer.FaceBoundaryAspect().SetColor(black)
        self.thumbnail_drawer.FaceBoundaryAspect().SetWidth(2)
        ...
        self.thumbnail_display.DisplayShape(shape, color=face_color, update=True)
 
Last edited:

natalia

CAD community veteran
Hello @kiiu.rib and welcome to our community.

You’re following the right way when you change parameters for the face boundary aspect.

You do not have these parameters influence in view because you did not redisplay your presentation after setting them. So, you need calling Redisplay for your shape presentation if it was already shown (in your sample after DisplayShape). To do this, you may get the presentations as output parameter of DisplayShape and after change face boundary aspect and call redisplay for the presentations (have a look at ‘to_display’ processing in LayerManager.py of https://github.com/tpaviot/pythonocc-core).

Or you may follow another way and create AIS_Shape outside of DisplayShape like it’s done in core_visualization_glsl.py sample of (https://github.com/tpaviot/pythonocc-demos). In this case you may set a new face boundary aspect directly to the presentation and after display it without additional redisplay.

I’ve checked face boundary aspect using on C++ sample by implementing the next code:

C++:
  // create presentation
  Handle(AIS_Shape) object = new AIS_Shape(shape);
  ...

  // display presentation in the viewer
  context->Display(object);
  ...

  // change parameters of face boundary aspect for the presentation
  auto drawer = object->Attributes();
  drawer->SetFaceBoundaryDraw(true);
  Handle(Prs3d_LineAspect) aspect = new Prs3d_LineAspect(Quantity_NOC_BLUE1,
                                                         Aspect_TOL_SOLID,
                                                         5);
  drawer->SetFaceBoundaryAspect(aspect);
  // redisplay presentation to have applyed parameters of face boundary aspect
  object->Redisplay(true);

The result is:
edge_width_color.png
 

kiiu.rib

Looking around for some CAD
Thank yo @natalia,

finally... With your snippet I managed to get a running example also with pythonocc.

The missing piece was actually the AIS_Shape thingy.
I wasn't aware that I need an instance of AIS_Shape in order to change those properties...
Ok, now with the knowlegde it makes of course... separation of concern and so on.
The TopoDS_Shape thingy is "only" for the "structural" information and the "rendering" part gets controlled via AIS_Shape (only my naive intepretation). And changing it globally in view isn't provided I guess (that was what I tried to do).

For what actually stands "AIS"?
TopoDS, I found out thanks to OpenAI stands for "Topological Data Structure".

While I'm at it.
Is there somewhere of a glossary for all the abbreviations used in OpenCascade?
(I already had some headcaches because of those)
 
Last edited:
Top