A fix for bug #8814:
authorChris Want <cwant@ualberta.ca>
Mon, 6 Oct 2008 17:06:13 +0000 (17:06 +0000)
committerChris Want <cwant@ualberta.ca>
Mon, 6 Oct 2008 17:06:13 +0000 (17:06 +0000)
http://projects.blender.org/tracker/?func=detail&atid=125&aid=8814&group_id=9

Smarter handling of faces that have a material index that points
to a null material.

release/scripts/vrml97_export.py

index b28c7f5bbdc615506c299afdc07f12d6e5624d30..6ec05495327fde3e0f8844529063413eab4cee40 100644 (file)
@@ -556,31 +556,28 @@ class VRML2Export:
                issmooth = 0
 
                maters = me.materials
-               nummats = self.getNumMaterials(me)
+               nummats = len(me.materials)
 
                # Vertex and Face colors trump materials and image textures
                if (self.facecolors or self.vcolors):
                        if nummats > 0:
-                               if maters[0]:
-                                       self.writeShape(ob, me, 0, None)
-                               else:
-                                       self.writeShape(ob, me, -1, None)
+                               self.writeShape(ob, me, 0, None)
                        else:
                                self.writeShape(ob, me, -1, None)
-               # Do meshes with materials, possible with image textures
+
+               # Do meshes with materials, possibly with image textures
                elif nummats > 0:
                        for matnum in range(len(maters)):
-                               if maters[matnum]:
-                                       images = []
-                                       if me.faceUV:
-                                               images = self.getImages(me, matnum)
-                                               if len(images) > 0:
-                                                       for image in images:
-                                                               self.writeShape(ob, me, matnum, image)
-                                               else:
-                                                       self.writeShape(ob, me, matnum, None)
+                               images = []
+                               if me.faceUV:
+                                       images = self.getImages(me, matnum)
+                                       if len(images) > 0:
+                                               for image in images:
+                                                       self.writeShape(ob, me, matnum, image)
                                        else:
                                                self.writeShape(ob, me, matnum, None)
+                               else:
+                                       self.writeShape(ob, me, matnum, None)
                else:
                        if me.faceUV:
                                images = self.getImages(me, -1)
@@ -608,15 +605,6 @@ class VRML2Export:
                                                imageNames[imName]=1
                return images
 
-       def getNumMaterials(self, me):
-               # Oh silly Blender, why do you sometimes have 'None' as
-               # a member of the me.materials array?
-               num = 0
-               for mat in me.materials:
-                       if mat:
-                               num = num + 1
-               return num
-
        def writeCoordinates(self, me, meshName):
                coordName = "coord_%s" % (meshName)
                # look up coord name, use it if available
@@ -644,20 +632,43 @@ class VRML2Export:
                self.writeIndented("}\n", -1)
                self.writeIndented("\n")
 
+       def testShape(self, ob, me, matnum, image):
+               if ( (matnum == -1) and (image == None) ):
+                       if ( len(me.faces) > 0 ):
+                               return True
+               # Check if any faces the material or image
+               for face in me.faces:
+                       if (matnum == -1):
+                               if (f.image == image):
+                                       return True
+                       elif (image == None):
+                               if (face.mat == matnum):
+                                       return True
+                       else:
+                               if ((face.image == image) and (face.mat == matnum)):
+                                       return True
+
+               return False
+
        def writeShape(self, ob, me, matnum, image):
-               # Note: at this point it is assumed for matnum!=-1 that the 
-               # material in me.materials[matnum] is not equal to 'None'.
-               # Such validation should be performed by the function that
-               # calls this one.
+               # matnum == -1  means don't check the face.mat
+               # image == None means don't check face.image
+
+               if ( not self.testShape(ob, me, matnum, image) ):
+                       return False
+
                self.writeIndented("Shape {\n",1)
 
                self.writeIndented("appearance Appearance {\n", 1)
                if (matnum != -1):
                        mater = me.materials[matnum]
-                       self.writeMaterial(mater, self.cleanStr(mater.name,''))
-                       if (mater.mode & Blender.Material.Modes['TEXFACE']):
-                               if image != None:
-                                       self.writeImageTexture(image.name, image.filename)
+                       if (mater):
+                               self.writeMaterial(mater, self.cleanStr(mater.name,''))
+                               if (mater.mode & Blender.Material.Modes['TEXFACE']):
+                                       if image != None:
+                                               self.writeImageTexture(image.name, image.filename)
+                       else:
+                               self.writeDefaultMaterial()     
                else:
                        if image != None:
                                self.writeImageTexture(image.name, image.filename)
@@ -668,6 +679,8 @@ class VRML2Export:
 
                self.writeIndented("}\n", -1)
 
+               return True
+
        def writeGeometry(self, ob, me, matnum, image):
 
                #-- IndexedFaceSet or IndexedLineSet
@@ -784,6 +797,23 @@ class VRML2Export:
                self.writeIndented("]\n",-1)
                self.writeIndented("}\n",-1)
 
+       def writeDefaultMaterial(self):
+               matName = "default"
+
+               # look up material name, use it if available
+               if self.matNames.has_key(matName):
+                       self.writeIndented("material USE MA_%s\n" % matName)
+                       self.matNames[matName]+=1
+                       return;
+
+               self.matNames[matName]=1
+               self.writeIndented("material DEF MA_%s Material {\n" % matName, 1)
+               self.writeIndented("diffuseColor 0.8 0.8 0.8\n")
+               self.writeIndented("specularColor 1.0 1.0 1.0\n")
+               self.writeIndented("shininess 0.5\n")
+               self.writeIndented("transparency 0.0\n")
+               self.writeIndented("}\n",-1)
+
        def writeMaterial(self, mat, matName):
                # look up material name, use it if available
                if self.matNames.has_key(matName):