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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/collada/MeshImporter.cpp')
-rw-r--r--source/blender/collada/MeshImporter.cpp78
1 files changed, 71 insertions, 7 deletions
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index d458b47885f..b6576858c51 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -22,6 +22,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
+/** \file blender/collada/MeshImporter.cpp
+ * \ingroup collada
+ */
+
+
#include <algorithm>
#if !defined(WIN32) || defined(FREE_WINDOWS)
@@ -160,7 +165,7 @@ void UVDataWrapper::getUV(int uv_index[2], float *uv)
}
break;
- case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
+ case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
default:
fprintf(stderr, "MeshImporter.getUV(): unknown data type\n");
}
@@ -273,7 +278,7 @@ void MeshImporter::print_index_list(COLLADAFW::IndexList& index_list)
}
#endif
-bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
+bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has supported primitive types: polylist, triangles, triangle_fans
{
COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
@@ -302,7 +307,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
}
}
- else if(type != COLLADAFW::MeshPrimitive::TRIANGLES) {
+ else if(type != COLLADAFW::MeshPrimitive::TRIANGLES && type!= COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
fprintf(stderr, "Primitive type %s is not supported.\n", type_str);
return false;
}
@@ -421,7 +426,7 @@ int MeshImporter::count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me)
}
// TODO: import uv set names
-void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
+void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //TODO:: Refactor. Possibly replace by iterators
{
unsigned int i;
@@ -473,6 +478,12 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
size_t prim_totface = mp->getFaceCount();
unsigned int *indices = mp->getPositionIndices().getData();
unsigned int *nind = mp->getNormalIndices().getData();
+
+ if (has_normals && mp->getPositionIndices().getCount() != mp->getNormalIndices().getCount()) {
+ fprintf(stderr, "Warning: Number of normals is different from the number of vertcies, skipping normals\n");
+ has_normals = false;
+ }
+
unsigned int j, k;
int type = mp->getPrimitiveType();
int index = 0;
@@ -527,6 +538,43 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
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) {
+ 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 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);
+
+ if (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++;
+ }
+
+ mface++; // same inplementation as for the triangles
+ indices++;
+ face_index++;
+ prim.totface++;
+ }
+
+ // Moving cursor to the next triangle fan.
+ if (has_normals)
+ nind += 2;
+
+ indices += 2;
+ }
+ }
else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp;
COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
@@ -755,6 +803,18 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
return NULL;
}
+ // different nodes can point to same geometry, but still also specify the same materials
+ // again. Make sure we don't overwrite them on the next occurrences, so keep list of
+ // what we already have handled.
+ std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId>::iterator it;
+ it=materials_mapped_to_geom.find(*geom_uid);
+ while(it!=materials_mapped_to_geom.end()) {
+ if(it->second == ma_uid) return NULL; // do nothing if already found
+ it++;
+ }
+ // first time we get geom_uid, ma_uid pair. Save for later check.
+ materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
+
Material *ma = uid_material_map[ma_uid];
assign_material(ob, ma, ob->totcol + 1);
@@ -864,9 +924,13 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
// loop through geom's materials
for (unsigned int i = 0; i < mat_array.getCount(); i++) {
- texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
- &color_texture, layername, texture_face,
- material_texture_mapping_map, i);
+ 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,
+ material_texture_mapping_map, i);
+ } else {
+ fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
+ }
}
return ob;