/*! * Export surface tasselation in a STL format. No check is perfomed on element type * therefore tasselation containing vertex, line or quad elements will produce * ill-formed stl triangulation. * * \param[in] stl_name name of the stl file * \param[in] isBinary flag for binary (true) or ASCII (false) file * \param[in] exportInternalsOnly flag for exporting only internal cells (true), * or internal+ghost cells (false). * * \result on output returns an error flag for I/O error. */ unsigned short SurfUnstructured::exportSTL(const string &stl_name, const bool &isBinary, bool exportInternalsOnly) { // ====================================================================== // // VARIABLES DECLARATION // // ====================================================================== // // Local variables int nVertex; int nSimplex; vector<array<double, 3>> vertexList; vector<array<double, 3>> normalList; vector<vector<int>> connectivityList; unordered_map<long, long> vertexMap; // Counters int v_count ,j; vector<array<double, 3>>::iterator i_; vector<vector<int>>::iterator j_; vector<int>::iterator k_, ke_; VertexIterator v_, ve_; CellIterator c_, cb_, ce_; // ====================================================================== // // INITIALIZE DATA STRUCTURE // // ====================================================================== // nSimplex = m_nInternals; if (!exportInternalsOnly) nSimplex += m_nGhosts; vertexList.resize(getVertexCount()); normalList.resize(nSimplex); connectivityList.resize(nSimplex, vector<int>(3, 0)); // ====================================================================== // // CREATE VERTEX LIST // // ====================================================================== // i_ = vertexList.begin(); ve_ = vertexEnd(); v_count = 0; for (v_ = vertexBegin(); v_ != ve_; ++v_) { // Store vertex coordinates *i_ = v_->getCoords(); vertexMap[v_->getId()] = v_count; // Update counters ++v_count; ++i_; } //next v_ nVertex = getVertexCount(); // ====================================================================== // // CREATE CONNECTIVITY // // ====================================================================== // if (exportInternalsOnly) { cb_ = internalBegin(); ce_ = internalEnd(); } else { cb_ = cellBegin(); ce_ = cellEnd(); } i_ = normalList.begin(); j_ = connectivityList.begin(); for (c_ = cb_; c_ != ce_; ++c_) { // Build normals *i_ = std::move(evalFacetNormal(c_->getId())); // Build connectivity ke_ = j_->end(); j = 0; for (k_ = j_->begin(); k_ != ke_; ++k_) { *k_ = vertexMap[c_->getVertex(j)]; ++j; } //next k_ // Update counters ++j_; ++i_; } //next c_ // ====================================================================== // // EXPORT STL DATA // // ====================================================================== // STLObj STL(stl_name, isBinary); STL.save("", nVertex, nSimplex, vertexList, normalList, connectivityList); return 0; }
bool read(const PATH& _path, comp::TriangleMesh<SCALAR>& _mesh) { if (!STL()(_path,_mesh.triangles())) return false; _mesh.update(); return true; }
/*! * Import surface tasselation from S.T.L. file. STL facet are added at to the * present mesh, i.e. current mesh content is not discarded. Howver no checks * are performed to ensure that no duplicated vertices or cells are created. * * If the input file is a multi-solid ASCII file, all solids will be loaded * and a different PID will be assigned to the PID of the different solids. * * \param[in] stl_name name of stl file * \param[in] isBinary flag for binary (true), of ASCII (false) stl file * \param[in] PIDOffset is the offset for the PID numbering * * \result on output returns an error flag for I/O error */ unsigned short SurfUnstructured::importSTL(const string &stl_name, const bool &isBinary, int PIDOffset) { // ====================================================================== // // VARIABLES DECLARATION // // ====================================================================== // // Parameters const unordered_map<size_t, ElementInfo::Type> ele_type{ {0, ElementInfo::UNDEFINED}, {1, ElementInfo::VERTEX}, {2, ElementInfo::LINE}, {3, ElementInfo::TRIANGLE}, {4, ElementInfo::QUAD} }; // STL Object STLObj STL(stl_name, isBinary); // ====================================================================== // // OPEN STL FILE // // ====================================================================== // STL.open("in"); if (STL.err != 0) { return STL.err; } // ====================================================================== // // LOAD ALL SOLID FROM THE STL FILE // // ====================================================================== // int pid = PIDOffset - 1; while (true) { // ====================================================================== // // LOAD SOLID FROM THE STL FILE // // ====================================================================== // int nVertex = 0; int nSimplex = 0; std::vector<std::array<double, 3>> vertexList; std::vector<std::array<double, 3>> normalList; std::vector<std::vector<int>> connectivityList; STL.loadSolid(nVertex, nSimplex, vertexList, normalList, connectivityList); if (nVertex == 0) { break; } // ====================================================================== // // PID OF THE SOLID // // ====================================================================== // ++pid; // ====================================================================== // // PREPARE MESH FOR DATA IMPORT // // ====================================================================== // reserveVertices(getVertexCount() + nVertex); reserveCells(m_nInternals + m_nGhosts + nSimplex); // ====================================================================== // // ADD VERTICES TO MESH // // ====================================================================== // vector<array<double, 3>>::const_iterator v_, ve_; std::unordered_map<long, long> vertexMap; vertexMap.reserve(nVertex); long v_counter = 0; ve_ = vertexList.cend(); for (v_ = vertexList.cbegin(); v_ != ve_; ++v_) { VertexIterator i_ = addVertex(*v_); vertexMap[v_counter] = i_->getId(); ++v_counter; } //next v_ // ====================================================================== // // ADD CELLS TO MESH // // ====================================================================== // vector<vector<int>>::const_iterator c_, ce_; vector<int>::const_iterator w_, we_; ce_ = connectivityList.cend(); for (c_ = connectivityList.cbegin(); c_ != ce_; ++c_) { // Remap STL connectivity int n_v = c_->size(); std::vector<long> connect(n_v, Vertex::NULL_ID); we_ = c_->cend(); int i = 0; for (w_ = c_->cbegin(); w_ < we_; ++w_) { connect[i] = vertexMap[*w_]; ++i; } //next w_ // Add cell CellIterator cellIterator = addCell(ele_type.at(n_v), true, connect); cellIterator->setPID(pid); } //next c_ // ====================================================================== // // Multi-body STL files are supported only in ASCII mode // // ====================================================================== // if (isBinary) { break; } } // ====================================================================== // // CLOSE STL FILE // // ====================================================================== // STL.close("in"); return 0; }