From debc3ac91072b1fb8814629fa6545734cc5d90e3 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Wed, 27 Feb 2013 13:53:43 +0000 Subject: Collada export: Add ngon support (initial) --- source/blender/collada/ExportSettings.h | 1 + source/blender/collada/GeometryExporter.cpp | 144 ++++++++++++++++++++++++++-- source/blender/collada/GeometryExporter.h | 11 ++- source/blender/collada/collada.cpp | 2 + source/blender/collada/collada.h | 1 + 5 files changed, 152 insertions(+), 7 deletions(-) (limited to 'source/blender/collada') diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index cf45b9b8391..52a8adb9097 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -45,6 +45,7 @@ public: bool include_material_textures; bool use_texture_copies; + bool use_ngons; bool use_object_instantiation; bool sort_by_name; bool second_life; diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 4a6c5b43ce2..8c867281361 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -77,6 +77,7 @@ void GeometryExporter::operator()(Object *ob) #endif bool use_instantiation = this->export_settings->use_object_instantiation; + bool use_ngons = this->export_settings->use_ngons; Mesh *me; if (this->export_settings->apply_modifiers) { me = bc_to_mesh_apply_modifiers(mScene, ob, this->export_settings->export_mesh_type); @@ -139,11 +140,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, me, geom_id, norind); + createPolylist(a, use_ngons, has_uvs, has_color, ob, me, geom_id, norind); } } else { - createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); + createPolylist(0, use_ngons, has_uvs, has_color, ob, me, geom_id, norind); } } @@ -167,7 +168,7 @@ void GeometryExporter::operator()(Object *ob) kb = kb->next; for (; kb; kb = kb->next) { BKE_key_convert_to_mesh(kb, me); - export_key_mesh(ob, me, kb); + export_key_mesh(ob, me, kb, use_ngons); } } } @@ -176,7 +177,7 @@ void GeometryExporter::operator()(Object *ob) #endif } -void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb) +void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool use_ngons) { std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name); std::vector nor; @@ -227,11 +228,11 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb) // XXX slow if (ob->totcol) { for (int a = 0; a < ob->totcol; a++) { - createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); + createPolylist(a, use_ngons, has_uvs, has_color, ob, me, geom_id, norind); } } else { - createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); + createPolylist(0, use_ngons, has_uvs, has_color, ob, me, geom_id, norind); } closeMesh(); @@ -296,7 +297,138 @@ void GeometryExporter::createLooseEdgeList(Object *ob, } // powerful because it handles both cases when there is material and when there's not +// Call this function when ngons shall be exported unchanged void GeometryExporter::createPolylist(short material_index, + bool use_ngons, + bool has_uvs, + bool has_color, + Object *ob, + Mesh *me, + std::string& geom_id, + std::vector& norind) +{ + + if (!use_ngons) { + createTriangulatedPolylist( + material_index, + has_uvs, + has_color, + ob, + me, + geom_id, + norind); + return; + } + + MPoly *mpolys = me->mpoly; + MLoop *mloops = me->mloop; + int totpolys = me->totpoly; + + // + int i; + int faces_in_polylist = 0; + std::vector vcount_list; + + // count faces with this material + for (i = 0; i < totpolys; i++) { + MPoly *p = &mpolys[i]; + + if (p->mat_nr == material_index) { + faces_in_polylist++; + vcount_list.push_back(p->totloop); + } + } + + // no faces using this material + if (faces_in_polylist == 0) { + fprintf(stderr, "%s: material with index %d is not used.\n", id_name(ob).c_str(), material_index); + return; + } + + Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; + COLLADASW::Polylist polylist(mSW); + + // sets count attribute in + polylist.setCount(faces_in_polylist); + + // sets material name + if (ma) { + std::string material_id = get_material_id(ma); + std::ostringstream ostr; + ostr << translate_id(material_id); + polylist.setMaterial(ostr.str()); + } + + COLLADASW::InputList &til = polylist.getInputList(); + + // creates in for vertices + COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0); + + // creates in for normals + COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1); + + til.push_back(input1); + til.push_back(input2); + + // if mesh has uv coords writes for TEXCOORD + int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1; + for (i = 0; i < num_layers; i++) { + if (!this->export_settings->active_uv_only || i == active_uv_index) { + + // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); + COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, + makeUrl(makeTexcoordSourceId(geom_id, i)), + 2, // offset always 2, this is only until we have optimized UV sets + i // set number equals UV map index + ); + til.push_back(input3); + } + } + + if (has_color) { + COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::COLOR), has_uvs ? 3 : 2); + til.push_back(input4); + } + + // sets + polylist.setVCountList(vcount_list); + + // performs the actual writing + polylist.prepareToAppendValues(); + + //

+ int texindex = 0; + unsigned int vi = 0; + unsigned int ni = 0; + for (i = 0; i < totpolys; i++) { + MPoly *p = &mpolys[i]; + int loop_count = p->totloop; + + if (p->mat_nr == material_index) { + MLoop *l = &mloops[p->loopstart]; + unsigned int *n = &norind[i].v1; + + for (int j = 0; j < loop_count; j++) { + polylist.appendValues(l[j].v); + polylist.appendValues(n[j]); + if (has_uvs) + polylist.appendValues(texindex + j); + + if (has_color) + polylist.appendValues(texindex + j); + } + } + + texindex += loop_count; + } + + polylist.finish(); +} + +// powerful because it handles both cases when there is material and when there's not +// Call this function when ngons shall be exported as Tris or Quads +void GeometryExporter::createTriangulatedPolylist(short material_index, bool has_uvs, bool has_color, Object *ob, diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index 7cbbf0da8fa..ce1dc7832d3 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -75,7 +75,16 @@ public: std::vector& norind); // powerful because it handles both cases when there is material and when there's not + void createTriangulatedPolylist(short material_index, + bool has_uvs, + bool has_color, + Object *ob, + Mesh *me, + std::string& geom_id, + std::vector& norind); + void createPolylist(short material_index, + bool use_ngons, bool has_uvs, bool has_color, Object *ob, @@ -104,7 +113,7 @@ public: COLLADASW::URI makeUrl(std::string id); - void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb); + void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool use_ngons); /* int getTriCount(MFace *faces, int totface);*/ private: diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index b3c288c8fc5..a868bf2d52d 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -75,6 +75,7 @@ int collada_export(Scene *sce, int include_material_textures, int use_texture_copies, + int use_ngons, int use_object_instantiation, int sort_by_name, int second_life) @@ -106,6 +107,7 @@ int collada_export(Scene *sce, export_settings.include_material_textures= include_material_textures != 0; export_settings.use_texture_copies = use_texture_copies != 0; + export_settings.use_ngons = use_ngons != 0; export_settings.use_object_instantiation = use_object_instantiation != 0; export_settings.sort_by_name = sort_by_name != 0; export_settings.second_life = second_life != 0; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 2fa5b22bb15..e7e8555c59f 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -67,6 +67,7 @@ int collada_export(Scene *sce, int include_material_textures, int use_texture_copies, + int use_ngons, int use_object_instantiation, int sort_by_name, int second_life); -- cgit v1.2.3