# EggOctree, EggData & EggGroupNode Question

hi, im trying to use the eggoctree from the ‘Code Snipplets’ section to optimize my terrain model.

i met this problem when i try to run the .py file:
AttributeError: ‘libpandaegg.EggTexture’ object has no attribute ‘triangulatePolygons’

this is my code:
EggOctree.py:

``````from pandac.PandaModules import *
import direct.directbase.DirectStart
from direct.actor.Actor import Actor
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
import random, sys, os, math
import thread

import math

class EggOctree(object):

def build(self, sourceNode, destNode, cellSize, collide=False):

snode = sourceNode
snode.triangulatePolygons(0xff)

# First, extract the <VertexPool>
vpool = snode.getFirstChild()
assert type(vpool) == EggVertexPool, 'First child must be a <VertexPool>'

# Loop on the vertices determine the bounding box
minBB = Point3D()
maxBB = Point3D()

nverts = vpool.getHighestIndex()
for iv in range(nverts + 1) :
vtx = vpool[iv]
vtxPos = vtx.getPos3()

# Sets the X, Y or Z components
i = 0
for set in [Point3D.setX, Point3D.setY, Point3D.setZ]  :
if vtxPos[i] < minBB[i] :
set(minBB, vtxPos[i])

if vtxPos[i] > maxBB[i] :
set(maxBB, vtxPos[i])
i += 1

minBB -= Vec3D(0.001, 0.001, 0.001)
maxBB += Vec3D(0.001, 0.001, 0.001)

# Number of leaves x,y,z
bboxSize = maxBB - minBB
self.ncx = math.ceil(bboxSize.getX() / cellSize.getX())
self.ncy = math.ceil(bboxSize.getY() / cellSize.getY())
self.ncz = math.ceil(bboxSize.getZ() / cellSize.getZ())

# Depth of the tree x,y,z
self.depthX = math.ceil(math.log(self.ncx) / math.log(2))
self.depthY = math.ceil(math.log(self.ncy) / math.log(2))
self.depthZ = math.ceil(math.log(self.ncz) / math.log(2))
self.depth = max(self.depthX, self.depthY, self.depthZ)

self.cells = [[[
{'min':
Point3D(minBB.getX() + x * cellSize.getX(),
minBB.getY() + y * cellSize.getY(),
minBB.getZ() + z * cellSize.getZ()),
'max':
Point3D(minBB.getX() + (x+1) * cellSize.getX(),
minBB.getY() + (y+1) * cellSize.getY(),
minBB.getZ() + (z+1) * cellSize.getZ()),
'group':EggGroup('leaf_%d_%d_%d' % (x,y,z)) }

for z in range(self.ncz)]
for y in range(self.ncy)]
for x in range(self.ncx)]

print 'Cell grid is %dx%dx%d' % (len(self.cells), len(self.cells[0]), len(self.cells[0][0]))

if collide :
for x in range(self.ncx) :
for y in range(self.ncy) :
for z in range(self.ncz) :
self.cells[x][y][z]['group'].addObjectType('barrier')

# Iterate on the <Polygon>s (should be triangles)
poly = snode.getNextChild()
while poly != None :
if isinstance(poly, EggPolygon) :

# Get the triangle center
polyCenter = Point3D(0,0,0)
for i in range(3) :
polyCenter += poly.getVertex(i).getPos3()
polyCenter /= 3.0

# Add the triangle to the corresponding cell group
cx = int(math.floor((polyCenter.getX()-minBB.getX()) / cellSize.getX()))
cy = int(math.floor((polyCenter.getY()-minBB.getY()) / cellSize.getY()))
cz = int(math.floor((polyCenter.getZ()-minBB.getZ()) / cellSize.getZ()))

self.cells[cx][cy][cz]['group'].addChild(poly)

poly = snode.getNextChild()

# Add the vertex data
destNode.addChild(vpool)

self.nleaves = self.recur(destNode, 0, 0,0,0)

print self.nleaves, 'leaves added'

def recur(self, node, depth, x, y, z) :

if depth < self.depth :
nnode = EggGroup('')
delt = int(math.pow(2, self.depth - depth - 1))

nchilds = 0

nchilds += self.recur(nnode, depth+1, x, y, z)
nchilds += self.recur(nnode, depth+1, x + delt, y, z)
nchilds += self.recur(nnode, depth+1, x, y + delt, z)
nchilds += self.recur(nnode, depth+1, x + delt, y + delt, z)

nchilds += self.recur(nnode, depth+1, x, y, z + delt)
nchilds += self.recur(nnode, depth+1, x + delt, y, z + delt)
nchilds += self.recur(nnode, depth+1, x, y + delt, z + delt)
nchilds += self.recur(nnode, depth+1, x + delt, y + delt, z + delt)

if nchilds > 0 :
node.addChild(nnode)

return nchilds

else :

# We are in a leaf
if x < self.ncx and y < self.ncy and z < self.ncz :
node.addChild(self.cells[x][y][z]['group'])
return 1
else :
return 0 ``````

MyEggTree.py:

``````from pandac.PandaModules import *
from pandac.PandaModules import EggData,EggVertexPool,EggPolygon,EggVertex,EggGroupNode
import direct.directbase.DirectStart
from direct.actor.Actor import Actor
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
import random, sys, os, math
import thread

from EggOctree import EggOctree

class World(DirectObject, EggData, EggGroupNode):
def __init__(self):
self.config()
taskMgr.add(self.main, 'mainLoop')
pass

def config(self):
self.np = render.attachNewNode('np')
self.octree = EggOctree()

def main(self, task):
egg = EggData()
egg.read(Filename('Map_Tutorial_Level.egg'))
egg.getFirstChild()
sourceNode = egg.getNextChild() # the sourcenode must contain a VertexPool and a list of Polygons
if self.np != None :
self.np.removeNode()
self.np = None

ed = EggData()
ed.setCoordinateSystem(egg.getCoordinateSystem())

# Here, it's a quadtree since there will be only 1 leaf along the Y axis
self.octree.build(sourceNode, ed, Vec3D(3, 100, 3))

ed.writeEgg(Filename('Map_Tutorial_Level_Octree.egg'))
ed = None

self.np = loader.loadModel('Map_Tutorial_Level_Octree.egg')
self.np.reparentTo(render)
self.np.setScale(15);
print 'Been Here'

w = World()
run()``````

i found that the EggData inherits from the EggGroupNode, but im not too sure of how to use it in the function. im not too sure if i did my code in python correctly cos im still new to python, so i need some help here.

im stuck at this point and cant render anything to the screen or write any .egg files. please correct my code because im really lost

you probably should just insert code to ignore libpandaegg.EggTexture chunks.