Cleaned up Blender exporter (visually, code-wise and whitespaces-wise)

This commit is contained in:
Mr.doob
2011-04-11 13:03:19 +01:00
parent 7361be39df
commit bc520665d3
2 changed files with 262 additions and 235 deletions
@@ -20,7 +20,7 @@
# Init
# ################################################################
# To support reload properly, try to access a package var,
# To support reload properly, try to access a package var,
# if it's there, reload everything
if "bpy" in locals():
@@ -44,16 +44,16 @@ bpy.types.Object.THREE_meshCollider = bpy.props.BoolProperty()
bpy.types.Material.THREE_useVertexColors = bpy.props.BoolProperty()
class OBJECT_PT_hello( bpy.types.Panel ):
bl_label = "THREE"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
def draw(self, context):
layout = self.layout
obj = context.object
row = layout.row()
row.label(text="Selected object: " + obj.name )
@@ -65,16 +65,16 @@ class OBJECT_PT_hello( bpy.types.Panel ):
class MATERIAL_PT_hello( bpy.types.Panel ):
bl_label = "THREE"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "material"
def draw(self, context):
layout = self.layout
mat = context.material
row = layout.row()
row.label(text="Selected material: " + mat.name )
@@ -123,20 +123,20 @@ import json
def file_exists(filename):
"""Return true if file exists and accessible for reading.
Should be safer than just testing for existence due to links and
Should be safer than just testing for existence due to links and
permissions magic on Unix filesystems.
@rtype: boolean
"""
try:
f = open(filename, 'r')
f.close()
return True
except IOError:
return False
def get_settings_fullpath():
return os.path.join(bpy.app.tempdir, SETTINGS_FILE_EXPORT)
@@ -153,40 +153,42 @@ def save_settings_export(properties):
"option_uv_coords" : properties.option_uv_coords,
"option_edges" : properties.option_edges,
"option_truncate" : properties.option_truncate,
"option_vertices_truncate" : properties.option_vertices_truncate,
"option_scale" : properties.option_scale,
"align_model" : properties.align_model
}
fname = get_settings_fullpath()
f = open(fname, "w")
json.dump(settings, f)
def restore_settings_export(properties):
settings = {}
fname = get_settings_fullpath()
if file_exists(fname):
f = open(fname, "r")
settings = json.load(f)
properties.option_export_scene = settings.get("option_export_scene", False)
properties.option_flip_yz = settings.get("option_flip_yz", True)
properties.option_materials = settings.get("option_materials", True)
properties.option_vertices = settings.get("option_vertices", True)
properties.option_vertices_truncate = settings.get("option_vertices_truncate", False)
properties.option_faces = settings.get("option_faces", True)
properties.option_normals = settings.get("option_normals", True)
properties.option_edges = settings.get("option_edges", False)
properties.option_colors = settings.get("option_colors", True)
properties.option_uv_coords = settings.get("option_uv_coords", True)
properties.option_edges = settings.get("option_edges", False)
properties.option_truncate = settings.get("option_truncate", False)
properties.option_scale = settings.get("option_scale", 1.0)
properties.option_materials = settings.get("option_materials", True)
properties.align_model = settings.get("align_model", "None")
properties.option_scale = settings.get("option_scale", 1.0)
properties.option_flip_yz = settings.get("option_flip_yz", True)
properties.option_export_scene = settings.get("option_export_scene", False)
# ################################################################
# Exporter
# ################################################################
@@ -199,10 +201,13 @@ class ExportTHREEJS(bpy.types.Operator, ExportHelper):
filename_ext = ".js"
option_flip_yz = BoolProperty(name = "Flip YZ", description = "Flip YZ", default = True)
option_vertices = BoolProperty(name = "Vertices", description = "Export vertices", default = True)
option_vertices_deltas = BoolProperty(name = "Deltas", description = "Delta vertices", default = False)
option_vertices_truncate = BoolProperty(name = "Truncate", description = "Truncate vertices", default = False)
option_faces = BoolProperty(name = "Faces", description = "Export faces", default = True)
option_faces_deltas = BoolProperty(name = "Deltas", description = "Delta faces", default = False)
option_normals = BoolProperty(name = "Normals", description = "Export normals", default = True)
option_edges = BoolProperty(name = "Edges", description = "Export edges", default = False)
@@ -210,14 +215,14 @@ class ExportTHREEJS(bpy.types.Operator, ExportHelper):
option_uv_coords = BoolProperty(name = "UVs", description = "Export texture coordinates", default = True)
option_materials = BoolProperty(name = "Materials", description = "Export materials", default = True)
option_export_scene = BoolProperty(name = "Scene", description = "Export scene", default = False)
option_truncate = BoolProperty(name = "Truncate", description = "Truncate decimals", default = False)
option_scale = FloatProperty(name = "Scale", description = "Scale data", min = 0.01, max = 1000.0, soft_min = 0.01, soft_max = 1000.0, default = 1.0)
align_types = [("None","None","None"), ("Center","Center","Center"), ("Bottom","Bottom","Bottom"), ("Top","Top","Top")]
align_model = EnumProperty(name = "Align model", description = "Align model", items = align_types, default = "None")
option_scale = FloatProperty(name = "Scale", description = "Scale vertices", min = 0.01, max = 1000.0, soft_min = 0.01, soft_max = 1000.0, default = 1.0)
option_flip_yz = BoolProperty(name = "Flip YZ", description = "Flip YZ", default = True)
option_export_scene = BoolProperty(name = "Scene", description = "Export scene", default = False)
def invoke(self, context, event):
restore_settings_export(self.properties)
return ExportHelper.invoke(self, context, event)
@@ -242,25 +247,34 @@ class ExportTHREEJS(bpy.types.Operator, ExportHelper):
layout = self.layout
row = layout.row()
row.prop(self.properties, "option_export_scene")
layout.separator()
row = layout.row()
row.prop(self.properties, "option_flip_yz")
layout.separator()
row = layout.row()
row.prop(self.properties, "align_model")
layout.separator()
row.label(text="Geometry:")
row = layout.row()
row.prop(self.properties, "option_vertices")
row.prop(self.properties, "option_normals")
row = layout.row()
row.enabled = self.properties.option_vertices
# row.prop(self.properties, "option_vertices_deltas")
row.prop(self.properties, "option_vertices_truncate")
layout.separator()
row = layout.row()
row.prop(self.properties, "option_faces")
row = layout.row()
row.enabled = self.properties.option_faces
# row.prop(self.properties, "option_faces_deltas")
layout.separator()
row = layout.row()
row.prop(self.properties, "option_normals")
layout.separator()
row = layout.row()
row.prop(self.properties, "option_edges")
layout.separator()
row = layout.row()
row.label(text="Materials:")
row = layout.row()
row.prop(self.properties, "option_uv_coords")
row.prop(self.properties, "option_colors")
@@ -269,8 +283,21 @@ class ExportTHREEJS(bpy.types.Operator, ExportHelper):
layout.separator()
row = layout.row()
row.prop(self.properties, "option_truncate")
row.label(text="Settings:")
row = layout.row()
row.prop(self.properties, "align_model")
row = layout.row()
row.prop(self.properties, "option_flip_yz")
row.prop(self.properties, "option_scale")
layout.separator()
row = layout.row()
row.label(text="Beta:")
row = layout.row()
row.prop(self.properties, "option_export_scene")
layout.separator()
# ################################################################
@@ -49,7 +49,7 @@ DEFAULTS = {
"rotation" : [-math.pi/2, 0, 0],
"scale" : [1, 1, 1],
"camera" :
"camera" :
{
"name" : "default_camera",
"type" : "perspective",
@@ -71,7 +71,7 @@ DEFAULTS = {
}
}
# default colors for debugging (each material gets one distinct color):
# default colors for debugging (each material gets one distinct color):
# white, red, green, blue, yellow, cyan, magenta
COLORS = [0xeeeeee, 0xee0000, 0x00ee00, 0x0000ee, 0xeeee00, 0x00eeee, 0xee00ee]
@@ -90,7 +90,7 @@ TEMPLATE_SCENE_ASCII = """\
* geometries: %(ngeometries)s
* materials: %(nmaterials)s
* textures: %(ntextures)s
*/
*/
var scene = {
@@ -99,14 +99,14 @@ var scene = {
%(sections)s
"transform" :
"transform" :
{
"position" : %(position)s,
"rotation" : %(rotation)s,
"scale" : %(scale)s,
},
"defaults" :
"defaults" :
{
"bgcolor" : %(bgcolor)s,
"bgalpha" : %(bgalpha)f,
@@ -120,7 +120,7 @@ close();
"""
TEMPLATE_SECTION = """
"%s" :
"%s" :
{
%s
},
@@ -154,7 +154,7 @@ TEMPLATE_TEXTURE = """\
TEMPLATE_MATERIAL_SCENE = """\
%(material_id)s : {
"type": %(type)s,
"parameters": { %(parameters)s }
"parameters": { %(parameters)s }
}"""
TEMPLATE_CAMERA_PERSPECTIVE = """\
@@ -225,9 +225,9 @@ TEMPLATE_FILE_ASCII = """\
var model = {
"version" : 2,
"scale" : %(scale)f,
"materials": [%(materials)s],
"vertices": [%(vertices)s],
@@ -271,15 +271,15 @@ def veckey3d(v):
def veckey2d(v):
return round(v[0], 6), round(v[1], 6)
def get_normal_indices(v, normals, mesh):
n = []
mv = mesh.vertices
for i in v:
normal = mv[i].normal
normal = mv[i].normal
key = veckey3d(normal)
n.append( normals[key] )
return n
@@ -315,7 +315,7 @@ def write_file(fname, content):
def ensure_folder_exist(foldername):
"""Create folder (with whole path) if it doesn't exist yet."""
if not os.access(foldername, os.R_OK|os.W_OK|os.X_OK):
os.makedirs(foldername)
@@ -323,13 +323,13 @@ def ensure_extension(filepath, extension):
if not filepath.lower().endswith(extension):
filepath += extension
return filepath
def generate_mesh_filename(meshname, filepath):
normpath = os.path.normpath(filepath)
path, ext = os.path.splitext(normpath)
return "%s.%s%s" % (path, meshname, ext)
# #####################################################
# Utils - alignment
# #####################################################
@@ -410,36 +410,36 @@ def bottom(vertices):
translate(vertices, [-cx,-cy,-cz])
# #####################################################
# Elements rendering
# Elements rendering
# #####################################################
def hexcolor(c):
return ( int(c[0] * 255) << 16 ) + ( int(c[1] * 255) << 8 ) + int(c[2] * 255)
def generate_vertices(vertices, option_truncate, option_vertices):
def generate_vertices(vertices, option_vertices_truncate, option_vertices):
if not option_vertices:
return ""
return ",".join(generate_vertex(v, option_truncate) for v in vertices)
return ",".join(generate_vertex(v, option_vertices_truncate) for v in vertices)
def generate_vertex(v, option_truncate):
if not option_truncate:
def generate_vertex(v, option_vertices_truncate):
if not option_vertices_truncate:
return TEMPLATE_VERTEX % (v.co.x, v.co.y, v.co.z)
else:
return TEMPLATE_VERTEX_TRUNCATE % (v.co.x, v.co.y, v.co.z)
def generate_normal(n):
return TEMPLATE_N % (n[0], n[1], n[2])
def generate_vertex_color(c):
return TEMPLATE_C % c
def generate_uv(uv):
return TEMPLATE_UV % (uv[0], 1.0 - uv[1])
def generate_edge(e):
return TEMPLATE_EDGE % (e.vertices[0], e.vertices[1])
# #####################################################
# Model exporter - faces
# #####################################################
@@ -460,20 +460,20 @@ def generate_faces(normals, uvs, colors, mesh, option_normals, option_colors, op
def generate_face(f, faceIndex, normals, uvs, colors, mesh, option_normals, option_colors, option_uv_coords, option_materials, flipyz):
isTriangle = ( len(f.vertices) == 3 )
if isTriangle:
nVertices = 3
else:
nVertices = 4
hasMaterial = option_materials
hasFaceUvs = False # not supported in Blender
hasFaceVertexUvs = option_uv_coords
hasFaceNormals = False # don't export any face normals (as they are computed in engine)
hasFaceVertexNormals = option_normals
hasFaceColors = False # not supported in Blender
hasFaceVertexColors = option_colors
@@ -485,12 +485,12 @@ def generate_face(f, faceIndex, normals, uvs, colors, mesh, option_normals, opti
faceType = setBit(faceType, 4, hasFaceNormals)
faceType = setBit(faceType, 5, hasFaceVertexNormals)
faceType = setBit(faceType, 6, hasFaceColors)
faceType = setBit(faceType, 7, hasFaceVertexColors)
faceType = setBit(faceType, 7, hasFaceVertexColors)
faceData = []
# order is important, must match order in JSONLoader
# face type
# vertex indices
# material index
@@ -498,15 +498,15 @@ def generate_face(f, faceIndex, normals, uvs, colors, mesh, option_normals, opti
# face vertex uvs indices
# face color index
# face vertex colors indices
faceData.append(faceType)
faceData.append(faceType)
# must clamp in case on polygons bigger than quads
for i in range(nVertices):
index = f.vertices[i]
faceData.append(index)
if hasMaterial:
faceData.append( f.material_index )
@@ -521,7 +521,7 @@ def generate_face(f, faceIndex, normals, uvs, colors, mesh, option_normals, opti
for i in range(nVertices):
index = n[i]
faceData.append(index)
if hasFaceVertexColors:
c = get_color_indices(faceIndex, colors, mesh)
for i in range(nVertices):
@@ -544,10 +544,10 @@ def extract_vertex_normals(mesh, option_normals):
for f in mesh.faces:
for v in f.vertices:
normal = mesh.vertices[v].normal
normal = mesh.vertices[v].normal
key = veckey3d(normal)
if key not in normals:
normals[key] = count
count += 1
@@ -569,7 +569,7 @@ def generate_normals(normals, option_normals):
# #####################################################
def extract_vertex_colors(mesh, option_colors):
if not option_colors:
return {}, 0
@@ -579,10 +579,10 @@ def extract_vertex_colors(mesh, option_colors):
color_layer = mesh.vertex_colors.active.data
for face_index, face in enumerate(mesh.faces):
face_colors = color_layer[face_index]
face_colors = face_colors.color1, face_colors.color2, face_colors.color3, face_colors.color4
for c in face_colors:
key = hexcolor(c)
if key not in colors:
@@ -697,7 +697,7 @@ def generate_materials(mtl, materials, draw_type):
if draw_type in [ "BOUNDS", "WIRE" ]:
mtl[m]['wireframe'] = True
mtl[m]['DbgColor'] = 0xff0000
mtl_raw = ",\n".join(['\t"%s" : %s' % (n, value2string(v)) for n,v in sorted(mtl[m].items())])
mtl_string = "\t{\n%s\n\t}" % mtl_raw
mtl_array.append([index, mtl_string])
@@ -712,7 +712,7 @@ def extract_materials(mesh, scene, option_colors):
if m:
materials[m.name] = {}
material = materials[m.name]
material['colorDiffuse'] = [m.diffuse_intensity * m.diffuse_color[0],
m.diffuse_intensity * m.diffuse_color[1],
m.diffuse_intensity * m.diffuse_color[2]]
@@ -724,7 +724,7 @@ def extract_materials(mesh, scene, option_colors):
world_ambient_color = [0, 0, 0]
if world:
world_ambient_color = world.ambient_color
material['colorAmbient'] = [m.ambient * world_ambient_color[0],
m.ambient * world_ambient_color[1],
m.ambient * world_ambient_color[2]]
@@ -744,7 +744,7 @@ def extract_materials(mesh, scene, option_colors):
material['mapDiffuse'] = fn_strip
material["vertexColors"] = m.THREE_useVertexColors and option_colors
# can't really use this reliably to tell apart Phong from Lambert
# as Blender defaults to non-zero specular color
#if m.specular_intensity > 0.0 and (m.specular_color[0] > 0 or m.specular_color[1] > 0 or m.specular_color[2] > 0):
@@ -771,11 +771,11 @@ def generate_materials_string(mesh, scene, option_colors, draw_type):
materials = { 'default':0 }
# default dummy materials
mtl = generate_mtl(materials)
# extract real materials from the mesh
mtl.update(extract_materials(mesh, scene, option_colors))
return generate_materials(mtl, materials, draw_type)
@@ -784,18 +784,18 @@ def generate_materials_string(mesh, scene, option_colors, draw_type):
# ASCII model generator
# #####################################################
def generate_ascii_model(mesh, scene,
option_vertices,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
align_model,
flipyz,
option_truncate,
option_scale,
def generate_ascii_model(mesh, scene,
option_vertices,
option_vertices_truncate,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
align_model,
flipyz,
option_scale,
draw_type):
vertices = mesh.vertices[:]
@@ -813,15 +813,15 @@ def generate_ascii_model(mesh, scene,
materials_string = ""
nmaterial = 0
edges_string = ""
nedges = 0
if option_materials:
materials_string, nmaterial = generate_materials_string(mesh, scene, option_colors, draw_type)
if option_edges:
nedges = len(mesh.edges)
nedges = len(mesh.edges)
edges_string = ",".join(generate_edge(e) for e in mesh.edges)
text = TEMPLATE_FILE_ASCII % {
@@ -841,7 +841,7 @@ def generate_ascii_model(mesh, scene,
"materials" : materials_string,
"vertices" : generate_vertices(vertices, option_truncate, option_vertices),
"vertices" : generate_vertices(vertices, option_vertices_truncate, option_vertices),
"faces" : generate_faces(normals, uvs, colors, mesh, option_normals, option_colors, option_uv_coords, option_materials, flipyz, option_faces),
@@ -851,29 +851,29 @@ def generate_ascii_model(mesh, scene,
return text
# #####################################################
# Model exporter - export single mesh
# #####################################################
def export_mesh(obj, scene, filepath,
option_vertices,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
align_model,
flipyz,
option_truncate,
option_scale,
def export_mesh(obj, scene, filepath,
option_vertices,
option_vertices_truncate,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
align_model,
flipyz,
option_scale,
export_single_model):
"""Export single mesh"""
# collapse modifiers into mesh
mesh = obj.create_mesh(scene, True, 'RENDER')
if not mesh:
@@ -910,18 +910,18 @@ def export_mesh(obj, scene, filepath,
if not active_col_layer:
option_colors = False
text = generate_ascii_model(mesh, scene,
option_vertices,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
align_model,
flipyz,
option_truncate,
option_scale,
text = generate_ascii_model(mesh, scene,
option_vertices,
option_vertices_truncate,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
align_model,
flipyz,
option_scale,
obj.draw_type)
write_file(filepath, text)
@@ -931,8 +931,8 @@ def export_mesh(obj, scene, filepath,
bpy.data.meshes.remove(mesh)
print("writing", filepath, "done")
# #####################################################
# Scene exporter - render elements
# #####################################################
@@ -948,49 +948,49 @@ def generate_vec2(vec):
def generate_hex(number):
return TEMPLATE_HEX % number
def generate_string(s):
return TEMPLATE_STRING % s
def generate_string_list(src_list):
return ", ".join(generate_string(item) for item in src_list)
def generate_section(label, content):
return TEMPLATE_SECTION % (label, content)
def get_mesh_filename(mesh):
object_id = mesh["data"]["name"]
filename = "%s.js" % sanitize(object_id)
return filename
def generate_material_id_list(materials):
chunks = []
for material in materials:
chunks.append(material.name)
return chunks
def generate_group_id_list(obj):
chunks = []
for group in bpy.data.groups:
if obj.name in group.objects:
chunks.append(group.name)
return chunks
def generate_bool_property(property):
if property:
return "true"
return "false"
# #####################################################
# Scene exporter - objects
# #####################################################
def generate_objects(data):
chunks = []
for obj in data["objects"]:
if obj.type == "MESH":
object_id = obj.name
@@ -1018,11 +1018,11 @@ def generate_objects(data):
castsShadow = obj.THREE_castsShadow
meshCollider = obj.THREE_meshCollider
visible = True
if obj.draw_type in ["BOUNDS", "WIRE"] and meshCollider:
visible = False
object_string = TEMPLATE_OBJECT % {
"object_id" : generate_string(object_id),
"geometry_id" : generate_string(geometry_id),
@@ -1039,55 +1039,55 @@ def generate_objects(data):
"visible" : generate_bool_property(visible)
}
chunks.append(object_string)
return ",\n\n".join(chunks), len(chunks)
# #####################################################
# Scene exporter - geometries
# #####################################################
def generate_geometries(data):
chunks = []
geo_set = set()
for obj in data["objects"]:
if obj.type == "MESH":
if len(obj.modifiers) > 0:
name = obj.name
else:
name = obj.data.name
if name not in geo_set:
geometry_id = "geo_%s" % name
model_filename = os.path.basename(generate_mesh_filename(name, data["filepath"]))
geometry_string = TEMPLATE_GEOMETRY % {
"geometry_id" : generate_string(geometry_id),
"model_file" : generate_string(model_filename)
}
chunks.append(geometry_string)
geo_set.add(name)
return ",\n\n".join(chunks), len(chunks)
# #####################################################
# Scene exporter - textures
# #####################################################
def generate_textures_scene(data):
chunks = []
# TODO: extract just textures actually used by some objects in the scene
for img in bpy.data.images:
texture_id = img.name
texture_file = extract_texture_filename(img)
texture_string = TEMPLATE_TEXTURE % {
"texture_id" : generate_string(texture_id),
"texture_file" : generate_string(texture_file)
@@ -1101,16 +1101,16 @@ def extract_texture_filename(image):
fn = os.path.normpath(fn)
fn_strip = os.path.basename(fn)
return fn_strip
# #####################################################
# Scene exporter - materials
# #####################################################
def extract_material_data(m):
world = bpy.context.scene.world
material = { 'name': m.name }
material['colorDiffuse'] = [m.diffuse_intensity * m.diffuse_color[0],
m.diffuse_intensity * m.diffuse_color[1],
m.diffuse_intensity * m.diffuse_color[2]]
@@ -1122,7 +1122,7 @@ def extract_material_data(m):
world_ambient_color = [0, 0, 0]
if world:
world_ambient_color = world.ambient_color
material['colorAmbient'] = [m.ambient * world_ambient_color[0],
m.ambient * world_ambient_color[1],
m.ambient * world_ambient_color[2]]
@@ -1137,8 +1137,8 @@ def extract_material_data(m):
material['mapDiffuse'] = ""
material['mapLight'] = ""
material['mapNormal'] = ""
material['mapNormal'] = ""
# just take first textures of each, for the moment three.js materials can't handle more
for i in range(len(m.texture_slots)):
@@ -1155,23 +1155,23 @@ def extract_material_data(m):
material['mapDiffuse'] = name
else:
material['mapLight'] = name
if material['mapDiffuse'] and material['mapNormal'] and material['mapLight']:
break
if m.specular_intensity > 0.0 and (m.specular_color[0] > 0 or m.specular_color[1] > 0 or m.specular_color[2] > 0):
material['shading'] = "Phong"
else:
material['shading'] = "Lambert"
return material
def generate_material_string(material):
type_map = {
"Lambert" : "MeshLambertMaterial",
"Phong" : "MeshPhongMaterial"
}
material_id = material["name"]
shading = material["shading"]
material_type = type_map.get(shading, "MeshBasicMaterial")
@@ -1203,14 +1203,14 @@ def generate_material_string(material):
"type" : generate_string(material_type),
"parameters" : parameters
}
return material_string
def generate_materials_scene(data):
chunks = []
# TODO: extract just materials actually used by some objects in the scene
for m in bpy.data.materials:
material = extract_material_data(m)
material_string = generate_material_string(material)
@@ -1226,7 +1226,7 @@ def generate_cameras(data):
cameras = data.get("cameras", [])
if not cameras:
cameras.append(DEFAULTS["camera"])
chunks = []
for camera in cameras:
@@ -1253,9 +1253,9 @@ def generate_cameras(data):
"position" : generate_vec3(camera["position"]),
"target" : generate_vec3(camera["target"])
}
chunks.append(camera_string)
return ",\n\n".join(chunks)
# #####################################################
@@ -1266,7 +1266,7 @@ def generate_lights(data):
lights = data.get("lights", [])
if not lights:
lights.append(DEFAULTS["light"])
chunks = []
for light in lights:
@@ -1287,9 +1287,9 @@ def generate_lights(data):
"color" : rgb2int(light["color"]),
"intensity" : light["intensity"]
}
chunks.append(light_string)
return ",\n\n".join(chunks)
# #####################################################
@@ -1305,7 +1305,7 @@ def generate_ascii_scene(data):
cameras = generate_cameras(data)
lights = generate_lights(data)
sections = [
["objects", objects],
["geometries", geometries],
@@ -1314,16 +1314,16 @@ def generate_ascii_scene(data):
["cameras", cameras],
["lights", lights]
]
chunks = []
for label, content in sections:
if content:
chunks.append(generate_section(label, content))
sections_string = "\n".join(chunks)
default_camera = "default_camera"
parameters = {
"fname" : data["source_file"],
@@ -1337,16 +1337,16 @@ def generate_ascii_scene(data):
"ngeometries" : ngeometries,
"ntextures" : ntextures,
"nmaterials" : nmaterials,
"position" : generate_vec3(DEFAULTS["position"]),
"rotation" : generate_vec3(DEFAULTS["rotation"]),
"scale" : generate_vec3(DEFAULTS["scale"])
}
text = TEMPLATE_SCENE_ASCII % parameters
return text
def export_scene(scene, filepath, flipyz):
source_file = os.path.basename(bpy.data.filepath)
@@ -1360,25 +1360,25 @@ def export_scene(scene, filepath, flipyz):
"flipyz" : flipyz
}
scene_text += generate_ascii_scene(data)
write_file(filepath, scene_text)
# #####################################################
# Main
# #####################################################
def save(operator, context, filepath = "",
option_flip_yz = True,
option_vertices = True,
option_faces = True,
option_normals = True,
option_edges = False,
option_uv_coords = True,
option_materials = True,
option_colors = True,
align_model = 0,
option_export_scene = False,
option_truncate = False,
def save(operator, context, filepath = "",
option_flip_yz = True,
option_vertices = True,
option_vertices_truncate = False,
option_faces = True,
option_normals = True,
option_edges = False,
option_uv_coords = True,
option_materials = True,
option_colors = True,
align_model = 0,
option_export_scene = False,
option_scale = 1.0):
filepath = ensure_extension(filepath, '.js')
@@ -1393,16 +1393,16 @@ def save(operator, context, filepath = "",
export_scene(scene, filepath, option_flip_yz)
geo_set = set()
for obj in scene.objects:
if obj.type == "MESH":
# create extra copy of geometry with applied modifiers
# (if they exist)
if len(obj.modifiers) > 0:
name = obj.name
# otherwise can share geometry
else:
@@ -1410,18 +1410,18 @@ def save(operator, context, filepath = "",
if name not in geo_set:
fname = generate_mesh_filename(name, filepath)
export_mesh(obj, scene, fname,
option_vertices,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
False,
option_flip_yz,
option_truncate,
option_scale,
export_mesh(obj, scene, fname,
option_vertices,
option_vertices_truncate,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
False,
option_flip_yz,
option_scale,
False)
geo_set.add(name)
@@ -1432,19 +1432,19 @@ def save(operator, context, filepath = "",
if not obj:
raise Exception("Error, Select 1 active object or select 'export scene'")
export_mesh(obj, scene, filepath,
option_vertices,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
align_model,
option_flip_yz,
option_truncate,
option_scale,
export_mesh(obj, scene, filepath,
option_vertices,
option_vertices_truncate,
option_faces,
option_normals,
option_edges,
option_uv_coords,
option_materials,
option_colors,
align_model,
option_flip_yz,
option_scale,
True)
return {'FINISHED'}