tpaviot / pythonocc-demos

Examples and demos for the pythonocc CAD package
216 stars 115 forks source link

Width in TopodsWires and selection in AIS_line #54

Open elliotaugust opened 2 years ago

elliotaugust commented 2 years ago

Hello Sir.

I am currently working on a project with pythonocc==7.5.1 where I am modeling a 2D object which can be written as multiple lines. I need to be able to do two things at the same time:

I tried two different methods, but neither satisfy both of the previous requirements:

  1. Creating the lines as wires: I get the information on which wire was selected, but I can't seem to change its aspect
  2. Creating the lines as AIS_lines: I can change the width, but can't get any information on which line was selected

Could you please give me any suggestions to be able to solve this issue? I thank you in advance for any insight you might provide!

Here is a simple example to demonstrate the issue I am having.

import numpy as np
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeWire
from OCC.Core.gp import gp_Pnt
from OCC.Core.TopoDS import TopoDS_Wire
from OCC.Core.Quantity import Quantity_Color, Quantity_TOC_RGB
from OCC.Core.Geom import Geom_CartesianPoint
from OCC.Core.AIS import AIS_Line
from OCC.Core.Prs3d import Prs3d_LineAspect

def on_click(shapes, *kwargs):

    if len(shapes) == 0:
        # AIS LINE ARE NOT CAUGHT! Shape is an empty list
        print("On click ===> Empty shape list!")

    for shape in shapes:  
        if isinstance(shape, TopoDS_Wire):
            # WIRES ARE CAUGHT HERE
            print("On click ===> TopoDS_Wire!")

def display_lines_as_wires(lines):

    for [x1,y1],[x2,y2] in lines:
        wire = BRepBuilderAPI_MakeWire()
        edge = BRepBuilderAPI_MakeEdge(gp_Pnt(x1, y1, 0), gp_Pnt(x2, y2, 0)).Edge()
        wire.Add(edge)

        display.DisplayShape(wire.Shape(), update=False, color="RED")

def display_ais_lines(lines):

    width = 5.
    color = Quantity_Color(13/255, 13/255, 203/255, Quantity_TOC_RGB)

    for [x1,y1],[x2,y2] in lines:

        ais_line = AIS_Line(
            Geom_CartesianPoint(x1,y1,0),Geom_CartesianPoint(x2,y2,0)
        )
        drawer = ais_line.Attributes()
        aspect = Prs3d_LineAspect(color, 0, width)
        drawer.SetLineAspect(aspect) 
        ais_line.SetAttributes(drawer)

        display.Context.Display(ais_line, False)

if __name__ == "__main__":

    points = np.random.normal(size=(5,2))
    lines = np.array([[points[i], points[i+1]] for i in range(len(points)-1)])
    offset_lines = lines + 4

    from OCC.Display.SimpleGui import init_display
    display, start_display, add_menu, add_function_to_menu = init_display()

    display_ais_lines(lines)
    display_lines_as_wires(offset_lines)
    display.register_select_callback(on_click)
    display.FitAll()
    start_display()