Apply [#26383] Triangle fans support for COLLADA importer
authorNathan Letwory <nathan@letworyinteractive.com>
Tue, 8 Mar 2011 13:26:41 +0000 (13:26 +0000)
committerNathan Letwory <nathan@letworyinteractive.com>
Tue, 8 Mar 2011 13:26:41 +0000 (13:26 +0000)
Submitted by Alexey Zakharov

This patch adds support to Blender for reading geometry data that's
represented as triangle fans.

source/blender/collada/MeshImporter.cpp

index 35098b140720c16a8187e9c124cc1624d26a91e9..89c8669a5d95c843135750ca407a3beb4b58f595 100644 (file)
@@ -165,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");
        }
@@ -278,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();
 
@@ -307,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;
                }
@@ -426,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;
        
@@ -478,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;
@@ -532,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();