coin, remove SoClipPlaneManip

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
bernd
Veteran
Posts: 12851
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland
Contact:

Re: coin, remove SoClipPlaneManip

Post by bernd »

:D

Code: Select all

import Part
Part.show(Part.makeBox(10,10,10))
from pivy import coin
clip_plane = coin.SoClipPlaneManip()
clip_plane.setValue(coin.SbBox3f(4, 4, 4, 8, 8, 8), coin.SbVec3f(-1, -1, -1), 1)
Gui.ActiveDocument.ActiveView.getSceneGraph().insertChild(clip_plane, 1)
Gui.ActiveDocument.ActiveView.viewAxonometric()
Gui.ActiveDocument.ActiveView.fitAll()
User avatar
looo
Veteran
Posts: 3941
Joined: Mon Nov 11, 2013 5:29 pm

Re: coin, remove SoClipPlaneManip

Post by looo »

because getChildren returns the internal list of the SoGroup instance and when removing a child the list will be affected, too. The first child will be removed correctly but with the second step the iterators are invalid.

That's why for node in list(a.getChildren()): works because you don't directly manipulate the list you iterate over.
Any chance we can avoid this? should getChildren() return a python-list containing the nodes?
wmayer
Founder
Posts: 20310
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: coin, remove SoClipPlaneManip

Post by wmayer »

Any chance we can avoid this? should getChildren() return a python-list containing the nodes?
This might be an option but I am not sure if this can cause problems somewhere else. But the basic problem is that one shouldn't manipulate a list while iterating over it.

Here is a pure Python example where the result isn't obvious either:

Code: Select all

l=[1,2,3,4,5,6,7,8,9]
for i in l:
  l.remove(i)
  
l # -> [2, 4, 6, 8]
User avatar
Gift
Posts: 769
Joined: Tue Aug 18, 2015 10:08 am
Location: Germany, Sauerland

Re: coin, remove SoClipPlaneManip

Post by Gift »

I do not know main problem. But I would traverse the list in reverse order.

Code: Select all

l=range(1,9)
for i in reversed(l):
  l.remove(i)
Post Reply