void processCoordinates() { const Index nCoord = m_coord->getNumCoords(); m_vertexMap.resize(nCoord); auto vertexMap = m_vertexMap.data(); #pragma omp parallel for for (ssize_t i=0; i<nCoord; ++i) { const Vector p(x[i], y[i], z[i]); vertexMap[i] = m_decider(i) > 0 ? 1 : 0; } if (haveCornerList) { Index numIn = 0; for (Index i=0; i<nCoord; ++i) { if (vertexMap[i]) { numIn += vertexMap[i]; vertexMap[i] = numIn; } } m_outCoords->setSize(numIn); out_x = m_outCoords->x().data(); out_y = m_outCoords->y().data(); out_z = m_outCoords->z().data(); #pragma omp parallel for schedule(dynamic) for (ssize_t i=0; i<nCoord; ++i) { Index idx = vertexMap[i]; vassert(idx >= 0); if (idx > 0) { --idx; vassert(idx < numIn); out_x[idx] = x[i]; out_y[idx] = y[i]; out_z[idx] = z[i]; } } } }
Object::ptr ReadModel::load(const std::string &name) { Object::ptr ret; Assimp::Importer importer; bool indexed = false; unsigned int readFlags = aiProcess_PreTransformVertices|aiProcess_SortByPType|aiProcess_ImproveCacheLocality|aiProcess_OptimizeGraph|aiProcess_OptimizeMeshes; if (getIntParameter("indexed_geometry")) { readFlags |= aiProcess_JoinIdenticalVertices; indexed = true; } if (getIntParameter("triangulate")) readFlags |= aiProcess_Triangulate; const aiScene* scene = importer.ReadFile(name, readFlags); if (!scene) { if (!getIntParameter("ignore_errors")) { std::stringstream str; str << "failed to read " << name << ": " << importer.GetErrorString() << std::endl; std::string s = str.str(); sendError("%s", s.c_str()); } return ret; } for (unsigned int m=0; m<scene->mNumMeshes; ++m) { const aiMesh *mesh = scene->mMeshes[m]; if (mesh->HasPositions()) { Coords::ptr coords; if (mesh->HasFaces()) { auto numVert = mesh->mNumVertices; auto numFace = mesh->mNumFaces; if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON) { Index numIndex = 0; for (unsigned int f=0; f<numFace; ++f) { numIndex += mesh->mFaces[f].mNumIndices; } Polygons::ptr poly(new Polygons(numFace, numIndex, numVert)); coords = poly; auto *el = &poly->el()[0]; auto *cl = indexed ? &poly->cl()[0] : nullptr; Index idx=0, vertCount=0; for (unsigned int f=0; f<numFace; ++f) { el[idx++] = vertCount; if (indexed) { const auto &face = mesh->mFaces[f]; for (unsigned int i=0; i<face.mNumIndices; ++i) { cl[vertCount++] = face.mIndices[i]; } } } el[idx] = vertCount; } else if (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE) { Index numIndex = indexed ? mesh->mNumFaces*3 : 0; Triangles::ptr tri(new Triangles(numIndex, numVert)); coords = tri; if (indexed) { auto *cl = &tri->cl()[0]; Index vertCount=0; for (unsigned int f=0; f<numFace; ++f) { const auto &face = mesh->mFaces[f]; vassert(face.mNumIndices == 3); for (unsigned int i=0; i<face.mNumIndices; ++i) { cl[vertCount++] = face.mIndices[i]; } } } } } else { Points::ptr points(new Points(mesh->mNumVertices)); coords = points; } if (coords) { Scalar *x[3] = { nullptr, nullptr, nullptr }; for (int c=0; c<3; ++c) { x[c] = &coords->x(c)[0]; } for (Index i=0; i<mesh->mNumVertices; ++i) { const auto &vert = mesh->mVertices[i]; for (unsigned int c=0; c<3; ++c) { x[c][i] = vert[c]; } } ret = coords; if (mesh->HasNormals()) { Normals::ptr normals(new Normals(mesh->mNumVertices)); Scalar *n[3] = { nullptr, nullptr, nullptr }; for (int c=0; c<3; ++c) { n[c] = &normals->x(c)[0]; } for (Index i=0; i<mesh->mNumVertices; ++i) { const auto &norm = mesh->mNormals[i]; for (unsigned int c=0; c<3; ++c) { n[c][i] = norm[c]; } } coords->setNormals(normals); } } } break; } if (scene->mNumMeshes > 1) { sendInfo("file %s contains %d meshes, all but the first have been ignored", name.c_str(), scene->mNumMeshes); } return ret; }
bool process() { processCoordinates(); Index numCoordsIn = m_outCoords->getNumCoords(); if (m_tri) { const Index numElem = haveCornerList ? m_tri->getNumCorners()/3 : m_tri->getNumCoords()/3; std::vector<Index> outIdxCorner(numElem+1), outIdxCoord(numElem+1); outIdxCorner[0] = 0; outIdxCoord[0] = numCoordsIn; #pragma omp parallel for schedule (dynamic) for (ssize_t elem=0; elem<numElem; ++elem) { Index numCorner=0, numCoord=0; processTriangle(elem, numCorner, numCoord, true); outIdxCorner[elem+1] = numCorner; outIdxCoord[elem+1] = numCoord; } for (Index elem=0; elem<numElem; ++elem) { outIdxCoord[elem+1] += outIdxCoord[elem]; outIdxCorner[elem+1] += outIdxCorner[elem]; } Index numCoord = outIdxCoord[numElem]; Index numCorner = outIdxCorner[numElem]; if (haveCornerList) { m_outTri->cl().resize(numCorner); out_cl = m_outTri->cl().data(); } m_outTri->setSize(numCoord); out_x = m_outTri->x().data(); out_y = m_outTri->y().data(); out_z = m_outTri->z().data(); if (m_outData) { m_outData->x().resize(numCoord); out_d = m_outData->x().data(); } #pragma omp parallel for schedule (dynamic) for (ssize_t elem = 0; elem<numElem; ++elem) { processTriangle(elem, outIdxCorner[elem], outIdxCoord[elem], false); } //std::cerr << "CuttingSurface: << " << m_outData->x().size() << " vert, " << m_outData->x().size() << " data elements" << std::endl; return true; } else if (m_poly) { const Index numElem = m_poly->getNumElements(); std::vector<Index> outIdxPoly(numElem+1), outIdxCorner(numElem+1), outIdxCoord(numElem+1); outIdxPoly[0] = 0; outIdxCorner[0] = 0; outIdxCoord[0] = numCoordsIn; #pragma omp parallel for schedule (dynamic) for (ssize_t elem=0; elem<numElem; ++elem) { Index numPoly=0, numCorner=0, numCoord=0; processPolygon(elem, numPoly, numCorner, numCoord, true); outIdxPoly[elem+1] = numPoly; outIdxCorner[elem+1] = numCorner; outIdxCoord[elem+1] = numCoord; } for (Index elem=0; elem<numElem; ++elem) { outIdxPoly[elem+1] += outIdxPoly[elem]; outIdxCorner[elem+1] += outIdxCorner[elem]; outIdxCoord[elem+1] += outIdxCoord[elem]; } Index numPoly = outIdxPoly[numElem]; Index numCorner = outIdxCorner[numElem]; Index numCoord = outIdxCoord[numElem]; m_outPoly->el().resize(numPoly+1); out_el = m_outPoly->el().data(); out_el[numPoly] = numCorner; m_outPoly->cl().resize(numCorner); out_cl = m_outPoly->cl().data(); m_outPoly->setSize(numCoord); out_x = m_outPoly->x().data(); out_y = m_outPoly->y().data(); out_z = m_outPoly->z().data(); if (m_outData) { m_outData->x().resize(numCoord); out_d = m_outData->x().data(); } #pragma omp parallel for schedule (dynamic) for (ssize_t elem = 0; elem<numElem; ++elem) { processPolygon(elem, outIdxPoly[elem], outIdxCorner[elem], outIdxCoord[elem], false); } //std::cerr << "CuttingSurface: << " << m_outData->x().size() << " vert, " << m_outData->x().size() << " data elements" << std::endl; return true; } return true; }