From 441323973644509b857b865a8ed509eb3bf90633 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 3 Jun 2011 01:43:04 +0000 Subject: - ensure unique names (before it was possible 2+ cleaned names would collide) - use XML escaping rather then cleaning to for strings --- io_scene_x3d/export_x3d.py | 196 +++++++++++++++++++++------------------------ 1 file changed, 93 insertions(+), 103 deletions(-) (limited to 'io_scene_x3d') diff --git a/io_scene_x3d/export_x3d.py b/io_scene_x3d/export_x3d.py index 3ff2ea98..71df0e3d 100644 --- a/io_scene_x3d/export_x3d.py +++ b/io_scene_x3d/export_x3d.py @@ -73,25 +73,12 @@ def clamp_color(col): return tuple([max(min(c, 1.0), 0.0) for c in col]) -def matrix_direction_neg_z(mtx): - return (mathutils.Vector((0.0, 0.0, -1.0)) * mtx.to_3x3()).normalized()[:] +def matrix_direction_neg_z(matrix): + return (mathutils.Vector((0.0, 0.0, -1.0)) * matrix.to_3x3()).normalized()[:] -def clean_str(name, prefix='rsvd_'): - """cleanStr(name,prefix) - try to create a valid VRML DEF name from object name""" - - newName = name - - if newName in x3d_names_reserved: - newName = '%s%s' % (prefix, newName) - - if newName[0].isdigit(): - newName = '%s%s' % ('_', newName) - - for bad in [' ', '"', '#', "'", ', ', '.', '[', '\\', ']', '{', '}']: - newName = newName.replace(bad, '_') - return newName - +def prefix_quoted_str(value, prefix): + return value[0] + prefix + value[1:] ########################################################## # Functions for writing output file @@ -109,8 +96,18 @@ def export(file, ): # ------------------------------------------------------------------------- - # global setup + # Global Setup # ------------------------------------------------------------------------- + from bpy_extras.io_utils import unique_name + from xml.sax.saxutils import quoteattr + + uuid_cache_object = {} # object + uuid_cache_view = {} # object, different namespace + uuid_cache_mesh = {} # mesh + uuid_cache_material = {} # material + uuid_cache_image = {} # image + uuid_cache_world = {} # world + fw = file.write dirname = os.path.dirname(file.name) gpu_shader_cache = {} @@ -120,13 +117,14 @@ def export(file, gpu_shader_dummy_mat = bpy.data.materials.new('X3D_DYMMY_MAT') gpu_shader_cache[None] = gpu.export_shader(scene, gpu_shader_dummy_mat) -########################################################## -# Writing nodes routines -########################################################## + # ------------------------------------------------------------------------- + # File Writing Functions + # ------------------------------------------------------------------------- def writeHeader(ident): - filepath = fw.__self__.name - bfile = repr(os.path.basename(filepath).replace('<', '<').replace('>', '>'))[1:-1] # use outfile name + filepath_quoted = quoteattr(os.path.basename(file.name)) + blender_ver_quoted = quoteattr('Blender %s' % bpy.app.version_string) + fw('%s\n' % ident) if use_h3d: fw('%s\n' % ident) @@ -137,8 +135,8 @@ def export(file, ident += '\t' fw('%s\n' % ident) ident += '\t' - fw('%s\n' % (ident, bfile)) - fw('%s\n' % (ident, bpy.app.version_string)) + fw('%s\n' % (ident, filepath_quoted)) + fw('%s\n' % (ident, blender_ver_quoted)) # this info was never updated, so blender version should be enough # fw('%s\n' % ident) ident = ident[:-1] @@ -154,13 +152,14 @@ def export(file, fw('%s' % ident) return ident - def writeViewpoint(ident, obj, mat, scene): - loc, quat, scale = mat.decompose() + def writeViewpoint(ident, obj, matrix, scene): + view_id = unique_name(obj, 'CA_' + obj.name, uuid_cache_view, clean_func=quoteattr) + + loc, quat, scale = matrix.decompose() ident_step = ident + (' ' * (-len(ident) + \ fw('%s\n') - def writeSpotLight(ident, obj, mtx, lamp, world): - safeName = clean_str(obj.name) + def writeSpotLight(ident, obj, matrix, lamp, world): + # note, lamp_id is not re-used + lamp_id = unique_name(obj, 'LA_' + obj.name, uuid_cache_object, clean_func=quoteattr) + if world: ambi = world.ambient_color amb_intensity = ((ambi[0] + ambi[1] + ambi[2]) / 3.0) / 2.5 @@ -208,15 +209,15 @@ def export(file, # beamWidth=((lamp.spotSize*math.pi)/180.0)*.37 cutOffAngle = beamWidth * 1.3 - orientation = matrix_direction_neg_z(mtx) + orientation = matrix_direction_neg_z(matrix) - location = mtx.to_translation()[:] + location = matrix.to_translation()[:] radius = lamp.distance * math.cos(beamWidth) # radius = lamp.dist*math.cos(beamWidth) ident_step = ident + (' ' * (-len(ident) + \ fw('%s\n') - def writeDirectionalLight(ident, obj, mtx, lamp, world): - safeName = clean_str(obj.name) + def writeDirectionalLight(ident, obj, matrix, lamp, world): + # note, lamp_id is not re-used + lamp_id = unique_name(obj, 'LA_' + obj.name, uuid_cache_object, clean_func=quoteattr) + if world: ambi = world.ambient_color # ambi = world.amb @@ -239,20 +242,21 @@ def export(file, intensity = min(lamp.energy / 1.75, 1.0) - orientation = matrix_direction_neg_z(mtx) + orientation = matrix_direction_neg_z(matrix) ident_step = ident + (' ' * (-len(ident) + \ fw('%s\n') - def writePointLight(ident, obj, mtx, lamp, world): + def writePointLight(ident, obj, matrix, lamp, world): + # note, lamp_id is not re-used + lamp_id = unique_name(obj, 'LA_' + obj.name, uuid_cache_object, clean_func=quoteattr) - safeName = clean_str(obj.name) if world: ambi = world.ambient_color # ambi = world.amb @@ -262,11 +266,11 @@ def export(file, amb_intensity = 0.0 intensity = min(lamp.energy / 1.75, 1.0) - location = mtx.to_translation()[:] + location = matrix.to_translation()[:] ident_step = ident + (' ' * (-len(ident) + \ fw('%s\n') - def secureName(name): - name = name + str(secureName.nodeID) - secureName.nodeID += 1 - if len(name) <= 3: - newname = '_' + str(secureName.nodeID) - return "%s" % (newname) - else: - for bad in ('"', '#', "'", ', ', '.', '[', '\\', ']', '{', '}'): - name = name.replace(bad, '_') - if name in x3d_names_reserved: - newname = name[0:3] + '_' + str(secureName.nodeID) - return "%s" % (newname) - elif name[0].isdigit(): - newname = '_' + name + str(secureName.nodeID) - return "%s" % (newname) - else: - newname = name - return "%s" % (newname) - secureName.nodeID = 0 - - def writeIndexedFaceSet(ident, obj, mesh, mtx, world): - - shape_name_x3d = clean_str(obj.name) - mesh_name_x3d = clean_str(mesh.name) + def writeIndexedFaceSet(ident, obj, mesh, matrix, world): + obj_id = unique_name(obj, 'OB_' + obj.name, uuid_cache_object, clean_func=quoteattr) + mesh_id = unique_name(mesh, 'ME_' + mesh.name, uuid_cache_mesh, clean_func=quoteattr) + mesh_id_group = prefix_quoted_str(mesh_id, 'group_') + mesh_id_coords = prefix_quoted_str(mesh_id, 'coords_') + mesh_id_normals = prefix_quoted_str(mesh_id, 'normals_') if not mesh.faces: return @@ -336,11 +322,11 @@ def export(file, del texface_use_collision # del texface_use_object_color - loc, quat, sca = mtx.decompose() + loc, quat, sca = matrix.decompose() ident_step = ident + (' ' * (-len(ident) + \ fw('%s\n' % (ident, mesh_name_x3d)) + fw('%s\n' % (ident, mesh_id_group)) else: mesh.tag = True - fw('%s\n' % (ident, mesh_name_x3d)) + fw('%s\n' % (ident, mesh_id_group)) ident += '\t' is_uv = bool(mesh.uv_textures.active) @@ -480,11 +466,11 @@ def export(file, if use_h3d: mat_tmp = material if material else gpu_shader_dummy_mat - writeMaterialH3D(ident, mat_tmp, clean_str(mat_tmp.name, ''), world, + writeMaterialH3D(ident, mat_tmp, world, obj, gpu_shader) del mat_tmp else: - writeMaterial(ident, material, clean_str(material.name, ''), world) + writeMaterial(ident, material, world) ident = ident[:-1] fw('%s\n' % ident) @@ -687,13 +673,13 @@ def export(file, # --- Write IndexedFaceSet Elements if True: if is_coords_written: - fw('%s\n' % (ident, 'coord_', mesh_name_x3d)) + fw('%s\n' % (ident, mesh_id_coords)) if use_normals: - fw('%s\n' % (ident, 'normals_', mesh_name_x3d)) + fw('%s\n' % (ident, mesh_id_normals)) else: ident_step = ident + (' ' * (-len(ident) + \ fw('%s\n' % (ident, material_id)) + if material.tag: + fw('%s\n' % (ident, material_id)) else: - mat.tag = True + material.tag = True - emit = mat.emit - ambient = mat.ambient / 3.0 - diffuseColor = mat.diffuse_color[:] + emit = material.emit + ambient = material.ambient / 3.0 + diffuseColor = material.diffuse_color[:] if world: - ambiColor = tuple(((c * mat.ambient) * 2.0) for c in world.ambient_color) + ambiColor = ((material.ambient * 2.0) * world.ambient_color)[:] else: ambiColor = 0.0, 0.0, 0.0 emitColor = tuple(((c * emit) + ambiColor[i]) / 2.0 for i, c in enumerate(diffuseColor)) - shininess = mat.specular_hardness / 512.0 - specColor = tuple((c + 0.001) / (1.25 / (mat.specular_intensity + 0.001)) for c in mat.specular_color) - transp = 1.0 - mat.alpha + shininess = material.specular_hardness / 512.0 + specColor = tuple((c + 0.001) / (1.25 / (material.specular_intensity + 0.001)) for c in material.specular_color) + transp = 1.0 - material.alpha - if mat.use_shadeless: + if material.use_shadeless: ambient = 1.0 shininess = 0.0 specColor = emitColor = diffuseColor ident_step = ident + (' ' * (-len(ident) + \ fw('%s\n') - def writeMaterialH3D(ident, mat, material_id, world, + def writeMaterialH3D(ident, material, world, obj, gpu_shader): + material_id = unique_name(material, 'MA_' + material.name, uuid_cache_material, clean_func=quoteattr) fw('%s\n' % ident) - if mat.tag: - fw('%s\n' % (ident, material_id)) + if material.tag: + fw('%s\n' % (ident, material_id)) else: - mat.tag = True + material.tag = True #~ CD_MCOL 6 #~ CD_MTFACE 5 @@ -875,7 +864,7 @@ def export(file, ''' import gpu - fw('%s\n' % (ident, material_id)) + fw('%s\n' % (ident, material_id)) ident += '\t' shader_url_frag = 'shaders/glsl_%s.frag' % material_id @@ -943,7 +932,7 @@ def export(file, # value = ' '.join(['%.6g' % (f / 256) for f in uniform['texpixels']]) fw('%s\n' % (ident, uniform['varname'], value)) - print("ass", len(uniform['texpixels'])) + print('test', len(uniform['texpixels'])) else: assert(0) @@ -962,16 +951,16 @@ def export(file, fw('%s\n' % ident) def writeImageTexture(ident, image): - name = image.name + image_id = unique_name(image, 'IM_' + image.name, uuid_cache_image, clean_func=quoteattr) if image.tag: - fw('%s\n' % (ident, clean_str(name))) + fw('%s\n' % (ident, image_id)) else: image.tag = True ident_step = ident + (' ' * (-len(ident) + \ fw('%s