[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2001] trunk/py/scripts/addons/ io_scene_x3d: object hierarchy (parent/child) support for X3D export, tested with dupli-groups, scaling, rotations.

Campbell Barton ideasman42 at gmail.com
Sat Jun 4 08:37:05 CEST 2011


Revision: 2001
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2001
Author:   campbellbarton
Date:     2011-06-04 06:37:05 +0000 (Sat, 04 Jun 2011)
Log Message:
-----------
object hierarchy (parent/child) support for X3D export, tested with dupli-groups, scaling, rotations.
keep this optional so exporting without hierarchy is still supported.

Modified Paths:
--------------
    trunk/py/scripts/addons/io_scene_x3d/__init__.py
    trunk/py/scripts/addons/io_scene_x3d/export_x3d.py

Modified: trunk/py/scripts/addons/io_scene_x3d/__init__.py
===================================================================
--- trunk/py/scripts/addons/io_scene_x3d/__init__.py	2011-06-03 05:03:17 UTC (rev 2000)
+++ trunk/py/scripts/addons/io_scene_x3d/__init__.py	2011-06-04 06:37:05 UTC (rev 2001)
@@ -41,7 +41,7 @@
 
 import bpy
 from bpy.props import StringProperty, BoolProperty, EnumProperty
-from bpy_extras.io_utils import ImportHelper, ExportHelper, axis_conversion
+from bpy_extras.io_utils import ImportHelper, ExportHelper, axis_conversion, path_reference_mode
 
 
 class ImportX3D(bpy.types.Operator, ImportHelper):
@@ -99,6 +99,7 @@
     use_triangulate = BoolProperty(name="Triangulate", description="Write quads into 'IndexedTriangleSet'", default=True)
     use_normals = BoolProperty(name="Normals", description="Write normals with geometry", default=False)
     use_compress = BoolProperty(name="Compress", description="GZip the resulting file, requires a full python install", default=False)
+    use_hierarchy = BoolProperty(name="Hierarchy", description="Export parent child relationships", default=True)
     use_h3d = BoolProperty(name="H3D Extensions", description="Export shaders for H3D", default=False)
 
     axis_forward = EnumProperty(
@@ -125,6 +126,8 @@
             default='-Y',
             )
 
+    # path_mode = path_reference_mode
+
     def execute(self, context):
         from . import export_x3d
         from mathutils import Matrix

Modified: trunk/py/scripts/addons/io_scene_x3d/export_x3d.py
===================================================================
--- trunk/py/scripts/addons/io_scene_x3d/export_x3d.py	2011-06-03 05:03:17 UTC (rev 2000)
+++ trunk/py/scripts/addons/io_scene_x3d/export_x3d.py	2011-06-04 06:37:05 UTC (rev 2001)
@@ -80,11 +80,31 @@
 def prefix_quoted_str(value, prefix):
     return value[0] + prefix + value[1:]
 
+
+def build_hierarchy(objects):
+    """ returns parent child relationships, skipping 
+    """
+    objects_set = set(objects)
+    par_lookup = {}
+
+    def test_parent(parent):
+        while (parent is not None) and (parent not in objects_set):
+            parent = parent.parent
+        return parent
+
+    for obj in objects_set:
+        par_lookup.setdefault(test_parent(obj.parent), []).append((obj, []))
+
+    for parent, children in par_lookup.items():
+        for obj, subchildren in children:
+            subchildren[:] = par_lookup.get(obj, [])
+
+    return par_lookup[None]
+
 ##########################################################
 # Functions for writing output file
 ##########################################################
 
-
 def export(file,
            global_matrix,
            scene,
@@ -92,6 +112,7 @@
            use_selection=True,
            use_triangulate=False,
            use_normals=False,
+           use_hierarchy=True,
            use_h3d=False,
            ):
 
@@ -102,6 +123,7 @@
     from xml.sax.saxutils import quoteattr
 
     uuid_cache_object = {}    # object
+    uuid_cache_lamp = {}      # 'LA_' + object.name 
     uuid_cache_view = {}      # object, different namespace
     uuid_cache_mesh = {}      # mesh
     uuid_cache_material = {}  # material
@@ -192,9 +214,32 @@
         fw(ident_step + 'avatarSize="0.25, 1.75, 0.75"\n')
         fw(ident_step + '/>\n')
 
+    def writeTransform_begin(ident, matrix, def_id):
+        ident_step = ident + (' ' * (-len(ident) + \
+        fw('%s<Transform ' % ident)))
+        if def_id is not None:
+            fw('DEF=%s\n' % def_id)
+        else:
+            fw('\n')
+
+        loc, quat, sca = matrix.decompose()
+
+        fw(ident_step + 'translation="%.6g %.6g %.6g"\n' % loc[:])
+        # fw(ident_step + 'center="%.6g %.6g %.6g"\n' % (0, 0, 0))
+        fw(ident_step + 'scale="%.6g %.6g %.6g"\n' % sca[:])
+        fw(ident_step + 'rotation="%.6g %.6g %.6g %.6g"\n' % (quat.axis[:] + (quat.angle, )))
+        fw(ident_step + '>\n')
+        ident += '\t'
+        return ident
+        
+    def writeTransform_end(ident):
+        ident = ident[:-1]
+        fw('%s</Transform>\n' % ident)
+        return ident
+
     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)
+        lamp_id = unique_name(obj, 'LA_' + obj.name, uuid_cache_lamp, clean_func=quoteattr)
 
         if world:
             ambi = world.ambient_color
@@ -230,7 +275,7 @@
 
     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)
+        lamp_id = unique_name(obj, 'LA_' + obj.name, uuid_cache_lamp, clean_func=quoteattr)
 
         if world:
             ambi = world.ambient_color
@@ -255,7 +300,7 @@
 
     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)
+        lamp_id = unique_name(obj, 'LA_' + obj.name, uuid_cache_lamp, clean_func=quoteattr)
 
         if world:
             ambi = world.ambient_color
@@ -322,17 +367,8 @@
         del texface_use_collision
         # del texface_use_object_color
 
-        loc, quat, sca = matrix.decompose()
+        ident = writeTransform_begin(ident, matrix, None)
 
-        ident_step = ident + (' ' * (-len(ident) + \
-        fw('%s<Transform ' % ident)))
-        fw('DEF=%s\n' % obj_id)
-        fw(ident_step + 'translation="%.6g %.6g %.6g"\n' % loc[:])
-        fw(ident_step + 'scale="%.6g %.6g %.6g"\n' % sca[:])
-        fw(ident_step + 'rotation="%.6g %.6g %.6g %.6g"\n' % (quat.axis[:] + (quat.angle, )))
-        fw(ident_step + '>\n')
-        ident += '\t'
-
         if mesh.tag:
             fw('%s<Group USE=%s />\n' % (ident, mesh_id_group))
         else:
@@ -470,7 +506,8 @@
                                          obj, gpu_shader)
                         del mat_tmp
                     else:
-                        writeMaterial(ident, material, world)
+                        if material:
+                            writeMaterial(ident, material, world)
 
                     ident = ident[:-1]
                     fw('%s</Appearance>\n' % ident)
@@ -726,8 +763,7 @@
             ident = ident[:-1]
             fw('%s</Group>\n' % ident)
 
-        ident = ident[:-1]
-        fw('%s</Transform>\n' % ident)
+        ident = writeTransform_end(ident)
 
         if use_halonode:
             ident = ident[:-1]
@@ -1049,9 +1085,83 @@
 
         fw(ident_step + '/>\n')
 
-##########################################################
-# export routine
-##########################################################
+    # -------------------------------------------------------------------------
+    # Export Object Hierarchy (recursively called)
+    # -------------------------------------------------------------------------
+    def export_object(ident, obj_main_parent, obj_main, obj_children):
+        world = scene.world
+        free, derived = create_derived_objects(scene, obj_main)
+
+        if derived is None:
+            return
+
+        if use_hierarchy:
+            obj_main_matrix_world = obj_main.matrix_world
+            if obj_main_parent:
+                obj_main_matrix = obj_main_parent.matrix_world.inverted() * obj_main_matrix_world
+            else:
+                obj_main_matrix = obj_main_matrix_world
+            obj_main_matrix_world_invert = obj_main_matrix_world.inverted()
+
+            obj_main_id = unique_name(obj_main, obj_main.name, uuid_cache_object, clean_func=quoteattr)
+                
+            ident = writeTransform_begin(ident, obj_main_matrix if obj_main_parent else global_matrix * obj_main_matrix, obj_main_id)
+
+        for obj, obj_matrix in derived:
+            obj_type = obj.type
+            
+            if use_hierarchy:
+                # make transform node relative
+                obj_matrix = obj_main_matrix_world_invert * obj_matrix
+
+            if obj_type == 'CAMERA':
+                writeViewpoint(ident, obj, obj_matrix, scene)
+            elif obj_type in ('MESH', 'CURVE', 'SURF', 'FONT'):
+                if (obj_type != 'MESH') or (use_apply_modifiers and obj.is_modified(scene, 'PREVIEW')):
+                    try:
+                        me = obj.to_mesh(scene, use_apply_modifiers, 'PREVIEW')
+                    except:
+                        me = None
+                else:
+                    me = obj.data
+
+                if me is not None:
+                    writeIndexedFaceSet(ident, obj, me, obj_matrix, world)
+
+                    # free mesh created with create_mesh()
+                    if me != obj.data:
+                        bpy.data.meshes.remove(me)
+
+            elif obj_type == 'LAMP':
+                data = obj.data
+                datatype = data.type
+                if datatype == 'POINT':
+                    writePointLight(ident, obj, obj_matrix, data, world)
+                elif datatype == 'SPOT':
+                    writeSpotLight(ident, obj, obj_matrix, data, world)
+                elif datatype == 'SUN':
+                    writeDirectionalLight(ident, obj, obj_matrix, data, world)
+                else:
+                    writeDirectionalLight(ident, obj, obj_matrix, data, world)
+            else:
+                #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType)
+                pass
+
+        if free:
+            free_derived_objects(obj_main)
+
+        # ---------------------------------------------------------------------
+        # write out children recursively
+        # ---------------------------------------------------------------------
+        for obj_child, obj_child_children in obj_children:
+            export_object(ident, obj_main, obj_child, obj_child_children)
+
+        if use_hierarchy:
+            ident = writeTransform_end(ident)
+
+    # -------------------------------------------------------------------------
+    # Main Export Function
+    # -------------------------------------------------------------------------
     def export_main():
         world = scene.world
 
@@ -1075,53 +1185,14 @@
         else:
             objects = (obj for obj in scene.objects if obj.is_visible(scene))
 
-        for obj_main in objects:

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list