Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/vrml97_export.py')
-rw-r--r--release/scripts/vrml97_export.py1300
1 files changed, 0 insertions, 1300 deletions
diff --git a/release/scripts/vrml97_export.py b/release/scripts/vrml97_export.py
deleted file mode 100644
index bd1a35f7c3b..00000000000
--- a/release/scripts/vrml97_export.py
+++ /dev/null
@@ -1,1300 +0,0 @@
-#!BPY
-""" Registration info for Blender menus:
-Name: 'VRML97 (.wrl)...'
-Blender: 241
-Group: 'Export'
-Tooltip: 'Export to VRML97 file (.wrl)'
-"""
-
-__author__ = ("Rick Kimball", "Ken Miller", "Steve Matthews", "Bart")
-__url__ = ["blender", "blenderartists.org",
-"Author's (Rick) homepage, http://kimballsoftware.com/blender",
-"Author's (Bart) homepage, http://www.neeneenee.de/vrml"]
-__email__ = ["Bart, bart:neeneenee*de"]
-__version__ = "2006/01/17"
-__bpydoc__ = """\
-This script exports to VRML97 format.
-
-Usage:
-
-Run this script from "File->Export" menu. A pop-up will ask whether you
-want to export only selected or all relevant objects.
-"""
-
-
-# $Id$
-#
-#------------------------------------------------------------------------
-# VRML97 exporter for blender 2.36 or above
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# ***** END GPL LICENCE BLOCK *****
-#
-
-####################################
-# Library dependancies
-####################################
-
-import Blender
-from Blender import Object, Mesh, Lamp, Draw, BGL, \
- Image, Text, sys, Mathutils, Registry
-from Blender.Scene import Render
-
-import math
-
-####################################
-# Global Variables
-####################################
-
-scene = Blender.Scene.getCurrent()
-world = Blender.World.GetCurrent()
-worldmat = Blender.Texture.Get()
-filename = Blender.Get('filename')
-_safeOverwrite = True
-extension = ''
-
-# Matrices below are used only when export_rotate_z_to_y.val:
-#
-# Blender is Z up, VRML is Y up, both are right hand coordinate
-# systems, so to go from Blender coords to VRML coords we rotate
-# by 90 degrees around the X axis. In matrix notation, we have a
-# matrix, and it's inverse, as:
-M_blen2vrml = Mathutils.Matrix([1,0,0,0], \
- [0,0,1,0], \
- [0,-1,0,0], \
- [0,0,0,1])
-M_vrml2blen = Mathutils.Matrix([1,0,0,0], \
- [0,0,-1,0], \
- [0,1,0,0], \
- [0,0,0,1])
-
-
-class DrawTypes:
- """Object DrawTypes enum values
- BOUNDS - draw only the bounding box of the object
- WIRE - draw object as a wire frame
- SOLID - draw object with flat shading
- SHADED - draw object with OpenGL shading
-"""
- BOUNDBOX = 1
- WIRE = 2
- SOLID = 3
- SHADED = 4
- TEXTURE = 5
-
-if not hasattr(Blender.Object,'DrawTypes'):
- Blender.Object.DrawTypes = DrawTypes()
-
-##########################################################
-# Functions for writing output file
-##########################################################
-
-class VRML2Export:
-
- def __init__(self, filename):
- #--- public you can change these ---
- self.wire = 0
- self.proto = 1
- self.facecolors = 0
- self.vcolors = 0
- self.billnode = 0
- self.halonode = 0
- self.collnode = 0
- self.tilenode = 0
- self.wire = 0
- self.twosided = 0
-
- # level of verbosity in console 0-none, 1-some, 2-most
- try:
- rt = Blender.Get('rt')
- if (rt == 42):
- self.verbose = 1
- elif (rt == 43):
- self.verbose = 2
- else:
- self.verbose = 0
- except:
- self.verbose = 0
-
- # decimals for material color values 0.000 - 1.000
- self.cp=7
- # decimals for vertex coordinate values 0.000 - n.000
- self.vp=7
- # decimals for texture coordinate values 0.000 - 1.000
- self.tp=7
-
- #--- class private don't touch ---
- self.texNames={} # dictionary of textureNames
- self.matNames={} # dictionary of materialNames
- self.meshNames={} # dictionary of meshNames
- self.coordNames={} # dictionary of coordNames
- self.indentLevel=0 # keeps track of current indenting
- self.filename=filename
- self.file = open(filename, "w")
- self.bNav=0
- self.nodeID=0
- self.namesReserved=[ "Anchor", "Appearance", "AudioClip",
- "Background","Billboard", "Box",
- "Collision", "Color", "ColorInterpolator",
- "Cone", "Coordinate",
- "CoordinateInterpolator", "Cylinder",
- "CylinderSensor",
- "DirectionalLight",
- "ElevationGrid", "Extrustion",
- "Fog", "FontStyle", "Group",
- "ImageTexture", "IndexedFaceSet",
- "IndexedLineSet", "Inline",
- "LOD", "Material", "MovieTexture",
- "NavigationInfo", "Normal",
- "NormalInterpolator",
- "OrientationInterpolator", "PixelTexture",
- "PlaneSensor", "PointLight", "PointSet",
- "PositionInterpolator", "ProxmimitySensor",
- "ScalarInterpolator", "Script", "Shape",
- "Sound", "Sphere", "SphereSensor",
- "SpotLight", "Switch", "Text",
- "TextureCoordinate", "TextureTransform",
- "TimeSensor", "TouchSensor", "Transform",
- "Viewpoint", "VisibilitySensor", "WorldInfo" ]
- self.namesStandard=[ "Empty", "Empty.000", "Empty.001",
- "Empty.002", "Empty.003", "Empty.004",
- "Empty.005", "Empty.006", "Empty.007",
- "Empty.008", "Empty.009", "Empty.010",
- "Empty.011", "Empty.012",
- "Scene.001", "Scene.002", "Scene.003",
- "Scene.004", "Scene.005", "Scene.06",
- "Scene.013", "Scene.006", "Scene.007",
- "Scene.008", "Scene.009", "Scene.010",
- "Scene.011","Scene.012",
- "World", "World.000", "World.001",
- "World.002", "World.003", "World.004",
- "World.005" ]
- self.namesFog=[ "", "LINEAR"," EXPONENTIAL", "" ]
-
-##########################################################
-# Writing nodes routines
-##########################################################
-
- def writeHeader(self):
- bfile = sys.expandpath(Blender.Get('filename'))
- self.file.write("#VRML V2.0 utf8\n\n")
- self.file.write("# This file was authored with Blender " \
- "(http://www.blender.org/)\n")
- self.file.write("# Blender version %s\n" % Blender.Get('version'))
- self.file.write("# Blender file %s\n" % sys.basename(bfile))
- self.file.write("# Exported using VRML97 exporter " \
- "v1.55 (2006/01/17)\n\n")
-
- def writeInline(self):
- inlines = Blender.Scene.Get()
- allinlines = len(inlines)
- if scene != inlines[0]:
- return
- else:
- for i in xrange(allinlines):
- nameinline=inlines[i].getName()
- if (nameinline not in self.namesStandard) and (i > 0):
- self.writeIndented("DEF %s Inline {\n" % \
- (self.cleanStr(nameinline)), 1)
- nameinline = nameinline+".wrl"
- self.writeIndented("url \"%s\" \n" % nameinline)
- self.writeIndented("}\n", -1)
- self.writeIndented("\n")
-
- def writeScript(self):
- textEditor = Blender.Text.Get()
- alltext = len(textEditor)
- for i in xrange(alltext):
- nametext = textEditor[i].getName()
- nlines = textEditor[i].getNLines()
- if (self.proto == 1):
- if (nametext == "proto" or nametext == "proto.js" or \
- nametext == "proto.txt") and (nlines != None):
- nalllines = len(textEditor[i].asLines())
- alllines = textEditor[i].asLines()
- for j in xrange(nalllines):
- self.writeIndented(alllines[j] + "\n")
- elif (self.proto == 0):
- if (nametext == "route" or nametext == "route.js" or \
- nametext == "route.txt") and (nlines != None):
- nalllines = len(textEditor[i].asLines())
- alllines = textEditor[i].asLines()
- for j in xrange(nalllines):
- self.writeIndented(alllines[j] + "\n")
- self.writeIndented("\n")
-
- def writeViewpoint(self, thisObj):
- # NOTE: The transform node above this will take care of
- # the position and orientation of the camera
- context = scene.getRenderingContext()
- ratio = float(context.imageSizeY()) / float(context.imageSizeX())
- temp = ratio * 16 / thisObj.data.getLens()
- lens = 2 * math.atan(temp)
- lens = min(lens, math.pi)
-
- self.writeIndented("DEF %s Viewpoint {\n" % \
- (self.cleanStr(thisObj.name)), 1)
- self.writeIndented('description "%s" \n' % thisObj.name)
- self.writeIndented("position 0.0 0.0 0.0\n")
- # Need camera to point to -y in local space to accomodate
- # the transforma node above
- self.writeIndented("orientation 1.0 0.0 0.0 %f\n" % (-math.pi/2.0))
- self.writeIndented("fieldOfView %.3f\n" % (lens))
- self.writeIndented("}\n", -1)
- self.writeIndented("\n")
-
- def writeFog(self):
- if world:
- mtype = world.getMistype()
- mparam = world.getMist()
- grd = world.getHor()
- grd0, grd1, grd2 = grd[0], grd[1], grd[2]
- else:
- return
- if (mtype == 1 or mtype == 2):
- self.writeIndented("Fog {\n",1)
- self.writeIndented('fogType "%s"\n' % self.namesFog[mtype])
- self.writeIndented("color %s %s %s\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("visibilityRange %s\n" % \
- round(mparam[2],self.cp))
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
- else:
- return
-
- def writeNavigationInfo(self, scene):
- allObj = []
- allObj = list(scene.objects)
- headlight = "TRUE"
- vislimit = 0.0
- for thisObj in allObj:
- objType=thisObj.type
- if objType == "Camera":
- vislimit = thisObj.data.getClipEnd()
- elif objType == "Lamp":
- headlight = "FALSE"
- self.writeIndented("NavigationInfo {\n",1)
- self.writeIndented("headlight %s\n" % headlight)
- self.writeIndented("visibilityLimit %s\n" % \
- (round(vislimit,self.cp)))
- self.writeIndented("type [\"EXAMINE\", \"ANY\"]\n")
- self.writeIndented("avatarSize [0.25, 1.75, 0.75]\n")
- self.writeIndented("} \n",-1)
- self.writeIndented(" \n")
-
- def writeSpotLight(self, object, lamp):
- # Note: location and orientation are handled by the
- # transform node above this object
- if world:
- ambi = world.getAmb()
- ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
- else:
- ambi = 0
- ambientIntensity = 0
-
- # compute cutoff and beamwidth
- intensity=min(lamp.energy/1.75,1.0)
- beamWidth=((lamp.spotSize*math.pi)/180.0)*.37;
- cutOffAngle=beamWidth*1.3
-
- radius = lamp.dist*math.cos(beamWidth)
- self.writeIndented("DEF %s SpotLight {\n" % \
- self.cleanStr(object.name),1)
- self.writeIndented("radius %s\n" % (round(radius,self.cp)))
- self.writeIndented("ambientIntensity %s\n" % \
- (round(ambientIntensity,self.cp)))
- self.writeIndented("intensity %s\n" % (round(intensity,self.cp)))
- self.writeIndented("color %s %s %s\n" % \
- (round(lamp.col[0],self.cp), \
- round(lamp.col[1],self.cp), \
- round(lamp.col[2],self.cp)))
- self.writeIndented("beamWidth %s\n" % (round(beamWidth,self.cp)))
- self.writeIndented("cutOffAngle %s\n" % \
- (round(cutOffAngle,self.cp)))
- # Note: point down -Y axis, transform node above will rotate
- self.writeIndented("direction 0.0 -1.0 0.0\n")
- self.writeIndented("location 0.0 0.0 0.0\n")
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
-
- def writeDirectionalLight(self, object, lamp):
- # Note: location and orientation are handled by the
- # transform node above this object
- if world:
- ambi = world.getAmb()
- ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
- else:
- ambi = 0
- ambientIntensity = 0
-
- intensity=min(lamp.energy/1.75,1.0)
- self.writeIndented("DEF %s DirectionalLight {\n" % \
- self.cleanStr(object.name),1)
- self.writeIndented("ambientIntensity %s\n" % \
- (round(ambientIntensity,self.cp)))
- self.writeIndented("color %s %s %s\n" % \
- (round(lamp.col[0],self.cp), \
- round(lamp.col[1],self.cp), \
- round(lamp.col[2],self.cp)))
- self.writeIndented("intensity %s\n" % \
- (round(intensity,self.cp)))
- # Note: point down -Y axis, transform node above will rotate
- self.writeIndented("direction 0.0 -1.0 0.0\n")
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
-
- def writePointLight(self, object, lamp):
- # Note: location is at origin because parent transform node
- # takes care of this
- if world:
- ambi = world.getAmb()
- ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
- else:
- ambi = 0
- ambientIntensity = 0
- om = object.getMatrix()
- intensity=min(lamp.energy/1.75,1.0)
- radius = lamp.dist
- self.writeIndented("DEF %s PointLight {\n" % \
- self.cleanStr(object.name),1)
- self.writeIndented("ambientIntensity %s\n" % \
- (round(ambientIntensity,self.cp)))
- self.writeIndented("color %s %s %s\n" % \
- (round(lamp.col[0],self.cp), \
- round(lamp.col[1],self.cp), \
- round(lamp.col[2],self.cp)))
- self.writeIndented("intensity %s\n" % (round(intensity,self.cp)))
- self.writeIndented("location 0.0 0.0 0.0\n")
- self.writeIndented("radius %s\n" % radius )
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
-
- def writeNode(self, thisObj):
- # Note: location and orientation are handled by the
- # transform node above this object
- objectname=str(thisObj.getName())
- if objectname in self.namesStandard:
- return
- else:
- self.writeIndented("%s {\n" % objectname,1)
- # May need to check that the direction is done right
- self.writeIndented("direction 0.0 -1.0 0.0\n")
- self.writeIndented("location 0.0 0.0 0.0\n")
- self.writeIndented("}\n",-1)
- self.writeIndented("\n")
-
- def secureName(self, name):
- name = name + str(self.nodeID)
- self.nodeID += 1
- if len(name) <= 3:
- newname = "_" + str(self.nodeID)
- return "%s" % (newname)
- else:
- for bad in ['"','#',"'",',','.','[','\\',']','{','}']:
- name=name.replace(bad,'_')
- if name in self.namesReserved:
- newname = name[0:3] + "_" + str(self.nodeID)
- return "%s" % (newname)
- elif name[0].isdigit():
- newname = "_" + name + str(self.nodeID)
- return "%s" % (newname)
- else:
- newname = name
- return "%s" % (newname)
-
- def classifyMesh(self, me, ob):
- self.halonode = 0
- self.billnode = 0
- self.facecolors = 0
- self.vcolors = 0
- self.tilenode = 0
- self.colnode = 0
- self.wire = 0
- if me.faceUV:
- for face in me.faces:
- if (face.mode & Mesh.FaceModes['HALO']):
- self.halonode = 1
- if (face.mode & Mesh.FaceModes['BILLBOARD']):
- self.billnode = 1
- if (face.mode & Mesh.FaceModes['OBCOL']):
- self.facecolors = 1
- if (face.mode & Mesh.FaceModes['SHAREDCOL']):
- self.vcolors = 1
- if (face.mode & Mesh.FaceModes['TILES']):
- self.tilenode = 1
- if not (face.mode & Mesh.FaceModes['DYNAMIC']):
- self.collnode = 1
- if (face.mode & Mesh.FaceModes['TWOSIDE']):
- self.twosided = 1
-
- # Bit of a crufty trick, but if mesh has vertex colors
- # (as a non-face property) and if first material has
- # vcol paint set, we export the vertex colors
- if (me.vertexColors):
- if len(me.materials) > 0:
- mat = me.materials[0]
- if mat:
- if (mat.mode & Blender.Material.Modes['VCOL_PAINT']):
- self.vcolors = 1
- else:
- self.vcolors = 0
-
- # check if object is wireframe only
- if ob.drawType == Blender.Object.DrawTypes.WIRE:
- # user selected WIRE=2 on the Drawtype=Wire on (F9) Edit page
- self.wire = 1
-
- ###
- ### The next few functions nest Collision/Billboard/Halo nodes.
- ### For real mesh data export, jump down to writeMeshData()
- ###
- def writeMesh(self, ob, normals = 0):
-
- imageMap={} # set of used images
- sided={} # 'one':cnt , 'two':cnt
- vColors={} # 'multi':1
-
- if (len(ob.modifiers) > 0):
- me = Mesh.New()
- me.getFromObject(ob.name)
- # Careful with the name, the temporary mesh may
- # reuse the default name for other meshes. So we
- # pick our own name.
- me.name = "MOD_%s" % (ob.name)
- else:
- me = ob.getData(mesh = 1)
-
- self.classifyMesh(me, ob)
-
- if (self.collnode):
- self.writeCollisionMesh(me, ob, normals)
- return
- else:
- self.writeRegularMesh(me, ob, normals)
- return
-
- def writeCollisionMesh(self, me, ob, normals = 0):
- self.writeIndented("Collision {\n",1)
- self.writeIndented("collide FALSE\n")
- self.writeIndented("children [\n")
-
- self.writeRegularMesh(me, ob, normals)
-
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- def writeRegularMesh(self, me, ob, normals = 0):
- if (self.billnode):
- self.writeBillboardMesh(me, ob, normals)
- elif (self.halonode):
- self.writeHaloMesh(me, ob, normals)
- else:
- self.writeMeshData(me, ob, normals)
-
- def writeBillboardMesh(self, me, ob, normals = 0):
- self.writeIndented("Billboard {\n",1)
- self.writeIndented("axisOfRotation 0 1 0\n")
- self.writeIndented("children [\n")
-
- self.writeMeshData(me, ob, normals)
-
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- def writeHaloMesh(self, me, ob, normals = 0):
- self.writeIndented("Billboard {\n",1)
- self.writeIndented("axisOfRotation 0 0 0\n")
- self.writeIndented("children [\n")
-
- self.writeMeshData(me, ob, normals)
-
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- ###
- ### Here is where real mesh data is written
- ###
- def writeMeshData(self, me, ob, normals = 0):
- meshName = self.cleanStr(me.name)
-
- if self.meshNames.has_key(meshName):
- self.writeIndented("USE ME_%s\n" % meshName, 0)
- self.meshNames[meshName]+=1
- if (self.verbose == 1):
- print " Using Mesh %s (Blender mesh: %s)\n" % \
- (meshName, me.name)
- return
- self.meshNames[meshName]=1
-
- if (self.verbose == 1):
- print " Writing Mesh %s (Blender mesh: %s)\n" % \
- (meshName, me.name)
- return
-
- self.writeIndented("DEF ME_%s Group {\n" % meshName,1)
- self.writeIndented("children [\n", 1)
-
- hasImageTexture = 0
- issmooth = 0
-
- maters = me.materials
- nummats = len(me.materials)
-
- # Vertex and Face colors trump materials and image textures
- if (self.facecolors or self.vcolors):
- if nummats > 0:
- self.writeShape(ob, me, 0, None)
- else:
- self.writeShape(ob, me, -1, None)
-
- # Do meshes with materials, possibly with image textures
- elif nummats > 0:
- for matnum in xrange(len(maters)):
- 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)
- if len(images) > 0:
- for image in images:
- self.writeShape(ob, me, -1, image)
- else:
- self.writeShape(ob, me, -1, None)
- else:
- self.writeShape(ob, me, -1, None)
-
-
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- def getImages(self, me, matnum):
- imageNames = {}
- images = []
- for face in me.faces:
- if (matnum == -1) or (face.mat == matnum):
- if (face.image):
- imName = self.cleanStr(face.image.name)
- if not imageNames.has_key(imName):
- images.append(face.image)
- imageNames[imName]=1
- return images
-
- def writeCoordinates(self, me, meshName):
- coordName = "coord_%s" % (meshName)
- # look up coord name, use it if available
- if self.coordNames.has_key(coordName):
- self.writeIndented("coord USE %s\n" % coordName, 0)
- self.coordNames[coordName]+=1
- return;
-
- self.coordNames[coordName]=1
-
- #-- vertices
- self.writeIndented("coord DEF %s Coordinate {\n" % (coordName), 1)
- self.writeIndented("point [\n", 1)
- meshVertexList = me.verts
-
- for vertex in meshVertexList:
- vrmlvert = blenvert = Mathutils.Vector(vertex.co)
- if export_rotate_z_to_y.val:
- vrmlvert = M_blen2vrml * vrmlvert
- self.writeUnindented("%s %s %s\n " % \
- (vrmlvert[0], \
- vrmlvert[1], \
- vrmlvert[2]))
- self.writeIndented("]\n", -1)
- 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 (face.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):
- # 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]
- 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)
-
- self.writeIndented("}\n", -1)
-
- self.writeGeometry(ob, me, matnum, image)
-
- self.writeIndented("}\n", -1)
-
- return True
-
- def writeGeometry(self, ob, me, matnum, image):
-
- #-- IndexedFaceSet or IndexedLineSet
- meshName = self.cleanStr(me.name)
-
- # check if object is wireframe only
- if (self.wire):
- ifStyle="IndexedLineSet"
- else:
- # user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5
- ifStyle="IndexedFaceSet"
-
- self.writeIndented("geometry %s {\n" % ifStyle, 1)
- if not self.wire:
- if self.twosided == 1:
- self.writeIndented("solid FALSE\n")
- else:
- self.writeIndented("solid TRUE\n")
-
- self.writeCoordinates(me, meshName)
- self.writeCoordIndex(me, meshName, matnum, image)
- self.writeTextureCoordinates(me, meshName, matnum, image)
- if self.facecolors:
- self.writeFaceColors(me)
- elif self.vcolors:
- self.writeVertexColors(me)
- self.writeIndented("}\n", -1)
-
- def writeCoordIndex(self, me, meshName, matnum, image):
- meshVertexList = me.verts
- self.writeIndented("coordIndex [\n", 1)
- coordIndexList=[]
- for face in me.faces:
- if (matnum == -1) or (face.mat == matnum):
- if (image == None) or (face.image == image):
- cordStr=""
- for v in face.verts:
- indx=v.index
- cordStr = cordStr + "%s " % indx
- self.writeUnindented(cordStr + "-1, \n")
- self.writeIndented("]\n", -1)
-
- def writeTextureCoordinates(self, me, meshName, matnum, image):
- if (image == None):
- return
-
- texCoordList=[]
- texIndexList=[]
- j=0
-
- for face in me.faces:
- coordStr = ""
- indexStr = ""
- if (matnum == -1) or (face.mat == matnum):
- if (face.image == image):
- for i in xrange(len(face.verts)):
- uv = face.uv[i]
- indexStr += "%s " % (j)
- coordStr += "%s %s, " % \
- (round(uv[0], self.tp), \
- round(uv[1], self.tp))
- j=j+1
- indexStr += "-1"
- texIndexList.append(indexStr)
- texCoordList.append(coordStr)
-
- self.writeIndented("texCoord TextureCoordinate {\n", 1)
- self.writeIndented("point [\n", 1)
- for coord in texCoordList:
- self.writeUnindented("%s\n" % (coord))
- self.writeIndented("]\n", -1)
- self.writeIndented("}\n", -1)
-
- self.writeIndented("texCoordIndex [\n", 1)
- for ind in texIndexList:
- self.writeUnindented("%s\n" % (ind))
- self.writeIndented("]\n", -1)
-
- def writeFaceColors(self, me):
- self.writeIndented("colorPerVertex FALSE\n")
- self.writeIndented("color Color {\n",1)
- self.writeIndented("color [\n", 1)
-
- for face in me.faces:
- if face.col:
- c=face.col[0]
- if self.verbose >= 2:
- print "Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)
-
- aColor = self.rgbToFS(c)
- self.writeUnindented("%s,\n" % aColor)
- self.writeIndented("]\n",-1)
- self.writeIndented("}\n",-1)
-
- def writeVertexColors(self, me):
- self.writeIndented("colorPerVertex TRUE\n")
- self.writeIndented("color Color {\n",1)
- self.writeIndented("color [\n\t\t\t\t\t\t", 1)
-
- cols = [None] * len(me.verts)
-
- for face in me.faces:
- for vind in xrange(len(face.v)):
- vertex = face.v[vind]
- i = vertex.index
- if cols[i] == None:
- cols[i] = face.col[vind]
-
- for i in xrange(len(me.verts)):
- aColor = self.rgbToFS(cols[i])
- self.writeUnindented("%s\n" % aColor)
-
- self.writeIndented("\n", 0)
- 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):
- self.writeIndented("material USE MA_%s\n" % matName)
- self.matNames[matName]+=1
- return;
-
- self.matNames[matName]=1
-
- ambient = mat.amb/3
- diffuseR, diffuseG, diffuseB = \
- mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2]
- if world:
- ambi = world.getAmb()
- ambi0, ambi1, ambi2 = (ambi[0]*mat.amb) * 2, \
- (ambi[1]*mat.amb) * 2, \
- (ambi[2]*mat.amb) * 2
- else:
- ambi0, ambi1, ambi2 = 0, 0, 0
- emisR, emisG, emisB = (diffuseR*mat.emit+ambi0) / 2, \
- (diffuseG*mat.emit+ambi1) / 2, \
- (diffuseB*mat.emit+ambi2) / 2
-
- shininess = mat.hard/512.0
- specR = (mat.specCol[0]+0.001) / (1.25/(mat.getSpec()+0.001))
- specG = (mat.specCol[1]+0.001) / (1.25/(mat.getSpec()+0.001))
- specB = (mat.specCol[2]+0.001) / (1.25/(mat.getSpec()+0.001))
- transp = 1 - mat.alpha
- matFlags = mat.getMode()
- if matFlags & Blender.Material.Modes['SHADELESS']:
- ambient = 1
- shine = 1
- specR = emitR = diffuseR
- specG = emitG = diffuseG
- specB = emitB = diffuseB
- self.writeIndented("material DEF MA_%s Material {\n" % matName, 1)
- self.writeIndented("diffuseColor %s %s %s\n" % \
- (round(diffuseR,self.cp), \
- round(diffuseG,self.cp), \
- round(diffuseB,self.cp)))
- self.writeIndented("ambientIntensity %s\n" % \
- (round(ambient,self.cp)))
- self.writeIndented("specularColor %s %s %s\n" % \
- (round(specR,self.cp), \
- round(specG,self.cp), \
- round(specB,self.cp)))
- self.writeIndented("emissiveColor %s %s %s\n" % \
- (round(emisR,self.cp), \
- round(emisG,self.cp), \
- round(emisB,self.cp)))
- self.writeIndented("shininess %s\n" % (round(shininess,self.cp)))
- self.writeIndented("transparency %s\n" % (round(transp,self.cp)))
- self.writeIndented("}\n",-1)
-
- def writeImageTexture(self, name, filename):
- if self.texNames.has_key(name):
- self.writeIndented("texture USE %s\n" % self.cleanStr(name))
- self.texNames[name] += 1
- return
- else:
- self.writeIndented("texture DEF %s ImageTexture {\n" % \
- self.cleanStr(name), 1)
- self.writeIndented('url "%s"\n' % \
- filename.split("\\")[-1].split("/")[-1])
- self.writeIndented("}\n",-1)
- self.texNames[name] = 1
-
- def writeBackground(self):
- if world:
- worldname = world.getName()
- else:
- return
- blending = world.getSkytype()
- grd = world.getHor()
- grd0, grd1, grd2 = grd[0], grd[1], grd[2]
- sky = world.getZen()
- sky0, sky1, sky2 = sky[0], sky[1], sky[2]
- mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2]
- mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2
- if worldname in self.namesStandard:
- self.writeIndented("Background {\n",1)
- else:
- self.writeIndented("DEF %s Background {\n" % \
- self.secureName(worldname),1)
- # No Skytype - just Hor color
- if blending == 0:
- self.writeIndented("groundColor %s %s %s\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("skyColor %s %s %s\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- # Blend Gradient
- elif blending == 1:
- self.writeIndented("groundColor [ %s %s %s, " % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(mix0,self.cp), \
- round(mix1,self.cp), \
- round(mix2,self.cp)))
- self.writeIndented("groundAngle [ 1.57, 1.57 ]\n")
- self.writeIndented("skyColor [ %s %s %s, " % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(mix0,self.cp), \
- round(mix1,self.cp), \
- round(mix2,self.cp)))
- self.writeIndented("skyAngle [ 1.57, 1.57 ]\n")
- # Blend+Real Gradient Inverse
- elif blending == 3:
- self.writeIndented("groundColor [ %s %s %s, " % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(mix0,self.cp), \
- round(mix1,self.cp), \
- round(mix2,self.cp)))
- self.writeIndented("groundAngle [ 1.57, 1.57 ]\n")
- self.writeIndented("skyColor [ %s %s %s, " % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(mix0,self.cp), \
- round(mix1,self.cp), \
- round(mix2,self.cp)))
- self.writeIndented("skyAngle [ 1.57, 1.57 ]\n")
- # Paper - just Zen Color
- elif blending == 4:
- self.writeIndented("groundColor %s %s %s\n" % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("skyColor %s %s %s\n" % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- # Blend+Real+Paper - komplex gradient
- elif blending == 7:
- self.writeIndented("groundColor [ %s %s %s, " % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("groundAngle [ 1.57, 1.57 ]\n")
- self.writeIndented("skyColor [ %s %s %s, " % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- self.writeIndented("%s %s %s ]\n" % \
- (round(grd0,self.cp),
- round(grd1,self.cp),
- round(grd2,self.cp)))
- self.writeIndented("skyAngle [ 1.57, 1.57 ]\n")
- # Any Other two colors
- else:
- self.writeIndented("groundColor %s %s %s\n" % \
- (round(grd0,self.cp), \
- round(grd1,self.cp), \
- round(grd2,self.cp)))
- self.writeIndented("skyColor %s %s %s\n" % \
- (round(sky0,self.cp), \
- round(sky1,self.cp), \
- round(sky2,self.cp)))
- alltexture = len(worldmat)
- for i in xrange(alltexture):
- namemat = worldmat[i].getName()
- pic = worldmat[i].getImage()
- if pic:
- # Stripped path.
- pic_path= pic.filename.split('\\')[-1].split('/')[-1]
- if namemat == "back":
- self.writeIndented('backUrl "%s"\n' % pic_path)
- elif namemat == "bottom":
- self.writeIndented('bottomUrl "%s"\n' % pic_path)
- elif namemat == "front":
- self.writeIndented('frontUrl "%s"\n' % pic_path)
- elif namemat == "left":
- self.writeIndented('leftUrl "%s"\n' % pic_path)
- elif namemat == "right":
- self.writeIndented('rightUrl "%s"\n' % pic_path)
- elif namemat == "top":
- self.writeIndented('topUrl "%s"\n' % pic_path)
- self.writeIndented("}",-1)
- self.writeIndented("\n\n")
-
- def writeLamp(self, ob):
- la = ob.data
- laType = la.getType()
-
- if laType == Lamp.Types.Lamp:
- self.writePointLight(ob, la)
- elif laType == Lamp.Types.Spot:
- self.writeSpotLight(ob, la)
- elif laType == Lamp.Types.Sun:
- self.writeDirectionalLight(ob, la)
- else:
- self.writeDirectionalLight(ob, la)
-
- def writeObject(self, ob):
-
- obname = self.cleanStr(ob.name)
-
- try:
- obtype=ob.getType()
- except AttributeError:
- print "Error: Unable to get type info for %s" % obname
- return
-
- if self.verbose >= 1:
- print "++ Writing %s object %s (Blender name: %s)\n" % \
- (obtype, obname, ob.name)
-
- # Note: I am leaving empties out for now -- the original
- # script does some really weird stuff with empties
- if ( (obtype != "Camera") and \
- (obtype != "Mesh") and \
- (obtype != "Lamp") ):
- print "Info: Ignoring [%s], object type [%s] " \
- "not handle yet" % (obname, obtype)
- return
-
- ob_matrix = Mathutils.Matrix(ob.getMatrix('worldspace'))
- if export_rotate_z_to_y.val:
- matrix = M_blen2vrml * ob_matrix * M_vrml2blen
- else:
- matrix = ob_matrix
- e = matrix.rotationPart().toEuler()
-
- v = matrix.translationPart()
- (axis, angle) = self.eulToVecRot(self.deg2rad(e.x), \
- self.deg2rad(e.y), \
- self.deg2rad(e.z))
-
- mrot = e.toMatrix().resize4x4()
- try:
- mrot.invert()
- except:
- print "Warning: %s has degenerate transformation!" % (obname)
- return
-
- diag = matrix * mrot
- sizeX = diag[0][0]
- sizeY = diag[1][1]
- sizeZ = diag[2][2]
-
- if self.verbose >= 1:
- print " Transformation:\n" \
- " loc: %f %f %f\n" \
- " size: %f %f %f\n" \
- " Rot: (%f %f %f), %f\n" % \
- (v.x, v.y, v.z, \
- sizeX, sizeY, sizeZ, \
- axis[0], axis[1], axis[2], angle)
-
- self.writeIndented("DEF OB_%s Transform {\n" % (obname), 1)
- self.writeIndented("translation %f %f %f\n" % \
- (v.x, v.y, v.z) )
-
- self.writeIndented("rotation %f %f %f %f\n" % \
- (axis[0],axis[1],axis[2],angle) )
-
- self.writeIndented("scale %f %f %f\n" % \
- (sizeX, sizeY, sizeZ) )
-
- self.writeIndented("children [\n", 1)
-
- self.writeObData(ob)
-
- self.writeIndented("]\n", -1) # end object
- self.writeIndented("}\n", -1) # end object
-
- def writeObData(self, ob):
-
- obtype = ob.getType()
-
- if obtype == "Camera":
- self.writeViewpoint(ob)
- elif obtype == "Mesh":
- self.writeMesh(ob)
- elif obtype == "Lamp":
- self.writeLamp(ob)
- elif obtype == "Empty":
- self.writeNode(ob)
-
-
-##########################################################
-# export routine
-##########################################################
-
- def export(self, scene, world, worldmat):
- print "Info: starting VRML97 export to " + self.filename + "..."
- self.writeHeader()
- self.writeScript()
- self.writeNavigationInfo(scene)
- self.writeBackground()
- self.writeFog()
- self.proto = 0
- allObj = []
- if export_selection_only.val:
- allObj = list(scene.objects.context)
- else:
- allObj = list(scene.objects)
- self.writeInline()
-
- for thisObj in allObj:
- self.writeObject(thisObj)
-
- if not export_selection_only.val:
- self.writeScript()
- self.cleanup()
-
-##########################################################
-# Utility methods
-##########################################################
-
- def cleanup(self):
- self.file.close()
- self.texNames={}
- self.matNames={}
- self.indentLevel=0
- print "Info: finished VRML97 export to %s\n" % self.filename
-
- def cleanStr(self, name, prefix='rsvd_'):
- """cleanStr(name,prefix) - try to create a valid VRML DEF \
- name from object name"""
-
- newName=name[:]
- if len(newName) == 0:
- self.nNodeID+=1
- return "%s%d" % (prefix, self.nNodeID)
-
- if newName in self.namesReserved:
- newName='%s%s' % (prefix,newName)
-
- if newName[0].isdigit():
- newName='%s%s' % ('_',newName)
-
- for bad in (' ','"','#',"'",',','.','[','\\',']','{','}'):
- newName=newName.replace(bad,'_')
- return newName
-
- def rgbToFS(self, c):
- s = "%s %s %s" % \
- (round(c.r/255.0,self.cp), \
- round(c.g/255.0,self.cp), \
- round(c.b/255.0,self.cp))
- return s
-
- def rad2deg(self, v):
- return round(v*180.0/math.pi,4)
-
- def deg2rad(self, v):
- return (v*math.pi)/180.0;
-
- def eulToVecRot(self, RotX, RotY, RotZ):
-
- ti = RotX*0.5
- tj = RotY*0.5
- th = RotZ*0.5
-
- ci = math.cos(ti)
- cj = math.cos(tj)
- ch = math.cos(th)
- si = math.sin(ti)
- sj = math.sin(tj)
- sh = math.sin(th)
- cc = ci*ch
- cs = ci*sh
- sc = si*ch
- ss = si*sh
-
- q0 = cj*cc + sj*ss
- q1 = cj*sc - sj*cs
- q2 = cj*ss + sj*cc
- q3 = cj*cs - sj*sc
-
- angle = 2 * math.acos(q0)
- if (math.fabs(angle) < 0.000001):
- axis = [1.0, 0.0, 0.0]
- else:
- sphi = 1.0/math.sqrt(1.0 - (q0*q0))
- axis = [q1 * sphi, q2 * sphi, q3 * sphi]
-
- a = Mathutils.Vector(axis)
- a.normalize()
- return ([a.x, a.y, a.z], angle)
-
-
- # For writing well formed VRML code
- #----------------------------------
- def writeIndented(self, s, inc=0):
- if inc < 1:
- self.indentLevel = self.indentLevel + inc
-
- self.file.write( self.indentLevel*"\t" + s)
-
- if inc > 0:
- self.indentLevel = self.indentLevel + inc
-
- # Sometimes better to not have too many
- # tab characters in a long list, for file size
- #----------------------------------
- def writeUnindented(self, s):
- self.file.write(s)
-
-##########################################################
-# Callbacks, needed before Main
-##########################################################
-
-def select_file(filename):
- if sys.exists(filename) and _safeOverwrite:
- result = \
- Draw.PupMenu("File Already Exists, Overwrite?%t|Yes%x1|No%x0")
- if(result != 1):
- return
-
- if not filename.endswith(extension):
- filename += extension
-
- wrlexport=VRML2Export(filename)
- wrlexport.export(scene, world, worldmat)
-
-#########################################################
-# UI and Registry utilities
-#########################################################
-
-export_selection_only = Draw.Create(0)
-export_rotate_z_to_y = Draw.Create(1)
-export_compressed = Draw.Create(0)
-
-def save_to_registry():
- d = {}
- d['selection_only'] = export_selection_only.val
- d['rotate_z_to_y'] = export_rotate_z_to_y.val
- d['compressed'] = export_compressed.val
- Registry.SetKey('vrml97_export', d, True)
-
-def load_from_registry():
- d = Registry.GetKey('vrml97_export', True)
- if d:
- try:
- export_selection_only.val = d['selection_only']
- export_rotate_z_to_y.val = d['rotate_z_to_y']
- export_compressed.val = d['compressed']
- except: save_to_registry() # If data is not valid, rewrite it.
-
-def show_popup():
- pup_block = [
- ('Selection Only', export_selection_only, 'Only export objects in visible selection. Else export whole scene.'),
- ('Rotate +Z to +Y', export_rotate_z_to_y, 'Rotate such that +Z axis (Blender up) becomes +Y (VRML up).'),
- ('Compress', export_compressed, 'Generate a .wrz file (normal VRML compressed by gzip).')
- ]
- return Draw.PupBlock('Export VRML 97...', pup_block)
-
-#########################################################
-# main routine
-#########################################################
-
-load_from_registry()
-
-# Note that show_popup must be done before Blender.Window.FileSelector,
-# because export_compressed affects the suggested extension of resulting
-# file.
-
-if show_popup():
- save_to_registry()
- if export_compressed.val:
- extension=".wrz"
- from gzip import *
- else:
- extension=".wrl"
- Blender.Window.FileSelector(select_file, "Export VRML97", \
- sys.makename(ext=extension))