diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index 80e20acbe48..41fa7e1ed38 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -31,6 +31,7 @@ struct ExportSettings { public: bool selected; + bool apply_modifiers; bool second_life; char *filepath; }; diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 8e4fa057daf..8c7bff285eb 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -36,10 +36,18 @@ #include "GeometryExporter.h" #include "DNA_meshdata_types.h" + +extern "C" { + #include "BKE_DerivedMesh.h" + #include "BKE_main.h" + #include "BKE_global.h" + #include "BKE_library.h" +} + + #include "BKE_customdata.h" #include "BKE_material.h" #include "BKE_mesh.h" - #include "collada_internal.h" // TODO: optimize UV sets by making indexed list with duplicates removed @@ -57,6 +65,25 @@ 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? @@ -64,8 +91,8 @@ void GeometryExporter::operator()(Object *ob) #if 0 DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH); #endif - Mesh *me = (Mesh*)ob->data; - BKE_mesh_tessface_ensure(me); + + Mesh *me = get_mesh(ob, this->export_settings->apply_modifiers); std::string geom_id = get_geometry_id(ob); std::string geom_name = id_name(ob->data); @@ -110,11 +137,11 @@ void GeometryExporter::operator()(Object *ob) // XXX slow if (ob->totcol) { for (int a = 0; a < ob->totcol; a++) { - createPolylist(a, has_uvs, has_color, ob, geom_id, norind); + createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); } } else { - createPolylist(0, has_uvs, has_color, ob, geom_id, norind); + createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); } closeMesh(); @@ -124,7 +151,12 @@ void GeometryExporter::operator()(Object *ob) } closeGeometry(); - + + if (this->export_settings->apply_modifiers) + { + BKE_libblock_free_us(&(G.main->mesh), me); + } + #if 0 dm->release(dm); #endif @@ -135,10 +167,10 @@ void GeometryExporter::createPolylist(short material_index, bool has_uvs, bool has_color, Object *ob, + Mesh *me, std::string& geom_id, std::vector& norind) { - Mesh *me = (Mesh*)ob->data; MFace *mfaces = me->mface; int totfaces = me->totface; diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index 5d79fabb713..55dc179e5e2 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -69,6 +69,7 @@ public: bool has_uvs, bool has_color, Object *ob, + Mesh *me, std::string& geom_id, std::vector& norind); @@ -98,6 +99,8 @@ private: std::set exportedGeometry; const ExportSettings *export_settings; + + Mesh * get_mesh(Object *ob, int apply_modifiers); }; struct GeometryFunctor { diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index 70bf0556b5b..ae024ec52a7 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -49,13 +49,14 @@ extern "C" return 0; } - int collada_export(Scene *sce, const char *filepath, int selected, int second_life) + int collada_export(Scene *sce, const char *filepath, int selected, int apply_modifiers, int second_life) { ExportSettings export_settings; - export_settings.selected = selected != 0; - export_settings.second_life = second_life != 0; - export_settings.filepath = (char *)filepath; + export_settings.selected = selected != 0; + export_settings.apply_modifiers = apply_modifiers != 0; + export_settings.second_life = second_life != 0; + export_settings.filepath = (char *)filepath; /* annoying, collada crashes if file cant be created! [#27162] */ if (!BLI_exists(filepath)) { diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index f8afc797447..f335796f799 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -37,7 +37,7 @@ extern "C" { * both return 1 on success, 0 on error */ int collada_import(bContext *C, const char *filepath); - int collada_export(Scene *sce, const char *filepath, int selected, int second_life); + int collada_export(Scene *sce, const char *filepath, int selected, int apply_modifiers, int second_life); #ifdef __cplusplus } #endif diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index e3bb6e7b58a..ca01d61f630 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -85,9 +85,9 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name /* don't remove this, as COLLADA exporting cannot be done through operators in render() callback. */ #include "../../collada/collada.h" -static void rna_Scene_collada_export(Scene *scene, const char *filepath, int selected, int second_life) +static void rna_Scene_collada_export(Scene *scene, const char *filepath, int selected, int apply_modifiers, int second_life) { - collada_export(scene, filepath, selected, second_life); + collada_export(scene, filepath, selected, apply_modifiers, second_life); } #endif @@ -115,7 +115,8 @@ 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, "Export only selected", "Export only selected elements"); + 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, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life"); RNA_def_function_ui_description(func, "Export to collada file"); #endif diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 1a9a5ff2cb6..27c4a38c131 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2154,7 +2154,7 @@ 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; + int selected, second_life, apply_modifiers; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); @@ -2162,13 +2162,16 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) } RNA_string_get(op->ptr, "filepath", filename); - selected = RNA_boolean_get(op->ptr, "selected"); - second_life = RNA_boolean_get(op->ptr, "second_life"); + + /* Options panel */ + selected = RNA_boolean_get(op->ptr, "selected"); + second_life = RNA_boolean_get(op->ptr, "second_life"); + apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers"); /* get editmode results */ ED_object_exit_editmode(C, 0); /* 0 = does not exit editmode */ - if (collada_export(CTX_data_scene(C), filename, selected, second_life)) { + if (collada_export(CTX_data_scene(C), filename, selected, apply_modifiers, second_life)) { return OPERATOR_FINISHED; } else { @@ -2187,8 +2190,10 @@ static void WM_OT_collada_export(wmOperatorType *ot) ot->poll = WM_operator_winactive; WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); - RNA_def_boolean(ot->srna, "selected", 0, "Export only selected", + RNA_def_boolean(ot->srna, "selected", 0, "Selection Only", "Export only selected elements"); + RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers", + "Apply modifiers (Preview Resolution)"); RNA_def_boolean(ot->srna, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life"); }