| 87 | } |
| 88 | |
| 89 | void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o) |
| 90 | { |
| 91 | obj_stream.stream << "g " << object_id(o) << "\n"; |
| 92 | obj_stream.stream << "s 1" << "\n"; |
| 93 | const bool isyup = settings().get<ifcopenshell::geometry::settings::UseYUp>().get(); |
| 94 | |
| 95 | const IfcGeom::Representation::Triangulation& mesh = o->geometry(); |
| 96 | |
| 97 | size_t vcount = mesh.verts().size() / 3; |
| 98 | size_t ncount = mesh.normals().size() / 3; |
| 99 | |
| 100 | for (auto it = mesh.verts().begin(); it != mesh.verts().end();) { |
| 101 | const double x = *(it++); |
| 102 | const double y = *(it++); |
| 103 | const double z = *(it++); |
| 104 | |
| 105 | if (isyup) { |
| 106 | obj_stream.stream << "v " << x << " " << z << " " << -y << "\n"; |
| 107 | } else { |
| 108 | obj_stream.stream << "v " << x << " " << y << " " << z << "\n"; |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | for (auto it = mesh.normals().begin(); it != mesh.normals().end();) { |
| 113 | const double x = *(it++); |
| 114 | const double y = *(it++); |
| 115 | const double z = *(it++); |
| 116 | obj_stream.stream << "vn " << x << " " << y << " " << z << "\n"; |
| 117 | } |
| 118 | |
| 119 | for (auto it = mesh.uvs().begin(); it != mesh.uvs().end();) { |
| 120 | const double u = *it++; |
| 121 | const double v = *it++; |
| 122 | obj_stream.stream << "vt " << u << " " << v << "\n"; |
| 123 | } |
| 124 | |
| 125 | int previous_material_id = -2; |
| 126 | std::vector<int>::const_iterator material_it = mesh.material_ids().begin(); |
| 127 | |
| 128 | const bool has_uvs = !mesh.uvs().empty(); |
| 129 | const bool has_normals = !mesh.normals().empty(); |
| 130 | for ( std::vector<int>::const_iterator it = mesh.faces().begin(); it != mesh.faces().end(); ) { |
| 131 | |
| 132 | const int material_id = *(material_it++); |
| 133 | if (material_id != previous_material_id) { |
| 134 | const ifcopenshell::geometry::taxonomy::style::ptr material = mesh.materials()[material_id]; |
| 135 | std::string material_name = material->name; |
| 136 | IfcUtil::sanitate_material_name(material_name); |
| 137 | obj_stream.stream << "usemtl " << material_name << "\n"; |
| 138 | if (materials.find(material_name) == materials.end()) { |
| 139 | writeMaterial(material); |
| 140 | materials.insert(material_name); |
| 141 | } |
| 142 | previous_material_id = material_id; |
| 143 | } |
| 144 | |
| 145 | const int v1 = *(it++) + vcount_total; |
| 146 | const int v2 = *(it++) + vcount_total; |