This commit is contained in:
Daniel Genrich
2008-05-12 12:24:52 +00:00
101 changed files with 6691 additions and 4251 deletions

View File

@@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
"""
Name: '3D Studio (.3ds)...'
Blender: 243

View File

@@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
""" Registration info for Blender menus
Name: 'Bevel Center'
Blender: 243

View File

@@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
"""
Name: 'BlenderLipSynchro'
Blender: 242

View File

@@ -68,11 +68,7 @@ def add_mesh_simple(name, verts, edges, faces):
else:
# Mesh with no data, unlikely
me.edges.extend(edges)
me.faces.extend(faces)
if is_editmode or Blender.Get('add_editmode'):
EditMode(1)
me.faces.extend(faces)
else:
# Object mode add new
@@ -95,9 +91,13 @@ def add_mesh_simple(name, verts, edges, faces):
ob_act.setMatrix(mat)
ob_act.loc = cursor
if is_editmode or Blender.Get('add_editmode'):
EditMode(1)
if is_editmode or Blender.Get('add_editmode'):
EditMode(1)
else: # adding in object mode means we need to calc normals
me.calcNormals()
def write_mesh_script(filepath, me):
@@ -112,7 +112,7 @@ def write_mesh_script(filepath, me):
file.write('#!BPY\n')
file.write('"""\n')
file.write('Name: \'%s\'\n' % name)
file.write('Blender: 243\n')
file.write('Blender: 245\n')
file.write('Group: \'AddMesh\'\n')
file.write('"""\n\n')
file.write('import BPyAddMesh\n')

View File

@@ -1,11 +1,12 @@
"""This module provides a function for reading dxf files and parsing them into a useful tree of objects and data.
The convert function is called by the readDXF fuction to convert dxf strings into the correct data based
on their type code. readDXF expects a (full path) file name as input.
The convert function is called by the readDXF fuction to convert dxf strings into the correct data based
on their type code. readDXF expects a (full path) file name as input.
"""
# --------------------------------------------------------------------------
# DXF Reader v0.9 by Ed Blake (AKA Kitsu)
# 2008.05.08 modif.def convert() by Remigiusz Fiedler (AKA migius)
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
@@ -30,215 +31,215 @@
#from dxfImportObjects import *
class Object:
"""Empty container class for dxf objects"""
def __init__(self, _type='', block=False):
"""_type expects a string value."""
self.type = _type
self.name = ''
self.data = []
def __str__(self):
if self.name:
return self.name
else:
return self.type
def __repr__(self):
return str(self.data)
def get_type(self, kind=''):
"""Despite the name, this method actually returns all objects of type 'kind' from self.data."""
if type:
objects = []
for item in self.data:
if type(item) != list and item.type == kind:
# we want this type of object
objects.append(item)
elif type(item) == list and item[0] == kind:
# we want this type of data
objects.append(item[1])
return objects
"""Empty container class for dxf objects"""
def __init__(self, _type='', block=False):
"""_type expects a string value."""
self.type = _type
self.name = ''
self.data = []
def __str__(self):
if self.name:
return self.name
else:
return self.type
def __repr__(self):
return str(self.data)
def get_type(self, kind=''):
"""Despite the name, this method actually returns all objects of type 'kind' from self.data."""
if type:
objects = []
for item in self.data:
if type(item) != list and item.type == kind:
# we want this type of object
objects.append(item)
elif type(item) == list and item[0] == kind:
# we want this type of data
objects.append(item[1])
return objects
class InitializationError(Exception): pass
class StateMachine:
"""(finite) State Machine from the great David Mertz's great Charming Python article."""
def __init__(self):
self.handlers = []
self.startState = None
self.endStates = []
def add_state(self, handler, end_state=0):
"""All states and handlers are functions which return
a state and a cargo."""
self.handlers.append(handler)
if end_state:
self.endStates.append(handler)
def set_start(self, handler):
"""Sets the starting handler function."""
self.startState = handler
def run(self, cargo=None):
if not self.startState:
raise InitializationError,\
"must call .set_start() before .run()"
if not self.endStates:
raise InitializationError, \
"at least one state must be an end_state"
handler = self.startState
while 1:
(newState, cargo) = handler(cargo)
#print cargo
if newState in self.endStates:
return newState(cargo)
#break
elif newState not in self.handlers:
raise RuntimeError, "Invalid target %s" % newState
else:
handler = newState
"""(finite) State Machine from the great David Mertz's great Charming Python article."""
def __init__(self):
self.handlers = []
self.startState = None
self.endStates = []
def add_state(self, handler, end_state=0):
"""All states and handlers are functions which return
a state and a cargo."""
self.handlers.append(handler)
if end_state:
self.endStates.append(handler)
def set_start(self, handler):
"""Sets the starting handler function."""
self.startState = handler
def run(self, cargo=None):
if not self.startState:
raise InitializationError,\
"must call .set_start() before .run()"
if not self.endStates:
raise InitializationError, \
"at least one state must be an end_state"
handler = self.startState
while 1:
(newState, cargo) = handler(cargo)
#print cargo
if newState in self.endStates:
return newState(cargo)
#break
elif newState not in self.handlers:
raise RuntimeError, "Invalid target %s" % newState
else:
handler = newState
def get_name(data):
"""Get the name of an object from its object data.
Returns a pair of (data_item, name) where data_item is the list entry where the name was found
(the data_item can be used to remove the entry from the object data). Be sure to check
name not None before using the returned values!
"""
value = None
for item in data:
if item[0] == 2:
value = item[1]
break
return item, value
"""Get the name of an object from its object data.
Returns a pair of (data_item, name) where data_item is the list entry where the name was found
(the data_item can be used to remove the entry from the object data). Be sure to check
name not None before using the returned values!
"""
value = None
for item in data:
if item[0] == 2:
value = item[1]
break
return item, value
def get_layer(data):
"""Expects object data as input.
Returns (entry, layer_name) where entry is the data item that provided the layer name.
"""
value = None
for item in data:
if item[0] == 8:
value = item[1]
break
return item, value
"""Expects object data as input.
Returns (entry, layer_name) where entry is the data item that provided the layer name.
"""
value = None
for item in data:
if item[0] == 8:
value = item[1]
break
return item, value
def convert(code, value):
"""Convert a string to the correct Python type based on its dxf code.
code types:
ints = 60-79, 170-179, 270-289, 370-389, 400-409, 1060-1070
longs = 90-99, 420-429, 440-459, 1071
floats = 10-39, 40-59, 110-139, 140-149, 210-239, 460-469, 1010-1059
hex = 105, 310-379, 390-399
strings = 0-9, 100, 102, 300-309, 410-419, 430-439, 470-479, 999, 1000-1009
"""
if 59 < code < 80 or 169 < code < 180 or 269 < code < 290 or 369 < code < 390 or 399 < code < 410 or 1059 < code < 1071:
value = int(value)
elif 89 < code < 100 or 419 < code < 430 or 439 < code < 460 or code == 1071:
value = long(value)
elif 9 < code < 60 or 109 < code < 150 or 209 < code < 240 or 459 < code < 470 or 1009 < code < 1060:
value = float(value)
elif code == 105 or 309 < code < 380 or 389 < code < 400:
value = int(value, 16) # should be left as string?
else: # it's already a string so do nothing
pass
return value
"""Convert a string to the correct Python type based on its dxf code.
code types:
ints = 60-79, 170-179, 270-289, 370-389, 400-409, 1060-1070
longs = 90-99, 420-429, 440-459, 1071
floats = 10-39, 40-59, 110-139, 140-149, 210-239, 460-469, 1010-1059
hex = 105, 310-379, 390-399
strings = 0-9, 100, 102, 300-309, 410-419, 430-439, 470-479, 999, 1000-1009
"""
if 59 < code < 80 or 169 < code < 180 or 269 < code < 290 or 369 < code < 390 or 399 < code < 410 or 1059 < code < 1071:
value = int(float(value))
elif 89 < code < 100 or 419 < code < 430 or 439 < code < 460 or code == 1071:
value = long(float(value))
elif 9 < code < 60 or 109 < code < 150 or 209 < code < 240 or 459 < code < 470 or 1009 < code < 1060:
value = float(value)
elif code == 105 or 309 < code < 380 or 389 < code < 400:
value = int(value, 16) # should be left as string?
else: # it's already a string so do nothing
pass
return value
def findObject(infile, kind=''):
"""Finds the next occurance of an object."""
obj = False
while 1:
line = infile.readline()
if not line: # readline returns '' at eof
return False
if not obj: # We're still looking for our object code
if line.lower().strip() == '0':
obj = True # found it
else: # we are in an object definition
if kind: # if we're looking for a particular kind
if line.lower().strip() == kind:
obj = Object(line.lower().strip())
break
else: # otherwise take anything non-numeric
if line.lower().strip() not in string.digits:
obj = Object(line.lower().strip())
break
obj = False # whether we found one or not it's time to start over
return obj
"""Finds the next occurance of an object."""
obj = False
while 1:
line = infile.readline()
if not line: # readline returns '' at eof
return False
if not obj: # We're still looking for our object code
if line.lower().strip() == '0':
obj = True # found it
else: # we are in an object definition
if kind: # if we're looking for a particular kind
if line.lower().strip() == kind:
obj = Object(line.lower().strip())
break
else: # otherwise take anything non-numeric
if line.lower().strip() not in string.digits:
obj = Object(line.lower().strip())
break
obj = False # whether we found one or not it's time to start over
return obj
def handleObject(infile):
"""Add data to an object until end of object is found."""
line = infile.readline()
if line.lower().strip() == 'section':
return 'section' # this would be a problem
elif line.lower().strip() == 'endsec':
return 'endsec' # this means we are done with a section
else: # add data to the object until we find a new object
obj = Object(line.lower().strip())
obj.name = obj.type
done = False
data = []
while not done:
line = infile.readline()
if not data:
if line.lower().strip() == '0':
#we've found an object, time to return
return obj
else:
# first part is always an int
data.append(int(line.lower().strip()))
else:
data.append(convert(data[0], line.strip()))
obj.data.append(data)
data = []
"""Add data to an object until end of object is found."""
line = infile.readline()
if line.lower().strip() == 'section':
return 'section' # this would be a problem
elif line.lower().strip() == 'endsec':
return 'endsec' # this means we are done with a section
else: # add data to the object until we find a new object
obj = Object(line.lower().strip())
obj.name = obj.type
done = False
data = []
while not done:
line = infile.readline()
if not data:
if line.lower().strip() == '0':
#we've found an object, time to return
return obj
else:
# first part is always an int
data.append(int(line.lower().strip()))
else:
data.append(convert(data[0], line.strip()))
obj.data.append(data)
data = []
def handleTable(table, infile):
"""Special handler for dealing with nested table objects."""
item, name = get_name(table.data)
if name: # We should always find a name
table.data.remove(item)
table.name = name.lower()
# This next bit is from handleObject
# handleObject should be generalized to work with any section like object
while 1:
obj = handleObject(infile)
if obj.type == 'table':
print "Warning: previous table not closed!"
return table
elif obj.type == 'endtab':
return table # this means we are done with the table
else: # add objects to the table until one of the above is found
table.data.append(obj)
"""Special handler for dealing with nested table objects."""
item, name = get_name(table.data)
if name: # We should always find a name
table.data.remove(item)
table.name = name.lower()
# This next bit is from handleObject
# handleObject should be generalized to work with any section like object
while 1:
obj = handleObject(infile)
if obj.type == 'table':
print "Warning: previous table not closed!"
return table
elif obj.type == 'endtab':
return table # this means we are done with the table
else: # add objects to the table until one of the above is found
table.data.append(obj)
def handleBlock(block, infile):
"""Special handler for dealing with nested table objects."""
item, name = get_name(block.data)
if name: # We should always find a name
block.data.remove(item)
block.name = name
# This next bit is from handleObject
# handleObject should be generalized to work with any section like object
while 1:
obj = handleObject(infile)
if obj.type == 'block':
print "Warning: previous block not closed!"
return block
elif obj.type == 'endblk':
return block # this means we are done with the table
else: # add objects to the table until one of the above is found
block.data.append(obj)
"""Special handler for dealing with nested table objects."""
item, name = get_name(block.data)
if name: # We should always find a name
block.data.remove(item)
block.name = name
# This next bit is from handleObject
# handleObject should be generalized to work with any section like object
while 1:
obj = handleObject(infile)
if obj.type == 'block':
print "Warning: previous block not closed!"
return block
elif obj.type == 'endblk':
return block # this means we are done with the table
else: # add objects to the table until one of the above is found
block.data.append(obj)
"""These are the states/functions used in the State Machine.
states:
@@ -250,133 +251,131 @@ states:
"""
def start(cargo):
"""Expects the infile as cargo, initializes the cargo."""
#print "Entering start state!"
infile = cargo
drawing = Object('drawing')
section = findObject(infile, 'section')
if section:
return start_section, (infile, drawing, section)
else:
return error, (infile, "Failed to find any sections!")
"""Expects the infile as cargo, initializes the cargo."""
#print "Entering start state!"
infile = cargo
drawing = Object('drawing')
section = findObject(infile, 'section')
if section:
return start_section, (infile, drawing, section)
else:
return error, (infile, "Failed to find any sections!")
def start_section(cargo):
"""Expects [infile, drawing, section] as cargo, builds a nested section object."""
#print "Entering start_section state!"
infile = cargo[0]
drawing = cargo[1]
section = cargo[2]
# read each line, if it is an object declaration go to object mode
# otherwise create a [index, data] pair and add it to the sections data.
done = False
data = []
while not done:
line = infile.readline()
if not data: # if we haven't found a dxf code yet
if line.lower().strip() == '0':
# we've found an object
while 1: # no way out unless we find an end section or a new section
obj = handleObject(infile)
if obj == 'section': # shouldn't happen
print "Warning: failed to close previous section!"
return end_section, (infile, drawing)
elif obj == 'endsec': # This section is over, look for the next
drawing.data.append(section)
return end_section, (infile, drawing)
elif obj.type == 'table': # tables are collections of data
obj = handleTable(obj, infile) # we need to find all there contents
section.data.append(obj) # before moving on
elif obj.type == 'block': # the same is true of blocks
obj = handleBlock(obj, infile) # we need to find all there contents
section.data.append(obj) # before moving on
else: # found another sub-object
section.data.append(obj)
else:
data.append(int(line.lower().strip()))
else: # we have our code, now we just need to convert the data and add it to our list.
data.append(convert(data[0], line.strip()))
section.data.append(data)
data = []
"""Expects [infile, drawing, section] as cargo, builds a nested section object."""
#print "Entering start_section state!"
infile = cargo[0]
drawing = cargo[1]
section = cargo[2]
# read each line, if it is an object declaration go to object mode
# otherwise create a [index, data] pair and add it to the sections data.
done = False
data = []
while not done:
line = infile.readline()
if not data: # if we haven't found a dxf code yet
if line.lower().strip() == '0':
# we've found an object
while 1: # no way out unless we find an end section or a new section
obj = handleObject(infile)
if obj == 'section': # shouldn't happen
print "Warning: failed to close previous section!"
return end_section, (infile, drawing)
elif obj == 'endsec': # This section is over, look for the next
drawing.data.append(section)
return end_section, (infile, drawing)
elif obj.type == 'table': # tables are collections of data
obj = handleTable(obj, infile) # we need to find all there contents
section.data.append(obj) # before moving on
elif obj.type == 'block': # the same is true of blocks
obj = handleBlock(obj, infile) # we need to find all there contents
section.data.append(obj) # before moving on
else: # found another sub-object
section.data.append(obj)
else:
data.append(int(line.lower().strip()))
else: # we have our code, now we just need to convert the data and add it to our list.
data.append(convert(data[0], line.strip()))
section.data.append(data)
data = []
def end_section(cargo):
"""Expects (infile, drawing) as cargo, searches for next section."""
#print "Entering end_section state!"
infile = cargo[0]
drawing = cargo[1]
section = findObject(infile, 'section')
if section:
return start_section, (infile, drawing, section)
else:
return end, (infile, drawing)
"""Expects (infile, drawing) as cargo, searches for next section."""
#print "Entering end_section state!"
infile = cargo[0]
drawing = cargo[1]
section = findObject(infile, 'section')
if section:
return start_section, (infile, drawing, section)
else:
return end, (infile, drawing)
def end(cargo):
"""Expects (infile, drawing) as cargo, called when eof has been reached."""
#print "Entering end state!"
infile = cargo[0]
drawing = cargo[1]
#infile.close()
return drawing
"""Expects (infile, drawing) as cargo, called when eof has been reached."""
#print "Entering end state!"
infile = cargo[0]
drawing = cargo[1]
#infile.close()
return drawing
def error(cargo):
"""Expects a (infile, string) as cargo, called when there is an error during processing."""
#print "Entering error state!"
infile = cargo[0]
err = cargo[1]
infile.close()
print "There has been an error:"
print err
return False
"""Expects a (infile, string) as cargo, called when there is an error during processing."""
#print "Entering error state!"
infile = cargo[0]
err = cargo[1]
infile.close()
print "There has been an error:"
print err
return False
def readDXF(filename, objectify):
"""Given a file name try to read it as a dxf file.
Output is an object with the following structure
drawing
header
header data
classes
class data
tables
table data
blocks
block data
entities
entity data
objects
object data
where foo data is a list of sub-objects. True object data
is of the form [code, data].
"""Given a file name try to read it as a dxf file.
Output is an object with the following structure
drawing
header
header data
classes
class data
tables
table data
blocks
block data
entities
entity data
objects
object data
where foo data is a list of sub-objects. True object data
is of the form [code, data].
"""
infile = open(filename)
infile = open(filename)
sm = StateMachine()
sm.add_state(error, True)
sm.add_state(end, True)
sm.add_state(start_section)
sm.add_state(end_section)
sm.add_state(start)
sm.set_start(start)
try:
drawing = sm.run(infile)
if drawing:
drawing.name = filename
for obj in drawing.data:
item, name = get_name(obj.data)
if name:
obj.data.remove(item)
obj.name = name.lower()
setattr(drawing, name.lower(), obj)
# Call the objectify function to cast
# raw objects into the right types of object
obj.data = objectify(obj.data)
#print obj.name
finally:
infile.close()
return drawing
sm = StateMachine()
sm.add_state(error, True)
sm.add_state(end, True)
sm.add_state(start_section)
sm.add_state(end_section)
sm.add_state(start)
sm.set_start(start)
try:
drawing = sm.run(infile)
if drawing:
drawing.name = filename
for obj in drawing.data:
item, name = get_name(obj.data)
if name:
obj.data.remove(item)
obj.name = name.lower()
setattr(drawing, name.lower(), obj)
# Call the objectify function to cast
# raw objects into the right types of object
obj.data = objectify(obj.data)
#print obj.name
finally:
infile.close()
return drawing
if __name__ == "__main__":
filename = r".\examples\block-test.dxf"
drawing = readDXF(filename)
for item in drawing.entities.data:
print item
filename = r".\examples\block-test.dxf"
drawing = readDXF(filename)
for item in drawing.entities.data:
print item

View File

@@ -1,4 +1,5 @@
#!BPY
# coding: utf-8
""" Registration info for Blender menus:
Name: 'M3G (.m3g, .java)...'
Blender: 244
@@ -3069,4 +3070,5 @@ def file_callback_m3g(filename):
Window.RedrawAll()
if __name__ == '__main__':
gui()
gui()

View File

@@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
""" Registration info for Blender menus:
Name: 'HotKey and MouseAction Reference'
Blender: 242
@@ -918,4 +918,4 @@ def bevent(evt):
Blender.Window.Redraw()
if __name__ == '__main__':
Register(draw, event, bevent)
Register(draw, event, bevent)

View File

@@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
"""
Name: 'Autodesk DXF (.dxf)'
Blender: 244
@@ -5942,4 +5942,5 @@ if 1:
main(_dxf)
print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
"""
"""

View File

@@ -77,7 +77,11 @@ def copy_vgroups(source_ob, target_ob):
for vgroupname in vgroups:
target_me.addVertGroup(vgroupname)
if len(target_me.verts) == len(source_me.verts):
vlist = source_me.getVertsFromGroup(vgroupname, True)
try: # in rare cases this can raise an 'no deform groups assigned to mesh' error
vlist = source_me.getVertsFromGroup(vgroupname, True)
except:
vlist = []
try:
for vpair in vlist:
target_me.assignVertsToGroup(vgroupname, [vpair[0]], vpair[1], ADD)
@@ -171,4 +175,4 @@ def apply_deform():
Blender.Window.RedrawAll()
if __name__=='__main__':
apply_deform()
apply_deform()

View File

@@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
"""
Name: 'Paths (.svg, .ps, .eps, .ai, Gimp)'
Blender: 233
@@ -92,4 +92,5 @@ elif argv=='Gimp_2_0':
fonctionSELECT = functionSELECT # can they all be called function?
text = 'Import %s' % argv
Blender.Window.FileSelector (fonctionSELECT, text)
Blender.Window.FileSelector (fonctionSELECT, text)

View File

@@ -47,8 +47,12 @@ rend = sce.render
# default filename: theme's name + '_theme.py' in user's scripts dir:
default_fname = Blender.Get("scriptsdir")
default_fname = Blender.sys.join(default_fname, sce.name + '_renderlayer.py')
default_fname = default_fname.replace(' ','_')
if not default_fname:
default_fname = Blender.Get("uscriptsdir")
if default_fname:
default_fname = Blender.sys.join(default_fname, sce.name + '_renderlayer.py')
default_fname = default_fname.replace(' ','_')
def write_renderlayers(filename):
"Write the current renderlayer as a bpython script"
@@ -113,4 +117,4 @@ rend = sce.render
except:
Blender.Draw.PupMenu("Warning - check console!%t|Menus could not be automatically updated")
FileSelector(write_renderlayers, "Save RenderLayers", default_fname)
FileSelector(write_renderlayers, "Save RenderLayers", default_fname)

View File

@@ -1,5 +1,5 @@
#!BPY
# coding: utf-8
""" Registration info for Blender menus: <- these words are ignored
Name: 'Deformed mesh to Rvk'
Blender: 243
@@ -270,4 +270,4 @@ def deform2rvk():
EDITMODE=Blender.Window.EditMode()
Blender.Window.EditMode(0)
deform2rvk()
Blender.Window.EditMode(EDITMODE)
Blender.Window.EditMode(EDITMODE)

View File

@@ -57,6 +57,8 @@ import Blender
from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
from Blender.Scene import Render
import math
import BPyObject
import BPyMesh
#
DEG2RAD=0.017453292519943295
@@ -68,14 +70,14 @@ MATWORLD= Blender.Mathutils.RotationMatrix(-90, 4, 'x')
filename = Blender.Get('filename')
_safeOverwrite = True
ARG=''
extension = ''
##########################################################
# Functions for writing output file
##########################################################
class VRML2Export:
class x3d_class:
def __init__(self, filename):
#--- public you can change these ---
@@ -101,7 +103,18 @@ class VRML2Export:
self.meshNames={} # dictionary of meshNames
self.indentLevel=0 # keeps track of current indenting
self.filename=filename
self.file = open(filename, "w")
self.file = None
if filename.lower().endswith('.x3dz'):
try:
import gzip
self.file = gzip.open(filename, "w")
except:
print "failed to import compression modules, exporting uncompressed"
self.filename = filename[:-1] # remove trailing z
if self.file == None:
self.file = open(self.filename, "w")
self.bNav=0
self.nodeID=0
self.namesReserved=[ "Anchor","Appearance","Arc2D","ArcClose2D","AudioClip","Background","Billboard",
@@ -169,7 +182,7 @@ class VRML2Export:
nameinline = nameinline+".x3d"
self.file.write("url=\"%s\" />" % nameinline)
self.file.write("\n\n")
'''
def writeScript(self):
textEditor = Blender.Text.Get()
@@ -190,15 +203,17 @@ class VRML2Export:
for j in xrange(nalllines):
self.writeIndented(alllines[j] + "\n")
self.writeIndented("\n")
def writeViewpoint(self, ob, scene):
'''
def writeViewpoint(self, ob, mat, scene):
context = scene.render
ratio = float(context.imageSizeY())/float(context.imageSizeX())
lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180)
lens = min(lens, math.pi)
# get the camera location, subtract 90 degress from X to orient like X3D does
mat = ob.matrixWorld
# mat = ob.matrixWorld - mat is now passed!
loc = self.rotatePointForVRML(mat.translationPart())
rot = mat.toEuler()
rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
@@ -229,23 +244,11 @@ class VRML2Export:
self.file.write("visibilityRange=\"%s\" />\n\n" % round(mparam[2],self.cp))
else:
return
'''
def writeNavigationInfo(self, scene):
allObj = []
allObj = list(scene.objects)
headlight = "true"
vislimit = 0.0
for ob in allObj:
objType=ob.type
if objType == "Camera":
vislimit = ob.data.clipEnd
elif objType == "Lamp":
headlight = "false"
self.file.write("<NavigationInfo headlight=\"%s\" " % headlight)
self.file.write("visibilityLimit=\"%s\" " % (round(vislimit,self.cp)))
self.file.write("type=\"EXAMINE\", \"ANY\" avatarSize=\"0.25, 1.75, 0.75\" />\n\n")
'''
def writeSpotLight(self, ob, lamp, world):
self.file.write('<NavigationInfo headlight="FALSE" visibilityLimit="0.0" type=\'"EXAMINE","ANY"\' avatarSize="0.25, 1.75, 0.75" />\n')
def writeSpotLight(self, ob, mtx, lamp, world):
safeName = self.cleanStr(ob.name)
if world:
ambi = world.amb
@@ -259,12 +262,14 @@ class VRML2Export:
beamWidth=((lamp.spotSize*math.pi)/180.0)*.37;
cutOffAngle=beamWidth*1.3
dx,dy,dz=self.computeDirection(ob)
dx,dy,dz=self.computeDirection(mtx)
# note -dx seems to equal om[3][0]
# note -dz seems to equal om[3][1]
# note dy seems to equal om[3][2]
location=(ob.matrixWorld*MATWORLD).translationPart()
#location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
location=(mtx*MATWORLD).translationPart()
radius = lamp.dist*math.cos(beamWidth)
self.file.write("<SpotLight DEF=\"%s\" " % safeName)
self.file.write("radius=\"%s\" " % (round(radius,self.cp)))
@@ -277,7 +282,7 @@ class VRML2Export:
self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
def writeDirectionalLight(self, ob, lamp, world):
def writeDirectionalLight(self, ob, mtx, lamp, world):
safeName = self.cleanStr(ob.name)
if world:
ambi = world.amb
@@ -287,14 +292,14 @@ class VRML2Export:
ambientIntensity = 0
intensity=min(lamp.energy/1.75,1.0)
(dx,dy,dz)=self.computeDirection(ob)
(dx,dy,dz)=self.computeDirection(mtx)
self.file.write("<DirectionalLight DEF=\"%s\" " % safeName)
self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
self.file.write("direction=\"%s %s %s\" />\n\n" % (round(dx,4),round(dy,4),round(dz,4)))
def writePointLight(self, ob, lamp, world):
def writePointLight(self, ob, mtx, lamp, world):
safeName = self.cleanStr(ob.name)
if world:
ambi = world.amb
@@ -303,29 +308,30 @@ class VRML2Export:
ambi = 0
ambientIntensity = 0
location=(ob.matrixWorld*MATWORLD).translationPart()
intensity=min(lamp.energy/1.75,1.0)
radius = lamp.dist
# location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
location= (mtx*MATWORLD).translationPart()
self.file.write("<PointLight DEF=\"%s\" " % safeName)
self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
self.file.write("radius=\"%s\" " % radius )
self.file.write("intensity=\"%s\" " % (round( min(lamp.energy/1.75,1.0) ,self.cp)))
self.file.write("radius=\"%s\" " % lamp.dist )
self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
def writeNode(self, ob):
'''
def writeNode(self, ob, mtx):
obname=str(ob.name)
if obname in self.namesStandard:
return
else:
dx,dy,dz = self.computeDirection(ob)
location=(ob.matrixWorld*MATWORLD).translationPart()
dx,dy,dz = self.computeDirection(mtx)
# location=(ob.matrixWorld*MATWORLD).translationPart()
location=(mtx*MATWORLD).translationPart()
self.writeIndented("<%s\n" % obname,1)
self.writeIndented("# direction %s %s %s\n" % (round(dx,3),round(dy,3),round(dz,3)))
self.writeIndented("# location %s %s %s\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
self.writeIndented("direction=\"%s %s %s\"\n" % (round(dx,3),round(dy,3),round(dz,3)))
self.writeIndented("location=\"%s %s %s\"\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
self.writeIndented("/>\n",-1)
self.writeIndented("\n")
'''
def secureName(self, name):
name = name + str(self.nodeID)
self.nodeID=self.nodeID+1
@@ -345,13 +351,13 @@ class VRML2Export:
newname = name
return "%s" % (newname)
def writeIndexedFaceSet(self, ob, world, normals = 0):
def writeIndexedFaceSet(self, ob, mesh, mtx, world, EXPORT_TRI = False):
imageMap={} # set of used images
sided={} # 'one':cnt , 'two':cnt
vColors={} # 'multi':1
meshName = self.cleanStr(ob.name)
mesh=ob.getData(mesh=1)
meshME = self.cleanStr(mesh.name)
meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not
if len(mesh.faces) == 0: return
mode = 0
if mesh.faceUV:
@@ -371,7 +377,7 @@ class VRML2Export:
elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0:
self.writeIndented("<Collision enabled=\"false\">\n",1)
self.collnode = 1
nIFSCnt=self.countIFSSetsNeeded(mesh, imageMap, sided, vColors)
if nIFSCnt > 1:
@@ -382,7 +388,8 @@ class VRML2Export:
else:
bTwoSided=0
mtx = ob.matrixWorld * MATWORLD
# mtx = ob.matrixWorld * MATWORLD # mtx is now passed
mtx = mtx * MATWORLD
loc= mtx.translationPart()
sca= mtx.scalePart()
@@ -456,12 +463,12 @@ class VRML2Export:
elif hasImageTexture == 1:
self.writeTextureCoordinates(mesh)
#--- output coordinates
self.writeCoordinates(ob, mesh, meshName)
self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI)
self.writingcoords = 1
self.writingtexture = 1
self.writingcolor = 1
self.writeCoordinates(ob, mesh, meshName)
self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI)
#--- output textureCoordinates if UV texture used
if mesh.faceUV:
@@ -498,17 +505,23 @@ class VRML2Export:
self.file.write("\n")
def writeCoordinates(self, ob, mesh, meshName):
def writeCoordinates(self, ob, mesh, meshName, EXPORT_TRI = False):
# create vertex list and pre rotate -90 degrees X for VRML
if self.writingcoords == 0:
self.file.write('coordIndex="')
for face in mesh.faces:
fv = face.v
if len(face)==4:
self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index))
if len(face)==3:
self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
else:
self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
if EXPORT_TRI:
self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index))
else:
self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index))
self.file.write("\">\n")
else:
#-- vertices
@@ -679,43 +692,74 @@ class VRML2Export:
# export routine
##########################################################
def export(self, scene, world, alltextures):
def export(self, scene, world, alltextures,\
EXPORT_APPLY_MODIFIERS = False,\
EXPORT_TRI= False,\
):
print "Info: starting X3D export to " + self.filename + "..."
self.writeHeader()
self.writeScript()
# self.writeNavigationInfo(scene) # This seems to position me in some strange area I cant see the model (with BS Contact) - Campbell
# self.writeScript()
self.writeNavigationInfo(scene)
self.writeBackground(world, alltextures)
self.writeFog(world)
self.proto = 0
for ob in scene.objects.context:
objType=ob.type
objName=ob.name
self.matonly = 0
if objType == "Camera":
self.writeViewpoint(ob, scene)
elif objType == "Mesh":
self.writeIndexedFaceSet(ob, world, normals = 0)
elif objType == "Lamp":
data= ob.data
datatype=data.type
if datatype == Lamp.Types.Lamp:
self.writePointLight(ob, data, world)
elif datatype == Lamp.Types.Spot:
self.writeSpotLight(ob, data, world)
elif datatype == Lamp.Types.Sun:
self.writeDirectionalLight(ob, data, world)
else:
self.writeDirectionalLight(ob, data, world)
elif objType == "Empty" and objName != "Empty":
self.writeNode(ob)
else:
#print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType)
print ""
if ARG != 'selected':
self.writeScript()
# COPIED FROM OBJ EXPORTER
if EXPORT_APPLY_MODIFIERS:
temp_mesh_name = '~tmp-mesh'
# Get the container mesh. - used for applying modifiers and non mesh objects.
containerMesh = meshName = tempMesh = None
for meshName in Blender.NMesh.GetNames():
if meshName.startswith(temp_mesh_name):
tempMesh = Mesh.Get(meshName)
if not tempMesh.users:
containerMesh = tempMesh
if not containerMesh:
containerMesh = Mesh.New(temp_mesh_name)
# --------------------------
for ob_main in scene.objects.context:
for ob, ob_mat in BPyObject.getDerivedObjects(ob_main):
objType=ob.type
objName=ob.name
self.matonly = 0
if objType == "Camera":
self.writeViewpoint(ob, ob_mat, scene)
elif objType in ("Mesh", "Curve", "Surf", "Text") :
if EXPORT_APPLY_MODIFIERS or objType != 'Mesh':
me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene)
else:
me = ob.getData(mesh=1)
self.writeIndexedFaceSet(ob, me, ob_mat, world, EXPORT_TRI = EXPORT_TRI)
elif objType == "Lamp":
data= ob.data
datatype=data.type
if datatype == Lamp.Types.Lamp:
self.writePointLight(ob, ob_mat, data, world)
elif datatype == Lamp.Types.Spot:
self.writeSpotLight(ob, ob_mat, data, world)
elif datatype == Lamp.Types.Sun:
self.writeDirectionalLight(ob, ob_mat, data, world)
else:
self.writeDirectionalLight(ob, ob_mat, data, world)
# do you think x3d could document what to do with dummy objects?
#elif objType == "Empty" and objName != "Empty":
# self.writeNode(ob, ob_mat)
else:
#print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType)
pass
self.file.write("\n</Scene>\n</X3D>")
if EXPORT_APPLY_MODIFIERS:
if containerMesh:
containerMesh.verts = None
self.cleanup()
##########################################################
@@ -837,10 +881,10 @@ class VRML2Export:
round(c.b/255.0,self.cp))
return s
def computeDirection(self, ob):
def computeDirection(self, mtx):
x,y,z=(0,-1.0,0) # point down
ax,ay,az = (ob.matrixWorld*MATWORLD).toEuler()
ax,ay,az = (mtx*MATWORLD).toEuler()
ax *= DEG2RAD
ay *= DEG2RAD
@@ -931,7 +975,36 @@ class VRML2Export:
# Callbacks, needed before Main
##########################################################
def select_file(filename):
def x3d_export(filename, \
EXPORT_APPLY_MODIFIERS= False,\
EXPORT_TRI= False,\
EXPORT_GZIP= False,\
):
if EXPORT_GZIP:
if not filename.lower().endswith('.x3dz'):
filename = '.'.join(filename.split('.')[:-1]) + '.x3dz'
else:
if not filename.lower().endswith('.x3d'):
filename = '.'.join(filename.split('.')[:-1]) + '.x3d'
scene = Blender.Scene.GetCurrent()
world = scene.world
alltextures = Blender.Texture.Get()
wrlexport=x3d_class(filename)
wrlexport.export(\
scene,\
world,\
alltextures,\
\
EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS,\
EXPORT_TRI = EXPORT_TRI,\
)
def x3d_export_ui(filename):
if not filename.endswith(extension):
filename += extension
#if _safeOverwrite and sys.exists(filename):
@@ -939,18 +1012,40 @@ def select_file(filename):
#if(result != 1):
# return
scene = Blender.Scene.GetCurrent()
world = scene.world
alltextures = Blender.Texture.Get()
# Get user options
EXPORT_APPLY_MODIFIERS = Draw.Create(1)
EXPORT_TRI = Draw.Create(0)
EXPORT_GZIP = Draw.Create( filename.lower().endswith('.x3dz') )
# Get USER Options
pup_block = [\
('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object.'),\
('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\
('Compress', EXPORT_GZIP, 'GZip the resulting file, requires a full python install'),\
]
if not Draw.PupBlock('Export...', pup_block):
return
Blender.Window.EditMode(0)
Blender.Window.WaitCursor(1)
x3d_export(filename,\
EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val,\
EXPORT_TRI = EXPORT_TRI.val,\
EXPORT_GZIP = EXPORT_GZIP.val\
)
Blender.Window.WaitCursor(0)
wrlexport=VRML2Export(filename)
wrlexport.export(scene, world, alltextures)
#########################################################
# main routine
#########################################################
if __name__ == '__main__':
Blender.Window.FileSelector(select_file,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
# select_file('/shared/bed1.x3d')
Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))