forked from bartvdbraak/blender
Collada: (Exporter) Add new option 'deform bones only'
This commit is contained in:
parent
a2d4fddfd3
commit
9f6a66d5f9
@ -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
|
||||
|
@ -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);
|
||||
|
||||
copy_m4_m4((*i)->parentinv, backup_parinv);
|
||||
child_objects.erase(i++);
|
||||
}
|
||||
|
||||
se->writeNodes(*i, sce);
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
@ -2224,14 +2228,16 @@ void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
|
||||
row = uiLayoutRow(box, 0);
|
||||
uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE);
|
||||
|
||||
row = uiLayoutRow(box, 0);
|
||||
uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE);
|
||||
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
|
||||
|
||||
row = uiLayoutRow(box, 0);
|
||||
uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE);
|
||||
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
|
||||
|
||||
row = uiLayoutRow(box, 0);
|
||||
uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE);
|
||||
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
|
||||
|
||||
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_armatures", 0, "Include Armatures",
|
||||
"Include armature(s) even if not selected");
|
||||
|
||||
RNA_def_boolean(ot->srna, "include_children", 0, "Include Children",
|
||||
"Include all children even if not selected");
|
||||
"Export all children of selected objects (even if not selected)");
|
||||
|
||||
RNA_def_boolean(ot->srna, "include_armatures", 0, "Include Armatures",
|
||||
"Export related armatures (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");
|
||||
|
Loading…
Reference in New Issue
Block a user