I have some code that creates a sphere using the EggData system, and I want to alter the colours of the sphere in python.

I was going to use the following code that is based on code in another thread:

``````def manipulateGeom(geom):
geomNode = geom.find('**/+GeomNode').node()
vertexArray = geomNode.getGeom(0).getCoordsArray()
size = vertexArray.size()
#do stuff with vertices``````

This function works fine for any egg files loaded from disk, however the vertexArray returns an incorrect (small) list of vertices for a sphere I create using loadEggData. Should I be doing anything different here?

The following code creates a sphere in panda correctly(it has normals, texture coords and is the right size) but when I call manipulateGeom on it it gives me a vertex size of 6. However calling manipulateGeom on the planet sphere that comes with the basic panda samples returns 700 odd vertices.

``````def createSphere(r, nRings = 32, nSegments = 32):
data = EggData()
vp = EggVertexPool('triangle')

fDeltaRingAngle = (math.pi / nRings);
fDeltaSegAngle = (2 * math.pi / nSegments);

wVerticeIndex = 0
vertexList = [] #keep our own list of vertices so we can create shared vertices easily

# Generate the group of rings for the sphere
for ring in range(nRings +1):
r0 = r * math.sin (ring * fDeltaRingAngle);
y0 = r * math.cos (ring * fDeltaRingAngle);

# Generate the group of segments for the current ring
for seg in range(nSegments+1):
x0 = r0 * math.sin(seg * fDeltaSegAngle);
z0 = r0 * math.cos(seg * fDeltaSegAngle);

# Add one vertex to the strip which makes up the sphere
v = EggVertex()
p = Point3D(x0, z0, -y0) #this code was originally from a different coord system
v.setPos(p)

n = Vec3D(p)
n = n / n.length()
v.setNormal(n)

v.setUv(Point2D(seg /  float(nSegments), ring /  float(nRings)))

for ring in range(nRings +1):
for seg in range(nSegments+1):
if (ring != nRings):
poly =  EggPolygon()

poly =  EggPolygon()
wVerticeIndex += 1

return NodePath(node)``````

help!

You are having problems because there is more than one Geom for your sphere. The first Geom probably contains a few independent triangles, and hence has very few vertices; the rest of the vertices are in the remaining Geom(s). Rather than calling getGeom(0), iterate through all of the geoms, specified by geomNode.getNumGeoms().

Of course, if you are only setting the overall color of the sphere, it is easiest to do this with the nodePath.setColor() operation. And if you are applying a uniform scale to all colors of the sphere, you can use nodePath.setColorScale(). More advanced per-vertex operations, of course, will indeed require iterating through all of the vertices as you describe.

David

Thanks David,

I managed to work this out on the weekend but haven’t been at a computer with inet access to post a reply.

My new question is this. I am colouring the vertices based on their position in their mesh for a sky sphere that uses atmosphere scattering. When I iterate through the colour arrays how do I grab the corresponding vertex position that matches the vertex colour? I have seen the getCoordIndex etc but I cant seem to do anything with them…

Is this the right way to go?

I should caution you that the Geom interface will be replaced in an upcoming release of Panda, so all of this will change. The current Geom interface has a number of problems, including the difficulty of matching up colors to vertices.

As an optimization, when a model’s vertices all have the same color value, Panda will flatten all of the color elements into a single element that is shared by all vertices. To avoid this optimization, choose a different color for at least some of the vertices when you construct the egg data. This will force Panda to create a color element for each vertex; and then the colors array will match one-for-one with the coords array.

David

Thanks David,

That seems to be a simple enough solution.

Any idea of the ETA on the new version with the improved Geom implementation?

Should be within a handful of weeks. It would have been sooner but I’ve been selected for jury duty and I’ve been serving my time in court this past two weeks.

David