Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorGaia Clary <gaia.clary@machinimatrix.org>2012-06-07 21:55:26 +0400
committerGaia Clary <gaia.clary@machinimatrix.org>2012-06-07 21:55:26 +0400
commit49a5141cded6db36642461dc24064e6b695609af (patch)
treead64c8dc797a2cefd8218f8aadd68489994a5590 /source
parent64c45caff963c30cb9d4f6c0e94036ffa8363882 (diff)
[#31739] Collada: New Export selections 'Include Armatures'
Diffstat (limited to 'source')
-rw-r--r--source/blender/collada/ArmatureExporter.cpp58
-rw-r--r--source/blender/collada/ArmatureExporter.h4
-rw-r--r--source/blender/collada/DocumentExporter.cpp6
-rw-r--r--source/blender/collada/ExportSettings.h1
-rw-r--r--source/blender/collada/GeometryExporter.cpp29
-rw-r--r--source/blender/collada/GeometryExporter.h2
-rw-r--r--source/blender/collada/SceneExporter.cpp52
-rw-r--r--source/blender/collada/collada.cpp6
-rw-r--r--source/blender/collada/collada.h6
-rw-r--r--source/blender/collada/collada_utils.cpp39
-rw-r--r--source/blender/collada/collada_utils.h3
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c6
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c11
13 files changed, 160 insertions, 63 deletions
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index 9d59be39f33..107a3fc5796 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -37,6 +37,14 @@
#include "BKE_action.h"
#include "BKE_armature.h"
+
+extern "C" {
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+}
+
#include "ED_armature.h"
#include "BLI_listbase.h"
@@ -45,6 +53,8 @@
#include "ArmatureExporter.h"
#include "SceneExporter.h"
+#include "collada_utils.h"
+
// XXX exporter writes wrong data for shared armatures. A separate
// controller should be written for each armature-mesh binding how do
// we make controller ids then?
@@ -66,12 +76,12 @@ void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene* sce,
bool ArmatureExporter::is_skinned_mesh(Object *ob)
{
- return get_assigned_armature(ob) != NULL;
+ return bc_get_assigned_armature(ob) != NULL;
}
-void ArmatureExporter::add_instance_controller(Object *ob)
+bool ArmatureExporter::add_instance_controller(Object *ob)
{
- Object *ob_arm = get_assigned_armature(ob);
+ Object *ob_arm = bc_get_assigned_armature(ob);
bArmature *arm = (bArmature*)ob_arm->data;
const std::string& controller_id = get_controller_id(ob_arm, ob);
@@ -79,6 +89,9 @@ void ArmatureExporter::add_instance_controller(Object *ob)
COLLADASW::InstanceController ins(mSW);
ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id));
+ Mesh *me = (Mesh *)ob->data;
+ if (!me->dvert) return false;
+
// write root bone URLs
Bone *bone;
for (bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) {
@@ -89,6 +102,7 @@ void ArmatureExporter::add_instance_controller(Object *ob)
InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob);
ins.add();
+ return true;
}
void ArmatureExporter::export_controllers(Scene *sce)
@@ -105,7 +119,7 @@ void ArmatureExporter::export_controllers(Scene *sce)
void ArmatureExporter::operator()(Object *ob)
{
- Object *ob_arm = get_assigned_armature(ob);
+ Object *ob_arm = bc_get_assigned_armature(ob);
if (ob_arm /*&& !already_written(ob_arm)*/)
export_controller(ob, ob_arm);
@@ -139,27 +153,6 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<O
}
#endif
-Object *ArmatureExporter::get_assigned_armature(Object *ob)
-{
- Object *ob_arm = NULL;
-
- if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
- ob_arm = ob->parent;
- }
- else {
- ModifierData *mod = (ModifierData*)ob->modifiers.first;
- while (mod) {
- if (mod->type == eModifierType_Armature) {
- ob_arm = ((ArmatureModifierData*)mod)->object;
- }
-
- mod = mod->next;
- }
- }
-
- return ob_arm;
-}
-
std::string ArmatureExporter::get_joint_sid(Bone *bone, Object *ob_arm)
{
return get_joint_id(bone, ob_arm);
@@ -325,7 +318,16 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm)
*/
bool use_instantiation = this->export_settings->use_object_instantiation;
- Mesh *me = (Mesh*)ob->data;
+ Mesh *me;
+
+ if ( this->export_settings->apply_modifiers ) {
+ me = bc_to_mesh_apply_modifiers(scene, ob);
+ }
+ else {
+ me = (Mesh*)ob->data;
+ }
+ BKE_mesh_tessface_ensure(me);
+
if (!me->dvert) return;
std::string controller_name = id_name(ob_arm);
@@ -393,6 +395,10 @@ void ArmatureExporter::export_controller(Object* ob, Object *ob_arm)
add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id);
add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints);
+ if (this->export_settings->apply_modifiers)
+ {
+ BKE_libblock_free_us(&(G.main->mesh), me);
+ }
closeSkin();
closeController();
}
diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h
index e9ee38d36cf..beef77af767 100644
--- a/source/blender/collada/ArmatureExporter.h
+++ b/source/blender/collada/ArmatureExporter.h
@@ -64,7 +64,7 @@ public:
bool is_skinned_mesh(Object *ob);
- void add_instance_controller(Object *ob);
+ bool add_instance_controller(Object *ob);
void export_controllers(Scene *sce);
@@ -85,8 +85,6 @@ private:
void find_objects_using_armature(Object *ob_arm, std::vector<Object *>& objects, Scene *sce);
#endif
- Object *get_assigned_armature(Object *ob);
-
std::string get_joint_sid(Bone *bone, Object *ob_arm);
// Scene, SceneExporter and the list of child_objects
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index 19fc30a2790..69f302eaec7 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -262,8 +262,10 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
// <library_controllers>
ArmatureExporter arm_exporter(&sw, this->export_settings);
- if (has_object_type(sce, OB_ARMATURE)) {
- arm_exporter.export_controllers(sce);
+ if (this->export_settings->include_armatures) {
+ if (has_object_type(sce, OB_ARMATURE)) {
+ arm_exporter.export_controllers(sce);
+ }
}
// <library_visual_scenes>
diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h
index f0d3f810831..a6ae29bf2b2 100644
--- a/source/blender/collada/ExportSettings.h
+++ b/source/blender/collada/ExportSettings.h
@@ -32,6 +32,7 @@ struct ExportSettings
public:
bool selected;
bool apply_modifiers;
+ bool include_armatures;
bool include_bone_children;
bool use_object_instantiation;
bool second_life;
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index 6df16165e4b..53d7f1e6449 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -49,6 +49,7 @@ extern "C" {
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "collada_internal.h"
+#include "collada_utils.h"
// TODO: optimize UV sets by making indexed list with duplicates removed
GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings) {}
@@ -65,25 +66,6 @@ void GeometryExporter::exportGeom(Scene *sce)
closeLibrary();
}
-Mesh * GeometryExporter::get_mesh(Object *ob, int apply_modifiers)
-{
- Mesh *tmpmesh;
- if (!apply_modifiers)
- {
- tmpmesh = (Mesh*)ob->data;
- }
- else
- {
- CustomDataMask mask = CD_MASK_MESH;
- DerivedMesh *dm = mesh_create_derived_view(mScene, ob, mask);
- tmpmesh = BKE_mesh_add("ColladaMesh"); // name is not important here
- DM_to_mesh(dm, tmpmesh, ob);
- dm->release(dm);
- }
- BKE_mesh_tessface_ensure(tmpmesh);
- return tmpmesh;
-}
-
void GeometryExporter::operator()(Object *ob)
{
// XXX don't use DerivedMesh, Mesh instead?
@@ -93,7 +75,14 @@ void GeometryExporter::operator()(Object *ob)
#endif
bool use_instantiation = this->export_settings->use_object_instantiation;
- Mesh *me = get_mesh(ob, this->export_settings->apply_modifiers);
+ Mesh *me;
+ if ( this->export_settings->apply_modifiers ) {
+ me = bc_to_mesh_apply_modifiers(mScene, ob);
+ }
+ else {
+ me = (Mesh*)ob->data;
+ }
+ BKE_mesh_tessface_ensure(me);
std::string geom_id = get_geometry_id(ob, use_instantiation);
std::vector<Normal> nor;
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index aae095e819e..23cdcc0a5ba 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -105,7 +105,7 @@ private:
const ExportSettings *export_settings;
- Mesh * get_mesh(Object *ob, int apply_modifiers);
+ Mesh * get_mesh(Scene *sce, Object *ob, int apply_modifiers);
};
struct GeometryFunctor {
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index d258f4ef5e1..510107272cd 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -25,6 +25,7 @@
*/
#include "SceneExporter.h"
+#include "collada_utils.h"
SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings)
: COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings)
@@ -40,19 +41,36 @@ void SceneExporter::exportScene(Scene *sce)
closeLibrary();
}
+// Returns true if the parent chain does not contain any selected object
+// Otherwise return false (ob has selected predecessor)
+bool is_exported_base_node(Object *ob, bool selection_only) {
+
+ if (selection_only && ob->flag & SELECT) {
+ // Move up towards root object,
+ // stop at first selected predecessor's child,
+ // or at root, if no parent was selected
+ while (ob->parent && (ob->parent->type==OB_ARMATURE || !(ob->parent->flag & SELECT)))
+ {
+ ob = ob->parent;
+ }
+ }
+
+ return !ob->parent;
+}
+
void SceneExporter::exportHierarchy(Scene *sce)
{
Base *base= (Base*) sce->base.first;
while (base) {
Object *ob = base->object;
- if (!ob->parent) {
+ bool is_export_base_node = is_exported_base_node(ob, this->export_settings->selected);
+ if (is_export_base_node) {
if (sce->lay & ob->lay) {
switch (ob->type) {
case OB_MESH:
case OB_CAMERA:
case OB_LAMP:
- case OB_ARMATURE:
case OB_EMPTY:
if (this->export_settings->selected && !(ob->flag & SELECT)) {
break;
@@ -70,6 +88,14 @@ void SceneExporter::exportHierarchy(Scene *sce)
void SceneExporter::writeNodes(Object *ob, Scene *sce)
{
+
+ // Add associated armature first if available
+ if (this->export_settings->include_armatures) {
+ Object *ob_arm = bc_get_assigned_armature(ob);
+ if(ob_arm != NULL)
+ writeNodes(ob_arm, sce);
+ }
+
COLLADASW::Node node(mSW);
node.setNodeId(translate_id(id_name(ob)));
node.setNodeName(translate_id(id_name(ob)));
@@ -80,8 +106,19 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
bool is_skinned_mesh = arm_exporter->is_skinned_mesh(ob);
std::list<Object*> child_objects;
+ // XXX Not sure about this.
+ // For me this looks more like a very special case for a very special purpose.
+ // Wouldn't it be better to have only one option here ?
+ //
+ // - include children
+ //
+ // Instead of "include_bone_children" ?
+ // then we could just ask:
+ // if (this->export_settings->include_children)
+ // ...
+ if (this->export_settings->include_armatures
+ && this->export_settings->include_bone_children) {
- if (this->export_settings->include_bone_children) {
// list child objects
Base *b = (Base*) sce->base.first;
while (b) {
@@ -105,7 +142,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
}
- if (ob->type == OB_MESH && is_skinned_mesh)
+ if (ob->type == OB_MESH && this->export_settings->include_armatures && is_skinned_mesh)
// for skinned mesh we write obmat in <bind_shape_matrix>
TransformWriter::add_node_transform_identity(node);
else
@@ -113,10 +150,11 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
// <instance_geometry>
if (ob->type == OB_MESH) {
- if (is_skinned_mesh) {
- arm_exporter->add_instance_controller(ob);
+ bool instance_controller_created = false;
+ if (this->export_settings->include_armatures && is_skinned_mesh) {
+ instance_controller_created = arm_exporter->add_instance_controller(ob);
}
- else {
+ if (!instance_controller_created){
COLLADASW::InstanceGeometry instGeom(mSW);
instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation)));
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index 951fecec049..e880082c9ec 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -54,14 +54,18 @@ extern "C"
const char *filepath,
int selected,
int apply_modifiers,
+
+ int include_armatures,
int include_bone_children,
+
int use_object_instantiation,
- int second_life)
+ int second_life )
{
ExportSettings export_settings;
export_settings.selected = selected != 0;
export_settings.apply_modifiers = apply_modifiers != 0;
+ export_settings.include_armatures = include_armatures != 0;
export_settings.include_bone_children = include_bone_children != 0;
export_settings.second_life = second_life != 0;
export_settings.use_object_instantiation = use_object_instantiation != 0;
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index 67aaf1ff6c7..646c8469e6b 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -38,13 +38,17 @@ extern "C" {
*/
int collada_import(bContext *C, const char *filepath);
int collada_export(
- Scene *sce,
+ Scene *sce,
const char *filepath,
int selected,
int apply_modifiers,
+
+ int include_armatures,
int include_bone_children,
+
int use_object_instantiation,
int second_life);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index 8b7a28e5fbe..8693441d7c8 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -32,8 +32,10 @@
#include "COLLADAFWMeshPrimitive.h"
#include "COLLADAFWMeshVertexData.h"
+#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 "BLI_math.h"
@@ -42,8 +44,13 @@
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_object.h"
+#include "BKE_mesh.h"
#include "BKE_scene.h"
+extern "C" {
+#include "BKE_DerivedMesh.h"
+}
+
#include "WM_api.h" // XXX hrm, see if we can do without this
#include "WM_types.h"
@@ -125,3 +132,35 @@ Object *bc_add_object(Scene *scene, int type, const char *name)
return ob;
}
+Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob)
+{
+ Mesh *tmpmesh;
+ CustomDataMask mask = CD_MASK_MESH;
+ DerivedMesh *dm = mesh_create_derived_view(scene, ob, mask);
+ tmpmesh = BKE_mesh_add("ColladaMesh"); // name is not important here
+ DM_to_mesh(dm, tmpmesh, ob);
+ dm->release(dm);
+ return tmpmesh;
+}
+
+Object *bc_get_assigned_armature(Object *ob)
+{
+ Object *ob_arm = NULL;
+
+ if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
+ ob_arm = ob->parent;
+ }
+ else {
+ ModifierData *mod = (ModifierData*)ob->modifiers.first;
+ while (mod) {
+ if (mod->type == eModifierType_Armature) {
+ ob_arm = ((ArmatureModifierData*)mod)->object;
+ }
+
+ mod = mod->next;
+ }
+ }
+
+ return ob_arm;
+}
+
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index 1f5d2b1d8da..9882b44d94c 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -36,6 +36,7 @@
#include <map>
#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_customdata_types.h"
#include "DNA_texture_types.h"
#include "BKE_context.h"
@@ -50,5 +51,7 @@ extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_sp
extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n);
extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type);
extern Object *bc_add_object(Scene *scene, int type, const char *name);
+extern Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob);
+extern Object *bc_get_assigned_armature(Object *ob);
#endif
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 09e0428058a..b2ff36285e6 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -90,11 +90,14 @@ static void rna_Scene_collada_export(
const char *filepath,
int selected,
int apply_modifiers,
+ int include_armatures,
int include_bone_children,
int use_object_instantiation,
int second_life)
{
- collada_export(scene, filepath, selected, apply_modifiers, include_bone_children, use_object_instantiation, second_life);
+ collada_export(scene, filepath, selected, apply_modifiers,
+ include_armatures, include_bone_children,
+ use_object_instantiation, second_life);
}
#endif
@@ -124,6 +127,7 @@ void RNA_api_scene(StructRNA *srna)
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_bone_children", 0, "Include Bone Children", "Include all objects attached to bones of selected Armature(s)");
parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instantiation", "Instantiate multiple Objects from same Data");
parm = RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life");
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 1cf58b4345b..ed023e42ea3 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2162,7 +2162,11 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED
static int wm_collada_export_exec(bContext *C, wmOperator *op)
{
char filename[FILE_MAX];
- int selected, second_life, apply_modifiers, include_bone_children, use_object_instantiation;
+ int selected, second_life,
+ include_armatures,
+ apply_modifiers,
+ include_bone_children,
+ use_object_instantiation;
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
BKE_report(op->reports, RPT_ERROR, "No filename given");
@@ -2174,6 +2178,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
/* 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");
include_bone_children = RNA_boolean_get(op->ptr, "include_bone_children");
use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation");
second_life = RNA_boolean_get(op->ptr, "second_life");
@@ -2186,6 +2191,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
filename,
selected,
apply_modifiers,
+ include_armatures,
include_bone_children,
use_object_instantiation,
second_life)) {
@@ -2216,6 +2222,9 @@ static void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers",
"Apply modifiers (Preview Resolution)");
+ RNA_def_boolean(ot->srna, "include_armatures", 0, "Include Armatures",
+ "Include armature(s) used by the exported objects");
+
RNA_def_boolean(ot->srna, "include_bone_children", 0, "Include Bone Children",
"Include all objects attached to bones of selected Armature(s)");