How to reduce Draw/Primitive/Setup?

Hi, I am trying to improve performances into my current project. The worst section in pstats is Draw/Primitive/Setup, which requires 480ms more or less (while pstats is running on the same machine).
What does this section measure? How could I reduce it?

This is the output of render2d.analyze():

23 total nodes (including 0 instances); 0 LODNodes.
19 transforms; 17% of nodes have some render attribute.
1 Geoms, with 1 GeomVertexDatas and 1 GeomVertexFormats, appear on 1 GeomNodes.
4 vertices, 4 normals, 0 colors, 4 texture coordinates.
GeomVertexData arrays occupy 1K memory.
GeomPrimitive arrays occupy 0K memory.
2 triangles:
  2 of these are on 1 tristrips (2 average tris per strip).
  0 of these are independent triangles.
1 textures, estimated minimum 352K texture memory required.

This is the output of render2d.ls():

PandaNode render2d S:(CullFaceAttrib DepthTestAttrib DepthWriteAttrib MaterialAttrib)
  PGTop aspect2d T:(scale 0.562225 1 1) S:(CullBinAttrib)
    PandaNode a2dBackground
    PandaNode a2dTopCenter T:(pos 0 1 1)
    PandaNode a2dTopCenterNS T:(pos 0 1 1)
    PandaNode a2dBottomCenter T:(pos 0 -1 -1)
    PandaNode a2dBottomCenterNS T:(pos 0 -1 -1)
    PandaNode a2dLeftCenter T:(pos -1.77865 0 0)
    PandaNode a2dLeftCenterNS T:(pos -1.77865 0 0)
    PandaNode a2dRightCenter T:(pos 1.77865 0 0)
    PandaNode a2dRightCenterNS T:(pos 1.77865 0 0)
    PandaNode a2dTopLeft T:(pos -1.77865 1 1)
    PandaNode a2dTopLeftNS T:(pos -1.77865 1 1)
    PandaNode a2dTopRight T:(pos 1.77865 1 1)
    PandaNode a2dTopRightNS T:(pos 1.77865 1 1)
    PandaNode a2dBottomLeft T:(pos -1.77865 -1 -1)
    PandaNode a2dBottomLeftNS T:(pos -1.77865 -1 -1)
    PandaNode a2dBottomRight T:(pos 1.77865 -1 -1)
    PandaNode a2dBottomRightNS T:(pos 1.77865 -1 -1)
    GeomNode OnscreenImage (1 geoms) T:(pos 1.60644 0 -0.515712 scale 0.0581818 1 0.08) S:(CullBinAttrib TextureAttrib TransparencyAttrib) (hidden)
  PGTop pixel2d T:(pos -1 0 1 scale 0.00146413 1 0.00260417) S:(CullBinAttrib)
  PandaNode camera2d
    Camera cam2d ( OrthographicLens )
      OrthographicLens film size = 2 2

This is the output of render.analyze():

123 total nodes (including 0 instances); 0 LODNodes.
49 transforms; 8% of nodes have some render attribute.
1310 Geoms, with 1310 GeomVertexDatas and 1 GeomVertexFormats, appear on 66 GeomNodes.
3409336 vertices, 3409336 normals, 0 colors, 3409336 texture coordinates.
GeomVertexData arrays occupy 106883K memory.
GeomPrimitive arrays occupy 17098K memory.
3 vertices are unreferenced by any GeomPrimitives.
570 GeomVertexArrayDatas are redundant, wasting 316K.
3551 GeomPrimitive arrays are redundant, wasting 16234K.
2975040 triangles:
  259498 of these are on 87141 tristrips (2.97791 average tris per strip).
  2715542 of these are independent triangles.
107 textures, estimated minimum 420162K texture memory required.

This is the output of render.ls():

PandaNode render S:(CullFaceAttrib LightAttrib RescaleNormalAttrib ShaderAttrib)
  ModelNode camera T:q(pos 151.447 175.52 30.4225 hpr 43.2293 -50.4029 -2.67899e-06)
    Camera cam ( PerspectiveLens )
      PerspectiveLens fov = 50.9637 30
  PandaNode world
    BulletRigidBodyNode RoadOBJTrackasphalt (1 shapes) static mass=0
    BulletRigidBodyNode RoadOBJTrackdirt (1 shapes) static mass=0
    BulletRigidBodyNode Vehicle (1 shapes) mass=1400 T:(pos 136.341 193.646 0.233021 hpr 88.023 0 0)
      ModelRoot car.egg S:(DepthOffsetAttrib)
        GeomNode Car (1 geoms: S:(MaterialAttrib TextureAttrib))
    ModelRoot track.egg (per-camera hidden)
      GeomNode OBJPerimeter3 (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode OBJDoors (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode OBJGoal (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode OBJPerimeter2 (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode OBJPerimeter (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode OBJBridge (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode OBJTrackdirt (1 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode OBJTemple2 (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode OBJGate (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode OBJRock3 (1 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode OBJRock2 (1 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode OBJRock1 (1 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode OBJCurb (1 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode OBJBackground (1 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode OBJTrackasphalt (1 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode OBJTemple (1 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode OBJChain (1 geoms: S:(MaterialAttrib TextureAttrib TransparencyAttrib))
      GeomNode OBJPit (2 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode OBJWatertank (1 geoms: S:(MaterialAttrib TextureAttrib)) [friction speed]
      GeomNode Skydome (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Roulotte (3 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Poster3 (2 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Poster2 (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Poster (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Palm (18 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Tree2 (29 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Palm2 (146 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Palm3 (123 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Palm4 (29 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Roulotte2 (6 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Home2 (3 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Plant (128 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Well (3 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Tree (14 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Wallstone (4 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Electricpole (2 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Lampdesert1 (3 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Homedesert (13 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Milestone (2 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Electricwire1 (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Homedesert2 (4 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Homedesert3 (3 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Billboard4 (2 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Fencepole (12 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Homedesert6 (3 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Homedesert7 (13 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Homedesert4 (4 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Homedesert5 (14 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Tent3 (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Tent2 (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Homedesert8 (12 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Gasstation (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Stone1 (1 geoms: S:(MaterialAttrib TexMatrixAttrib TextureAttrib))
      GeomNode Tent4 (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Tent (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Wallstone2 (8 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Wallstone3 (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Fenceplank (11 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Stone (1 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Plant4 (74 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Home4 (5 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Home3 (3 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Home1 (3 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Plant2 (184 geoms: S:(MaterialAttrib TextureAttrib))
      GeomNode Plant3 (394 geoms: S:(MaterialAttrib TextureAttrib))
      PandaNode EmptyNameBillboard4Anim.008 T:(pos 228.672 162.416 5.15964 hpr 29.3223 0 0 scale 1.5) S:(TextureAttrib)
      PandaNode EmptyNameBillboard4Anim.007 T:(pos 399.039 80.7737 4.70668 hpr 29.3223 0 0 scale 1.5) S:(TextureAttrib)
      PandaNode EmptyNameBillboard4Anim.006 T:(pos 280.356 45.1327 2.48407 hpr -145.109 0 0 scale 1.5) S:(TextureAttrib)
      PandaNode EmptyNameBillboard4Anim.005 T:(pos 192.317 -104.641 3.35724 hpr -145.109 0 0 scale 1.5) S:(TextureAttrib)
      PandaNode EmptyNameBillboard4Anim.004 T:(pos 90.7823 -28.6396 -5.8146 hpr 59.7578 0 0 scale 1.5) S:(TextureAttrib)
      PandaNode EmptyNameBillboard4Anim.003 T:(pos -30.003 -97.9793 5.16697 hpr 59.7578 0 0 scale 1.5) S:(TextureAttrib)
      PandaNode EmptyNameBillboard4Anim.002 T:(pos -147.456 -19.9568 4.75931 hpr -125.336 0 0 scale 1.5) S:(TextureAttrib)
      PandaNode EmptyNameBillboard4Anim.001 T:(pos -95.9472 125.529 4.75931 hpr -99.7094 0 0 scale 1.5) S:(TextureAttrib)
      PandaNode EmptyNameBillboard4Anim T:(pos -43.4899 157.248 4.75931 hpr 34.3424 0 0 scale 1.5) S:(TextureAttrib)
      PandaNode EmptyHomedesert5Anim.013 T:(pos 15.3968 104.02 3.20816 hpr -177.21 -0.856079 -1.27381)
      PandaNode EmptyHomedesert5Anim.012 T:(pos 466.423 48.5392 21.2397 hpr -72.4667 0 0)
      PandaNode EmptyHomedesert5Anim.011 T:(pos 598.422 -123.659 33.3622 hpr -4.74453 0 0)
      PandaNode EmptyHomedesert2Anim.011 T:(pos 581.069 -150.763 33.3988 hpr 67.0011 0 0)
      PandaNode EmptyHomedesert8Anim.011 T:(pos 413.847 156.826 6.44169 hpr -89.8294 0 0)
      PandaNode EmptyHomedesert8Anim.010 T:(pos 411.788 365.536 6.41836 hpr 165.851 0 0)
      PandaNode EmptyHomedesert5Anim.010 T:(pos 411.563 318.087 5.40462 hpr -176.065 0 0)
      PandaNode EmptyHomedesert2Anim.010 T:(pos 424.627 347.499 5.29659 hpr -104.319 0 0)
      PandaNode EmptyHomedesert2Anim.009 T:(pos 334.651 -190.643 35.5382)
      PandaNode EmptyHomedesert5Anim.009 T:(pos 366.381 -196.027 35.5285 hpr -71.7456 0 0)
      PandaNode EmptyHomedesert8Anim.009 T:(pos 320.35 -207.544 36.8057 hpr -89.8294 0 0)
      PandaNode EmptyHomedesert8Anim.008 T:(pos 375.399 -254.651 37.2732 hpr -22.8283 0 0)
      PandaNode EmptyHomedesert5Anim.008 T:(pos 382.782 -207.779 35.546 hpr -4.74453 0 0)
      PandaNode EmptyHomedesert2Anim.008 T:(pos 365.429 -234.883 35.6557 hpr 67.0011 0 0)
      PandaNode EmptyHomedesert2Anim.007 T:(pos 304.437 -275.239 35.9011 hpr 67.0011 0 0)
      PandaNode EmptyHomedesert5Anim.007 T:(pos 321.79 -248.135 35.928 hpr -4.74453 0 0)
      PandaNode EmptyHomedesert8Anim.007 T:(pos 314.406 -295.006 36.8066 hpr -22.8283 0 0)
      PandaNode EmptyHomedesert8Anim.006 T:(pos 259.358 -247.9 36.4085 hpr -89.8294 0 0)
      PandaNode EmptyHomedesert5Anim.006 T:(pos 305.389 -236.383 35.9874 hpr -71.7456 0 0)
      PandaNode EmptyHomedesert2Anim.006 T:(pos 273.659 -230.999 35.6666)
      PandaNode EmptyHomedesert2Anim.005 T:(pos 401.605 -183.306 34.6609)
      PandaNode EmptyHomedesert5Anim.005 T:(pos 433.335 -188.69 34.7456 hpr -71.7456 0 0)
      PandaNode EmptyHomedesert8Anim.005 T:(pos 387.304 -200.207 36.4219 hpr -89.8294 0 0)
      PandaNode EmptyHomedesert8Anim.004 T:(pos 442.353 -247.313 36.8678 hpr -22.8283 0 0)
      PandaNode EmptyHomedesert5Anim.004 T:(pos 449.736 -200.441 34.7377 hpr -4.74453 0 0)
      PandaNode EmptyHomedesert2Anim.004 T:(pos 432.383 -227.545 34.5355 hpr 67.0011 0 0)
      PandaNode EmptyHomedesert2Anim.003 T:(pos 493.375 -187.19 33.7269 hpr 67.0011 0 0)
      PandaNode EmptyHomedesert5Anim.003 T:(pos 510.728 -160.086 33.4331 hpr -4.74453 0 0)
      PandaNode EmptyHomedesert8Anim.003 T:(pos 503.345 -206.957 35.7483 hpr -22.8283 0 0)
      PandaNode EmptyHomedesert8Anim.002 T:(pos 448.296 -159.851 34.4199 hpr -89.8294 0 0)
      PandaNode EmptyHomedesert5Anim.002 T:(pos 494.327 -148.334 33.1321 hpr -71.7456 0 0)
      PandaNode EmptyHomedesert2Anim.002 T:(pos 462.598 -142.95 33.2071)
      PandaNode EmptyHomedesert2Anim.001 T:(pos 565.312 309.985 5.22949)
      PandaNode EmptyHomedesert5Anim.001 T:(pos 597.042 304.601 5.43169 hpr -71.7456 0 0)
      PandaNode EmptyHomedesert8Anim.001 T:(pos 551.011 293.084 6.4423 hpr -89.8294 0 0)
      PandaNode EmptyHomedesert8Anim T:(pos 428.455 86.808 6.4423 hpr -89.8294 0 0)
      PandaNode EmptyHomedesert5Anim T:(pos -25.9026 -153.396 8.7636 hpr -72.1979 3.66274 -4.1989)
      PandaNode EmptyHomedesert2Anim T:(pos -54.6472 -149.839 6.57131 hpr 117.828 -2.41384 2.96857)
  AmbientLight ambient light:
    color 0.7 0.7 0.55 1

Thank you very much!

Take a look what’s inside
Tree2 (29 geoms)
Palm2 (146 geoms)
Palm3 (123 geoms)
Palm4 (29 geoms)
Plant (128 geoms)
Plant4 (74 geoms)
Plant2 (184 geoms
Plant3 (394 geoms)
8 objects out of 120 make up over a 1000 from the 1300 geoms in your scene, that can’t be good.
If these objects are static decorations each should be 1 geom, if you use them for something fancy like a destructible tree that breaks into 394 parts you should have it in two versions - a static 1 geom and the breakable 400 geoms version and switch them when the model is about to explode.

Hi wezu, thanks for your answer! Actually, these meshes are the result of flatten_strong, so there is something I am missing there.

Please, consider this example:

from panda3d.core import NodePath
import direct.directbase.DirectStart
base.disableMouse()
base.camera.set_pos(10, 10, 80)
base.camera.look_at(10, 10, 0)
root = NodePath('root')
root.reparent_to(render)
for i in range(100):
    panda = loader.loadModel('smiley')
    panda.reparentTo(root)
    panda.set_pos(i / 10 * 3, i % 10 * 3, 0)
print '\n\nanalyze (before)\n\n'
root.analyze()
print '\n\nls (before)\n\n'
root.ls()
root.clear_model_nodes()
root.flatten_strong()
print '\n\nanalyze (after)\n\n'
root.analyze()
print '\n\nls (after)\n\n'
root.ls()
base.run()

This is the output of analyze (before flatten_strong):

201 total nodes (including 0 instances); 0 LODNodes.
99 transforms; 0% of nodes have some render attribute.
100 Geoms, with 1 GeomVertexDatas and 1 GeomVertexFormats, appear on 100 GeomNodes.
673 vertices, 673 normals, 0 colors, 673 texture coordinates.
GeomVertexData arrays occupy 22K memory.
GeomPrimitive arrays occupy 8K memory.
128000 triangles:
  0 of these are on 0 tristrips.
  128000 of these are independent triangles.
1 textures, estimated minimum 384K texture memory required.

This is the output of ls (before flatten_strong):

PandaNode root
  ModelRoot smiley.egg
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 0 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 0 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 0 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 0 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 0 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 0 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 0 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 0 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 0 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 0 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 3 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 0 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 6 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 0 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 9 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 0 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 12 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 0 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 15 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 0 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 18 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 0 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 21 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 0 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 24 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 0 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 3 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 6 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 9 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 12 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 15 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 18 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 21 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 24 0)
    GeomNode  (1 geoms: S:(TextureAttrib))
  ModelRoot smiley.egg T:(pos 27 27 0)
    GeomNode  (1 geoms: S:(TextureAttrib))

This is the output of analyze (after flatten_strong):

2 total nodes (including 0 instances); 0 LODNodes.
0 transforms; 0% of nodes have some render attribute.
25 Geoms, with 25 GeomVertexDatas and 1 GeomVertexFormats, appear on 1 GeomNodes.
67300 vertices, 67300 normals, 0 colors, 67300 texture coordinates.
GeomVertexData arrays occupy 2104K memory.
GeomPrimitive arrays occupy 750K memory.
144 GeomPrimitive arrays are redundant, wasting 720K.
128000 triangles:
  0 of these are on 0 tristrips.
  128000 of these are independent triangles.
1 textures, estimated minimum 384K texture memory required.

This is the output of ls (after flatten_strong):

PandaNode root
  GeomNode smiley.egg (25 geoms: S:(TextureAttrib))

So, from 100 identical nodes I obtain one node which contains 25 geoms. Is it the expected behavior (I thought it could produce a single geom)? Can’t flatten_strong produce a single geom (sorry, but I don’t know its internals)? Thank you very much!

I would have expected one geom in this case… 100 would make some sort of sense, but 25? I have no idea.

I know flatten_strong can’t combine objects with different textures and/or materials (maybe also some other attributes), but that’s not the case here, smiley has just one texture.

Someone smarter is needed here :mrgreen:

Geoms can’t be flattened together if they have a different material. So, even a slightly different colour can have dramatic consequences.

480 ms is a bit excessive, though. I’d like to run your program through a profiler. Is the source code publicly available?

Thank you for the hint! The problem is that they should have the same material (or maybe I am misunderstanding the concept of “material”).

As instance, please consider the program into my second post. It creates 100 instances of smiley.egg; I saw its definition and it has a single Texture, a single Group, and a single VertexPool. Into that program, I have created 100 instances and I didn’t modified their material (so, it should be the same material for each instance), but Panda has collected 25 Geoms. Is it the expected behavior?

Oh, sure, here it is (it needs a recursive cloning since it uses a submodule). Please note that the asyncFlattenStrong is executed at the first time you play on a new track (at the end of the flattening it caches the result into a bam file), so you need to wait the end of the flattening to actually see the flattened models (it prints when the bam file has been created in the console).

Thank you very much!

PS I have not optimized the App section yet (there are several computations that I repeat more than once per frame), so bad performances are expected in that section.

PPS 480ms have been measured on my ATI r7 m440.

This is what I get running your code:

ls (after)

PandaNode root
  GeomNode smiley.egg (2 geoms: S:(TextureAttrib))

Which version of Panda do you have?

1.9.3.