diff options
author | Gaia Clary <gaia.clary@machinimatrix.org> | 2012-06-16 02:00:25 +0400 |
---|---|---|
committer | Gaia Clary <gaia.clary@machinimatrix.org> | 2012-06-16 02:00:25 +0400 |
commit | 9f6a66d5f9feb34377cf0e6465020cc80f673d8e (patch) | |
tree | 769bcd7da9a8f762f4a12dbb6206380703f8805b | |
parent | a2d4fddfd38ce0795d21ec9c5b5cc51fc50f3bd1 (diff) |
Collada: (Exporter) Add new option 'deform bones only'
-rw-r--r-- | release/scripts/presets/operator/wm.collada_export/second_life.py | 6 | ||||
-rw-r--r-- | source/blender/collada/ArmatureExporter.cpp | 111 | ||||
-rw-r--r-- | source/blender/collada/ArmatureExporter.h | 2 | ||||
-rw-r--r-- | source/blender/collada/ExportSettings.h | 5 | ||||
-rw-r--r-- | source/blender/collada/collada.cpp | 30 | ||||
-rw-r--r-- | source/blender/collada/collada.h | 5 | ||||
-rw-r--r-- | source/blender/collada/collada_utils.cpp | 28 | ||||
-rw-r--r-- | source/blender/collada/collada_utils.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene_api.c | 18 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 40 |
10 files changed, 155 insertions, 91 deletions
diff --git a/release/scripts/presets/operator/wm.collada_export/second_life.py b/release/scripts/presets/operator/wm.collada_export/second_life.py index be9656428ab..bacf49a61ae 100644 --- a/release/scripts/presets/operator/wm.collada_export/second_life.py +++ b/release/scripts/presets/operator/wm.collada_export/second_life.py @@ -1,10 +1,10 @@ import bpy op = bpy.context.active_operator - -op.selected = True op.apply_modifiers = True -op.include_armatures = False +op.selected = True op.include_children = False +op.include_armatures = True +op.deform_bones_only = True op.use_object_instantiation = False op.sort_by_name = True op.second_life = True diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 98047df8aa4..8301066edaf 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -80,6 +80,18 @@ bool ArmatureExporter::is_skinned_mesh(Object *ob) return bc_get_assigned_armature(ob) != NULL; } + +void ArmatureExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone) +{ + if ( bc_is_root_bone(bone, this->export_settings->deform_bones_only) ) + ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); + else { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + write_bone_URLs(ins, ob_arm, child); + } + } +} + bool ArmatureExporter::add_instance_controller(Object *ob) { Object *ob_arm = bc_get_assigned_armature(ob); @@ -96,8 +108,7 @@ bool ArmatureExporter::add_instance_controller(Object *ob) // write root bone URLs Bone *bone; for (bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) { - if (!bone->parent) - ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); + write_bone_URLs(ins, ob_arm, bone); } InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob); @@ -164,67 +175,73 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se, std::list<Object *>& child_objects) { - std::string node_id = get_joint_id(bone, ob_arm); - std::string node_name = std::string(bone->name); - std::string node_sid = get_joint_sid(bone, ob_arm); + if (!(this->export_settings->deform_bones_only && bone->flag & BONE_NO_DEFORM)) { + std::string node_id = get_joint_id(bone, ob_arm); + std::string node_name = std::string(bone->name); + std::string node_sid = get_joint_sid(bone, ob_arm); - COLLADASW::Node node(mSW); + COLLADASW::Node node(mSW); - node.setType(COLLADASW::Node::JOINT); - node.setNodeId(node_id); - node.setNodeName(node_name); - node.setNodeSid(node_sid); + node.setType(COLLADASW::Node::JOINT); + node.setNodeId(node_id); + node.setNodeName(node_name); + node.setNodeSid(node_sid); - /*if ( bone->childbase.first == NULL || BLI_countlist(&(bone->childbase))>=2) - add_blender_leaf_bone( bone, ob_arm , node ); - else{*/ - node.start(); + /*if ( bone->childbase.first == NULL || BLI_countlist(&(bone->childbase))>=2) + add_blender_leaf_bone( bone, ob_arm , node ); + else{*/ + node.start(); - add_bone_transform(ob_arm, bone, node); + add_bone_transform(ob_arm, bone, node); - // Write nodes of childobjects, remove written objects from list - std::list<Object *>::iterator i = child_objects.begin(); + // Write nodes of childobjects, remove written objects from list + std::list<Object *>::iterator i = child_objects.begin(); - while (i != child_objects.end()) { - if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) { - float backup_parinv[4][4]; - copy_m4_m4(backup_parinv, (*i)->parentinv); + while (i != child_objects.end()) { + if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) { + float backup_parinv[4][4]; + copy_m4_m4(backup_parinv, (*i)->parentinv); - // crude, temporary change to parentinv - // so transform gets exported correctly. + // crude, temporary change to parentinv + // so transform gets exported correctly. - // Add bone tail- translation... don't know why - // bone parenting is against the tail of a bone - // and not it's head, seems arbitrary. - (*i)->parentinv[3][1] += bone->length; + // Add bone tail- translation... don't know why + // bone parenting is against the tail of a bone + // and not it's head, seems arbitrary. + (*i)->parentinv[3][1] += bone->length; - // SECOND_LIFE_COMPATIBILITY - // TODO: when such objects are animated as - // single matrix the tweak must be applied - // to the result. - if (export_settings->second_life) { - // tweak objects parentinverse to match compatibility - float temp[4][4]; + // SECOND_LIFE_COMPATIBILITY + // TODO: when such objects are animated as + // single matrix the tweak must be applied + // to the result. + if (export_settings->second_life) { + // tweak objects parentinverse to match compatibility + float temp[4][4]; - copy_m4_m4(temp, bone->arm_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; + copy_m4_m4(temp, bone->arm_mat); + temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - mult_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv); - } + mult_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv); + } - se->writeNodes(*i, sce); + se->writeNodes(*i, sce); - copy_m4_m4((*i)->parentinv, backup_parinv); - child_objects.erase(i++); + copy_m4_m4((*i)->parentinv, backup_parinv); + child_objects.erase(i++); + } + else i++; } - else i++; - } - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - add_bone_node(child, ob_arm, sce, se, child_objects); + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + add_bone_node(child, ob_arm, sce, se, child_objects); + } + node.end(); + } + else { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + add_bone_node(child, ob_arm, sce, se, child_objects); + } } - node.end(); - //} } #if 0 diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h index beef77af767..a7575e9fc09 100644 --- a/source/blender/collada/ArmatureExporter.h +++ b/source/blender/collada/ArmatureExporter.h @@ -120,6 +120,8 @@ private: void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, const std::list<int>& vcount, const std::list<int>& joints); + + void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone); }; #endif diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index e856eefab99..c93a1b500ae 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -34,10 +34,11 @@ extern "C" { struct ExportSettings { public: - bool selected; bool apply_modifiers; - bool include_armatures; + bool selected; bool include_children; + bool include_armatures; + bool deform_bones_only; bool use_object_instantiation; bool sort_by_name; bool second_life; diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index 9a4fd44b9e9..5b970c236a4 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -50,17 +50,19 @@ int collada_import(bContext *C, const char *filepath) } int collada_export( - Scene *sce, - const char *filepath, - int selected, - int apply_modifiers, + Scene *sce, + const char *filepath, - int include_armatures, - int include_children, + int apply_modifiers, - int use_object_instantiation, + int selected, + int include_children, + int include_armatures, + int deform_bones_only, + + int use_object_instantiation, int sort_by_name, - int second_life) + int second_life) { ExportSettings export_settings; @@ -73,15 +75,19 @@ int collada_export( } /* end! */ + export_settings.filepath = (char *)filepath; - export_settings.selected = selected != 0; export_settings.apply_modifiers = apply_modifiers != 0; + + export_settings.selected = selected != 0; + export_settings.include_children = include_children != 0; export_settings.include_armatures = include_armatures != 0; - export_settings.include_children = include_children != 0; - export_settings.second_life = second_life != 0; + export_settings.deform_bones_only = deform_bones_only != 0; + export_settings.use_object_instantiation = use_object_instantiation != 0; export_settings.sort_by_name = sort_by_name != 0; - export_settings.filepath = (char *)filepath; + export_settings.second_life = second_life != 0; + int includeFilter = OB_REL_NONE; if (export_settings.include_armatures) includeFilter |= OB_REL_MOD_ARMATURE; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 8daf2b65fe2..89b0e299408 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -40,11 +40,12 @@ extern "C" { int collada_export( Scene *sce, const char *filepath, - int selected, int apply_modifiers, - int include_armatures, + int selected, int include_children, + int include_armatures, + int deform_bones_only, int use_object_instantiation, int sort_by_name, diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index aa6f0b3c515..041ffd48f9d 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -34,11 +34,14 @@ #include "collada_utils.h" +extern "C" { + #include "DNA_modifier_types.h" #include "DNA_customdata_types.h" #include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" +#include "DNA_armature_types.h" #include "BLI_math.h" @@ -49,13 +52,13 @@ #include "BKE_mesh.h" #include "BKE_scene.h" -extern "C" { #include "BKE_DerivedMesh.h" #include "BLI_linklist.h" -} + #include "WM_api.h" // XXX hrm, see if we can do without this #include "WM_types.h" +} float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index) { @@ -181,6 +184,7 @@ Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *o return ancestor; } + bool bc_is_base_node(LinkNode *export_set, Object *ob) { Object *root = bc_get_highest_selected_ancestor_or_self(export_set, ob); @@ -253,3 +257,23 @@ void bc_bubble_sort_by_Object_name(LinkNode *export_set) } } } + +/* Check if a bone is the top most exportable bone in the bone hierarchy. + * When deform_bones_only == false, then only bones with NO parent + * can be root bones. Otherwise the top most deform bones in the hierarchy + * are root bones. + */ +bool bc_is_root_bone(Bone *aBone, bool deform_bones_only) { + if(deform_bones_only) { + Bone *root = NULL; + Bone *bone = aBone; + while (bone) { + if (!(bone->flag & BONE_NO_DEFORM)) + root = bone; + bone = bone->parent; + } + return aBone==root; + } + else + return !(aBone->parent); +} diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 139a2cb93bd..6558ad3e9ca 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -72,5 +72,6 @@ extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); extern void bc_bubble_sort_by_Object_name(LinkNode *export_set); +extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only); #endif diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 76366efe0d1..4e4316b0227 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -88,16 +88,17 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name static void rna_Scene_collada_export( Scene *scene, const char *filepath, - int selected, int apply_modifiers, - int include_armatures, + int selected, int include_children, + int include_armatures, + int deform_bones_only, int use_object_instantiation, int sort_by_name, int second_life) { - collada_export(scene, filepath, selected, apply_modifiers, - include_armatures, include_children, + collada_export(scene, filepath, apply_modifiers, selected, + include_children, include_armatures, deform_bones_only, use_object_instantiation, sort_by_name, second_life); } @@ -126,11 +127,12 @@ void RNA_api_scene(StructRNA *srna) parm = RNA_def_string(func, "filepath", "", FILE_MAX, "File Path", "File path to write Collada file"); RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_property_subtype(parm, PROP_FILEPATH); /* allow non utf8 */ - parm = RNA_def_boolean(func, "selected", 0, "Selection Only", "Export only selected elements"); parm = RNA_def_boolean(func, "apply_modifiers", 0, "Apply Modifiers", "Apply modifiers (in Preview resolution)"); - parm = RNA_def_boolean(func, "include_armatures", 0, "Include Armatures", "Include armature(s) used by the exported objects"); - parm = RNA_def_boolean(func, "include_children", 0, "Include Children", "Include all children even if not selected"); - parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instantiation", "Instantiate multiple Objects from same Data"); + parm = RNA_def_boolean(func, "selected", 0, "Selection Only", "Export only selected elements"); + parm = RNA_def_boolean(func, "include_children", 0, "Include Children", "Export all children of selected objects (even if not selected)"); + parm = RNA_def_boolean(func, "include_armatures", 0, "Include Armatures", "Export related armatures (even if not selected)"); + parm = RNA_def_boolean(func, "deform_bones_only", 0, "Deform Bones only", "Only export deforming bones with armatures"); + parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instances", "Instantiate multiple Objects from same Data"); parm = RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name", "Sort exported data by Object name"); parm = RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life"); RNA_def_function_ui_description(func, "Export to collada file"); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index f39b8f267a5..35261a84f49 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2162,13 +2162,15 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED static int wm_collada_export_exec(bContext *C, wmOperator *op) { char filepath[FILE_MAX]; - int selected, second_life; - int include_armatures; int apply_modifiers; + int selected; int include_children; + int include_armatures; + int deform_bones_only; int use_object_instantiation; int sort_by_name; - + int second_life; + if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); return OPERATOR_CANCELLED; @@ -2178,10 +2180,11 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) BLI_ensure_extension(filepath, sizeof(filepath), ".dae"); /* Options panel */ - selected = RNA_boolean_get(op->ptr, "selected"); apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers"); - include_armatures = RNA_boolean_get(op->ptr, "include_armatures"); + selected = RNA_boolean_get(op->ptr, "selected"); include_children = RNA_boolean_get(op->ptr, "include_children"); + include_armatures = RNA_boolean_get(op->ptr, "include_armatures"); + deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only"); use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation"); sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name"); second_life = RNA_boolean_get(op->ptr, "second_life"); @@ -2192,11 +2195,12 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) if (collada_export( CTX_data_scene(C), filepath, - selected, apply_modifiers, - include_armatures, + selected, include_children, - use_object_instantiation, + include_armatures, + deform_bones_only, + use_object_instantiation, sort_by_name, second_life)) { return OPERATOR_FINISHED; @@ -2225,13 +2229,15 @@ void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE); row = uiLayoutRow(box, 0); - uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE); + uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE); uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected")); row = uiLayoutRow(box, 0); - uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE); + uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE); uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected")); + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "deform_bones_only", 0, NULL, ICON_NONE); // Collada options: box = uiLayoutBox(layout); @@ -2271,18 +2277,22 @@ static void WM_OT_collada_export(wmOperatorType *ot) WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); + RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers", + "Apply modifiers (Preview Resolution)"); + RNA_def_boolean(ot->srna, "selected", 0, "Selection Only", "Export only selected elements"); + RNA_def_boolean(ot->srna, "include_children", 0, "Include Children", + "Export all children of selected objects (even if not selected)"); + RNA_def_boolean(ot->srna, "include_armatures", 0, "Include Armatures", - "Include armature(s) even if not selected"); + "Export related armatures (even if not selected)"); - RNA_def_boolean(ot->srna, "include_children", 0, "Include Children", - "Include all children even if not selected"); + RNA_def_boolean(ot->srna, "deform_bones_only", 0, "Deform Bones only", + "Only export deforming bones with armatures"); - RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers", - "Apply modifiers (Preview Resolution)"); RNA_def_boolean(ot->srna, "use_object_instantiation", 1, "Use Object Instances", "Instantiate multiple Objects from same Data"); |