From be701b6278769465495ec43d1d6817cf5fbfeaca Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Sat, 2 Mar 2013 15:58:13 +0000 Subject: Collada: Added support for ngon export/import and added triangulate option to export --- source/blender/collada/CMakeLists.txt | 2 +- source/blender/collada/ControllerExporter.cpp | 35 +- source/blender/collada/DocumentImporter.cpp | 3 +- source/blender/collada/ExportSettings.h | 2 +- source/blender/collada/GeometryExporter.cpp | 228 ++--------- source/blender/collada/GeometryExporter.h | 12 +- source/blender/collada/MeshImporter.cpp | 560 ++++++++------------------ source/blender/collada/MeshImporter.h | 48 +-- source/blender/collada/collada.cpp | 4 +- source/blender/collada/collada.h | 2 +- source/blender/collada/collada_utils.cpp | 44 +- source/blender/collada/collada_utils.h | 5 +- 12 files changed, 283 insertions(+), 662 deletions(-) (limited to 'source/blender/collada') diff --git a/source/blender/collada/CMakeLists.txt b/source/blender/collada/CMakeLists.txt index 326ca2b9937..8747d2995f2 100644 --- a/source/blender/collada/CMakeLists.txt +++ b/source/blender/collada/CMakeLists.txt @@ -38,7 +38,7 @@ set(INC ../../../intern/guardedalloc ../ikplugin ../../../intern/iksolver/extern - + ../bmesh ) set(INC_SYS diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp index 39ed0334ae0..6b367b9cea9 100644 --- a/source/blender/collada/ControllerExporter.cpp +++ b/source/blender/collada/ControllerExporter.cpp @@ -201,13 +201,12 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm) bool use_instantiation = this->export_settings->use_object_instantiation; Mesh *me; - if (this->export_settings->apply_modifiers) - me = bc_to_mesh_apply_modifiers(scene, ob, this->export_settings->export_mesh_type); - else - me = (Mesh *)ob->data; + me = bc_get_mesh_copy(scene, + ob, + this->export_settings->export_mesh_type, + this->export_settings->apply_modifiers, + this->export_settings->triangulate); - BKE_mesh_tessface_ensure(me); - if (!me->dvert) return; std::string controller_name = id_name(ob_arm); @@ -292,10 +291,8 @@ void ControllerExporter::export_skin_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); - } + BKE_libblock_free_us(&(G.main->mesh), me); + closeSkin(); closeController(); } @@ -305,13 +302,11 @@ void ControllerExporter::export_morph_controller(Object *ob, Key *key) bool use_instantiation = this->export_settings->use_object_instantiation; Mesh *me; - if (this->export_settings->apply_modifiers) { - me = bc_to_mesh_apply_modifiers(scene, ob, this->export_settings->export_mesh_type); - } - else { - me = (Mesh *)ob->data; - } - BKE_mesh_tessface_ensure(me); + me = bc_get_mesh_copy(scene, + ob, + this->export_settings->export_mesh_type, + this->export_settings->apply_modifiers, + this->export_settings->triangulate); std::string controller_name = id_name(ob) + "-morph"; std::string controller_id = get_controller_id(key, ob); @@ -332,10 +327,8 @@ void ControllerExporter::export_morph_controller(Object *ob, Key *key) COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, morph_weights_id))); targets.add(); - if (this->export_settings->apply_modifiers) - { - BKE_libblock_free_us(&(G.main->mesh), me); - } + BKE_libblock_free_us(&(G.main->mesh), me); + //support for animations //can also try the base element and param alternative diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index b52a33b21e3..49db6f033d9 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -157,7 +157,8 @@ bool DocumentImporter::import() delete ehandler; - mesh_importer.bmeshConversion(); + //XXX No longer needed (geometries are now created as bmesh) + //mesh_importer.bmeshConversion(); return true; } diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index 52a8adb9097..ec71fb2747c 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -45,7 +45,7 @@ public: bool include_material_textures; bool use_texture_copies; - bool use_ngons; + bool triangulate; 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 8c867281361..bb177cc0455 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -57,7 +57,6 @@ GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSett { } - void GeometryExporter::exportGeom(Scene *sce) { openLibrary(); @@ -77,15 +76,12 @@ 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); - } - else { - me = (Mesh *)ob->data; - } - BKE_mesh_tessface_ensure(me); + bool triangulate = this->export_settings->triangulate; + Mesh *me = bc_get_mesh_copy( mScene, + ob, + this->export_settings->export_mesh_type, + this->export_settings->apply_modifiers, + this->export_settings->triangulate); std::string geom_id = get_geometry_id(ob, use_instantiation); std::vector nor; @@ -118,12 +114,13 @@ void GeometryExporter::operator()(Object *ob) bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE); // writes for uv coords if mesh has uv coords - if (has_uvs) + if (has_uvs) { createTexcoordsSource(geom_id, me); + } - if (has_color) + if (has_color) { createVertexColorSource(geom_id, me); - + } // COLLADASW::Vertices verts(mSW); @@ -140,11 +137,11 @@ void GeometryExporter::operator()(Object *ob) // XXX slow if (ob->totcol) { for (int a = 0; a < ob->totcol; a++) { - createPolylist(a, use_ngons, has_uvs, has_color, ob, me, geom_id, norind); + createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); } } else { - createPolylist(0, use_ngons, has_uvs, has_color, ob, me, geom_id, norind); + createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); } } @@ -156,10 +153,6 @@ void GeometryExporter::operator()(Object *ob) closeGeometry(); - if (this->export_settings->apply_modifiers) { - BKE_libblock_free_us(&(G.main->mesh), me); - } - if (this->export_settings->include_shapekeys) { Key * key = BKE_key_from_object(ob); if (key) { @@ -168,16 +161,16 @@ 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, use_ngons); + export_key_mesh(ob, me, kb); } } } -#if 0 - dm->release(dm); -#endif + + BKE_libblock_free_us(&(G.main->mesh), me); + } -void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool use_ngons) +void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb) { std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name); std::vector nor; @@ -208,11 +201,13 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE); // writes for uv coords if mesh has uv coords - if (has_uvs) + if (has_uvs) { createTexcoordsSource(geom_id, me); + } - if (has_color) + if (has_color) { createVertexColorSource(geom_id, me); + } // @@ -228,11 +223,11 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool // XXX slow if (ob->totcol) { for (int a = 0; a < ob->totcol; a++) { - createPolylist(a, use_ngons, has_uvs, has_color, ob, me, geom_id, norind); + createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); } } else { - createPolylist(0, use_ngons, has_uvs, has_color, ob, me, geom_id, norind); + createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); } closeMesh(); @@ -297,9 +292,7 @@ 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, @@ -308,18 +301,6 @@ void GeometryExporter::createPolylist(short material_index, 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; @@ -426,127 +407,6 @@ void GeometryExporter::createPolylist(short material_index, 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, - Mesh *me, - std::string& geom_id, - std::vector& norind) -{ - MFace *mfaces = me->mface; - int totfaces = me->totface; - - // - int i; - int faces_in_polylist = 0; - std::vector vcount_list; - - // count faces with this material - for (i = 0; i < totfaces; i++) { - MFace *f = &mfaces[i]; - - if (f->mat_nr == material_index) { - faces_in_polylist++; - if (f->v4 == 0) { - vcount_list.push_back(3); - } - else { - vcount_list.push_back(4); - } - } - } - - // 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; - for (i = 0; i < totfaces; i++) { - MFace *f = &mfaces[i]; - - if (f->mat_nr == material_index) { - - unsigned int *v = &f->v1; - unsigned int *n = &norind[i].v1; - for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { - polylist.appendValues(v[j]); - polylist.appendValues(n[j]); - - if (has_uvs) - polylist.appendValues(texindex + j); - - if (has_color) - polylist.appendValues(texindex + j); - } - } - - texindex += 3; - if (f->v4 != 0) - texindex++; - } - - polylist.finish(); -} // creates for positions void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) @@ -617,6 +477,7 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) source.finish(); } + std::string GeometryExporter::makeTexcoordSourceId(std::string& geom_id, int layer_index) { char suffix[20]; @@ -627,38 +488,21 @@ std::string GeometryExporter::makeTexcoordSourceId(std::string& geom_id, int lay //creates for texcoords void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) { -#if 0 - int totfaces = dm->getNumTessFaces(dm); - MFace *mfaces = dm->getTessFaceArray(dm); -#endif - int totfaces = me->totface; - MFace *mfaces = me->mface; - - int totuv = 0; - int i; - // count totuv - for (i = 0; i < totfaces; i++) { - MFace *f = &mfaces[i]; - if (f->v4 == 0) { - totuv += 3; - } - else { - totuv += 4; - } - } + int totpoly = me->totpoly; + int totuv = me->totloop; + MPoly *mpolys = me->mpoly; - int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); // write for each layer // each will get id like meshName + "map-channel-1" int map_index = 0; - int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1; + int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); for (int a = 0; a < num_layers; a++) { if (!this->export_settings->active_uv_only || a == active_uv_index) { - MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); - // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a); + MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a); COLLADASW::FloatSourceF source(mSW); std::string layer_id = makeTexcoordSourceId(geom_id, map_index++); @@ -673,12 +517,12 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) source.prepareToAppendValues(); - for (i = 0; i < totfaces; i++) { - MFace *f = &mfaces[i]; - - for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { - source.appendValues(tface[i].uv[j][0], - tface[i].uv[j][1]); + for (int index = 0; index < totpoly; index++) { + MPoly *mpoly = mpolys+index; + MLoopUV *mloop = mloops+mpoly->loopstart; + for (int j = 0; j < mpoly->totloop; j++) { + source.appendValues(mloop[j].uv[0], + mloop[j].uv[1]); } } diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index ce1dc7832d3..c880dfdbfcd 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -75,16 +75,7 @@ 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, @@ -101,6 +92,7 @@ public: //creates for texcoords void createTexcoordsSource(std::string geom_id, Mesh *me); + void createTesselatedTexcoordsSource(std::string geom_id, Mesh *me); //creates for normals void createNormalsSource(std::string geom_id, Mesh *me, std::vector& nor); @@ -113,7 +105,7 @@ public: COLLADASW::URI makeUrl(std::string id); - void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool use_ngons); + void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb); /* int getTriCount(MFace *faces, int totface);*/ private: diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index 26915f37002..69944563b6a 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -173,83 +173,30 @@ void UVDataWrapper::getUV(int uv_index, float *uv) } } -void MeshImporter::set_face_indices(MFace *mface, unsigned int *indices, bool quad) -{ - mface->v1 = indices[0]; - mface->v2 = indices[1]; - mface->v3 = indices[2]; - if (quad) mface->v4 = indices[3]; - else mface->v4 = 0; -#ifdef COLLADA_DEBUG - // fprintf(stderr, "%u, %u, %u\n", indices[0], indices[1], indices[2]); -#endif -} - -// not used anymore, test_index_face from blenkernel is better -#if 0 -// change face indices order so that v4 is not 0 -void MeshImporter::rotate_face_indices(MFace *mface) -{ - mface->v4 = mface->v1; - mface->v1 = mface->v2; - mface->v2 = mface->v3; - mface->v3 = 0; +MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) { } -#endif -void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, - COLLADAFW::IndexList& index_list, unsigned int *tris_indices) +void MeshImporter::set_poly_indices(MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count) { - // per face vertex indices, this means for quad we have 4 indices, not 8 - COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); + mpoly->loopstart = loop_index; + mpoly->totloop = loop_count; - uvs.getUV(indices[tris_indices[0]], mtface->uv[0]); - uvs.getUV(indices[tris_indices[1]], mtface->uv[1]); - uvs.getUV(indices[tris_indices[2]], mtface->uv[2]); + for (int index=0; index < loop_count; index++) { + mloop->v = indices[index]; + mloop++; + } } -void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, - COLLADAFW::IndexList& index_list, int index, bool quad) +void MeshImporter::set_face_uv(MLoopUV *mloopuv, UVDataWrapper &uvs, + int start_index, COLLADAFW::IndexList& index_list, int count) { // per face vertex indices, this means for quad we have 4 indices, not 8 COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); - uvs.getUV(indices[index + 0], mtface->uv[0]); - uvs.getUV(indices[index + 1], mtface->uv[1]); - uvs.getUV(indices[index + 2], mtface->uv[2]); - - if (quad) uvs.getUV(indices[index + 3], mtface->uv[3]); - -#ifdef COLLADA_DEBUG - if (quad) { - fprintf(stderr, "face uv:\n" - "((%d, %d, %d, %d))\n" - "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", - - indices[index + 0], - indices[index + 1], - indices[index + 2], - indices[index + 3], - - mtface->uv[0][0], mtface->uv[0][1], - mtface->uv[1][0], mtface->uv[1][1], - mtface->uv[2][0], mtface->uv[2][1], - mtface->uv[3][0], mtface->uv[3][1]); + for (int index = 0; index < count; index++) { + int uv_index = indices[index+start_index]; + uvs.getUV(uv_index, mloopuv[index].uv); } - else { - fprintf(stderr, "face uv:\n" - "((%d, %d, %d))\n" - "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", - - indices[index + 0], - indices[index + 1], - indices[index + 2], - - mtface->uv[0][0], mtface->uv[0][1], - mtface->uv[1][0], mtface->uv[1][1], - mtface->uv[2][0], mtface->uv[2][1]); - } -#endif } #ifdef COLLADA_DEBUG @@ -329,91 +276,6 @@ void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) } } -int MeshImporter::triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector& tri) -{ - ListBase dispbase; - DispList *dl; - float *vert; - int i = 0; - - dispbase.first = dispbase.last = NULL; - - dl = (DispList *)MEM_callocN(sizeof(DispList), "poly disp"); - dl->nr = totvert; - dl->type = DL_POLY; - dl->parts = 1; - dl->verts = vert = (float *)MEM_callocN(totvert * 3 * sizeof(float), "poly verts"); - dl->index = (int *)MEM_callocN(sizeof(int) * 3 * totvert, "dl index"); - - BLI_addtail(&dispbase, dl); - - for (i = 0; i < totvert; i++) { - copy_v3_v3(vert, verts[indices[i]].co); - vert += 3; - } - - BKE_displist_fill(&dispbase, &dispbase, 0); - - int tottri = 0; - dl = (DispList *)dispbase.first; - - if (dl->type == DL_INDEX3) { - tottri = dl->parts; - - int *index = dl->index; - for (i = 0; i < tottri; i++) { - int t[3] = {*index, *(index + 1), *(index + 2)}; - - std::sort(t, t + 3); - - tri.push_back(t[0]); - tri.push_back(t[1]); - tri.push_back(t[2]); - - index += 3; - } - } - - BKE_displist_free(&dispbase); - - return tottri; -} - -int MeshImporter::count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me) -{ - COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); - unsigned int i; - int tottri = 0; - - for (i = 0; i < prim_arr.getCount(); i++) { - - COLLADAFW::MeshPrimitive *mp = prim_arr[i]; - int type = mp->getPrimitiveType(); - size_t prim_totface = mp->getFaceCount(); - unsigned int *indices = mp->getPositionIndices().getData(); - - if (type == COLLADAFW::MeshPrimitive::POLYLIST || - type == COLLADAFW::MeshPrimitive::POLYGONS) - { - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; - COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); - - for (unsigned int j = 0; j < prim_totface; j++) { - int vcount = vcounta[j]; - - if (vcount > 4) { - std::vector tri; - - // tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?! - tottri += triangulate_poly(indices, vcount, me->mvert, tri); - } - - indices += vcount; - } - } - } - return tottri; -} // ===================================================================== // condition 1: The Primitive has normals @@ -471,10 +333,11 @@ bool MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) { // hint: This is done because mesh->getFacesCount() does // count loose edges as extra faces, which is not what we want here. // ================================================================= -void MeshImporter::allocate_face_data(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) +void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) { - COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); - int total_facecount = 0; + COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives(); + int total_poly_count = 0; + int total_loop_count = 0; // collect edge_count and face_count from all parts for (int i = 0; i < prim_arr.getCount(); i++) { @@ -485,21 +348,77 @@ void MeshImporter::allocate_face_data(COLLADAFW::Mesh *mesh, Mesh *me, int new_t case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: case COLLADAFW::MeshPrimitive::POLYLIST: case COLLADAFW::MeshPrimitive::POLYGONS: { - size_t prim_totface = mp->getFaceCount(); - total_facecount += prim_totface; + + COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; + size_t prim_poly_count = mpvc->getFaceCount(); + + size_t prim_loop_count = 0; + for(int index=0; index < prim_poly_count; index++) { + prim_loop_count += get_vertex_count(mpvc, index); + } + + total_poly_count += prim_poly_count; + total_loop_count += prim_loop_count; break; } default: break; } } - // allocate space for faces - if (total_facecount > 0) { - me->totface = total_facecount + new_tris; - me->mface = (MFace *)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); + // Add the data containers + if (total_poly_count > 0) { + me->totpoly = total_poly_count; + me->totloop = total_loop_count; + me->mpoly = (MPoly *)CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, me->totpoly); + me->mloop = (MLoop *)CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, me->totloop); + + unsigned int totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount(); + for (int i = 0; i < totuvset; i++) { + if (collada_mesh->getUVCoords().getLength(i) == 0) { + totuvset = 0; + break; + } + } + + if (totuvset > 0) { + for (int i = 0; i < totuvset; i++) { + COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getUVCoords().getInputInfosArray()[i]; + COLLADAFW::String &uvname = info->mName; + int x = 0; + // Allocate space for UV_data + CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname.c_str()); + CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, uvname.c_str()); + } + // activate the first uv map + me->mtpoly = (MTexPoly *)CustomData_get_layer_n(&me->pdata, CD_MTEXPOLY, 0); + me->mloopuv = (MLoopUV *) CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0); + } } } +unsigned int MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index) { + int type = mp->getPrimitiveType(); + int result; + switch (type) { + case COLLADAFW::MeshPrimitive::TRIANGLES: + case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: { + result = 3; + break; + } + case COLLADAFW::MeshPrimitive::POLYLIST: + case COLLADAFW::MeshPrimitive::POLYGONS: { + result = mp->getGroupedVerticesVertexCountArray()[index]; + break; + } + default: { + result = -1; + break; + } + } + return result; +} + + unsigned int MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh) { COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); int loose_edge_count = 0; @@ -606,256 +525,118 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me) // // TODO: import uv set names // ======================================================================== -void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //TODO:: Refactor. Possibly replace by iterators +void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) { unsigned int i; - allocate_face_data(mesh, me, new_tris); - - // allocate UV Maps - unsigned int totuvset = mesh->getUVCoords().getInputInfosArray().getCount(); + allocate_poly_data(collada_mesh, me); - for (i = 0; i < totuvset; i++) { - if (mesh->getUVCoords().getLength(i) == 0) { - totuvset = 0; - break; - } - } - - for (i = 0; i < totuvset; i++) { - COLLADAFW::MeshVertexData::InputInfos *info = mesh->getUVCoords().getInputInfosArray()[i]; - CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface, info->mName.c_str()); - //this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); - } - - // activate the first uv map - if (totuvset) me->mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0); - - UVDataWrapper uvs(mesh->getUVCoords()); - -#ifdef COLLADA_DEBUG - // uvs.print(); -#endif + UVDataWrapper uvs(collada_mesh->getUVCoords()); - MFace *mface = me->mface; + MPoly *mpoly = me->mpoly; + MLoop *mloop = me->mloop; + int loop_index = 0; MaterialIdPrimitiveArrayMap mat_prim_map; - int face_index = 0; - - COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); - - COLLADAFW::MeshVertexData& nor = mesh->getNormals(); + COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives(); + COLLADAFW::MeshVertexData& nor = collada_mesh->getNormals(); for (i = 0; i < prim_arr.getCount(); i++) { COLLADAFW::MeshPrimitive *mp = prim_arr[i]; // faces - size_t prim_totface = mp->getFaceCount(); - unsigned int *indices = mp->getPositionIndices().getData(); - unsigned int *nind = mp->getNormalIndices().getData(); + size_t prim_totpoly = mp->getFaceCount(); + unsigned int *position_indices = mp->getPositionIndices().getData(); + unsigned int *normal_indices = mp->getNormalIndices().getData(); bool mp_has_normals = primitive_has_useable_normals(mp); bool mp_has_faces = primitive_has_faces(mp); - int type = mp->getPrimitiveType(); - int index = 0; + int collada_meshtype = mp->getPrimitiveType(); - // since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive - Primitive prim = {mface, 0}; + // since we cannot set mpoly->mat_nr here, we store a portion of me->mface in Primitive + Primitive prim = {mpoly, 0}; COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray(); -#ifdef COLLADA_DEBUG - /* - fprintf(stderr, "Primitive %d:\n", i); - for (unsigned int j = 0; j < totuvset; j++) { - print_index_list(*index_list_array[j]); - } - */ -#endif - - if (type == COLLADAFW::MeshPrimitive::TRIANGLES) { - for (unsigned int j = 0; j < prim_totface; j++) { - - set_face_indices(mface, indices, false); - indices += 3; - -#if 0 - for (unsigned int k = 0; k < totuvset; k++) { - if (!index_list_array.empty() && index_list_array[k]) { - // get mtface by face index and uv set index - MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); - set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false); - } - } -#else - for (unsigned int k = 0; k < index_list_array.getCount(); k++) { - // get mtface by face index and uv set index - MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); - set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false); - } -#endif - - test_index_face(mface, &me->fdata, face_index, 3); - - if (mp_has_normals) { - if (!flat_face(nind, nor, 3)) - mface->flag |= ME_SMOOTH; - - nind += 3; - } - - index += 3; - mface++; - face_index++; - prim.totface++; - } - } - // If MeshPrimitive is TRIANGLE_FANS we split it into triangles // The first trifan vertex will be the first vertex in every triangle - if (type == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { + // XXX The proper function of TRIANGLE_FANS is not tested!!! + // XXX In particular the handling of the normal_indices looks very wrong to me + if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount(); for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) { - unsigned int first_vertex = indices[0]; // Store first trifan vertex - unsigned int first_normal = nind[0]; // Store first trifan vertex normal + unsigned int first_vertex = position_indices[0]; // Store first trifan vertex + unsigned int first_normal = normal_indices[0]; // Store first trifan vertex normal unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index); for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) { // For each triangle store indeces of its 3 vertices - unsigned int triangle_vertex_indices[3] = {first_vertex, indices[1], indices[2]}; - set_face_indices(mface, triangle_vertex_indices, false); - test_index_face(mface, &me->fdata, face_index, 3); + unsigned int triangle_vertex_indices[3] = {first_vertex, position_indices[1], position_indices[2]}; + set_poly_indices(mpoly, mloop, loop_index, triangle_vertex_indices, 3); if (mp_has_normals) { // vertex normals, same inplementation as for the triangles // the same for vertces normals - unsigned int vertex_normal_indices[3] = {first_normal, nind[1], nind[2]}; - if (!flat_face(vertex_normal_indices, nor, 3)) - mface->flag |= ME_SMOOTH; - nind++; + unsigned int vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]}; + if (!is_flat_face(vertex_normal_indices, nor, 3)) + mpoly->flag |= ME_SMOOTH; + normal_indices++; } - mface++; // same inplementation as for the triangles - indices++; - face_index++; - prim.totface++; + mpoly++; + mloop += 3; + loop_index += 3; + prim.totpoly++; + } // Moving cursor to the next triangle fan. if (mp_has_normals) - nind += 2; + normal_indices += 2; - indices += 2; + position_indices += 2; } } - else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; - COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); - for (unsigned int j = 0; j < prim_totface; j++) { + if (collada_meshtype == COLLADAFW::MeshPrimitive::POLYLIST || + collada_meshtype == COLLADAFW::MeshPrimitive::POLYGONS || + collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLES) { + COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; + for (unsigned int j = 0; j < prim_totpoly; j++) { - // face - int vcount = vcounta[j]; - if (vcount == 3 || vcount == 4) { - - set_face_indices(mface, indices, vcount == 4); - - // set mtface for each uv set - // it is assumed that all primitives have equal number of UV sets - -#if 0 - for (unsigned int k = 0; k < totuvset; k++) { - if (!index_list_array.empty() && index_list_array[k]) { - // get mtface by face index and uv set index - MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); - set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0); - } - } -#else - for (unsigned int k = 0; k < index_list_array.getCount(); k++) { - // get mtface by face index and uv set index - MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); - set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, vcount == 4); - } -#endif + // Vertices in polygon: + int vcount = get_vertex_count(mpvc, j); + set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount); - test_index_face(mface, &me->fdata, face_index, vcount); - if (mp_has_normals) { - if (!flat_face(nind, nor, vcount)) - mface->flag |= ME_SMOOTH; + for (unsigned int l = 0; l < index_list_array.getCount(); l++) { + int uvset_index = index_list_array[l]->getSetIndex(); - nind += vcount; - } - - mface++; - face_index++; - prim.totface++; - - } - else { - std::vector tri; - - triangulate_poly(indices, vcount, me->mvert, tri); - - for (unsigned int k = 0; k < tri.size() / 3; k++) { - int v = k * 3; - unsigned int uv_indices[3] = { - index + tri[v], - index + tri[v + 1], - index + tri[v + 2] - }; - unsigned int tri_indices[3] = { - indices[tri[v]], - indices[tri[v + 1]], - indices[tri[v + 2]] - }; - - set_face_indices(mface, tri_indices, false); - -#if 0 - for (unsigned int l = 0; l < totuvset; l++) { - if (!index_list_array.empty() && index_list_array[l]) { - // get mtface by face index and uv set index - MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l); - set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices); - } - } -#else - for (unsigned int l = 0; l < index_list_array.getCount(); l++) { - int uvset_index = index_list_array[l]->getSetIndex(); - - // get mtface by face index and uv set index - MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); - set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices); - } -#endif - - - test_index_face(mface, &me->fdata, face_index, 3); - - if (mp_has_normals) { - unsigned int ntri[3] = {nind[tri[v]], nind[tri[v + 1]], nind[tri[v + 2]]}; + // get mtface by face index and uv set index + MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uvset_index); - if (!flat_face(ntri, nor, 3)) - mface->flag |= ME_SMOOTH; - } - - mface++; - face_index++; - prim.totface++; - } + set_face_uv(mloopuv+loop_index, uvs, loop_index, *index_list_array[l], vcount); + } - if (mp_has_normals) - nind += vcount; + if (mp_has_normals) { + if (!is_flat_face(normal_indices, nor, vcount)) + mpoly->flag |= ME_SMOOTH; } + + mpoly++; + mloop += vcount; + loop_index += vcount; + prim.totpoly++; + + if (mp_has_normals) + normal_indices += vcount; - index += vcount; - indices += vcount; + position_indices += vcount; } } - else if (type == COLLADAFW::MeshPrimitive::LINES) { + + else if (collada_meshtype == COLLADAFW::MeshPrimitive::LINES) { continue; // read the lines later after all the rest is done } @@ -863,7 +644,7 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T mat_prim_map[mp->getMaterialId()].push_back(prim); } - geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map; + geom_uid_mat_mapping_map[collada_mesh->getUniqueId()] = mat_prim_map; } void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride) @@ -896,8 +677,7 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, break; } } - -bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count) +bool MeshImporter::is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count) { float a[3], b[3]; @@ -919,8 +699,6 @@ bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, return true; } -MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) { -} void MeshImporter::bmeshConversion() { @@ -929,10 +707,9 @@ void MeshImporter::bmeshConversion() { if ((*m).second) { Mesh *me = (*m).second; - BKE_mesh_convert_mfaces_to_mpolys(me); BKE_mesh_tessface_clear(me); - BKE_mesh_calc_normals_mapping(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL, NULL, 0, NULL, NULL); + //BKE_mesh_validate(me, 1); } } } @@ -1137,9 +914,10 @@ void MeshImporter::optimize_material_assignements() MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, std::map& uid_material_map, Object *ob, const COLLADAFW::UniqueId *geom_uid, - MTex **color_texture, char *layername, MTFace *texture_face, + char *layername, MTFace *texture_face, std::map& material_texture_mapping_map, short mat_index) { + MTex *color_texture = NULL; Mesh *me = (Mesh *)ob->data; const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial(); @@ -1167,17 +945,17 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri // loop through for (i = 0; i < tex_array.getCount(); i++) { - *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map, - *color_texture); + color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map, + color_texture); } // set texture face - if (*color_texture && - strlen((*color_texture)->uvname) && - strcmp(layername, (*color_texture)->uvname) != 0) { + if (color_texture && + strlen((color_texture)->uvname) && + strcmp(layername, color_texture->uvname) != 0) { texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE, - (*color_texture)->uvname); - strcpy(layername, (*color_texture)->uvname); + color_texture->uvname); + strcpy(layername, color_texture->uvname); } MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid]; @@ -1192,19 +970,18 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri for (it = prims.begin(); it != prims.end(); it++) { Primitive& prim = *it; - MFace *mface = prim.mface; + MPoly *mpoly = prim.mpoly; - for (i = 0; i < prim.totface; i++, mface++) { - mface->mat_nr = mat_index; + for (i = 0; i < prim.totpoly; i++, mpoly++) { + mpoly->mat_nr = mat_index; // bind texture images to faces - if (texture_face && (*color_texture)) { - texture_face->tpage = (Image *)(*color_texture)->tex->ima; + if (texture_face && color_texture) { + texture_face->tpage = (Image *)color_texture->tex->ima; texture_face++; } } } - } - + } return texture_face; } @@ -1251,15 +1028,15 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta // replace ob->data freeing the old one Mesh *old_mesh = (Mesh *)ob->data; + Mesh *new_mesh = uid_mesh_map[*geom_uid]; - set_mesh(ob, uid_mesh_map[*geom_uid]); + set_mesh(ob, new_mesh); if (old_mesh->id.us == 0) BKE_libblock_free(&G.main->mesh, old_mesh); char layername[100]; layername[0] = '\0'; MTFace *texture_face = NULL; - MTex *color_texture = NULL; COLLADAFW::MaterialBindingArray& mat_array = geom->getMaterialBindings(); @@ -1269,7 +1046,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta if (mat_array[i].getReferencedMaterial().isValid()) { texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, - &color_texture, layername, texture_face, + layername, texture_face, material_texture_mapping_map, i); } else { @@ -1283,11 +1060,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom) { - // TODO: import also uvs, normals - // XXX what to do with normal indices? - // XXX num_normals may be != num verts, then what to do? - // check geometry->getType() first if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) { // TODO: report warning fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType())); @@ -1306,23 +1079,16 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom) me->id.us--; // is already 1 here, but will be set later in set_mesh // store the Mesh pointer to link it later with an Object + // mesh_geom_map needed to map mesh to its geometry name (for shape key naming) this->uid_mesh_map[mesh->getUniqueId()] = me; - // needed to map mesh to its geometry name (needed for shape key naming) this->mesh_geom_map[std::string(me->id.name)] = str_geom_id; - - int new_tris = 0; read_vertices(mesh, me); - - new_tris = count_new_tris(mesh, me); - - read_faces(mesh, me, new_tris); - - BKE_mesh_make_edges(me, 0); + read_polys(mesh, me); + BKE_mesh_calc_edges(me, 0); // read_lines() must be called after the face edges have been generated. // Oterwise the loose edges will be silently deleted again. read_lines(mesh, me); - return true; } diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h index 8b0f5cdc200..751e6faf02b 100644 --- a/source/blender/collada/MeshImporter.h +++ b/source/blender/collada/MeshImporter.h @@ -31,6 +31,7 @@ #include #include "COLLADAFWIndexList.h" +#include "COLLADAFWPolygons.h" #include "COLLADAFWInstanceGeometry.h" #include "COLLADAFWMaterialBinding.h" #include "COLLADAFWMesh.h" @@ -89,30 +90,28 @@ private: std::map uid_mesh_map; // geometry unique id-to-mesh map std::map uid_object_map; // geom uid-to-object std::vector imported_objects; // list of imported objects - // this structure is used to assign material indices to faces + + // this structure is used to assign material indices to polygons // it holds a portion of Mesh faces and corresponds to a DAE primitive list (, , etc.) struct Primitive { - MFace *mface; - unsigned int totface; + MPoly *mpoly; + unsigned int totpoly; }; typedef std::map > MaterialIdPrimitiveArrayMap; std::map geom_uid_mat_mapping_map; // crazy name! std::multimap materials_mapped_to_geom; //< materials that have already been mapped to a geometry. A pair of geom uid and mat uid, one geometry can have several materials - - void set_face_indices(MFace *mface, unsigned int *indices, bool quad); - - // not used anymore, test_index_face from blenkernel is better -#if 0 - // change face indices order so that v4 is not 0 - void rotate_face_indices(MFace *mface); -#endif - - void set_face_uv(MTFace *mtface, UVDataWrapper &uvs, - COLLADAFW::IndexList& index_list, unsigned int *tris_indices); - - void set_face_uv(MTFace *mtface, UVDataWrapper &uvs, - COLLADAFW::IndexList& index_list, int index, bool quad); + void set_poly_indices(MPoly *mpoly, + MLoop *mloop, + int loop_index, + unsigned int *indices, + int loop_count); + + void set_face_uv(MLoopUV *mloopuv, + UVDataWrapper &uvs, + int loop_index, + COLLADAFW::IndexList& index_list, + int count); #ifdef COLLADA_DEBUG void print_index_list(COLLADAFW::IndexList& index_list); @@ -121,11 +120,7 @@ private: bool is_nice_mesh(COLLADAFW::Mesh *mesh); void read_vertices(COLLADAFW::Mesh *mesh, Mesh *me); - - int triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector& tri); - - int count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me); - + bool primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp); bool primitive_has_faces(COLLADAFW::MeshPrimitive *mp); @@ -135,15 +130,16 @@ private: CustomData create_edge_custom_data(EdgeHash *eh); - void allocate_face_data(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris); + void allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me); // TODO: import uv set names - void read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris); + void read_polys(COLLADAFW::Mesh *mesh, Mesh *me); void read_lines(COLLADAFW::Mesh *mesh, Mesh *me); + unsigned int get_vertex_count(COLLADAFW::Polygons *mp, int index); void get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride); - bool flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count); + bool is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count); std::vector get_all_users_of(Mesh *reference_mesh); @@ -166,7 +162,7 @@ public: MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, std::map& uid_material_map, Object *ob, const COLLADAFW::UniqueId *geom_uid, - MTex **color_texture, char *layername, MTFace *texture_face, + char *layername, MTFace *texture_face, std::map& material_texture_mapping_map, short mat_index); diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index a868bf2d52d..e75123c1e76 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -75,7 +75,7 @@ int collada_export(Scene *sce, int include_material_textures, int use_texture_copies, - int use_ngons, + int triangulate, int use_object_instantiation, int sort_by_name, int second_life) @@ -107,7 +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.triangulate = triangulate != 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 e7e8555c59f..642259da7fc 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -67,7 +67,7 @@ int collada_export(Scene *sce, int include_material_textures, int use_texture_copies, - int use_ngons, + int triangulate, int use_object_instantiation, int sort_by_name, int second_life); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index f43878943c1..d8f15696c6d 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -56,6 +56,8 @@ extern "C" { #include "WM_api.h" // XXX hrm, see if we can do without this #include "WM_types.h" +#include "bmesh.h" + } float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index) @@ -137,25 +139,38 @@ Object *bc_add_object(Scene *scene, int type, const char *name) return ob; } -Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type) +Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate) { Mesh *tmpmesh; CustomDataMask mask = CD_MASK_MESH; DerivedMesh *dm = NULL; - switch (export_mesh_type) { - case BC_MESH_TYPE_VIEW: { - dm = mesh_create_derived_view(scene, ob, mask); - break; - } - case BC_MESH_TYPE_RENDER: { - dm = mesh_create_derived_render(scene, ob, mask); - break; + if(apply_modifiers) { + switch (export_mesh_type) { + case BC_MESH_TYPE_VIEW: { + dm = mesh_create_derived_view(scene, ob, mask); + break; + } + case BC_MESH_TYPE_RENDER: { + dm = mesh_create_derived_render(scene, ob, mask); + break; + } } } + else { + dm = mesh_create_derived((Mesh *)ob->data, ob, NULL); + } tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here DM_to_mesh(dm, tmpmesh, ob); dm->release(dm); + + if (triangulate) { + bc_triangulate_mesh(tmpmesh); + } + + // XXX Not sure if we need that for ngon_export as well. + BKE_mesh_tessface_ensure(tmpmesh); + return tmpmesh; } @@ -366,3 +381,14 @@ void bc_match_scale(std::vector *objects_done, } } + +void bc_triangulate_mesh(Mesh *me) { + bool use_beauty = false; + bool tag_only = false; + + BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default); + BM_mesh_bm_from_me(bm, me, FALSE, 0); + BM_mesh_triangulate(bm, use_beauty, tag_only, NULL, NULL); + BM_mesh_bm_to_me(bm, me, FALSE); + BM_mesh_free(bm); +} diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 892b57e6a4a..2b2c8c5108f 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -62,7 +62,7 @@ extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsi extern int bc_test_parent_loop(Object *par, Object *ob); extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space = true); extern Object *bc_add_object(Scene *scene, int type, const char *name); -extern Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type); +extern Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate); extern Object *bc_get_assigned_armature(Object *ob); extern Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob); @@ -84,4 +84,7 @@ extern int bc_get_active_UVLayer(Object *ob); extern std::string bc_replace_string(std::string data, const std::string& pattern, const std::string& replacement); extern std::string bc_url_encode(std::string data); extern void bc_match_scale(std::vector *objects_done, Scene &sce, UnitConverter &unit_converter); + +extern void bc_triangulate_mesh(Mesh *me); + #endif -- cgit v1.2.3