bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has supported primitive types: lines, polylist, triangles, triangle_fans { COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives(); const std::string &name = bc_get_dae_name(mesh); int hole_count = 0; for (unsigned i = 0; i < prim_arr.getCount(); i++) { COLLADAFW::MeshPrimitive *mp = prim_arr[i]; COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType(); const char *type_str = bc_primTypeToStr(type); // OpenCollada passes POLYGONS type for <polylist> if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray(); for (unsigned int j = 0; j < vca.getCount(); j++) { int count = vca[j]; if (abs(count) < 3) { fprintf(stderr, "ERROR: Primitive %s in %s has at least one face with vertex count < 3\n", type_str, name.c_str()); return false; } if (count < 0) { hole_count ++; } } if (hole_count > 0) { fprintf(stderr, "WARNING: Primitive %s in %s: %d holes not imported (unsupported)\n", type_str, name.c_str(), hole_count); } } else if (type == COLLADAFW::MeshPrimitive::LINES) { // TODO: Add Checker for line syntax here } else if (type != COLLADAFW::MeshPrimitive::TRIANGLES && type != COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { fprintf(stderr, "ERROR: Primitive type %s is not supported.\n", type_str); return false; } } if (mesh->getPositions().empty()) { fprintf(stderr, "ERROR: Mesh %s has no vertices.\n", name.c_str()); return false; } return true; }
static shared_ptr <GLTF::GLTFPrimitive> ConvertOpenCOLLADAMeshPrimitive( COLLADAFW::MeshPrimitive *openCOLLADAMeshPrimitive, IndicesVector &primitiveIndicesVector) { shared_ptr <GLTF::GLTFPrimitive> cvtPrimitive(new GLTF::GLTFPrimitive()); // We want to match OpenGL/ES mode , as WebGL spec points to OpenGL/ES spec... // "Symbolic constants GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, and GL_TRIANGLES are accepted." std::string type; bool shouldTriangulate = false; switch(openCOLLADAMeshPrimitive->getPrimitiveType()) { //these 2 requires transforms case COLLADAFW::MeshPrimitive::POLYLIST: case COLLADAFW::MeshPrimitive::POLYGONS: // FIXME: perform conversion, but until not done report error //these mode are supported by WebGL shouldTriangulate = true; //force triangles type = "TRIANGLES"; break; case COLLADAFW::MeshPrimitive::LINES: type = "LINES"; break; case COLLADAFW::MeshPrimitive::LINE_STRIPS: type = "LINE_STRIP"; break; case COLLADAFW::MeshPrimitive::TRIANGLES: type = "TRIANGLES"; break; case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: type = "TRIANGLE_FANS"; break; case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: type = "TRIANGLE_STRIPS"; break; case COLLADAFW::MeshPrimitive::POINTS: type = "POINTS"; break; default: break; } cvtPrimitive->setMaterialObjectID((unsigned int)openCOLLADAMeshPrimitive->getMaterialId()); cvtPrimitive->setType(type); //count of indices , it must be the same for all kind of indices size_t count = openCOLLADAMeshPrimitive->getPositionIndices().getCount(); //vertex //IndexList &positionIndexList = openCOLLADAMeshPrimitive->getPositionIndices(); unsigned int *indices = openCOLLADAMeshPrimitive->getPositionIndices().getData(); unsigned int *verticesCountArray = 0; unsigned int vcount = 0; //count of elements in the array containing the count of indices per polygon & polylist. if (shouldTriangulate) { unsigned int triangulatedIndicesCount = 0; //We have to upcast to polygon to retrieve the array of vertexCount //OpenCOLLADA use polylist as polygon. COLLADAFW::Polygons *polygon = (COLLADAFW::Polygons*)openCOLLADAMeshPrimitive; const COLLADAFW::Polygons::VertexCountArray& vertexCountArray = polygon->getGroupedVerticesVertexCountArray(); vcount = (unsigned int)vertexCountArray.getCount(); verticesCountArray = (unsigned int*)malloc(sizeof(unsigned int) * vcount); for (size_t i = 0; i < vcount; i++) { verticesCountArray[i] = polygon->getGroupedVerticesVertexCount(i);; } indices = createTrianglesFromPolylist(verticesCountArray, indices, vcount, &triangulatedIndicesCount); count = triangulatedIndicesCount; } shared_ptr <GLTFBufferView> positionBuffer = createBufferViewWithAllocatedBuffer(indices, 0, count * sizeof(unsigned int), shouldTriangulate ? true : false); shared_ptr <GLTF::GLTFIndices> positionIndices(new GLTF::GLTFIndices(positionBuffer,count)); __AppendIndices(cvtPrimitive, primitiveIndicesVector, positionIndices, POSITION, 0); if (openCOLLADAMeshPrimitive->hasNormalIndices()) { unsigned int triangulatedIndicesCount = 0; indices = openCOLLADAMeshPrimitive->getNormalIndices().getData(); if (shouldTriangulate) { indices = createTrianglesFromPolylist(verticesCountArray, indices, vcount, &triangulatedIndicesCount); count = triangulatedIndicesCount; } shared_ptr <GLTF::GLTFBufferView> normalBuffer = createBufferViewWithAllocatedBuffer(indices, 0, count * sizeof(unsigned int), shouldTriangulate ? true : false); shared_ptr <GLTF::GLTFIndices> normalIndices(new GLTF::GLTFIndices(normalBuffer, count)); __AppendIndices(cvtPrimitive, primitiveIndicesVector, normalIndices, NORMAL, 0); } if (openCOLLADAMeshPrimitive->hasColorIndices()) { COLLADAFW::IndexListArray& colorListArray = openCOLLADAMeshPrimitive->getColorIndicesArray(); for (size_t i = 0 ; i < colorListArray.getCount() ; i++) { COLLADAFW::IndexList* indexList = openCOLLADAMeshPrimitive->getColorIndices(i); __HandleIndexList(i, indexList, GLTF::COLOR, shouldTriangulate, count, vcount, verticesCountArray, cvtPrimitive, primitiveIndicesVector); } } if (openCOLLADAMeshPrimitive->hasUVCoordIndices()) { COLLADAFW::IndexListArray& uvListArray = openCOLLADAMeshPrimitive->getUVCoordIndicesArray(); for (size_t i = 0 ; i < uvListArray.getCount() ; i++) { COLLADAFW::IndexList* indexList = openCOLLADAMeshPrimitive->getUVCoordIndices(i); __HandleIndexList(i, indexList, GLTF::TEXCOORD, shouldTriangulate, count, vcount, verticesCountArray, cvtPrimitive, primitiveIndicesVector); } } if (verticesCountArray) { free(verticesCountArray); } return cvtPrimitive; }