SceneGraphReducer, how to exclude nodes

I have made a database with windmills (windgenerators) that are animated to spin the rotors. In order to reduce the GeomNodes, the SceneGraphReducer is used to flatten the database. This works fine, the number of GeomNodes are strongly reduced, but ofcourse the animations of the windgenerators don’t work then anymore. So, I tried to put those windgenerators in a different NodePath (self.generators) and reparent that to render, see the attached code, to exclude them from being flattened. But then they are not rendered anymore. So I obviously overlooked something.
How can I change this code, so that the windgenerators are rendered again ?

            self.world = loader.loadModel(fname)
            self.world.reparentTo(render)
            # make WindGenerator list for animations
            self.WindGenerators = self.world.findAllMatches("**/WindGenerator")
            self.generators = NodePath("generatornode")
            self.generators.reparentTo(render)
            for generator in self.WindGenerators:
                generator.reparentTo( self.generators )
  
            gr = SceneGraphReducer()
            gr.applyAttribs(self.world.node())
            gr.setCombineRadius(300)
            gr.flatten(self.world.node(), ~gr.CSOther)
            gr.makeCompatibleState(self.world.node())
            gr.collectVertexData(self.world.node(),~(gr.CVDFormat|gr.CVDName|gr.CVDAnimationType))
            gr.unify(self.world.node(), False)
            
            self.world.analyze()
            taskMgr.add(self.animateWindGenerators, "WindGenerator task")

When you say the windmills are “animated”, you mean they are animated using keyframes in the source package? And that you play the animation using the Actor code? Do you load the model as one big Actor, with all windmills already contained within it, and only call play() once to play all the windmills?

If so, then that explains why reparenting the windmills will cause problems, because you can’t move nodes out from under an Actor and expect things to work the same way. On the other hand, it’s maybe time to look for a different area of optimization, because it’s likely that your windmills are already combined into a single Geom (or as few as possible)–this is the default behavior of the Actor loader (unless you have flagged many pieces, for instance for the purpose of allowing reparenting). You can use root.analyze() or PStats to determine how many Geoms you actually have.

If you are animating them through some other means, for instance due to an interval or a task that changes each node’s hpr at runtime, then you can use the RigidBodyCombiner to flatten the windmill blades succesfully. But regardless of the RigidBodyCombiner, in this case, your reparenting approach should have worked, unless of course you have overlooked an intervening transform. If there was an intervening transform, then you moved the windmills when you reparented them–try using generator.wrtReparentTo() instead of generator.reparentTo().

David

I am animating them via setting the heading of a node each interval. The generator.wrtReparentTo() modification did the trick though. Now they are visible again and the animation works. Thank you very much !