25 fprintf(fp,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
26 fprintf(fp,
"<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.3//EN\" "
27 "\"http://www.web3d.org/specifications/x3d-3.3.dtd\">\n");
28 fprintf(fp,
"<X3D profile='Interchange' version='3.3' "
29 "xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' >\n");
30 fprintf(fp,
" <head>\n");
31 fprintf(fp,
" <meta name='creator' content='gmsh'/> \n");
32 for(
auto it = metadata.begin(); it != metadata.end(); ++it) {
33 fprintf(fp,
" <meta name='metadata_%s' content='%s'/> \n",
37 fprintf(fp,
" </head>\n");
38 fprintf(fp,
" <Scene>\n");
43 fprintf(fp,
" </Scene>\n");
44 fprintf(fp,
"</X3D>\n");
49 fprintf(fp,
"<!DOCTYPE HTML\n>");
50 fprintf(fp,
"<html lang=\"en\"> \n");
51 fprintf(fp,
"<head>\n");
52 fprintf(fp,
" <title> gmsh x3d render</title>\n");
53 fprintf(fp,
" <meta charset=\"utf-8\">\n");
54 fprintf(fp,
" <link rel=\"stylesheet\" type=\"text/css\" "
55 "href=\"https://x3dom.org/release/x3dom.css\">\n");
57 " <script src=\"https://x3dom.org/release/x3dom.js\"></script>\n");
58 fprintf(fp,
" <style>\n");
59 fprintf(fp,
" body {\n");
60 fprintf(fp,
" background: #ced7de;\n");
61 fprintf(fp,
" margin: 0px;\n");
62 fprintf(fp,
" overflow: hidden;\n");
64 fprintf(fp,
" a {\n");
65 fprintf(fp,
" color: #f7941e;\n");
66 fprintf(fp,
" text-decoration: none;\n");
68 fprintf(fp,
" a:hover {\n");
69 fprintf(fp,
" color: #ffffff;\n");
71 fprintf(fp,
" </style>\n");
72 fprintf(fp,
"</head>\n");
77 fprintf(fp,
"<body>\n");
78 fprintf(fp,
" <x3d id=\"gmsh-scene\" style=\"width: 100%%; height: "
79 "100%%;border: none\" >\n");
80 fprintf(fp,
" <Scene>\n");
81 fprintf(fp,
" <transform scale=\"1,1,1\">\n");
84 " <transform id=\"plane_axis\" rotation=\"1 0 0 -1.57079632679\">\n");
88 "url=\"https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/"
89 "plane.x3d\" mapDEFToID=\"true\" namespaceName=\"plane\"></inline>\n");
90 fprintf(fp,
" <inline "
91 "url=\"https://rawcdn.githack.com/x3dom/component-editor/master/"
92 "static/x3d/axesSmall.x3d\" mapDEFToID=\"true\" "
93 "namespaceName=\"axesSmall\"></inline>\n");
94 fprintf(fp,
" </transform>\n");
98 "url=\"https://rawcdn.githack.com/x3dom/component-editor/master/static/x3d/"
99 "axes.x3d\" mapDEFToID=\"true\" namespaceName=\"axes\"></inline>\n");
100 fprintf(fp,
" </transform>\n");
103 " <transform id=\"components\" rotation=\"1 0 0 -1.57079632679\">\n");
104 for(
auto it = x3dfiles.begin(); it != x3dfiles.end(); ++it) {
107 std::string x3dname = split[1] + split[2];
110 " <inline onload=\"fit()\" mapDEFToID=\"true\" url=%s></inline>\n",
113 fprintf(fp,
" </transform>\n");
114 fprintf(fp,
" </Scene>\n");
115 fprintf(fp,
" </x3d>\n");
116 fprintf(fp,
" <script>\n");
117 fprintf(fp,
" function fit()\n");
119 fprintf(fp,
" var x3dElem = document.getElementById('gmsh-scene');\n");
120 fprintf(fp,
" x3dElem.runtime.fitAll();\n");
122 fprintf(fp,
" </script>\n");
123 fprintf(fp,
"</body>\n");
124 fprintf(fp,
"</html>\n");
128 bool useIndexedSet,
double scalingFactor,
129 const std::string &name,
bool useColor,
130 std::vector<unsigned int> &colors)
132 bool useGeoSTL =
false;
133 unsigned int nfacets = 0;
134 for(
auto it =
faces.begin(); it !=
faces.end(); ++it) {
135 nfacets += (*it)->triangles.size() + 2 * (*it)->quadrangles.size();
140 for(
auto it =
faces.begin(); it !=
faces.end(); ++it) {
141 (*it)->buildSTLTriangulation();
142 nfacets += (*it)->stl_triangles.size() / 3;
147 fprintf(fp,
" <Shape DEF=\"%s\">\n", name.c_str());
149 fp,
" <Appearance><Material DEF=\"mat%s\"></Material></Appearance>\n",
153 if(colors.size() == 1) {
154 unsigned int cvalue = colors[0];
159 fprintf(fp,
" <Shape DEF=\"%s\">\n", name.c_str());
161 " <Appearance><Material DEF=\"mat%s\" diffuseColor=\"%s %s "
162 "%s\" shininess=\"0.9\" specularColor=\"0.2 0.2 0.2\" "
163 "transparency=\"0\"></Material></Appearance>\n",
164 name.c_str(), std::to_string(r).c_str(),
165 std::to_string(g).c_str(), std::to_string(b).c_str());
176 fprintf(fp,
" <IndexedTriangleSet DEF=\"set%s\" index=\"\n",
178 for(
auto it =
faces.begin(); it !=
faces.end(); ++it) {
179 if((*it)->stl_triangles.size()) {
180 for(std::size_t i = 0; i < (*it)->stl_triangles.size(); i++) {
181 fprintf(fp,
"%d ", (*it)->stl_triangles[i]);
186 fprintf(fp,
"\">\n");
188 fprintf(fp,
" <Coordinate point=\"\n");
189 for(
auto it =
faces.begin(); it !=
faces.end(); ++it) {
190 if((*it)->stl_vertices_uv.size()) {
191 for(std::size_t i = 0; i < (*it)->stl_vertices_uv.size(); i++) {
192 SPoint2 &p((*it)->stl_vertices_uv[i]);
193 GPoint gp = (*it)->point(p);
195 fprintf(fp,
"%g %g %g\n", gp.
x() * scalingFactor,
196 gp.
y() * scalingFactor, gp.
z() * scalingFactor);
203 fprintf(fp,
"\"></Coordinate>\n");
205 fprintf(fp,
" <Normal vector=\"\n");
206 for(
auto it =
faces.begin(); it !=
faces.end(); ++it) {
207 if((*it)->stl_normals.size()) {
208 for(std::size_t i = 0; i < (*it)->stl_normals.size(); i++) {
210 fprintf(fp,
"%g %g %g\n", n.
x(), n.
y(), n.
z());
217 fprintf(fp,
"\"></Normal>\n");
219 fprintf(fp,
" </IndexedTriangleSet>\n");
224 fprintf(fp,
" <TriangleSet DEF=\"set%s\">\n", name.c_str());
226 fprintf(fp,
" <Coordinate point=\"\n");
227 for(
auto it =
faces.begin(); it !=
faces.end(); ++it) {
228 if((*it)->stl_vertices_uv.size()) {
229 for(std::size_t i = 0; i < (*it)->stl_triangles.size(); i += 3) {
230 SPoint2 &p1((*it)->stl_vertices_uv[(*it)->stl_triangles[i]]);
231 SPoint2 &p2((*it)->stl_vertices_uv[(*it)->stl_triangles[i + 1]]);
232 SPoint2 &p3((*it)->stl_vertices_uv[(*it)->stl_triangles[i + 2]]);
233 GPoint gp1 = (*it)->point(p1);
234 GPoint gp2 = (*it)->point(p2);
235 GPoint gp3 = (*it)->point(p3);
236 double x[3] = {gp1.
x(), gp2.
x(), gp3.
x()};
237 double y[3] = {gp1.
y(), gp2.
y(), gp3.
y()};
238 double z[3] = {gp1.
z(), gp2.
z(), gp3.
z()};
240 for(
int j = 0; j < 3; j++) {
241 fprintf(fp,
"%g %g %g\n", x[j] * scalingFactor,
242 y[j] * scalingFactor,
z[j] * scalingFactor);
250 fprintf(fp,
"\"></Coordinate>\n");
252 fprintf(fp,
" <Normal vector=\"\n");
253 for(
auto it =
faces.begin(); it !=
faces.end(); ++it) {
254 if((*it)->stl_normals.size()) {
255 for(std::size_t i = 0; i < (*it)->stl_triangles.size(); i++) {
256 SVector3 &n((*it)->stl_normals[(*it)->stl_triangles[i]]);
257 fprintf(fp,
"%g %g %g\n", n.
x(), n.
y(), n.
z());
264 fprintf(fp,
"\"></Normal>\n");
266 fprintf(fp,
" </TriangleSet>\n");
270 fprintf(fp,
" <TriangleSet DEF=\"set%s\">\n", name.c_str());
271 fprintf(fp,
" <Coordinate point=\"\n");
272 for(
auto it =
faces.begin(); it !=
faces.end(); ++it) {
273 for(std::size_t i = 0; i < (*it)->triangles.size(); i++)
274 (*it)->triangles[i]->writeX3D(fp, scalingFactor);
275 for(std::size_t i = 0; i < (*it)->quadrangles.size(); i++)
276 (*it)->quadrangles[i]->writeX3D(fp, scalingFactor);
278 fprintf(fp,
"\"></Coordinate>\n");
279 fprintf(fp,
" </TriangleSet>\n");
282 fprintf(fp,
" </Shape>\n");
286 double scalingFactor,
const std::string &name)
288 for(
auto it =
edges.begin(); it !=
edges.end(); ++it) {
289 if((*it)->stl_vertices_xyz.size()) {
290 fprintf(fp,
" <Shape DEF=\"%s\">\n", name.c_str());
292 " <Appearance><Material "
293 "DEF=\"mat%s\"></Material><LineProperties "
294 "id=\"prop%s\"></LineProperties></Appearance>\n",
295 name.c_str(), name.c_str());
296 fprintf(fp,
" <LineSet vertexCount=\"%ld\">\n",
297 (*it)->stl_vertices_xyz.size());
298 fprintf(fp,
" <Coordinate point=\"\n");
299 for(std::size_t i = 0; i < (*it)->stl_vertices_xyz.size(); i++) {
300 SPoint3 &p((*it)->stl_vertices_xyz[i]);
302 fprintf(fp,
"%g %g %g\n", p.
x() * scalingFactor, p.
y() * scalingFactor,
303 p.
z() * scalingFactor);
305 fprintf(fp,
"\"/>\n");
306 fprintf(fp,
" </LineSet>\n");
307 fprintf(fp,
" </Shape>\n");
316 int x3dsurfaces,
int x3dedges,
int x3dvertices,
317 int x3dcolorize, std::vector<GFace *> &customFaces)
321 std::vector<GFace *> modelFaces;
322 if(customFaces.size() > 0) {
323 for(
auto it = customFaces.begin(); it != customFaces.end(); ++it) {
324 modelFaces.push_back(*it);
329 modelFaces.push_back(*it);
333 if(x3dsurfaces != 0) {
334 fprintf(fp,
" <Group DEF=\"faces\">\n");
335 if(x3dsurfaces == 1) {
337 std::vector<GFace *>
faces;
338 std::vector<unsigned int> colors;
340 for(
auto it = modelFaces.begin(); it != modelFaces.end(); ++it) {
341 if(saveAll || (*it)->physicals.size()) {
faces.push_back(*it); }
343 std::string name =
"face";
346 else if(x3dsurfaces == 2) {
349 for(
auto it = modelFaces.begin(); it != modelFaces.end(); ++it) {
350 if(saveAll || (*it)->physicals.size()) {
351 std::vector<GFace *>
faces(1, *it);
352 std::vector<unsigned int> colors;
355 unsigned int cvalue = (*it)->getColor();
356 colors.push_back(cvalue);
358 std::ostringstream s;
359 s <<
"face" << (*it)->tag();
362 bool useColor = x3dcolorize == 1;
367 else if(x3dsurfaces == 3) {
369 std::map<int, std::vector<GEntity *> > phys;
370 std::vector<unsigned int> colors;
372 for(
auto it = phys.begin(); it != phys.end(); it++) {
373 std::vector<GFace *>
faces;
374 for(std::size_t i = 0; i < it->second.size(); i++) {
375 faces.push_back(
static_cast<GFace *
>(it->second[i]));
379 std::ostringstream s;
380 s <<
"physicalsurface" << it->first;
387 fprintf(fp,
" </Group>\n");
392 fprintf(fp,
" <Group DEF=\"edges\">\n");
395 std::vector<GEdge *>
edges;
397 if(saveAll || (*it)->physicals.size()) {
edges.push_back(*it); }
399 std::string name =
"edge";
402 else if(x3dedges == 2) {
405 if(saveAll || (*it)->physicals.size()) {
406 std::vector<GEdge *>
edges(1, *it);
409 std::ostringstream s;
410 s <<
"edge" << (*it)->tag();
417 else if(x3dedges == 3) {
419 std::map<int, std::vector<GEntity *> > phys;
421 for(
auto it = phys.begin(); it != phys.end(); it++) {
422 std::vector<GEdge *>
edges;
423 for(std::size_t i = 0; i < it->second.size(); i++) {
424 edges.push_back(
static_cast<GEdge *
>(it->second[i]));
428 std::ostringstream s;
429 s <<
"physicaledge" << it->first;
435 fprintf(fp,
" </Group>\n");
439 if(x3dvertices != 0) {
440 fprintf(fp,
" <Group DEF=\"vertices\" render=\"false\">\n");
443 fprintf(fp,
" <Transform DEF=\"vertex%d\" translation=\"%g %g %g\">\n",
444 (*it)->tag(), (*it)->x(), (*it)->y(), (*it)->z());
445 fprintf(fp,
" <Shape>\n");
447 " <Appearance><Material "
448 "DEF=\"matvertex%d\"></Material></Appearance>\n",
450 fprintf(fp,
" <Sphere></Sphere>\n");
451 fprintf(fp,
" </Shape>\n");
452 fprintf(fp,
" </Transform>\n");
454 fprintf(fp,
" </Group>\n");
462 std::string new_name = split[1] +
"_" + std::to_string(tag);
463 return split[0] + new_name + split[2];
469 return split[0] +
"index.html";
473 double scalingFactor,
int x3dsurfaces,
int x3dedges,
474 int x3dvertices,
int x3dvolumes,
int x3dcolorize)
477 std::vector<std::string> metadata;
478 std::vector<std::string> x3dfiles;
479 if(x3dsurfaces == 0 && x3dedges == 0 && x3dvertices == 0) {
480 Msg::Info(
"no surfaces, edges or vertices to write into '%s'",
485 std::vector<GFace *>
faces;
486 if(x3dvolumes == 1) {
487 Msg::Info(
"separating volumes into separate files");
488 std::vector<GEntity *> volumes;
492 if(volumes.size() > 0) {
493 for(
auto it = volumes.begin(); it != volumes.end(); ++it) {
494 faces = (*it)->bindingsGetFaces();
496 metadata.push_back(_vol_name);
497 std::string _filename =
TagFileName(name, (*it)->tag());
498 x3dfiles.push_back(_filename);
499 fp =
Fopen(_filename.c_str(),
"w");
505 _writeX3dFile(fp, saveAll, scalingFactor, x3dsurfaces, x3dedges,
506 x3dvertices, x3dcolorize,
faces);
513 fp =
Fopen(_htmlname.c_str(),
"w");
522 x3dfiles.push_back(name);
523 fp =
Fopen(name.c_str(),
"w");
530 _writeX3dFile(fp, saveAll, scalingFactor, x3dsurfaces, x3dedges, x3dvertices,
536 fp =
Fopen(_htmlname.c_str(),
"w");