Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00028 #include <algorithm> 00029 00030 #if !defined(WIN32) || defined(FREE_WINDOWS) 00031 #include <iostream> 00032 #endif 00033 00034 /* COLLADABU_ASSERT, may be able to remove later */ 00035 #include "COLLADABUPlatform.h" 00036 00037 #include "COLLADAFWMeshPrimitive.h" 00038 #include "COLLADAFWMeshVertexData.h" 00039 #include "COLLADAFWPolygons.h" 00040 00041 extern "C" { 00042 #include "BKE_blender.h" 00043 #include "BKE_customdata.h" 00044 #include "BKE_displist.h" 00045 #include "BKE_global.h" 00046 #include "BKE_library.h" 00047 #include "BKE_main.h" 00048 #include "BKE_material.h" 00049 #include "BKE_mesh.h" 00050 #include "BKE_object.h" 00051 00052 #include "BLI_listbase.h" 00053 #include "BLI_math.h" 00054 #include "BLI_string.h" 00055 00056 #include "MEM_guardedalloc.h" 00057 } 00058 00059 #include "ArmatureImporter.h" 00060 #include "MeshImporter.h" 00061 #include "collada_utils.h" 00062 00063 // get node name, or fall back to original id if not present (name is optional) 00064 template<class T> 00065 static const char *bc_get_dae_name(T *node) 00066 { 00067 const std::string& name = node->getName(); 00068 return name.size() ? name.c_str() : node->getOriginalId().c_str(); 00069 } 00070 00071 static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type) 00072 { 00073 switch (type) { 00074 case COLLADAFW::MeshPrimitive::LINES: 00075 return "LINES"; 00076 case COLLADAFW::MeshPrimitive::LINE_STRIPS: 00077 return "LINESTRIPS"; 00078 case COLLADAFW::MeshPrimitive::POLYGONS: 00079 return "POLYGONS"; 00080 case COLLADAFW::MeshPrimitive::POLYLIST: 00081 return "POLYLIST"; 00082 case COLLADAFW::MeshPrimitive::TRIANGLES: 00083 return "TRIANGLES"; 00084 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 00085 return "TRIANGLE_FANS"; 00086 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 00087 return "TRIANGLE_FANS"; 00088 case COLLADAFW::MeshPrimitive::POINTS: 00089 return "POINTS"; 00090 case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE: 00091 return "UNDEFINED_PRIMITIVE_TYPE"; 00092 } 00093 return "UNKNOWN"; 00094 } 00095 00096 static const char *bc_geomTypeToStr(COLLADAFW::Geometry::GeometryType type) 00097 { 00098 switch (type) { 00099 case COLLADAFW::Geometry::GEO_TYPE_MESH: 00100 return "MESH"; 00101 case COLLADAFW::Geometry::GEO_TYPE_SPLINE: 00102 return "SPLINE"; 00103 case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH: 00104 return "CONVEX_MESH"; 00105 case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN: 00106 default: 00107 return "UNKNOWN"; 00108 } 00109 } 00110 00111 00112 UVDataWrapper::UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata) 00113 {} 00114 00115 #ifdef COLLADA_DEBUG 00116 void WVDataWrapper::print() 00117 { 00118 fprintf(stderr, "UVs:\n"); 00119 switch(mVData->getType()) { 00120 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: 00121 { 00122 COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues(); 00123 if (values->getCount()) { 00124 for (int i = 0; i < values->getCount(); i += 2) { 00125 fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i+1]); 00126 } 00127 } 00128 } 00129 break; 00130 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: 00131 { 00132 COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues(); 00133 if (values->getCount()) { 00134 for (int i = 0; i < values->getCount(); i += 2) { 00135 fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i+1]); 00136 } 00137 } 00138 } 00139 break; 00140 } 00141 fprintf(stderr, "\n"); 00142 } 00143 #endif 00144 00145 void UVDataWrapper::getUV(int uv_index, float *uv) 00146 { 00147 int stride = mVData->getStride(0); 00148 if(stride==0) stride = 2; 00149 00150 switch(mVData->getType()) { 00151 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: 00152 { 00153 COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues(); 00154 if (values->empty()) return; 00155 uv[0] = (*values)[uv_index*stride]; 00156 uv[1] = (*values)[uv_index*stride + 1]; 00157 00158 } 00159 break; 00160 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: 00161 { 00162 COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues(); 00163 if (values->empty()) return; 00164 uv[0] = (float)(*values)[uv_index*stride]; 00165 uv[1] = (float)(*values)[uv_index*stride + 1]; 00166 00167 } 00168 break; 00169 case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN: 00170 default: 00171 fprintf(stderr, "MeshImporter.getUV(): unknown data type\n"); 00172 } 00173 } 00174 00175 void MeshImporter::set_face_indices(MFace *mface, unsigned int *indices, bool quad) 00176 { 00177 mface->v1 = indices[0]; 00178 mface->v2 = indices[1]; 00179 mface->v3 = indices[2]; 00180 if (quad) mface->v4 = indices[3]; 00181 else mface->v4 = 0; 00182 #ifdef COLLADA_DEBUG 00183 // fprintf(stderr, "%u, %u, %u \n", indices[0], indices[1], indices[2]); 00184 #endif 00185 } 00186 00187 // not used anymore, test_index_face from blenkernel is better 00188 #if 0 00189 // change face indices order so that v4 is not 0 00190 void MeshImporter::rotate_face_indices(MFace *mface) 00191 { 00192 mface->v4 = mface->v1; 00193 mface->v1 = mface->v2; 00194 mface->v2 = mface->v3; 00195 mface->v3 = 0; 00196 } 00197 #endif 00198 00199 void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, 00200 COLLADAFW::IndexList& index_list, unsigned int *tris_indices) 00201 { 00202 // per face vertex indices, this means for quad we have 4 indices, not 8 00203 COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); 00204 00205 uvs.getUV(indices[tris_indices[0]], mtface->uv[0]); 00206 uvs.getUV(indices[tris_indices[1]], mtface->uv[1]); 00207 uvs.getUV(indices[tris_indices[2]], mtface->uv[2]); 00208 } 00209 00210 void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs, 00211 COLLADAFW::IndexList& index_list, int index, bool quad) 00212 { 00213 // per face vertex indices, this means for quad we have 4 indices, not 8 00214 COLLADAFW::UIntValuesArray& indices = index_list.getIndices(); 00215 00216 uvs.getUV(indices[index + 0], mtface->uv[0]); 00217 uvs.getUV(indices[index + 1], mtface->uv[1]); 00218 uvs.getUV(indices[index + 2], mtface->uv[2]); 00219 00220 if (quad) uvs.getUV(indices[index + 3], mtface->uv[3]); 00221 00222 #ifdef COLLADA_DEBUG 00223 if (quad) { 00224 fprintf(stderr, "face uv:\n" 00225 "((%d, %d, %d, %d))\n" 00226 "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", 00227 00228 indices[index + 0], 00229 indices[index + 1], 00230 indices[index + 2], 00231 indices[index + 3], 00232 00233 mtface->uv[0][0], mtface->uv[0][1], 00234 mtface->uv[1][0], mtface->uv[1][1], 00235 mtface->uv[2][0], mtface->uv[2][1], 00236 mtface->uv[3][0], mtface->uv[3][1]); 00237 } 00238 else { 00239 fprintf(stderr, "face uv:\n" 00240 "((%d, %d, %d))\n" 00241 "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n", 00242 00243 indices[index + 0], 00244 indices[index + 1], 00245 indices[index + 2], 00246 00247 mtface->uv[0][0], mtface->uv[0][1], 00248 mtface->uv[1][0], mtface->uv[1][1], 00249 mtface->uv[2][0], mtface->uv[2][1]); 00250 } 00251 #endif 00252 } 00253 00254 #ifdef COLLADA_DEBUG 00255 void MeshImporter::print_index_list(COLLADAFW::IndexList& index_list) 00256 { 00257 fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str()); 00258 for (int i = 0; i < index_list.getIndicesCount(); i += 2) { 00259 fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1)); 00260 } 00261 fprintf(stderr, "\n"); 00262 } 00263 #endif 00264 00265 bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has supported primitive types: polylist, triangles, triangle_fans 00266 { 00267 COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); 00268 00269 const char *name = bc_get_dae_name(mesh); 00270 00271 for (unsigned i = 0; i < prim_arr.getCount(); i++) { 00272 00273 COLLADAFW::MeshPrimitive *mp = prim_arr[i]; 00274 COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType(); 00275 00276 const char *type_str = bc_primTypeToStr(type); 00277 00278 // OpenCollada passes POLYGONS type for <polylist> 00279 if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { 00280 00281 COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; 00282 COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray(); 00283 00284 for(unsigned int j = 0; j < vca.getCount(); j++){ 00285 int count = vca[j]; 00286 if (count < 3) { 00287 fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n", 00288 type_str, name); 00289 return false; 00290 } 00291 } 00292 00293 } 00294 else if(type != COLLADAFW::MeshPrimitive::TRIANGLES && type!= COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { 00295 fprintf(stderr, "Primitive type %s is not supported.\n", type_str); 00296 return false; 00297 } 00298 } 00299 00300 if (mesh->getPositions().empty()) { 00301 fprintf(stderr, "Mesh %s has no vertices.\n", name); 00302 return false; 00303 } 00304 00305 return true; 00306 } 00307 00308 void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) 00309 { 00310 // vertices 00311 COLLADAFW::MeshVertexData& pos = mesh->getPositions(); 00312 int stride = pos.getStride(0); 00313 if(stride==0) stride = 3; 00314 00315 me->totvert = mesh->getPositions().getFloatValues()->getCount() / stride; 00316 me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); 00317 00318 MVert *mvert; 00319 int i; 00320 00321 for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { 00322 get_vector(mvert->co, pos, i, stride); 00323 } 00324 } 00325 00326 int MeshImporter::triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector<unsigned int>& tri) 00327 { 00328 ListBase dispbase; 00329 DispList *dl; 00330 float *vert; 00331 int i = 0; 00332 00333 dispbase.first = dispbase.last = NULL; 00334 00335 dl = (DispList*)MEM_callocN(sizeof(DispList), "poly disp"); 00336 dl->nr = totvert; 00337 dl->type = DL_POLY; 00338 dl->parts = 1; 00339 dl->verts = vert = (float*)MEM_callocN(totvert * 3 * sizeof(float), "poly verts"); 00340 dl->index = (int*)MEM_callocN(sizeof(int) * 3 * totvert, "dl index"); 00341 00342 BLI_addtail(&dispbase, dl); 00343 00344 for (i = 0; i < totvert; i++) { 00345 copy_v3_v3(vert, verts[indices[i]].co); 00346 vert += 3; 00347 } 00348 00349 filldisplist(&dispbase, &dispbase, 0); 00350 00351 int tottri = 0; 00352 dl= (DispList*)dispbase.first; 00353 00354 if (dl->type == DL_INDEX3) { 00355 tottri = dl->parts; 00356 00357 int *index = dl->index; 00358 for (i= 0; i < tottri; i++) { 00359 int t[3]= {*index, *(index + 1), *(index + 2)}; 00360 00361 std::sort(t, t + 3); 00362 00363 tri.push_back(t[0]); 00364 tri.push_back(t[1]); 00365 tri.push_back(t[2]); 00366 00367 index += 3; 00368 } 00369 } 00370 00371 freedisplist(&dispbase); 00372 00373 return tottri; 00374 } 00375 00376 int MeshImporter::count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me) 00377 { 00378 COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); 00379 unsigned int i; 00380 int tottri = 0; 00381 00382 for (i = 0; i < prim_arr.getCount(); i++) { 00383 00384 COLLADAFW::MeshPrimitive *mp = prim_arr[i]; 00385 int type = mp->getPrimitiveType(); 00386 size_t prim_totface = mp->getFaceCount(); 00387 unsigned int *indices = mp->getPositionIndices().getData(); 00388 00389 if (type == COLLADAFW::MeshPrimitive::POLYLIST || 00390 type == COLLADAFW::MeshPrimitive::POLYGONS) { 00391 00392 COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; 00393 COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); 00394 00395 for (unsigned int j = 0; j < prim_totface; j++) { 00396 int vcount = vcounta[j]; 00397 00398 if (vcount > 4) { 00399 std::vector<unsigned int> tri; 00400 00401 // tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?! 00402 tottri += triangulate_poly(indices, vcount, me->mvert, tri); 00403 } 00404 00405 indices += vcount; 00406 } 00407 } 00408 } 00409 return tottri; 00410 } 00411 00412 // TODO: import uv set names 00413 void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //TODO:: Refactor. Possibly replace by iterators 00414 { 00415 unsigned int i; 00416 00417 // allocate faces 00418 me->totface = mesh->getFacesCount() + new_tris; 00419 me->mface = (MFace*)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); 00420 00421 // allocate UV Maps 00422 unsigned int totuvset = mesh->getUVCoords().getInputInfosArray().getCount(); 00423 00424 for (i = 0; i < totuvset; i++) { 00425 if (mesh->getUVCoords().getLength(i) == 0) { 00426 totuvset = 0; 00427 break; 00428 } 00429 } 00430 00431 for (i = 0; i < totuvset; i++) { 00432 COLLADAFW::MeshVertexData::InputInfos *info = mesh->getUVCoords().getInputInfosArray()[i]; 00433 CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface, info->mName.c_str()); 00434 //this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); 00435 } 00436 00437 // activate the first uv map 00438 if (totuvset) me->mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0); 00439 00440 UVDataWrapper uvs(mesh->getUVCoords()); 00441 00442 #ifdef COLLADA_DEBUG 00443 // uvs.print(); 00444 #endif 00445 00446 MFace *mface = me->mface; 00447 00448 MaterialIdPrimitiveArrayMap mat_prim_map; 00449 00450 int face_index = 0; 00451 00452 COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); 00453 00454 bool has_normals = mesh->hasNormals(); 00455 COLLADAFW::MeshVertexData& nor = mesh->getNormals(); 00456 00457 for (i = 0; i < prim_arr.getCount(); i++) { 00458 00459 COLLADAFW::MeshPrimitive *mp = prim_arr[i]; 00460 00461 // faces 00462 size_t prim_totface = mp->getFaceCount(); 00463 unsigned int *indices = mp->getPositionIndices().getData(); 00464 unsigned int *nind = mp->getNormalIndices().getData(); 00465 00466 if (has_normals && mp->getPositionIndices().getCount() != mp->getNormalIndices().getCount()) { 00467 fprintf(stderr, "Warning: Number of normals is different from the number of vertcies, skipping normals\n"); 00468 has_normals = false; 00469 } 00470 00471 unsigned int j, k; 00472 int type = mp->getPrimitiveType(); 00473 int index = 0; 00474 00475 // since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive 00476 Primitive prim = {mface, 0}; 00477 COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray(); 00478 00479 #ifdef COLLADA_DEBUG 00480 /* 00481 fprintf(stderr, "Primitive %d:\n", i); 00482 for (int j = 0; j < totuvset; j++) { 00483 print_index_list(*index_list_array[j]); 00484 } 00485 */ 00486 #endif 00487 00488 if (type == COLLADAFW::MeshPrimitive::TRIANGLES) { 00489 for (j = 0; j < prim_totface; j++){ 00490 00491 set_face_indices(mface, indices, false); 00492 indices += 3; 00493 00494 #if 0 00495 for (k = 0; k < totuvset; k++) { 00496 if (!index_list_array.empty() && index_list_array[k]) { 00497 // get mtface by face index and uv set index 00498 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); 00499 set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false); 00500 } 00501 } 00502 #else 00503 for (k = 0; k < index_list_array.getCount(); k++) { 00504 // get mtface by face index and uv set index 00505 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); 00506 set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false); 00507 } 00508 #endif 00509 00510 test_index_face(mface, &me->fdata, face_index, 3); 00511 00512 if (has_normals) { 00513 if (!flat_face(nind, nor, 3)) 00514 mface->flag |= ME_SMOOTH; 00515 00516 nind += 3; 00517 } 00518 00519 index += 3; 00520 mface++; 00521 face_index++; 00522 prim.totface++; 00523 } 00524 } 00525 00526 // If MeshPrimitive is TRIANGLE_FANS we split it into triangles 00527 // The first trifan vertex will be the first vertex in every triangle 00528 if (type == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { 00529 unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount(); 00530 for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++){ 00531 unsigned int first_vertex = indices[0]; // Store first trifan vertex 00532 unsigned int first_normal = nind[0]; // Store first trifan vertex normal 00533 unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index); 00534 00535 for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++){ 00536 // For each triangle store indeces of its 3 vertices 00537 unsigned int triangle_vertex_indices[3]={first_vertex, indices[1], indices[2]}; 00538 set_face_indices(mface, triangle_vertex_indices, false); 00539 test_index_face(mface, &me->fdata, face_index, 3); 00540 00541 if (has_normals) { // vertex normals, same inplementation as for the triangles 00542 // the same for vertces normals 00543 unsigned int vertex_normal_indices[3]={first_normal, nind[1], nind[2]}; 00544 if (!flat_face(vertex_normal_indices, nor, 3)) 00545 mface->flag |= ME_SMOOTH; 00546 nind++; 00547 } 00548 00549 mface++; // same inplementation as for the triangles 00550 indices++; 00551 face_index++; 00552 prim.totface++; 00553 } 00554 00555 // Moving cursor to the next triangle fan. 00556 if (has_normals) 00557 nind += 2; 00558 00559 indices += 2; 00560 } 00561 } 00562 else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { 00563 COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp; 00564 COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray(); 00565 00566 for (j = 0; j < prim_totface; j++) { 00567 00568 // face 00569 int vcount = vcounta[j]; 00570 if (vcount == 3 || vcount == 4) { 00571 00572 set_face_indices(mface, indices, vcount == 4); 00573 00574 // set mtface for each uv set 00575 // it is assumed that all primitives have equal number of UV sets 00576 00577 #if 0 00578 for (k = 0; k < totuvset; k++) { 00579 if (!index_list_array.empty() && index_list_array[k]) { 00580 // get mtface by face index and uv set index 00581 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); 00582 set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0); 00583 } 00584 } 00585 #else 00586 for (k = 0; k < index_list_array.getCount(); k++) { 00587 // get mtface by face index and uv set index 00588 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k); 00589 set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, vcount == 4); 00590 } 00591 #endif 00592 00593 test_index_face(mface, &me->fdata, face_index, vcount); 00594 00595 if (has_normals) { 00596 if (!flat_face(nind, nor, vcount)) 00597 mface->flag |= ME_SMOOTH; 00598 00599 nind += vcount; 00600 } 00601 00602 mface++; 00603 face_index++; 00604 prim.totface++; 00605 00606 } 00607 else { 00608 std::vector<unsigned int> tri; 00609 00610 triangulate_poly(indices, vcount, me->mvert, tri); 00611 00612 for (k = 0; k < tri.size() / 3; k++) { 00613 int v = k * 3; 00614 unsigned int uv_indices[3] = { 00615 index + tri[v], 00616 index + tri[v + 1], 00617 index + tri[v + 2] 00618 }; 00619 unsigned int tri_indices[3] = { 00620 indices[tri[v]], 00621 indices[tri[v + 1]], 00622 indices[tri[v + 2]] 00623 }; 00624 00625 set_face_indices(mface, tri_indices, false); 00626 00627 #if 0 00628 for (unsigned int l = 0; l < totuvset; l++) { 00629 if (!index_list_array.empty() && index_list_array[l]) { 00630 // get mtface by face index and uv set index 00631 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l); 00632 set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices); 00633 } 00634 } 00635 #else 00636 for (unsigned int l = 0; l < index_list_array.getCount(); l++) { 00637 int uvset_index = index_list_array[l]->getSetIndex(); 00638 00639 // get mtface by face index and uv set index 00640 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index); 00641 set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices); 00642 } 00643 #endif 00644 00645 00646 test_index_face(mface, &me->fdata, face_index, 3); 00647 00648 if (has_normals) { 00649 unsigned int ntri[3] = {nind[tri[v]], nind[tri[v + 1]], nind[tri[v + 2]]}; 00650 00651 if (!flat_face(ntri, nor, 3)) 00652 mface->flag |= ME_SMOOTH; 00653 } 00654 00655 mface++; 00656 face_index++; 00657 prim.totface++; 00658 } 00659 00660 if (has_normals) 00661 nind += vcount; 00662 } 00663 00664 index += vcount; 00665 indices += vcount; 00666 } 00667 } 00668 00669 mat_prim_map[mp->getMaterialId()].push_back(prim); 00670 } 00671 00672 geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map; 00673 } 00674 00675 void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride) 00676 { 00677 i *= stride; 00678 00679 switch(arr.getType()) { 00680 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: 00681 { 00682 COLLADAFW::ArrayPrimitiveType<float>* values = arr.getFloatValues(); 00683 if (values->empty()) return; 00684 00685 v[0] = (*values)[i++]; 00686 v[1] = (*values)[i++]; 00687 v[2] = (*values)[i]; 00688 00689 } 00690 break; 00691 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: 00692 { 00693 COLLADAFW::ArrayPrimitiveType<double>* values = arr.getDoubleValues(); 00694 if (values->empty()) return; 00695 00696 v[0] = (float)(*values)[i++]; 00697 v[1] = (float)(*values)[i++]; 00698 v[2] = (float)(*values)[i]; 00699 } 00700 break; 00701 default: 00702 break; 00703 } 00704 } 00705 00706 bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count) 00707 { 00708 float a[3], b[3]; 00709 00710 get_vector(a, nor, *nind, 3); 00711 normalize_v3(a); 00712 00713 nind++; 00714 00715 for (int i = 1; i < count; i++, nind++) { 00716 get_vector(b, nor, *nind, 3); 00717 normalize_v3(b); 00718 00719 float dp = dot_v3v3(a, b); 00720 00721 if (dp < 0.99999f || dp > 1.00001f) 00722 return false; 00723 } 00724 00725 return true; 00726 } 00727 00728 MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {} 00729 00730 Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) 00731 { 00732 if (uid_object_map.find(geom_uid) != uid_object_map.end()) 00733 return uid_object_map[geom_uid]; 00734 return NULL; 00735 } 00736 00737 MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture, 00738 Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map, 00739 MTex *color_texture) 00740 { 00741 const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId(); 00742 size_t setindex = ctexture.getSetIndex(); 00743 std::string uvname = ctexture.getSemantic(); 00744 00745 if(setindex==-1) return NULL; 00746 00747 const CustomData *data = &me->fdata; 00748 int layer_index = CustomData_get_layer_index(data, CD_MTFACE); 00749 CustomDataLayer *cdl = &data->layers[layer_index+setindex]; 00750 00751 /* set uvname to bind_vertex_input semantic */ 00752 BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name)); 00753 00754 if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) { 00755 00756 fprintf(stderr, "Cannot find texture array by texture index.\n"); 00757 return color_texture; 00758 } 00759 00760 std::vector<MTex*> textures = texindex_texarray_map[texture_index]; 00761 00762 std::vector<MTex*>::iterator it; 00763 00764 for (it = textures.begin(); it != textures.end(); it++) { 00765 00766 MTex *texture = *it; 00767 00768 if (texture) { 00769 BLI_strncpy(texture->uvname, uvname.c_str(), sizeof(texture->uvname)); 00770 if (texture->mapto == MAP_COL) color_texture = texture; 00771 } 00772 } 00773 return color_texture; 00774 } 00775 00776 MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, 00777 std::map<COLLADAFW::UniqueId, Material*>& uid_material_map, 00778 Object *ob, const COLLADAFW::UniqueId *geom_uid, 00779 MTex **color_texture, char *layername, MTFace *texture_face, 00780 std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index) 00781 { 00782 Mesh *me = (Mesh*)ob->data; 00783 const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial(); 00784 00785 // do we know this material? 00786 if (uid_material_map.find(ma_uid) == uid_material_map.end()) { 00787 00788 fprintf(stderr, "Cannot find material by UID.\n"); 00789 return NULL; 00790 } 00791 00792 // different nodes can point to same geometry, but still also specify the same materials 00793 // again. Make sure we don't overwrite them on the next occurrences, so keep list of 00794 // what we already have handled. 00795 std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId>::iterator it; 00796 it=materials_mapped_to_geom.find(*geom_uid); 00797 while(it!=materials_mapped_to_geom.end()) { 00798 if(it->second == ma_uid && it->first == *geom_uid) return NULL; // do nothing if already found 00799 it++; 00800 } 00801 // first time we get geom_uid, ma_uid pair. Save for later check. 00802 materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid)); 00803 00804 Material *ma = uid_material_map[ma_uid]; 00805 assign_material(ob, ma, ob->totcol + 1); 00806 00807 COLLADAFW::TextureCoordinateBindingArray& tex_array = 00808 cmaterial.getTextureCoordinateBindingArray(); 00809 TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma]; 00810 unsigned int i; 00811 // loop through <bind_vertex_inputs> 00812 for (i = 0; i < tex_array.getCount(); i++) { 00813 00814 *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map, 00815 *color_texture); 00816 } 00817 00818 // set texture face 00819 if (*color_texture && 00820 strlen((*color_texture)->uvname) && 00821 strcmp(layername, (*color_texture)->uvname) != 0) { 00822 texture_face = (MTFace*)CustomData_get_layer_named(&me->fdata, CD_MTFACE, 00823 (*color_texture)->uvname); 00824 strcpy(layername, (*color_texture)->uvname); 00825 } 00826 00827 MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid]; 00828 COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId(); 00829 00830 // assign material indices to mesh faces 00831 if (mat_prim_map.find(mat_id) != mat_prim_map.end()) { 00832 00833 std::vector<Primitive>& prims = mat_prim_map[mat_id]; 00834 00835 std::vector<Primitive>::iterator it; 00836 00837 for (it = prims.begin(); it != prims.end(); it++) { 00838 Primitive& prim = *it; 00839 i = 0; 00840 while (i++ < prim.totface) { 00841 prim.mface->mat_nr = mat_index; 00842 prim.mface++; 00843 // bind texture images to faces 00844 if (texture_face && (*color_texture)) { 00845 texture_face->mode = TF_TEX; 00846 texture_face->tpage = (Image*)(*color_texture)->tex->ima; 00847 texture_face++; 00848 } 00849 } 00850 } 00851 } 00852 00853 return texture_face; 00854 } 00855 00856 00857 Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, 00858 bool isController, 00859 std::map<COLLADAFW::UniqueId, Material*>& uid_material_map, 00860 std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map) 00861 { 00862 const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId(); 00863 00864 // check if node instanciates controller or geometry 00865 if (isController) { 00866 00867 geom_uid = armature_importer->get_geometry_uid(*geom_uid); 00868 00869 if (!geom_uid) { 00870 fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n"); 00871 return NULL; 00872 } 00873 } 00874 else { 00875 00876 if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) { 00877 // this could happen if a mesh was not created 00878 // (e.g. if it contains unsupported geometry) 00879 fprintf(stderr, "Couldn't find a mesh by UID.\n"); 00880 return NULL; 00881 } 00882 } 00883 if (!uid_mesh_map[*geom_uid]) return NULL; 00884 00885 Object *ob = add_object(scene, OB_MESH); 00886 00887 // store object pointer for ArmatureImporter 00888 uid_object_map[*geom_uid] = ob; 00889 00890 // name Object 00891 const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId(); 00892 if (id.length()) 00893 rename_id(&ob->id, (char*)id.c_str()); 00894 00895 // replace ob->data freeing the old one 00896 Mesh *old_mesh = (Mesh*)ob->data; 00897 00898 set_mesh(ob, uid_mesh_map[*geom_uid]); 00899 00900 if (old_mesh->id.us == 0) free_libblock(&G.main->mesh, old_mesh); 00901 00902 char layername[100]; 00903 layername[0] = '\0'; 00904 MTFace *texture_face = NULL; 00905 MTex *color_texture = NULL; 00906 00907 COLLADAFW::MaterialBindingArray& mat_array = 00908 geom->getMaterialBindings(); 00909 00910 // loop through geom's materials 00911 for (unsigned int i = 0; i < mat_array.getCount(); i++) { 00912 00913 if(mat_array[i].getReferencedMaterial().isValid()) { 00914 texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, 00915 &color_texture, layername, texture_face, 00916 material_texture_mapping_map, i); 00917 } else { 00918 fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str()); 00919 } 00920 } 00921 00922 return ob; 00923 } 00924 00925 // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID 00926 bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom) 00927 { 00928 // TODO: import also uvs, normals 00929 // XXX what to do with normal indices? 00930 // XXX num_normals may be != num verts, then what to do? 00931 00932 // check geometry->getType() first 00933 if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) { 00934 // TODO: report warning 00935 fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType())); 00936 return true; 00937 } 00938 00939 COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh*)geom; 00940 00941 if (!is_nice_mesh(mesh)) { 00942 fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh)); 00943 return true; 00944 } 00945 00946 const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId(); 00947 Mesh *me = add_mesh((char*)str_geom_id.c_str()); 00948 00949 // store the Mesh pointer to link it later with an Object 00950 this->uid_mesh_map[mesh->getUniqueId()] = me; 00951 00952 int new_tris = 0; 00953 00954 read_vertices(mesh, me); 00955 00956 new_tris = count_new_tris(mesh, me); 00957 00958 read_faces(mesh, me, new_tris); 00959 00960 make_edges(me, 0); 00961 00962 mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); 00963 00964 return true; 00965 }