OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
MeshGenerator.cpp
Go to the documentation of this file.
2 #include "Physics/Physics.h"
3 #include "Utilities/Util.h"
4 #include "AbsBeamline/Bend2D.h"
5 #include "AbsBeamline/RBend3D.h"
7 
8 #include <iostream>
9 #include <fstream>
10 
11 extern Inform *gmsg;
12 
14  elements_m()
15 { }
16 
17 void MeshGenerator::add(const ElementBase &element) {
18  double start = 0.0;
19 
20  MeshData mesh;
21  if (element.getType() == ElementBase::SBEND ||
22  element.getType() == ElementBase::RBEND) {
23 
24  const Bend2D* dipole = static_cast<const Bend2D*>(&element);
25  mesh = dipole->getSurfaceMesh();
26  mesh.type_m = DIPOLE;
27  } else if (element.getType() == ElementBase::RBEND3D) {
28  const RBend3D* dipole = static_cast<const RBend3D*>(&element);
29  mesh = dipole->getSurfaceMesh();
30  mesh.type_m = DIPOLE;
31  } else if (element.getType() == ElementBase::DRIFT) {
32  return;
33  } else {
34  double end, length;
35  element.getElementDimensions(start, end);
36  length = end - start;
37  auto apert = element.getAperture();
38 
39  switch (apert.first) {
42  mesh = getBox(length, apert.second[0], apert.second[1], apert.second[2]);
43  break;
46  mesh = getCylinder(length, apert.second[0], apert.second[1], apert.second[2]);
47  break;
48  default:
49  return;
50  }
51 
52  switch(element.getType()) {
54  switch(static_cast<const Multipole*>(&element)->getMaxNormalComponentIndex()) {
55  case 1:
56  mesh.type_m = DIPOLE;
57  break;
58  case 2:
59  mesh.type_m = QUADRUPOLE;
60  break;
61  case 3:
62  mesh.type_m = SEXTUPOLE;
63  break;
64  case 4:
65  mesh.type_m = OCTUPOLE;
66  break;
67  default:
68  break;
69  }
70  break;
74  mesh.type_m = RFCAVITY;
75  break;
77  mesh.type_m = SOLENOID;
78  break;
79  default:
80  mesh.type_m = OTHER;
81  }
82  }
83 
85  Vector_t z = trafo.rotateTo(Vector_t(0, 0, 1));
86  for (unsigned int i = 0; i < mesh.vertices_m.size(); ++ i) {
87  mesh.vertices_m[i] = trafo.transformTo(mesh.vertices_m[i]) + start * z;
88  }
89 
90  for (unsigned int i = 0; i < mesh.decorations_m.size(); ++ i) {
91  mesh.decorations_m[i].first = trafo.transformTo(mesh.decorations_m[i].first) + start * z;
92  mesh.decorations_m[i].second = trafo.transformTo(mesh.decorations_m[i].second) + start * z;
93  }
94 
95  elements_m.push_back(mesh);
96 }
97 
98 #include <boost/iostreams/filtering_streambuf.hpp>
99 #include <boost/iostreams/copy.hpp>
100 #include <boost/iostreams/filter/zlib.hpp>
101 
102 void MeshGenerator::write(const std::string &fname) {
103  std::ofstream out("data/" + fname + "_ElementPositions.py");
104  const char *buffer;
105  const std::string indent(" ");
106 
107  out << std::fixed << std::setprecision(6);
108 
109  out << "import os, sys, argparse, math, base64, zlib, struct\n\n";
110  out << "if sys.version_info < (3,0):\n";
111  out << " range = xrange\n\n";
112 
113  std::stringstream vertices_ascii;
114  std::ostringstream vertices_compressed;
115  out << "vertices = []\n";
116  out << "numVertices = [";
117  for (auto &element: elements_m) {
118  auto &vertices = element.vertices_m;
119  out << vertices.size() << ", ";
120  for (unsigned int i = 0; i < vertices.size(); ++ i) {
121  buffer = reinterpret_cast<const char*>(&(vertices[i](0)));
122  vertices_ascii.write(buffer, 3 * sizeof(double));
123  }
124  }
125  out.seekp(-2, std::ios_base::end);
126  out << "]\n";
127 
128  {
129  boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
130  in.push(boost::iostreams::zlib_compressor());
131  in.push(vertices_ascii);
132  boost::iostreams::copy(in, vertices_compressed);
133  }
134 
135  std::string vertices_base64 = Util::base64_encode(vertices_compressed.str());
136  out << "vertices_base64 = \"" << vertices_base64 << "\"\n";
137  out << "triangles = [";
138  for (auto &element: elements_m) {
139  out << "[ ";
140  auto &triangles = element.triangles_m;
141  for (unsigned int i = 0; i < triangles.size(); ++ i) {
142  out << triangles[i](0) << ", " << triangles[i](1) << ", " << triangles[i](2) << ", ";
143  }
144  out.seekp(-2, std::ios_base::end);
145  out << "], ";
146  }
147  out.seekp(-2, std::ios_base::end);
148  out << "]\n";
149 
150 
151  out << "decoration = [";
152  for (auto &element: elements_m) {
153  out << "[ ";
154  for (auto &decoration: element.decorations_m) {
155  out << (decoration.first)(0) << ", " << (decoration.first)(1) << ", " << (decoration.first)(2) << ", "
156  << (decoration.second)(0) << ", " << (decoration.second)(1) << ", " << (decoration.second)(2) << ", ";
157  }
158  if (element.decorations_m.size() > 0)
159  out.seekp(-2, std::ios_base::end);
160  out << "], ";
161  }
162  if (elements_m.size() > 0)
163  out.seekp(-2, std::ios_base::end);
164  out << "]\n\n";
165 
166  out << "color = [";
167  for (auto &element: elements_m) {
168  out << element.type_m << ", ";
169  }
170  out.seekp(-2, std::ios_base::end);
171  out << "]\n\n";
172 
173  std::stringstream index_ascii;
174  std::ostringstream index_compressed;
175  index_ascii << "<!DOCTYPE html>\n"
176  << "<html>\n"
177  << " <head>\n"
178  << " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
179  << "\n"
180  << " <title>Babylon.js sample code</title>\n"
181  << " <!-- Babylon.js -->\n"
182  << " <script src=\"http://cdn.babylonjs.com/hand.minified-1.2.js\"></script>\n"
183  << " <script src=\"http://cdn.babylonjs.com/cannon.js\"></script>\n"
184  << " <script src=\"http://cdn.babylonjs.com/oimo.js\"></script>\n"
185  << " <script src=\"http://cdn.babylonjs.com/babylon.js\"></script>\n"
186  << " <style>\n"
187  << " html, body {\n"
188  << " overflow: hidden;\n"
189  << " width: 100%;\n"
190  << " height: 100%;\n"
191  << " margin: 0;\n"
192  << " padding: 0;\n"
193  << " }\n"
194  << "\n"
195  << " #renderCanvas {\n"
196  << " width: 100%;\n"
197  << " height: 100%;\n"
198  << " touch-action: none;\n"
199  << " }\n"
200  << " </style>\n"
201  << " </head>\n"
202  << "<body>\n"
203  << " <canvas id=\"renderCanvas\"></canvas>\n"
204  << " <script>\n"
205  << " var canvas = document.getElementById(\"renderCanvas\");\n"
206  << " var engine = new BABYLON.Engine(canvas, true);\n"
207  << "\n"
208  << " var createScene = function () {\n"
209  << " var scene = new BABYLON.Scene(engine);\n"
210  << "\n"
211  << " //Adding a light\n"
212  << " var light = new BABYLON.PointLight(\"Omni\", new BABYLON.Vector3(0, -100, 0), scene);\n"
213  << " //light.diffuse = new BABYLON.Color3(0.8, 0.8, 0.8);\n"
214  << " light.specular = new BABYLON.Color3(0.1, 0.1, 0.1);\n"
215  << " //light.groundColor = new BABYLON.Color3(0, 0, 0);\n"
216  << "\n"
217  << " //Adding an Arc Rotate Camera\n"
218  << " var camera = new BABYLON.ArcRotateCamera(\"Camera\", 0.0, Math.PI, 50, BABYLON.Vector3.Zero(), scene);\n"
219  << " camera.attachControl(canvas, false);\n"
220  << " camera.wheelPrecision = 20;\n"
221  << "\n"
222  << " var mymesh = ##DATA##;\n"
223  << " // The first parameter can be used to specify which mesh to import. Here we import all meshes\n"
224  << " BABYLON.SceneLoader.ImportMesh(\"\", \"\", mymesh, scene, function (newMeshes) {\n"
225  << " // Set the target of the camera to the first imported mesh\n"
226  << " camera.target = newMeshes[0];\n"
227  << "\n"
228  << " var material1 = new BABYLON.StandardMaterial(\"texture1\", scene);\n"
229  << " //material1.wireframe = true;\n"
230  << " newMeshes[0].material = material1;\n"
231  << " newMeshes[0].material.emissiveColor = new BABYLON.Color3(0.2, 0.2, 0.2);\n"
232  << " });\n"
233  << "\n"
234  << " return scene;\n"
235  << " }\n"
236  << "\n"
237  << "\n"
238  << " var scene = createScene();\n"
239  << "\n"
240  << " engine.runRenderLoop(function () {\n"
241  << " scene.render();\n"
242  << " });\n"
243  << "\n"
244  << " // Resize\n"
245  << " window.addEventListener(\"resize\", function () {\n"
246  << " engine.resize();\n"
247  << " });\n"
248  << " </script>\n"
249  << "</body>\n"
250  << "</html>";
251  {
252  boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
253  in.push(boost::iostreams::zlib_compressor());
254  in.push(index_ascii);
255  boost::iostreams::copy(in, index_compressed);
256  }
257 
258  out << "index_base64 = '" << Util::base64_encode(index_compressed.str()) << "'\n\n";
259 
260  out << "def decodeVertices():\n";
261  out << indent << "vertices_binary = zlib.decompress(base64.b64decode(vertices_base64))\n";
262  out << indent << "k = 0\n";
263  out << indent << "for i in range(len(numVertices)):\n";
264  out << indent << indent << "current = []\n";
265  out << indent << indent << "for j in range(numVertices[i] * 3):\n";
266  out << indent << indent << indent << "current.append(float(struct.unpack('=d', vertices_binary[k:k+8])[0]))\n";
267  out << indent << indent << indent << "k += 8\n";
268  out << indent << indent << "vertices.append(current)\n\n";
269 
270  out << "def dot(a, b):\n";
271  out << indent << "return sum(a[i]*b[i] for i in range(len(a)))\n\n";
272 
273  out << "def normalize(a):\n";
274  out << indent << "length = math.sqrt(dot(a, a))\n";
275  out << indent << "for i in range(3):\n";
276  out << indent << indent << "a[i]/=length\n";
277  out << indent << "return a\n\n";
278 
279  out << "def distance(a, b):\n";
280  out << indent << "c = [0] * 2\n";
281  out << indent << "for i in range(len(a)):\n";
282  out << indent << indent << "c[i] = a[i] - b[i]\n";
283  out << indent << "return math.sqrt(dot(c, c))\n\n";
284 
285  out << "def cross(a, b):\n";
286  out << indent << "c = [0, 0, 0]\n";
287  out << indent << "c[0] = a[1]*b[2] - a[2]*b[1]\n";
288  out << indent << "c[1] = a[2]*b[0] - a[0]*b[2]\n";
289  out << indent << "c[2] = a[0]*b[1] - a[1]*b[0]\n";
290  out << indent << "return c\n\n";
291 
292  out << "class Quaternion:\n";
293  out << indent << "def __init__(self, values):\n";
294  out << indent << indent << "self.R = values\n\n";
295 
296  out << indent << "def __str__(self):\n";
297  out << indent << indent << "return str(self.R)\n\n";
298 
299  out << indent << "def __mul__(self, other):\n";
300  out << indent << indent << "imagThis = self.imag()\n";
301  out << indent << indent << "imagOther = other.imag()\n";
302  out << indent << indent << "cro = cross(imagThis, imagOther)\n\n";
303 
304  out << indent << indent << "ret = ([self.R[0] * other.R[0] - dot(imagThis, imagOther)] +\n";
305  out << indent << indent << indent << " [self.R[0] * imagOther[0] + other.R[0] * imagThis[0] + cro[0],\n";
306  out << indent << indent << indent << indent << "self.R[0] * imagOther[1] + other.R[0] * imagThis[1] + cro[1],\n";
307  out << indent << indent << indent << indent << "self.R[0] * imagOther[2] + other.R[0] * imagThis[2] + cro[2]])\n\n";
308 
309  out << indent << indent << "return Quaternion(ret)\n\n";
310 
311  out << indent << "def imag(self):\n";
312  out << indent << indent << "return self.R[1:]\n\n";
313 
314  out << indent << "def conjugate(self):\n";
315  out << indent << indent << "ret = [0] * 4\n";
316  out << indent << indent << "ret[0] = self.R[0]\n";
317  out << indent << indent << "ret[1] = -self.R[1]\n";
318  out << indent << indent << "ret[2] = -self.R[2]\n";
319  out << indent << indent << "ret[3] = -self.R[3]\n\n";
320 
321  out << indent << indent << "return Quaternion(ret)\n\n";
322 
323  out << indent << "def inverse(self):\n";
324  out << indent << indent << "return self.conjugate()\n\n";
325 
326  out << indent << "def rotate(self, vec3D):\n";
327  out << indent << indent << "quat = Quaternion([0.0] + vec3D)\n";
328  out << indent << indent << "conj = self.conjugate()\n\n";
329 
330  out << indent << indent << "ret = self * (quat * conj)\n";
331  out << indent << indent << "return ret.R[1:]\n\n";
332 
333  out << "def getQuaternion(u, ref):\n";
334  out << indent << "u = normalize(u)\n";
335  out << indent << "ref = normalize(ref)\n";
336  out << indent << "axis = cross(u, ref)\n";
337  out << indent << "normAxis = math.sqrt(dot(axis, axis))\n\n";
338 
339  out << indent << "if normAxis < 1e-12:\n";
340  out << indent << indent << "if math.fabs(dot(u, ref) - 1.0) < 1e-12:\n";
341  out << indent << indent << indent << "return Quaternion([1.0, 0.0, 0.0, 0.0])\n\n";
342 
343  out << indent << indent << "return Quaternion([0.0, 1.0, 0.0, 0.0])\n\n";
344 
345  out << indent << "axis = normalize(axis)\n";
346  out << indent << "cosAngle = math.sqrt(0.5 * (1 + dot(u, ref)))\n";
347  out << indent << "sinAngle = math.sqrt(1 - cosAngle * cosAngle)\n\n";
348 
349  out << indent << "return Quaternion([cosAngle, sinAngle * axis[0], sinAngle * axis[1], sinAngle * axis[2]])\n\n";
350 
351  out << "def exportVTK():\n";
352  out << indent << "vertices_str = \"\"\n";
353  out << indent << "triangles_str = \"\"\n";
354  out << indent << "color_str = \"\"\n";
355  out << indent << "cellTypes_str = \"\"\n";
356  out << indent << "startIdx = 0\n";
357  out << indent << "vertexCounter = 0\n";
358  out << indent << "cellCounter = 0\n";
359  out << indent << "lookup_table = []\n";
360  out << indent << "lookup_table.append([0.5, 0.5, 0.5, 0.5])\n";
361  out << indent << "lookup_table.append([1.0, 0.847, 0.0, 1.0])\n";
362  out << indent << "lookup_table.append([1.0, 0.0, 0.0, 1.0])\n";
363  out << indent << "lookup_table.append([0.537, 0.745, 0.525, 1.0])\n";
364  out << indent << "lookup_table.append([0.5, 0.5, 0.0, 1.0])\n";
365  out << indent << "lookup_table.append([1.0, 0.541, 0.0, 1.0])\n";
366  out << indent << "lookup_table.append([0.0, 0.0, 1.0, 1.0])\n\n";
367 
368  out << indent << "decodeVertices()\n\n";
369 
370  out << indent << "for i in range(len(vertices)):\n";
371  out << indent << indent << "for j in range(0, len(vertices[i]), 3):\n";
372  out << indent << indent << indent << "vertices_str += (\"%f %f %f\\n\" %(vertices[i][j], vertices[i][j+1], vertices[i][j+2]))\n";
373  out << indent << indent << indent << "vertexCounter += 1\n\n";
374 
375  out << indent << indent << "for j in range(0, len(triangles[i]), 3):\n";
376  out << indent << indent << indent << "triangles_str += (\"3 %d %d %d\\n\" % (triangles[i][j] + startIdx, triangles[i][j+1] + startIdx, triangles[i][j+2] + startIdx))\n";
377  out << indent << indent << indent << "cellTypes_str += \"5\\n\"\n";
378  out << indent << indent << indent << "tmp_color = lookup_table[color[i]]\n";
379  out << indent << indent << indent << "color_str += (\"%f %f %f %f\\n\" % (tmp_color[0], tmp_color[1], tmp_color[2], tmp_color[3]))\n";
380  out << indent << indent << indent << "cellCounter += 1\n";
381 
382  out << indent << indent << "startIdx = vertexCounter\n\n";
383 
384  out << indent << "fh = open('" << fname << "_ElementPositions.vtk','w')\n";
385  out << indent << "fh.write(\"# vtk DataFile Version 2.0\\n\")\n";
386  out << indent << "fh.write(\"test\\nASCII\\n\\n\")\n";
387  out << indent << "fh.write(\"DATASET UNSTRUCTURED_GRID\\n\")\n";
388  out << indent << "fh.write(\"POINTS \" + str(vertexCounter) + \" float\\n\")\n";
389  out << indent << "fh.write(vertices_str)\n";
390  out << indent << "fh.write(\"CELLS \" + str(cellCounter) + \" \" + str(cellCounter * 4) + \"\\n\")\n";
391  out << indent << "fh.write(triangles_str)\n";
392  out << indent << "fh.write(\"CELL_TYPES \" + str(cellCounter) + \"\\n\")\n";
393  out << indent << "fh.write(cellTypes_str)\n";
394  out << indent << "fh.write(\"CELL_DATA \" + str(cellCounter) + \"\\n\")\n";
395  out << indent << "fh.write(\"COLOR_SCALARS type 4\\n\")\n";
396  out << indent << "fh.write(color_str + \"\\n\")\n";
397  out << indent << "fh.close()\n\n";
398 
399  out << "def getNormal(tri_vertices):\n";
400  out << indent << "vec1 = [tri_vertices[1][0] - tri_vertices[0][0],\n";
401  out << indent << " tri_vertices[1][1] - tri_vertices[0][1],\n";
402  out << indent << " tri_vertices[1][2] - tri_vertices[0][2]]\n";
403  out << indent << "vec2 = [tri_vertices[2][0] - tri_vertices[0][0],\n";
404  out << indent << " tri_vertices[2][1] - tri_vertices[0][1],\n";
405  out << indent << " tri_vertices[2][2] - tri_vertices[0][2]]\n";
406  out << indent << "return normalize(cross(vec1,vec2))\n\n";
407 
408  out << "def exportWeb(bgcolor):\n";
409  // out << indent << "if not os.path.exists('scenes'):\n";
410  // out << indent << indent << "os.makedirs('scenes')\n";
411  // out << indent << "fh = open('scenes/" << fname << "_ElementPositions.babylon','w')\n";
412  // out << indent << "indent = \"\";\n\n";
413 
414  out << indent << "lookup_table = []\n";
415  out << indent << "lookup_table.append([0.5, 0.5, 0.5])\n";
416  out << indent << "lookup_table.append([1.0, 0.847, 0.0])\n";
417  out << indent << "lookup_table.append([1.0, 0.0, 0.0])\n";
418  out << indent << "lookup_table.append([0.537, 0.745, 0.525])\n";
419  out << indent << "lookup_table.append([0.5, 0.5, 0.0])\n";
420  out << indent << "lookup_table.append([1.0, 0.541, 0.0])\n";
421  out << indent << "lookup_table.append([0.0, 0.0, 1.0])\n\n";
422 
423  out << indent << "decodeVertices()\n\n";
424 
425  out << indent << "mesh = \"'data:\"\n";
426  out << indent << "mesh += \"{\"\n";
427  out << indent << "mesh += \"\\\"autoClear\\\":true,\"\n";
428  out << indent << "mesh += \"\\\"clearColor\\\":[0.0000,0.0000,0.0000],\"\n";
429  out << indent << "mesh += \"\\\"ambientColor\\\":[0.0000,0.0000,0.0000],\"\n";
430  out << indent << "mesh += \"\\\"gravity\\\":[0.0000,-9.8100,0.0000],\"\n";
431  out << indent << "mesh += \"\\\"cameras\\\":[\"\n";
432  out << indent << "mesh += \"{\"\n";
433  out << indent << "mesh += \"\\\"name\\\":\\\"Camera\\\",\"\n";
434  out << indent << "mesh += \"\\\"id\\\":\\\"Camera\\\",\"\n";
435  out << indent << "mesh += \"\\\"position\\\":[21.7936,2.2312,-85.7292],\"\n";
436  out << indent << "mesh += \"\\\"rotation\\\":[0.0432,-0.1766,-0.0668],\"\n";
437  out << indent << "mesh += \"\\\"fov\\\":0.8578,\"\n";
438  out << indent << "mesh += \"\\\"minZ\\\":10.0000,\"\n";
439  out << indent << "mesh += \"\\\"maxZ\\\":10000.0000,\"\n";
440  out << indent << "mesh += \"\\\"speed\\\":1.0000,\"\n";
441  out << indent << "mesh += \"\\\"inertia\\\":0.9000,\"\n";
442  out << indent << "mesh += \"\\\"checkCollisions\\\":false,\"\n";
443  out << indent << "mesh += \"\\\"applyGravity\\\":false,\"\n";
444  out << indent << "mesh += \"\\\"ellipsoid\\\":[0.2000,0.9000,0.2000]\"\n";
445  out << indent << "mesh += \"}],\"\n";
446  out << indent << "mesh += \"\\\"activeCamera\\\":\\\"Camera\\\",\"\n";
447  out << indent << "mesh += \"\\\"lights\\\":[\"\n";
448  out << indent << "mesh += \"{\"\n";
449  out << indent << "mesh += \"\\\"name\\\":\\\"Lamp\\\",\"\n";
450  out << indent << "mesh += \"\\\"id\\\":\\\"Lamp\\\",\"\n";
451  out << indent << "mesh += \"\\\"type\\\":0.0000,\"\n";
452  out << indent << "mesh += \"\\\"position\\\":[4.0762,34.9321,-63.5788],\"\n";
453  out << indent << "mesh += \"\\\"intensity\\\":1.0000,\"\n";
454  out << indent << "mesh += \"\\\"diffuse\\\":[1.0000,1.0000,1.0000],\"\n";
455  out << indent << "mesh += \"\\\"specular\\\":[1.0000,1.0000,1.0000]\"\n";
456  out << indent << "mesh += \"}],\"\n";
457  out << indent << "mesh += \"\\\"materials\\\":[],\"\n";
458  out << indent << "mesh += \"\\\"meshes\\\":[\"\n\n";
459 
460  out << indent << "for i in range(len(triangles)):\n";
461  out << indent << indent << "vertex_list = []\n";
462  out << indent << indent << "indices_list = []\n";
463  out << indent << indent << "normals_list = []\n";
464  out << indent << indent << "color_list = []\n";
465  out << indent << indent << "for j in range(0, len(triangles[i]), 3):\n";
466  out << indent << indent << indent << "tri_vertices = []\n";
467  out << indent << indent << indent << "idcs = triangles[i][j:j + 3]\n";
468  out << indent << indent << indent << "tri_vertices.append(vertices[i][3 * idcs[0]:3 * (idcs[0] + 1)])\n";
469  out << indent << indent << indent << "tri_vertices.append(vertices[i][3 * idcs[1]:3 * (idcs[1] + 1)])\n";
470  out << indent << indent << indent << "tri_vertices.append(vertices[i][3 * idcs[2]:3 * (idcs[2] + 1)])\n";
471  out << indent << indent << indent << "indices_list.append(','.join(str(n) for n in range(len(vertex_list),len(vertex_list) + 3)))\n";
472  out << indent << indent << indent << "# left hand order!\n";
473  out << indent << indent << indent << "vertex_list.append(','.join(\"%.5f\" % (round(n,5) + 0.0) for n in tri_vertices[0]))\n";
474  out << indent << indent << indent << "vertex_list.append(','.join(\"%.5f\" % (round(n,5) + 0.0) for n in tri_vertices[2]))\n";
475  out << indent << indent << indent << "vertex_list.append(','.join(\"%.5f\" % (round(n,5) + 0.0) for n in tri_vertices[1]))\n";
476  out << indent << indent << indent << "normal = getNormal(tri_vertices)\n";
477  out << indent << indent << indent << "normals_list.append(','.join(\"%.5f\" % (round(n,5) + 0.0) for n in normal * 3))\n";
478  out << indent << indent << indent << "color_list.append(','.join([str(n) for n in lookup_table[color[i]]] * 3))\n";
479  out << indent << indent << "mesh += \"{\"\n";
480  out << indent << indent << "mesh += \"\\\"name\\\":\\\"element_\" + str(i) + \"\\\",\"\n";
481  out << indent << indent << "mesh += \"\\\"id\\\":\\\"element_\" + str(i) + \"\\\",\"\n";
482  out << indent << indent << "mesh += \"\\\"position\\\":[0.0,0.0,0.0],\"\n";
483  out << indent << indent << "mesh += \"\\\"rotation\\\":[0.0,0.0,0.0],\"\n";
484  out << indent << indent << "mesh += \"\\\"scaling\\\":[1.0,1.0,1.0],\"\n";
485  out << indent << indent << "mesh += \"\\\"isVisible\\\":true,\"\n";
486  out << indent << indent << "mesh += \"\\\"isEnabled\\\":true,\"\n";
487  out << indent << indent << "mesh += \"\\\"useFlatShading\\\":false,\"\n";
488  out << indent << indent << "mesh += \"\\\"checkCollisions\\\":false,\"\n";
489  out << indent << indent << "mesh += \"\\\"billboardMode\\\":0,\"\n";
490  out << indent << indent << "mesh += \"\\\"receiveShadows\\\":false,\"\n";
491  out << indent << indent << "mesh += \"\\\"positions\\\":[\" + ','.join(vertex_list) + \"],\"\n";
492  out << indent << indent << "mesh += \"\\\"normals\\\":[\" + ','.join(normals_list) + \"],\"\n";
493  out << indent << indent << "mesh += \"\\\"indices\\\":[\" + ','.join(indices_list) + \"],\"\n";
494  out << indent << indent << "mesh += \"\\\"colors\\\":[\" + ','.join(color_list) + \"],\"\n";
495  out << indent << indent << "mesh += \"\\\"subMeshes\\\":[\"\n";
496  out << indent << indent << "mesh += \"{\"\n";
497  out << indent << indent << "mesh += \"\\\"materialIndex\\\":0,\"\n";
498  out << indent << indent << "mesh += \" \\\"verticesStart\\\":0,\"\n";
499  out << indent << indent << "mesh += \" \\\"verticesCount\\\":\" + str(len(triangles[i])) + \",\"\n";
500  out << indent << indent << "mesh += \" \\\"indexStart\\\":0,\"\n";
501  out << indent << indent << "mesh += \" \\\"indexCount\\\":\" + str(len(triangles[i])) + \"\"\n";
502  out << indent << indent << "mesh += \"}]\"\n";
503  out << indent << indent << "mesh += \"}\"\n";
504  out << indent << indent << "mesh += \",\"\n\n";
505 
506  out << indent << indent << "del normals_list[:]\n";
507  out << indent << indent << "del vertex_list[:]\n";
508  out << indent << indent << "del color_list[:]\n";
509  out << indent << indent << "del indices_list[:]\n\n";
510 
511  out << indent << "mesh = mesh[:-1] + \"]\"\n";
512  out << indent << "mesh += \"}'\"\n";
513 
514  out << indent << "index_compressed = base64.b64decode(index_base64)\n";
515  out << indent << "index = str(zlib.decompress(index_compressed))\n";
516  out << indent << "if (len(bgcolor) == 3):\n";
517  out << indent << indent << "mesh += \";\\n \"\n";
518  out << indent << indent << "mesh += \"scene.clearColor = new BABYLON.Color3(%f, %f, %f)\" % (bgcolor[0], bgcolor[1], bgcolor[2])\n\n";
519  out << indent << "index = index.replace('##DATA##', mesh)\n";
520  out << indent << "fh = open('" << fname << "_ElementPositions.html','w')\n";
521  out << indent << "fh.write(index)\n";
522  out << indent << "fh.close()\n\n";
523 
524  out << "def computeMinAngle(idx, curAngle, positions, connections, check):\n";
525  out << indent << "matrix = [[-math.cos(curAngle), -math.sin(curAngle)], [math.sin(curAngle), -math.cos(curAngle)]]\n\n";
526 
527  out << indent << "minAngle = 2 * math.pi\n";
528  out << indent << "nextIdx = -1\n\n";
529 
530  out << indent << "for j in connections[idx]:\n";
531  out << indent << indent << "direction = [positions[j][0] - positions[idx][0],\n";
532  out << indent << indent << indent << " positions[j][1] - positions[idx][1]]\n";
533  out << indent << indent << "direction = [dot(matrix[0],direction), dot(matrix[1],direction)]\n\n";
534 
535  out << indent << indent << "if math.fabs(dot([1.0, 0.0], direction) / distance(positions[j], positions[idx]) - 1.0) < 1e-6: continue\n\n";
536 
537  out << indent << indent << "angle = math.fmod(math.atan2(direction[1],direction[0]) + 2 * math.pi, 2 * math.pi)\n\n";
538 
539  out << indent << indent << "if angle < minAngle:\n";
540  out << indent << indent << indent << "nextIdx = j\n";
541  out << indent << indent << indent << "minAngle = angle\n";
542  out << indent << indent << "if angle == minAngle and check:\n";
543  out << indent << indent << indent << "dire = [positions[j][0] - positions[idx][0],\n";
544  out << indent << indent << indent << " positions[j][1] - positions[idx][1]]\n";
545  out << indent << indent << indent << "minA0 = math.atan2(dire[1], dire[0])\n";
546  out << indent << indent << indent << "minA1 = computeMinAngle(nextIdx, minA0, positions, connections, False)\n";
547  out << indent << indent << indent << "minA2 = computeMinAngle(j, minA0, positions, connections, False)\n";
548  out << indent << indent << indent << "if minA2[1] < minA2[1]:\n";
549  out << indent << indent << indent << indent << "nextIdx = j\n\n";
550 
551  out << indent << "if nextIdx == -1:\n";
552  out << indent << indent << "nextIdx = connections[idx][0]\n\n";
553 
554  out << indent << "return (nextIdx, minAngle)\n\n";
555 
556  out << "def squashVertices(positionDict, connections):\n";
557  out << indent << "removedItems = []\n";
558  out << indent << "indices = [int(k) for k in positionDict.keys()]\n";
559  out << indent << "idxChanges = indices\n";
560  out << indent << "for i in indices:\n";
561  out << indent << indent << "if i in removedItems:\n";
562  out << indent << indent << indent << "continue\n";
563  out << indent << indent << "for j in indices:\n";
564  out << indent << indent << indent << "if j in removedItems or j == i:\n";
565  out << indent << indent << indent << indent << "continue\n\n";
566 
567  out << indent << indent << indent << "if distance(positionDict[i], positionDict[j]) < 1e-6:\n";
568  out << indent << indent << indent << indent << "connections[j] = list(set(connections[j]))\n";
569  out << indent << indent << indent << indent << "if i in connections[j]:\n";
570  out << indent << indent << indent << indent << indent << "connections[j].remove(i)\n";
571  out << indent << indent << indent << indent << "if j in connections[i]:\n";
572  out << indent << indent << indent << indent << indent << "connections[i].remove(j)\n\n";
573 
574  out << indent << indent << indent << indent << "connections[i].extend(connections[j])\n";
575  out << indent << indent << indent << indent << "connections[i] = list(set(connections[i]))\n";
576  out << indent << indent << indent << indent << "connections[i].sort()\n\n";
577 
578  out << indent << indent << indent << indent << "for k in connections.keys():\n";
579  out << indent << indent << indent << indent << indent << "if k == i: continue\n";
580  out << indent << indent << indent << indent << indent << "if j in connections[k]:\n";
581  out << indent << indent << indent << indent << indent << indent << "idx = connections[k].index(j)\n";
582  out << indent << indent << indent << indent << indent << indent << "connections[k][idx] = i\n\n";
583 
584  out << indent << indent << indent << indent << "idxChanges[j] = i\n";
585  out << indent << indent << indent << indent << "removedItems.append(j)\n\n";
586 
587  out << indent << "for i in removedItems:\n";
588  out << indent << indent << "del positionDict[i]\n";
589  out << indent << indent << "del connections[i]\n\n";
590 
591  out << indent << "for i in connections.keys():\n";
592  out << indent << indent << "connections[i] = list(set(connections[i]))\n";
593  out << indent << indent << "connections[i].sort()\n\n";
594 
595  out << indent << "return idxChanges\n\n";
596 
597  out << "def computeLineEquations(positions, connections):\n";
598  out << indent << "cons = set()\n";
599  out << indent << "for i in connections.keys():\n";
600  out << indent << indent << "for j in connections[i]:\n";
601  out << indent << indent << indent << "cons.add((min(i, j), max(i, j)))\n\n";
602 
603  out << indent << "lineEquations = {}\n";
604  out << indent << "for item in cons:\n";
605  out << indent << indent << "a = (positions[item[1]][1] - positions[item[0]][1])\n";
606  out << indent << indent << "b = -(positions[item[1]][0] - positions[item[0]][0])\n\n";
607 
608  out << indent << indent << "xm = 0.5 * (positions[item[0]][0] + positions[item[1]][0])\n";
609  out << indent << indent << "ym = 0.5 * (positions[item[0]][1] + positions[item[1]][1])\n";
610  out << indent << indent << "c = -(a * xm + b * ym)\n\n";
611 
612  out << indent << indent << "lineEquations[item] = (a, b, c)\n\n";
613 
614  out << indent << "return lineEquations\n\n";
615 
616  out << "def checkPossibleSegmentIntersection(segment, positions, lineEquations, minAngle, lastIntersection):\n";
617  out << indent << "item1 = (min(segment), max(segment))\n\n";
618 
619  out << indent << "(a1, b1, c1) = (0,0,0)\n";
620  out << indent << "A = [0]*2\n";
621  out << indent << "B = A\n\n";
622 
623  out << indent << "if segment[0] == None:\n";
624  out << indent << indent << "A = lastIntersection\n";
625  out << indent << indent << "B = positions[segment[1]]\n\n";
626 
627  out << indent << indent << "a1 = B[1] - A[1]\n";
628  out << indent << indent << "b1 = -(B[0] - A[0])\n";
629  out << indent << indent << "xm = 0.5 * (A[0] + B[0])\n";
630  out << indent << indent << "ym = 0.5 * (A[1] + B[1])\n";
631  out << indent << indent << "c1 = -(a1 * xm + b1 * ym)\n\n";
632 
633  out << indent << "else:\n";
634  out << indent << indent << "A = positions[segment[0]]\n";
635  out << indent << indent << "B = positions[segment[1]]\n\n";
636 
637  out << indent << indent << "(a1, b1, c1) = lineEquations[item1]\n\n";
638 
639  out << indent << indent << "if segment[1] < segment[0]:\n";
640  out << indent << indent << indent << "(a1, b1, c1) = (-a1, -b1, -c1)\n\n";
641 
642  out << indent << "curAngle = math.atan2(a1, -b1)\n";
643  out << indent << "matrix = [[-math.cos(curAngle), -math.sin(curAngle)], [math.sin(curAngle), -math.cos(curAngle)]]\n\n";
644 
645  out << indent << "origMinAngle = minAngle\n\n";
646 
647  out << indent << "segment1 = [B[0] - A[0], B[1] - A[1], 0.0]\n\n";
648 
649  out << indent << "intersectingSegments = []\n";
650  out << indent << "distanceAB = distance(A, B)\n";
651  out << indent << "for item2 in lineEquations.keys():\n";
652  out << indent << indent << "item = item2\n";
653  out << indent << indent << "C = positions[item[0]]\n";
654  out << indent << indent << "D = positions[item[1]]\n\n";
655 
656  out << indent << indent << "if segment[0] == None:\n";
657  out << indent << indent << indent << "if (segment[1] == item[0] or\n";
658  out << indent << indent << indent << indent << "segment[1] == item[1]): continue\n";
659  out << indent << indent << "else:\n";
660  out << indent << indent << indent << "if (item1[0] == item[0] or\n";
661  out << indent << indent << indent << indent << "item1[1] == item[0] or\n";
662  out << indent << indent << indent << indent << "item1[0] == item[1] or\n";
663  out << indent << indent << indent << indent << "item1[1] == item[1]): continue\n\n";
664 
665  out << indent << indent << "nodes = set([item1[0],item1[1],item[0],item[1]])\n";
666  out << indent << indent << "if len(nodes) < 4: continue # share same vertex\n\n";
667 
668  out << indent << indent << "(a2, b2, c2) = lineEquations[item]\n\n";
669 
670  out << indent << indent << "segment2 = [C[0] - A[0], C[1] - A[1], 0.0]\n";
671  out << indent << indent << "segment3 = [D[0] - A[0], D[1] - A[1], 0.0]\n\n";
672 
673  out << indent << indent << "# check that C and D aren't on the same side of AB\n";
674  out << indent << indent << "if cross(segment1, segment2)[2] * cross(segment1, segment3)[2] > 0.0: continue\n\n";
675 
676  out << indent << indent << "if cross(segment1, segment2)[2] < 0.0 or cross(segment1, segment3)[2] > 0.0:\n";
677  out << indent << indent << indent << "(C, D, a2, b2, c2) = (D, C, -a2, -b2, -c2)\n";
678  out << indent << indent << indent << "item = (item[1], item[0])\n\n";
679 
680  out << indent << indent << "denominator = a1 * b2 - b1 * a2\n";
681  out << indent << indent << "if math.fabs(denominator) < 1e-9: continue\n\n";
682 
683  out << indent << indent << "px = (b1 * c2 - b2 * c1) / denominator\n";
684  out << indent << indent << "py = (a2 * c1 - a1 * c2) / denominator\n\n";
685 
686  out << indent << indent << "distanceCD = distance(C, D)\n\n";
687 
688  out << indent << indent << "distanceAP = distance(A, [px, py])\n";
689  out << indent << indent << "distanceBP = distance(B, [px, py])\n";
690  out << indent << indent << "distanceCP = distance(C, [px, py])\n";
691  out << indent << indent << "distanceDP = distance(D, [px, py])\n\n";
692 
693  out << indent << indent << "# check intersection is between AB and CD\n";
694  out << indent << indent << "check1 = (distanceAP - 1e-6 < distanceAB and distanceBP - 1e-6 < distanceAB)\n";
695  out << indent << indent << "check2 = (distanceCP - 1e-6 < distanceCD and distanceDP - 1e-6 < distanceCD)\n";
696  out << indent << indent << "if not check1 or not check2: continue\n\n";
697 
698  out << indent << indent << "if math.fabs(dot(segment1, [D[0] - C[0], D[1] - C[1], 0.0]) / (distanceAB * distanceCD) + 1.0) < 1e-9: continue\n\n";
699 
700  out << indent << indent << "if ((distanceAP < 1e-6) or\n";
701  out << indent << indent << indent << "(distanceBP < 1e-6 and distanceCP < 1e-6) or\n";
702  out << indent << indent << indent << "(distanceDP < 1e-6)):\n";
703  out << indent << indent << indent << "continue\n\n";
704 
705  out << indent << indent << "direction = [D[0] - C[0], D[1] - C[1]]\n";
706  out << indent << indent << "direction = [dot(matrix[0], direction), dot(matrix[1], direction)]\n";
707  out << indent << indent << "angle = math.fmod(math.atan2(direction[1], direction[0]) + 2 * math.pi, 2 * math.pi)\n\n";
708 
709  out << indent << indent << "newSegment = ([px, py], item[1], distanceAP, angle)\n\n";
710 
711  out << indent << indent << "if distanceCP < 1e-6 and angle > origMinAngle: continue\n";
712  out << indent << indent << "if distanceBP > 1e-6 and angle > math.pi: continue\n\n";
713 
714  out << indent << indent << "if len(intersectingSegments) == 0:\n";
715  out << indent << indent << indent << "intersectingSegments.append(newSegment)\n";
716  out << indent << indent << indent << "minAngle = angle\n";
717  out << indent << indent << "else:\n";
718  out << indent << indent << indent << "if intersectingSegments[0][2] - 1e-9 > distanceAP:\n";
719  out << indent << indent << indent << indent << "intersectingSegments[0] = newSegment\n";
720  out << indent << indent << indent << indent << "minAngle = angle\n";
721  out << indent << indent << indent << "elif intersectingSegments[0][2] + 1e-9 > distanceAP and angle < minAngle:\n";
722  out << indent << indent << indent << indent << "intersectingSegments[0] = newSegment\n";
723  out << indent << indent << indent << indent << "minAngle = angle\n\n";
724 
725  out << indent << "return intersectingSegments\n\n";
726 
727  out << "def projectToPlane(normal):\n";
728  out << indent << "fh = open('" << fname << "_ElementPositions.gpl','w')\n";
729  // out << indent << "fg = open('test2.dat', 'w')\n";
730  out << indent << "normal = normalize(normal)\n";
731  out << indent << "ori = getQuaternion(normal, [0, 0, 1])\n\n";
732 
733  out << indent << "left2Right = [0, 0, 1]\n";
734  out << indent << "if math.fabs(math.fabs(dot(normal, left2Right)) - 1) < 1e-9:\n";
735  out << indent << indent << "left2Right = [1, 0, 0]\n";
736  out << indent << "rotL2R = ori.rotate(left2Right)\n";
737  out << indent << "deviation = math.atan2(rotL2R[1], rotL2R[0])\n";
738  out << indent << "rotBack = Quaternion([math.cos(0.5 * deviation), 0, 0, -math.sin(0.5 * deviation)])\n";
739  out << indent << "ori = rotBack * ori\n\n";
740 
741  out << indent << "decodeVertices()\n\n";
742 
743  out << indent << "for i in range(len(vertices)):\n";
744  out << indent << indent << "positions = {}\n";
745  out << indent << indent << "connections = {}\n";
746  out << indent << indent << "for j in range(0, len(vertices[i]), 3):\n";
747  out << indent << indent << indent << "nextPos3D = ori.rotate(vertices[i][j:j+3])\n";
748  out << indent << indent << indent << "nextPos2D = nextPos3D[0:2]\n";
749  out << indent << indent << indent << "positions[j/3] = nextPos2D\n\n";
750 
751  out << indent << indent << "if len(positions) == 0:\n";
752  out << indent << indent << indent << "continue\n\n";
753 
754  out << indent << indent << "idx = 0\n";
755  out << indent << indent << "maxX = positions[0][0]\n";
756  out << indent << indent << "for j in positions.keys():\n";
757  out << indent << indent << indent << "if positions[j][0] > maxX:\n";
758  out << indent << indent << indent << indent << "maxX = positions[j][0]\n";
759  out << indent << indent << indent << indent << "idx = j\n";
760  out << indent << indent << indent << "if positions[j][0] == maxX and positions[j][1] > positions[idx][1]:\n";
761  out << indent << indent << indent << indent << "idx = j\n\n";
762 
763  out << indent << indent << "for j in range(0, len(triangles[i]), 3):\n";
764  out << indent << indent << indent << "for k in range(0, 3):\n";
765  out << indent << indent << indent << indent << "vertIdx = triangles[i][j + k]\n";
766  out << indent << indent << indent << indent << "if not vertIdx in connections:\n";
767  out << indent << indent << indent << indent << indent << "connections[vertIdx] = []\n";
768  out << indent << indent << indent << indent << "for l in range(1, 3):\n";
769  out << indent << indent << indent << indent << indent << "connections[vertIdx].append(triangles[i][j + ((k + l) % 3)])\n\n";
770 
771  out << indent << indent << "numConnections = 0\n";
772  out << indent << indent << "for j in connections.keys():\n";
773  out << indent << indent << indent << "connections[j] = list(set(connections[j]))\n";
774  out << indent << indent << indent << "numConnections += len(connections[j])\n\n";
775  out << indent << indent << "numConnections /= 2\n";
776 
777  out << indent << indent << "idChanges = squashVertices(positions, connections)\n\n";
778 
779  out << indent << indent << "lineEquations = computeLineEquations(positions, connections)\n\n";
780 
781  // out << indent << indent << "for j in positions.keys():\n";
782  // out << indent << indent << indent << "for k in connections[j]:\n";
783  // out << indent << indent << indent << indent << "if j < k:\n";
784  // out << indent << indent << indent << indent << indent << "fg.write(\"%.8f %.8f \\n%.8f %.8f\\n# %d %d\\n\\n\" %(positions[j][0], positions[j][1], positions[k][0], positions[k][1], j, k))\n";
785  // out << indent << indent << indent << "fg.write(\"\\n\")\n\n";
786 
787  out << indent << indent << "idx = idChanges[int(idx)]\n";
788  out << indent << indent << "fh.write(\"%.6f %.6f\\n\" % (positions[idx][0], positions[idx][1]))\n\n";
789 
790  out << indent << indent << "curAngle = math.pi\n";
791  out << indent << indent << "origin = idx\n";
792  out << indent << indent << "count = 0\n";
793  out << indent << indent << "passed = []\n";
794  out << indent << indent << "while (count == 0 or distance(positions[origin], positions[idx]) > 1e-9) and not count > numConnections:\n";
795  out << indent << indent << indent << "nextGen = computeMinAngle(idx, curAngle, positions, connections, False)\n";
796  out << indent << indent << indent << "nextIdx = nextGen[0]\n";
797  out << indent << indent << indent << "direction = [positions[nextIdx][0] - positions[idx][0],\n";
798  out << indent << indent << indent << indent << " positions[nextIdx][1] - positions[idx][1]]\n";
799  out << indent << indent << indent << "curAngle = math.atan2(direction[1], direction[0])\n\n";
800 
801  out << indent << indent << indent << "intersections = checkPossibleSegmentIntersection((idx, nextIdx), positions, lineEquations, nextGen[1], [])\n";
802  out << indent << indent << indent << "if len(intersections) > 0:\n";
803  out << indent << indent << indent << indent << "while len(intersections) > 0 and not count > numConnections:\n";
804  out << indent << indent << indent << indent << indent << "fh.write(\"%.6f %.6f\\n\" %(intersections[0][0][0], intersections[0][0][1]))\n";
805  out << indent << indent << indent << indent << indent << "count += 1\n";
806  out << indent << "\n";
807  out << indent << indent << indent << indent << indent << "idx = intersections[0][1]\n";
808  out << indent << indent << indent << indent << indent << "direction = [positions[idx][0] - intersections[0][0][0],\n";
809  out << indent << indent << indent << indent << indent << " positions[idx][1] - intersections[0][0][1]]\n";
810  out << indent << indent << indent << indent << indent << "curAngle = math.atan2(direction[1], direction[0])\n";
811  out << indent << indent << indent << indent << indent << "nextGen = computeMinAngle(idx, curAngle, positions, connections, False)\n";
812  out << indent << "\n";
813  out << indent << indent << indent << indent << indent << "intersections = checkPossibleSegmentIntersection((None, idx), positions, lineEquations, nextGen[1], intersections[0][0])\n";
814  out << indent << indent << indent << "else:\n";
815  out << indent << indent << indent << indent << "idx = nextIdx\n";
816  out << indent << "\n";
817  out << indent << indent << indent << "fh.write(\"%.6f %.6f\\n\" % (positions[idx][0], positions[idx][1]))\n";
818  out << indent << "\n";
819  out << indent << indent << indent << "if idx in passed:\n";
820  out << indent << indent << indent << indent << "direction1 = [positions[idx][0] - positions[passed[-1]][0],\n";
821  out << indent << indent << indent << indent << indent << " positions[idx][1] - positions[passed[-1]][1]]\n";
822  out << indent << indent << indent << indent << "direction2 = [positions[origin][0] - positions[passed[-1]][0],\n";
823  out << indent << indent << indent << indent << indent << " positions[origin][1] - positions[passed[-1]][1]]\n";
824  out << indent << indent << indent << indent << "dist1 = distance(positions[idx], positions[passed[-1]])\n";
825  out << indent << indent << indent << indent << "dist2 = distance(positions[origin], positions[passed[-1]])\n";
826  out << indent << indent << indent << indent << "if dist1 * dist2 > 0.0 and math.fabs(math.fabs(dot(direction1, direction2) / (dist1 * dist2)) - 1.0) > 1e-9:\n";
827  out << indent << indent << indent << indent << indent << "sys.stderr.write(\"error: projection cycling on element id: %d, vertex id: %d\\n\" %(i, idx))\n";
828  out << indent << indent << indent << indent << "break\n\n";
829 
830  out << indent << indent << indent << "passed.append(idx)\n";
831  out << indent << indent << indent << "count += 1\n";
832  out << indent << indent << "fh.write(\"\\n\")\n\n";
833 
834  out << indent << indent << "if count > numConnections:\n";
835  out << indent << indent << indent << "sys.stderr.write(\"error: projection cycling on element id: %d\\n\" % i)\n\n";
836 
837  out << indent << indent << "for j in range(0, len(decoration[i]), 6):\n";
838  out << indent << indent << indent << "for k in range(j, j + 6, 3):\n";
839  out << indent << indent << indent << indent << "nextPos3D = ori.rotate(decoration[i][k:k+3])\n";
840  out << indent << indent << indent << indent << "fh.write(\"%.6f %.6f\\n\" % (nextPos3D[0], nextPos3D[1]))\n";
841  out << indent << indent << indent << "fh.write(\"\\n\")\n\n";
842 
843  out << indent << "fh.close()\n\n";
844 
845  out << "if __name__ == \"__main__\":\n";
846  out << indent << "parser = argparse.ArgumentParser()\n";
847  out << indent << "parser.add_argument('--export-vtk', action='store_true')\n";
848  out << indent << "parser.add_argument('--export-web', action='store_true')\n";
849  out << indent << "parser.add_argument('--background', nargs=3, type=float)\n";
850  out << indent << "parser.add_argument('--project-to-plane', action='store_true')\n";
851  out << indent << "parser.add_argument('--normal', nargs=3, type=float)\n";
852  out << indent << "args = parser.parse_args()\n\n";
853 
854  out << indent << "if (args.export_vtk):\n";
855  out << indent << indent << "exportVTK()\n";
856  out << indent << indent << "sys.exit()\n\n";
857 
858  out << indent << "if (args.export_web):\n";
859  out << indent << indent << "bgcolor = []\n";
860  out << indent << indent << "if (args.background):\n";
861  out << indent << indent << indent << "validBackground = True\n";
862  out << indent << indent << indent << "for comp in bgcolor:\n";
863  out << indent << indent << indent << indent << "if comp < 0.0 or comp > 1.0:\n";
864  out << indent << indent << indent << indent << indent << "validBackground = False\n";
865  out << indent << indent << indent << indent << indent << "break\n";
866  out << indent << indent << indent << "if (validBackground):\n";
867  out << indent << indent << indent << indent << "bgcolor = args.background\n";
868  out << indent << indent << "exportWeb(bgcolor)\n";
869  out << indent << indent << "sys.exit()\n\n";
870 
871  out << indent << "if (args.project_to_plane):\n";
872  out << indent << indent << "normal = [0.0, 1.0, 0.0]\n";
873  out << indent << indent << "if (args.normal):\n";
874  out << indent << indent << indent << "normal = args.normal\n";
875  out << indent << indent << "projectToPlane(normal)\n";
876  out << indent << indent << "sys.exit()\n\n";
877 
878  out << indent << "parser.print_help()\n";
879 }
880 
882  double minor,
883  double major,
884  double formFactor,
885  const unsigned int numSegments) {
886  double angle = 0;
887  double dAngle = Physics::two_pi / numSegments;
888 
889  MeshData mesh;
890  mesh.vertices_m.push_back(Vector_t(0.0));
891  for (unsigned int i = 0; i < numSegments; ++ i, angle += dAngle) {
892  Vector_t node(major * cos(angle), minor * sin(angle), 0);
893  mesh.vertices_m.push_back(node);
894 
895  unsigned int next = (i + 1) % numSegments;
896  Vektor<unsigned int, 3> baseTriangle(0u, next + 1, i + 1);
897  mesh.triangles_m.push_back(baseTriangle);
898 
899  Vektor<unsigned int, 3> sideTriangle1(i + 1, next + 1, i + numSegments + 2);
900  mesh.triangles_m.push_back(sideTriangle1);
901 
902  Vektor<unsigned int, 3> sideTriangle2(next + 1, next + numSegments + 2, i + numSegments + 2);
903  mesh.triangles_m.push_back(sideTriangle2);
904  }
905 
906  mesh.vertices_m.push_back(Vector_t(0.0, 0.0, length));
907  for (unsigned int i = 0; i < numSegments; ++ i, angle += dAngle) {
908  Vector_t node(formFactor * major * cos(angle), formFactor * minor * sin(angle), length);
909  mesh.vertices_m.push_back(node);
910 
911  unsigned int next = (i + 1) % numSegments;
912  Vektor<unsigned int, 3> topTriangle(numSegments + 1, i + numSegments + 2, next + numSegments + 2);
913  mesh.triangles_m.push_back(topTriangle);
914  }
915 
916  mesh.decorations_m.push_back(std::make_pair(Vector_t(0.0), Vector_t(0, 0, length)));
917 
918  return mesh;
919 }
920 
922  double width,
923  double height,
924  double formFactor) {
925 
926  MeshData mesh;
927  mesh.vertices_m.push_back(Vector_t(width, height, 0.0));
928  mesh.vertices_m.push_back(Vector_t(-width, height, 0.0));
929  mesh.vertices_m.push_back(Vector_t(-width, -height, 0.0));
930  mesh.vertices_m.push_back(Vector_t(width, -height, 0.0));
931 
932  mesh.vertices_m.push_back(Vector_t(formFactor * width, formFactor * height, length));
933  mesh.vertices_m.push_back(Vector_t(-formFactor * width, formFactor * height, length));
934  mesh.vertices_m.push_back(Vector_t(-formFactor * width, -formFactor * height, length));
935  mesh.vertices_m.push_back(Vector_t(formFactor * width, -formFactor * height, length));
936 
937  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(0, 2, 1));
938  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(0, 3, 2));
939 
940  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(0, 1, 4));
941  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(4, 1, 5));
942  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(1, 2, 5));
943  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(5, 2, 6));
944  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(2, 3, 6));
945  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(6, 3, 7));
946  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(3, 0, 7));
947  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(7, 0, 4));
948 
949  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(4, 5, 6));
950  mesh.triangles_m.push_back(Vektor<unsigned int, 3>(4, 6, 7));
951 
952  mesh.decorations_m.push_back(std::make_pair(Vector_t(0.0), Vector_t(0, 0, length)));
953 
954  return mesh;
955 }
Interface for solenoids.
Definition: RBend3D.h:39
std::vector< MeshData > elements_m
Definition: MeshGenerator.h:41
Interface for basic beam line object.
Definition: ElementBase.h:128
void write(const std::string &fname)
static MeshData getCylinder(double length, double minor, double major, double formFactor, const unsigned int numSegments=36)
Vector_t rotateTo(const Vector_t &r) const
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
constexpr double two_pi
The value of .
Definition: Physics.h:34
Inform * gmsg
Definition: Main.cpp:21
Vector_t transformTo(const Vector_t &r) const
MeshData getSurfaceMesh() const
Definition: RBend3D.cpp:269
virtual ElementType getType() const =0
Get element type std::string.
void add(const ElementBase &element)
MeshData getSurfaceMesh() const
Definition: Bend2D.cpp:1435
Definition: Bend2D.h:51
std::vector< Vector_t > vertices_m
Definition: MeshGenerator.h:5
std::string base64_encode(const std::string &string_to_encode)
Definition: Util.cpp:300
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
int type_m
Definition: MeshGenerator.h:8
std::vector< Vektor< unsigned int, 3 > > triangles_m
Definition: MeshGenerator.h:6
std::vector< std::pair< Vector_t, Vector_t > > decorations_m
Definition: MeshGenerator.h:7
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
static MeshData getBox(double length, double width, double height, double formFactor)
CoordinateSystemTrafo inverted() const
std::pair< ElementBase::ApertureType, std::vector< double > > getAperture() const
Definition: ElementBase.h:632
Definition: Inform.h:41
virtual void getElementDimensions(double &begin, double &end) const
Definition: ElementBase.h:226
CoordinateSystemTrafo getCSTrafoGlobal2Local() const
Definition: ElementBase.h:603