pythonocc-core icon indicating copy to clipboard operation
pythonocc-core copied to clipboard

Problem with own subclass of AIS_Shape

Open PM23999 opened this issue 1 year ago • 4 comments

Dear community,

I want to assign a unique ID to an AIS_Shape and have therefore created the subclass My_AIS_Shape:

class My_AIS_Shape(AIS_Shape):
    def __init__(self, shape: TopoDS_Shape, id: str):
        super().__init__(shape)
        self.ID = id
        ...

ais_context = display.GetContext()
new_aisshape = My_AIS_Shape(topodsshape, "newid")
ais_context.Display(new_aisshape, True)

new_gpTrsf = gp_Trsf(...)
ais_context.SetLocation(new_aisshape, TopLoc_Location(new_gpTrsf))
display.View.Redraw()

There is no problem assigning an instance of this class to the AIS_Context and manipulating it via the AIS_Context. My goal now is to use the "mouse picking logic" functions of the AIS_Context:

ais_context.MoveTo(100, 100, display.View, True)
has_detected = ais_context.HasDetected()
if has_detected:
    ais_detected = ais_context.DetectedInteractive()
	print("AIS_Shape with ID:", ais_detected.ID)  # ID from class My_AIS_Shape

The problem now is that ais_context.DetectedInteractive() returns an AIS_InteractiveObject whose class is AIS_Shape and not My_AIS_Shape as hoped.

ais_detected.IsInstance("AIS_Shape") -> True
ais_detected.IsInstance("My_AIS_Shape") -> False

How can I solve this problem and get an object of my own class back from ais_context.DetectedInteractive() to access the ID attribute?

Thank you very much in advance for tips and help,

best regards Michael

PM23999 avatar Feb 18 '24 10:02 PM23999

Interesting issue, I was not aware of this behavior. This needs further investigation.

tpaviot avatar Feb 22 '24 15:02 tpaviot

@PM23999 can you provide a full but small example ready to be launched pease?

tpaviot avatar Feb 22 '24 15:02 tpaviot

It might be necessary to subclass the AIS_InteractiveContext itself to implement the desired feature.

tpaviot avatar Feb 22 '24 15:02 tpaviot

Hello Thomas,

Thanks for your answer.

Here is the example you want:

from OCC.Display.SimpleGui import init_display
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeSphere
from OCC.Core.AIS import AIS_Shape


class My_AIS_Shape(AIS_Shape):
    def __init__(self, shape, my_id):
        super(My_AIS_Shape, self).__init__(shape)
        self.ID = my_id


display, start_display, add_menu, add_function_to_menu = init_display()
context = display.GetContext()

my_sphere = BRepPrimAPI_MakeSphere(100.).Shape()
new_my_ais_shape = My_AIS_Shape(my_sphere, "My_ID")
context.Display(new_my_ais_shape, True)

size = display.View.Window().Size()                                          # tuple = Window Size in Pixel
context.MoveTo(int(size[0] / 2), int(size[1] / 2), display.View, True)  # Sphere is now dynamic highlighted

if context.HasDetected():
    detected_interactive = context.DetectedInteractive()
    print(detected_interactive)                               # <class 'AIS_InteractiveObject'>
    print(type(detected_interactive))                         # <class 'OCC.Core.AIS.AIS_InteractiveObject'>
    print(detected_interactive.IsInstance("AIS_Shape"))       # True
    print(detected_interactive.IsInstance("My_AIS_Shape"))    # False

start_display()

Could it be that the problem is due to the RTTI (Run Time Type Information)? Doesn’t a new class of RTTI need to be announced?

Regarding your proposed solution to create a subclass of the AIS_InteractiveContext: How could this happen, can you show me an example of this?

As an alternative, I have already tried assigning an owner to the AIS_Shape (of type TCollection_HAsciiString) but unfortunately that doesn't work either (context.DetectedOwner()).

How else could I easily assign a unique ID to an AIS_Shape?

Thank you very much for your help

best Regards

Michael

PM23999 avatar Feb 23 '24 11:02 PM23999