Added a callback to display selected shapes properties
A feature that comes with recent PR from pythonocc-core https://github.com/tpaviot/pythonocc-core/pull/211
This enables the display of IFC product properties whenever the selection change. It should not be that hard to display the text in the graphic window, with some kind of pretty printing with tabs.
Great! Out of curiosity, a question though. How does a TopoDS_Shape in a Python dict work? Is it based on HashCode and IsEqual? Can we expect issues in case two IFC windows share the same geometry (hopefully with different location of course)?
hi @aothms ,
So your TopoDS_Shape has the IsSame method:
Returns True if two shapes are same, i.e. if they share the same TShape with the same Locations. Orientations may differ.
There's also the IsPartner method:
Returns True if two shapes are partners, i.e. if they share the same TShape. Locations and Orientations may differ.
@aothms For python objects to be used as distionary keys, the hash method is called. It must return a unique ID.
The rule for pythonocc wrapper is the following: for each oce class that declares a HashCode method, I overload the hash python method (see the rule in the pythonocc-generator https://github.com/tpaviot/pythonocc-generator/blob/master/src/generate_wrapper.py#L910). In the TopoDS.i file, fot instance, you can see:
%extend {
Standard_Integer __hash__() {
return $self->HashCode(2147483647);
}
};
This way, we use the internal oce hash mechanism. It's the safest way to ensure keys unicity.
For the case where two ifcproducts share the same representation, this must be tested.
Thanks both for the explanation.
It seems that the hashing and storing as dict keys works well for the quick tests I did.
Keep in mind though that Python does consider dictionary keys and set elements to be immutable. For this reason for example the frozenset element is introduced. TopoDS_Shapes are not immutable.
This means that:
>>> import OCC.BRepPrimAPI, OCC.gp, OCC.TopLoc
>>> s = OCC.BRepPrimAPI.BRepPrimAPI_MakeBox(1.,1.,1.).Shape()
>>> d = {s: 's'}
>>> trsf = OCC.gp.gp_Trsf()
>>> trsf.SetTranslation(OCC.gp.gp_Vec(1,1,1))
>>> s.Move(OCC.TopLoc.TopLoc_Location(trsf))
>>> s in d
False
Which I suppose is perfectly fine for most purposes. I mean, the shape has moved so it's no longer in the dictionary. But it also means the dictionary keys themselves are not in the dict, which is a bit inconsistent. Because they are stored in the wrong bucket according to the changed HashCode.
>>> next(iter(d.keys())) in d
False
This also means that if somehow the viewer turns into an editor and things subtly change there may be issues identifying selected elements. Anyway, I'm sure you're aware of these things and I don't really see a way around this other than also implementing a TopoDS_FrozenShape or wrapping a const TopoDS_Shape somehow, which due to all the Open Cascade handles might not be really possible anyway.