void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement<double>* o) { obj_stream << "g " << o->unique_id() << "\n"; obj_stream << "s 1" << "\n"; const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry(); const int vcount = (int)mesh.verts().size() / 3; for ( std::vector<double>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) { const double x = *(it++); const double y = *(it++); const double z = *(it++); obj_stream << "v " << x << " " << y << " " << z << "\n"; } for ( std::vector<double>::const_iterator it = mesh.normals().begin(); it != mesh.normals().end(); ) { const double x = *(it++); const double y = *(it++); const double z = *(it++); obj_stream << "vn " << x << " " << y << " " << z << "\n"; } int previous_material_id = -2; std::vector<int>::const_iterator material_it = mesh.material_ids().begin(); for ( std::vector<int>::const_iterator it = mesh.faces().begin(); it != mesh.faces().end(); ) { const int material_id = *(material_it++); if (material_id != previous_material_id) { const IfcGeom::Material& material = mesh.materials()[material_id]; const std::string material_name = material.name(); obj_stream << "usemtl " << material_name << "\n"; if (materials.find(material_name) == materials.end()) { writeMaterial(material); materials.insert(material_name); } previous_material_id = material_id; } const int v1 = *(it++)+vcount_total; const int v2 = *(it++)+vcount_total; const int v3 = *(it++)+vcount_total; obj_stream << "f " << v1 << "//" << v1 << " " << v2 << "//" << v2 << " " << v3 << "//" << v3 << "\n"; } std::set<int> faces_set (mesh.faces().begin(), mesh.faces().end()); const std::vector<int>& edges = mesh.edges(); for ( std::vector<int>::const_iterator it = edges.begin(); it != edges.end(); ) { const int i1 = *(it++); const int i2 = *(it++); if (faces_set.find(i1) != faces_set.end() || faces_set.find(i2) != faces_set.end()) { continue; } const int material_id = *(material_it++); if (material_id != previous_material_id) { const IfcGeom::Material& material = mesh.materials()[material_id]; const std::string material_name = material.name(); obj_stream << "usemtl " << material_name << "\n"; if (materials.find(material_name) == materials.end()) { writeMaterial(material); materials.insert(material_name); } previous_material_id = material_id; } const int v1 = i1 + vcount_total; const int v2 = i2 + vcount_total; obj_stream << "l " << v1 << " " << v2 << "\n"; } vcount_total += vcount; }
void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::string mesh_id, const std::string& default_material_name, const std::vector<double>& positions, const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int> material_ids, const std::vector<IfcGeom::Material>& materials) { openMesh(mesh_id); // The normals vector can be empty for example when the WELD_VERTICES setting is used. // IfcOpenShell does not provide them with multiple face normals collapsed into a single vertex. const bool has_normals = !normals.empty(); addFloatSource(mesh_id, COLLADASW::LibraryGeometries::POSITIONS_SOURCE_ID_SUFFIX, positions); if (has_normals) { addFloatSource(mesh_id, COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, normals); } COLLADASW::VerticesElement vertices(mSW); vertices.setId(mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX ); vertices.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::POSITION, "#" + mesh_id + COLLADASW::LibraryGeometries::POSITIONS_SOURCE_ID_SUFFIX)); vertices.add(); std::vector<int>::const_iterator index_range_start = faces.begin(); std::vector<int>::const_iterator material_it = material_ids.begin(); int previous_material_id = -1; for (std::vector<int>::const_iterator it = faces.begin(); !faces.empty(); it += 3) { const int current_material_id = *(material_it++); const unsigned long num_triangles = (unsigned long)std::distance(index_range_start, it) / 3; if ((previous_material_id != current_material_id && num_triangles > 0) || (it == faces.end())) { COLLADASW::Triangles triangles(mSW); triangles.setMaterial(materials[previous_material_id].name()); triangles.setCount(num_triangles); int offset = 0; triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX,"#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset++ ) ); if (has_normals) { triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::NORMAL,"#" + mesh_id + COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, offset++ ) ); } triangles.prepareToAppendValues(); for (std::vector<int>::const_iterator jt = index_range_start; jt != it; ++jt) { const int idx = *jt; if (has_normals) { triangles.appendValues(idx, idx); } else { triangles.appendValues(idx); } } triangles.finish(); index_range_start = it; } previous_material_id = current_material_id; if (it == faces.end()) { break; } } std::set<int> faces_set (faces.begin(), faces.end()); typedef std::vector< std::pair<int, std::vector<unsigned long> > > linelist_t; linelist_t linelist; int num_lines = 0; for ( std::vector<int>::const_iterator it = edges.begin(); it != edges.end(); ++num_lines) { const int i1 = *(it++); const int i2 = *(it++); if (faces_set.find(i1) != faces_set.end() || faces_set.find(i2) != faces_set.end()) { continue; } const int current_material_id = *(material_it++); if ((previous_material_id != current_material_id) || (num_lines == 0)) { linelist.resize(linelist.size() + 1); } linelist.rbegin()->second.push_back(i1); linelist.rbegin()->second.push_back(i2); } for (linelist_t::const_iterator it = linelist.begin(); it != linelist.end(); ++it) { COLLADASW::Lines lines(mSW); lines.setMaterial(materials[it->first].name()); lines.setCount((unsigned long)it->second.size()); int offset = 0; lines.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX, "#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, 0)); lines.prepareToAppendValues(); lines.appendValues(it->second); lines.finish(); } closeMesh(); closeGeometry(); }
void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement<real_t>* o) { const std::string name = (settings().get(IfcGeom::IteratorSettings::USE_ELEMENT_GUIDS) ? o->guid() : (settings().get(IfcGeom::IteratorSettings::USE_ELEMENT_NAMES) ? o->name() : o->unique_id())); obj_stream << "g " << name << "\n"; obj_stream << "s 1" << "\n"; const IfcGeom::Representation::Triangulation<real_t>& mesh = o->geometry(); const int vcount = (int)mesh.verts().size() / 3; for ( std::vector<real_t>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) { const real_t x = *(it++) + (real_t)settings().offset[0]; const real_t y = *(it++) + (real_t)settings().offset[1]; const real_t z = *(it++) + (real_t)settings().offset[2]; obj_stream << "v " << x << " " << y << " " << z << "\n"; } for ( std::vector<real_t>::const_iterator it = mesh.normals().begin(); it != mesh.normals().end(); ) { const real_t x = *(it++); const real_t y = *(it++); const real_t z = *(it++); obj_stream << "vn " << x << " " << y << " " << z << "\n"; } for (std::vector<real_t>::const_iterator it = mesh.uvs().begin(); it != mesh.uvs().end();) { const real_t u = *it++; const real_t v = *it++; obj_stream << "vt " << u << " " << v << "\n"; } int previous_material_id = -2; std::vector<int>::const_iterator material_it = mesh.material_ids().begin(); const bool has_uvs = !mesh.uvs().empty(); for ( std::vector<int>::const_iterator it = mesh.faces().begin(); it != mesh.faces().end(); ) { const int material_id = *(material_it++); if (material_id != previous_material_id) { const IfcGeom::Material& material = mesh.materials()[material_id]; std::string material_name = (settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) ? material.original_name() : material.name()); IfcUtil::sanitate_material_name(material_name); obj_stream << "usemtl " << material_name << "\n"; if (materials.find(material_name) == materials.end()) { writeMaterial(material); materials.insert(material_name); } previous_material_id = material_id; } const int v1 = *(it++)+vcount_total; const int v2 = *(it++)+vcount_total; const int v3 = *(it++)+vcount_total; obj_stream << "f " << v1 << "/" << (has_uvs ? boost::lexical_cast<std::string>(v1) : "") << "/" << v1 << " " << v2 << "/" << (has_uvs ? boost::lexical_cast<std::string>(v2) : "") << "/" << v2 << " " << v3 << "/" << (has_uvs ? boost::lexical_cast<std::string>(v3) : "") << "/" << v3 << "\n"; } std::set<int> faces_set (mesh.faces().begin(), mesh.faces().end()); const std::vector<int>& edges = mesh.edges(); for ( std::vector<int>::const_iterator it = edges.begin(); it != edges.end(); ) { const int i1 = *(it++); const int i2 = *(it++); if (faces_set.find(i1) != faces_set.end() || faces_set.find(i2) != faces_set.end()) { continue; } const int material_id = *(material_it++); if (material_id != previous_material_id) { const IfcGeom::Material& material = mesh.materials()[material_id]; std::string material_name = (settings().get(IfcGeom::IteratorSettings::USE_MATERIAL_NAMES) ? material.original_name() : material.name()); IfcUtil::sanitate_material_name(material_name); obj_stream << "usemtl " << material_name << "\n"; if (materials.find(material_name) == materials.end()) { writeMaterial(material); materials.insert(material_name); } previous_material_id = material_id; } const int v1 = i1 + vcount_total; const int v2 = i2 + vcount_total; obj_stream << "l " << v1 << " " << v2 << "\n"; } vcount_total += vcount; }