By the way, I have a related question, which may be more appropriate for the OCC forums, since I know it is an OCC issue and not specific to pythonocc. But maybe you OCC-gurus can help me out ;-)
Why is it that TopExp_Explorer sometimes returns the same shapes multiple times, e.g. in my code I'm using ShapeFix to turn a complex shell with internal faces into a COMPSOLID with multiple SOLIDs that share these internal faces, but for some reason the same SOLIDs get returned multiple times by TopExp_Explorer. E.g. say my COMPSOLID consists of two SOLIDs, these two solids get returned by the explorer 4 times each (S1, S2, S1, S2, etc.)! Yet another reason why we need the __hash__ to work properly for shapes, as every time the same SOLID is returned it has a different id, i.e. id(1st S1) != id(2nd S1), but S1.HashCode() == S2.HashCode(). Cheers, Frank Thomas Paviot wrote: > Hello Franck, > > It's really a good idea to map the Hash() OpenCascade method and the > python __hash__(). I read a few posts on the __hash__() topic. A good > one is, for instance: > http://mail.python.org/pipermail/python-dev/2003-September/037923.html . > > It's said that 'object.__hash__() returns id(obj) by default'. I > tested that a little: > >>> a = object() > >>> a.__hash__() > 10093672 > >>> id(a) > 10093672 > >>> > > But, if __hash__ is overloaded, then __hash() and id() returns 2 > different integers. > > This is then my proposition: > - *for each* pythonOCC object that is managed by Handle_* (and thus, > for which the HashCode() method is available), overload the __hash__ > method as Frank said. It can be done within SWIG with two or three > more lines in the SWIG_generator.py script. > - for other pythonOCC objects, leave the default __hash__ method (thus > equivalent to id() ) > > Thomas > > Frank Conradie a écrit : >> Hi Jelle >> >> My particular need was to hash TopoDS_Shape objects properly. I'm not >> sure if this is a good permanent solution, but this works for me, for >> shapes at least: >> >> def shape_hash(self): >> return self.HashCode(sys.maxint) >> TopoDS.TopoDS_Shape.__hash__ = shape_hash >> >> Now I can use shapes in a Python set and as keys in a Python dict - >> which also means that your Topology.Topo class works properly now (if >> topo_item in topo_set)! >> >> I can't help thinking there must be a more general way to incorporate >> this into the SWIG wrapper for *all* OCC classes, but I don't know >> enough about swig yet to know for sure. >> >> Cheers, >> Frank >> >> jelle feringa wrote: >>> >>> In order to use pythonocc objects in sets and as dict keys, they >>> must hash to the underlying OCC object. In fact, your Topo class >>> uses a set internally that does not work because of this very >>> fact, because set checks for set membership via hash, and thus, >>> two of the same objects that get explored will hash to different >>> values and thus be passed back twice. >>> >>> >>> Hi Frank, >>> >>> This is really interesting, thanks so much for explaining. >>> Actually, now I recall what I messed up. I looped through a list of >>> some topology, lets say vertices and checked for their id -> >>> id(vertex). >>> That did work, however as you point out hash != id. >>> I think overloading the hash with comparing id()'s could work. >>> >>> >>> Hope this makes sense. >>> >>> >>> A lot, thanks for your advice here. >>> >>> >>> I suppose I could overwrite __hash__ the same way you guys >>> initially got past the == issue. >>> >>> >>> What do you think of overloading hash with id? >>> I'll check tomorrow morning, would be great if this is a stable fix, >>> it sure could be useful. >>> >>> Thanks, >>> >>> -jelle >>> >> ------------------------------------------------------------------------ >> >> _______________________________________________ >> Pythonocc-users mailing list >> Pythonocc-users@gna.org >> https://mail.gna.org/listinfo/pythonocc-users >> > _______________________________________________ Pythonocc-users mailing list Pythonocc-users@gna.org https://mail.gna.org/listinfo/pythonocc-users