ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
PdmsTools.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "PdmsTools.h"
9 
10 #include <QSet>
11 
12 // System
13 #include <assert.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 #include <iostream>
18 
19 // CV_CORE_LIB
20 #include <CVMath.h>
21 
22 using namespace PdmsTools;
23 using namespace PdmsCommands;
24 using namespace PdmsObjects;
25 
27 
28 #define memalert(e, s) \
29  std::cerr << "Memory alert [" << __FILE__ << ", line " << __LINE__ \
30  << "] with size " << s << " : " << e.what() << std::endl;
31 #define memfail(e, s) \
32  memalert(e, s); \
33  abort();
34 
36 #define PDMS_SQR(a) (a * a)
37 
41 
43 // ITEM STACK
45 typedef QSet<PdmsObjects::GenericItem *> ElementsStack;
47 
49  assert(s_elementsStack.empty());
50  s_elementsStack.clear();
51 }
52 
54  // DGM: warning, while deleting some entities, the stack may be modified!!!
55  while (!s_elementsStack.empty()) {
56  GenericItem *item = *(s_elementsStack.begin());
57 
58  s_elementsStack.remove(item);
59 
60  if (item) {
61  // CVLog::Print(QString("[PDMS] Should be deleting
62  // %1").arg(item->name));
63  delete item;
64  }
65  }
66 
67  s_elementsStack.clear();
68 }
69 
71  if (item && s_elementsStack.remove(item)) {
72  // CVLog::Print(QString("[PDMS] Destroying %1").arg((item)->name));
73  delete item;
74  item = nullptr;
75  }
76 }
77 
79 // PDMS COMMANDS IMPLEMENTATION
81 
83  value = numvalue;
84  valueChanges++;
85  return valueChanges == 1;
86 }
87 
88 bool NumericalValue::isValid() const { return valueChanges <= 1; }
89 
91  switch (command) {
92  case PDMS_ANGLE:
93  case PDMS_X_TOP_SHEAR:
94  case PDMS_Y_TOP_SHEAR:
97  return cloudViewer::DegreesToRadians(value);
98  default:
99  return value;
100  }
101 }
102 
104  return item ? item->setValue(command, getValue()) : false;
105 }
106 
108  if (!PdmsToken::isUnit(t)) return false;
109  if (!isValid()) return false;
110  unit = t;
111  return true;
112 }
113 
115  if (unit == PDMS_MILLIMETRE && workingUnit == PDMS_METRE)
116  return value / static_cast<PointCoordinateType>(1000);
117  if (unit == PDMS_METRE && workingUnit == PDMS_MILLIMETRE)
118  return value * static_cast<PointCoordinateType>(1000);
119 
120  return value;
121 }
122 
124  return item ? item->setValue(command, getValueInWorkingUnit()) : false;
125 }
126 
128  command = ref.command;
129  token = ref.token;
130  strcpy(refname, ref.refname);
131 
132  return *this;
133 }
134 
136  if (isSet()) return false;
137  // Todo : handle other references than grouping elements or design element
138  if (!PdmsToken::isElement(t)) return false;
139 
140  token = t;
141  return true;
142 }
143 
144 bool Reference::handle(const char *str) {
145  if (isSet()) return false;
146  strcpy(refname, str);
147 
148  return true;
149 }
150 
151 bool Reference::isValid() const {
152  return ((command == PDMS_LAST && isSet() <= 1) || isSet() == 1);
153 }
154 
155 bool Reference::isNameReference() const { return strlen(refname) > 0; }
156 
157 bool Reference::isTokenReference() const { return token != PDMS_INVALID_TOKEN; }
158 
159 int Reference::isSet() const {
160  int nb = 0;
161  if (strlen(refname) > 0) nb++;
162  if (token != PDMS_INVALID_TOKEN) nb++;
163  return nb;
164 }
165 
167  // Handle the PDMS_LAST command
168  if (command == PDMS_LAST) {
169  if (s_elementsStack.size() < 2) return false;
170  ElementsStack::iterator it = s_elementsStack.begin();
171  if (isSet() == 1) {
172  while (true) {
173  if (it == s_elementsStack.end()) return false;
174  if (isNameReference() && strcmp(refname, (*it)->name) == 0)
175  break;
176  if (isTokenReference() && (*it)->getType() == token) break;
177  ++it;
178  }
179  }
180  item = *it;
181  return true;
182  }
183 
184  // Check that this reference is not a PDMS_OWNER termination command
185  if (command == PDMS_OWNER && !isSet()) {
186  // Redirect to an ending command
187  ElementEnding endCommand(PDMS_OWNER);
188  return endCommand.execute(item);
189  }
190 
191  GenericItem *result = nullptr;
192  // Search for the referenced item depending on the reference type
193  if (isNameReference()) {
194  // Use the hierarchy scanning function given the requested object name
195  if (item) return false;
196  result = item->getRoot()->scan(refname);
197  }
198  // Request for an element (hierarchical or design element only)
199  else if (isTokenReference()) {
200  if (PdmsToken::isGroupElement(token)) {
201  // Go up in the hierarchy to find a matching, or the first group
202  // which can own the request item
203  result = item;
204  while (result && result->getType() > token) result = result->owner;
205  if (!result) result = &defaultWorld;
206  } else if (PdmsToken::isDesignElement(token)) {
207  // Go up in the hierarchy until we meet the requested type
208  result = item;
209  while (result && result->getType() != token) result = result->owner;
210  } else
211  return false;
212  }
213 
214  // If the reference command is PDMS_OWNER, then we have to change the
215  // request item owner
216  if (command == PDMS_OWNER && result) {
217  if (!item) return false;
218  item->owner = result;
219  result = item;
220  }
221 
222  if (result) item = result;
223 
224  return (result != nullptr);
225 }
226 
228  if (current >= 3) return false;
229 
230  // Check that current active command cannot handle this token (if it cannot,
231  // check that it is valid before continuing)
232  if (current >= 0) {
233  if (coords[current].handle(t)) return true;
234  if (!coords[current].isValid()) return false;
235  }
236 
237  // Handle coordinates commands
238  if (!PdmsToken::isCoordinate(t)) return false;
239 
240  if (++current >= 3) return false;
241 
242  coords[current].command = t;
243  // coords[current].value = 1;
244  coords[current].value = 0;
245 
246  return true;
247 }
248 
250  if (current < 0 || current >= 3) return false;
251 
252  // Only coordinates can handle numerical values
253  if (!PdmsToken::isCoordinate(coords[current].command)) return false;
254 
255  return coords[current].handle(numvalue);
256 }
257 
258 bool Coordinates::isValid() const {
259  // Can't be invalid
260  return true;
261 }
262 
264  bool ok[3] = {false, false, false};
265  u = CCVector3(0, 0, 0);
266 
267  int nb = getNbComponents();
268  for (int i = 0; i < nb; i++) {
269  if (!coords[i].isValid()) return false;
270  if (ok[i]) return false;
271  switch (coords[i].command) {
272  case PDMS_X:
273  case PDMS_EST:
274  u[0] = coords[i].getValueInWorkingUnit();
275  ok[0] = true;
276  break;
277 
278  case PDMS_WEST:
279  u[0] = -coords[i].getValueInWorkingUnit();
280  ok[0] = true;
281  break;
282 
283  case PDMS_Y:
284  case PDMS_NORTH:
285  u[1] = coords[i].getValueInWorkingUnit();
286  ok[1] = true;
287  break;
288 
289  case PDMS_SOUTH:
290  u[1] = -coords[i].getValueInWorkingUnit();
291  ok[1] = true;
292  break;
293 
294  case PDMS_Z:
295  case PDMS_UP:
296  u[2] = coords[i].getValueInWorkingUnit();
297  ok[2] = true;
298  break;
299 
300  case PDMS_DOWN:
301  u[2] = -coords[i].getValueInWorkingUnit();
302  ok[2] = true;
303  break;
304 
305  default:
306  return false;
307  }
308  }
309  return true;
310 }
311 
312 int Coordinates::getNbComponents(bool onlyset) const {
313  int nb = 0;
314  for (int i = 0; i < 3; i++) {
315  if (PdmsToken::isCoordinate(coords[i].command)) {
316  if (!onlyset || coords[nb].valueChanges >= 1) nb++;
317  }
318  }
319  return nb;
320 }
321 
323  // Check if current activ command can handle this token (if it cannot, check
324  // that it is valid before continuing)
325  if (current) {
326  if (current->handle(t)) return true;
327  if (!current->isValid()) return false;
328  }
329  // If no current command is activ, then token must be either a reference
330  // command or a coordinate ID Handle PDMS_WRT (and check it has not been
331  // handled yet)
332  if (t == PDMS_WRT) {
333  current = &ref;
334  if (current->command) return false;
335  current->command = t;
336  return true;
337  }
338  // Handle coordinates ID
339  if (PdmsToken::isCoordinate(t)) {
340  current = &position;
341  return current->handle(t);
342  }
343  // Not handled
344  return false;
345 }
346 
348  if (!current) return false;
349  return current->handle(numvalue);
350 }
351 
352 bool Position::handle(const char *str) {
353  if (!current) return false;
354  return current->handle(str);
355 }
356 
357 bool Position::isValid() const {
358  if (!position.isValid()) return false;
359  if (ref.command == PDMS_WRT) return ref.isValid();
360  return true;
361 }
362 
364  if (!item) return false;
365 
366  // Resolve reference if needed
367  GenericItem *refpos = nullptr;
368  if (ref.isValid()) {
369  refpos = item;
370  if (!ref.execute(refpos)) return false;
371  }
372 
373  // Get position point
374  CCVector3 p;
375  position.getVector(p);
376  item->setPosition(p);
377  item->positionReference = refpos;
378 
379  return true;
380 }
381 
383  // Check that current active command cannot handle this token (if it cannot,
384  // check that it is valid before continuing)
385  if (current) {
386  if (current->handle(t)) return true;
387  if (!current->isValid()) return false;
388  }
389  // PDMS_AND command exits current coordinates system
390  if (t == PDMS_AND) {
391  if (!current || !current->isValid()) return false;
392  current = nullptr;
393  return true;
394  }
395  // PDMS_IS activates last specified component
396  if (t == PDMS_IS) {
397  if (component < 0 || component >= 3) return false;
398  if (current) return false;
399  current = &orientation[component];
400  return true;
401  }
402  // Handle PDMS_WRT (and check it has not been handled yet)
403  if (t == PDMS_WRT) {
404  if (component < 0 || component >= 3) return false;
405  current = &refs[component];
406  if (current->command) return false;
407  current->command = t;
408  return true;
409  }
410  // Handle coordinates ID : here, we should create a new orientation axis
411  // (since no current element is activ)
412  if (PdmsToken::isCoordinate(t)) {
413  if (++component >= 3) return false;
414  orientation[component].command = t;
415  current = nullptr;
416  return true;
417  }
418  return false;
419 }
420 
422  return current ? current->handle(numvalue) : false;
423 }
424 
425 bool Orientation::handle(const char *str) {
426  return current ? current->handle(str) : false;
427 }
428 
429 bool Orientation::isValid() const {
430  int nb = getNbComponents();
431  if (nb <= 0) return false;
432 
433  for (int i = 0; i < nb; i++) {
434  if (PdmsToken::isCoordinate(orientation[i].command)) return false;
435  if (!orientation[i].isValid()) return false;
436  if (refs[i].command == PDMS_WRT && !refs[i].isValid()) return false;
437  }
438 
439  return true;
440 }
441 
443  x = y = z = CCVector3(0, 0, 0);
444 
445  int nb = getNbComponents();
446  for (int i = 0; i < nb; i++) {
447  if (!orientation[i].isValid()) return false;
448 
449  switch (orientation[i].command) {
450  case PDMS_X:
451  case PDMS_EST:
452  if (!axisFromCoords(orientation[i], x)) return false;
453  break;
454 
455  case PDMS_WEST:
456  if (!axisFromCoords(orientation[i], x)) return false;
457  x *= -1.;
458  break;
459 
460  case PDMS_Y:
461  case PDMS_NORTH:
462  if (!axisFromCoords(orientation[i], y)) return false;
463  break;
464 
465  case PDMS_SOUTH:
466  if (!axisFromCoords(orientation[i], y)) return false;
467  y *= -1.;
468  break;
469 
470  case PDMS_Z:
471  case PDMS_UP:
472  if (!axisFromCoords(orientation[i], z)) return false;
473  break;
474 
475  case PDMS_DOWN:
476  if (!axisFromCoords(orientation[i], z)) return false;
477  z *= -1.;
478  break;
479 
480  default:
481  return false;
482  }
483  }
484 
485  return nb != 0;
486 }
487 
489  if (!coords.getVector(u)) return false;
490 
491  if (coords.getNbComponents(true) == 2) {
494  u[0] = cos(alpha) * cos(beta);
495  u[1] = sin(alpha) * cos(beta);
496  u[2] = sin(beta);
497  }
498 
499  return true;
500 }
501 
503  int nb = 0;
504  while (nb < 3 && orientation[nb].command) nb++;
505  return nb;
506 }
507 
509  if (!item) return false;
510 
511  // Resolve reference if needed
512  for (unsigned i = 0; i < 3; i++) {
513  GenericItem *refori = nullptr;
514  if (refs[i].isValid()) {
515  refori = item;
516  if (!refs[i].execute(refori)) return false;
517  }
518  item->orientationReferences[i] = refori;
519  }
520 
521  // Get position point
522  CCVector3 x, y, z;
523  if (!getAxes(x, y, z)) return false;
524 
525  item->setOrientation(x, y, z);
526  return true;
527 }
528 
530  if (!item) return false;
531 
532  strcpy(item->name, name);
533 
534  return true;
535 }
536 
537 bool ElementCreation::handle(const char *str) {
538  if (!elementType) return false;
539  if (path.size() > 0) return false;
540  return splitPath(str);
541 }
542 
544  if (PdmsToken::isElement(t)) {
545  if (elementType) return false;
546  elementType = t;
547  return true;
548  }
549  return false;
550 }
551 
553  return PdmsToken::isElement(elementType);
554 }
555 
557  switch (token) {
558  case PDMS_GROUP:
559  return "Group";
560  case PDMS_WORLD:
561  return "World";
562  case PDMS_SITE:
563  return "Site";
564  case PDMS_ZONE:
565  return "Zone";
566  case PDMS_EQUIPMENT:
567  return "Equipment";
568  case PDMS_STRUCTURE:
569  return "Structure";
570  case PDMS_SUBSTRUCTURE:
571  return "Sub-structure";
572  // PDMS elements
573  case PDMS_SCYLINDER:
574  return "Cylinder";
575  case PDMS_CTORUS:
576  return "Torus (C)";
577  case PDMS_RTORUS:
578  return "Torus (R)";
579  case PDMS_DISH:
580  return "Dish";
581  case PDMS_CONE:
582  return "Cone";
583  case PDMS_BOX:
584  return "Box";
585  case PDMS_NBOX:
586  return "Box(-)";
587  case PDMS_PYRAMID:
588  return "Pyramid";
589  case PDMS_SNOUT:
590  return "Snout";
591  case PDMS_EXTRU:
592  return "Extrusion";
593  case PDMS_NEXTRU:
594  return "Extrusion(-)";
595  case PDMS_LOOP:
596  return "Loop";
597  case PDMS_VERTEX:
598  return "Vertex";
599 
600  default:
601  break;
602  }
603 
604  return 0;
605 }
606 
608  GenericItem *newElement = nullptr;
609 
610  try {
611  switch (elementType) {
612  case PDMS_GROUP:
613  case PDMS_WORLD:
614  case PDMS_SITE:
615  case PDMS_ZONE:
616  case PDMS_EQUIPMENT:
617  case PDMS_STRUCTURE:
618  case PDMS_SUBSTRUCTURE:
619  newElement = new GroupElement(elementType);
620  break;
621  // PDMS elements
622  case PDMS_SCYLINDER:
623  newElement = new SCylinder;
624  break;
625  case PDMS_CTORUS:
626  newElement = new CTorus;
627  break;
628  case PDMS_RTORUS:
629  newElement = new RTorus;
630  break;
631  case PDMS_DISH:
632  newElement = new Dish;
633  break;
634  case PDMS_CONE:
635  newElement = new Cone;
636  break;
637  case PDMS_BOX:
638  case PDMS_NBOX:
639  newElement = new Box;
640  static_cast<Box *>(newElement)->negative =
641  (elementType == PDMS_NBOX);
642  break;
643  case PDMS_PYRAMID:
644  newElement = new Pyramid;
645  break;
646  case PDMS_SNOUT:
647  newElement = new Snout;
648  break;
649  case PDMS_EXTRU:
650  case PDMS_NEXTRU:
651  newElement = new Extrusion;
652  static_cast<Extrusion *>(newElement)->negative =
653  (elementType == PDMS_NEXTRU);
654  break;
655  case PDMS_LOOP:
656  newElement = new Loop;
657  break;
658  case PDMS_VERTEX:
659  newElement = new Vertex;
660  break;
661  default:
662  break;
663  }
664  } catch (std::exception &nex) {
665  memalert(nex, 1);
666  return false;
667  }
668 
669  if (!newElement) {
670  return false;
671  }
672 
673  const char *name = GetDefaultElementName(elementType);
674  if (name) {
675  strcpy(newElement->name, name);
676  }
677 
678  // If the path is changed during the creation, do it now
679  if (path.size() > 1) {
680  if (!item) {
681  // delete newElement;
682  PdmsObjects::Stack::Destroy(newElement);
683  return false;
684  }
685  PdmsObjects::GenericItem *mitem = item->getRoot();
686  for (unsigned i = 0; i + 1 < path.size(); i++) {
687  mitem = mitem->scan(path[i].c_str());
688  if (!mitem) {
689  // delete newElement;
690  PdmsObjects::Stack::Destroy(newElement);
691  return false;
692  }
693  }
694  item = mitem;
695  }
696 
697  // Then we can (try to) push the new element in the hierarchy
698  if (item && !item->push(newElement)) {
699  // delete newElement;
700  PdmsObjects::Stack::Destroy(newElement);
701  return false;
702  }
703 
704  newElement->creator = newElement->owner;
705  if (path.size()) {
706  strcpy(newElement->name, path.back().c_str());
707  }
708 
709  try {
710  s_elementsStack.insert(newElement);
711  } catch (std::exception &pex) {
712  memalert(pex, 1);
713  PdmsObjects::Stack::Destroy(newElement);
714  // delete newElement;
715  return false;
716  }
717  item = newElement;
718  return true;
719 }
720 
722  GenericItem *result = nullptr;
723  switch (command) {
724  case PDMS_OWNER:
725  // If the ending command is PDMS_OWNER, then we simply go back to
726  // the item owner
727  result = item ? item->owner : 0;
728  break;
729  case PDMS_END:
730  // Bug realworks : ignore END EXTRU command
731  if (end.isTokenReference() &&
732  (end.token == PDMS_EXTRU || end.token == PDMS_NEXTRU))
733  return true;
734  // In the general case, we have to find the references item (default
735  // : this one), and go back to its creator
736  result = item;
737  if (end.isValid() && !end.execute(result)) {
738  return false;
739  }
740  if (!result) return false;
741  result = result->creator;
742  break;
743  case PDMS_LAST:
744  if (!end.execute(result)) return false;
745  break;
746  default:
747  return false;
748  }
749 
750  item = result;
751 
752  return true;
753 }
754 
755 bool ElementCreation::splitPath(const char *str) {
756  path.clear();
757 
758  // Each time a new '/' is met, we create a new entry in the path
759  unsigned i = 0;
760  while (str[i]) {
761  if (str[i] == '/') {
762  if (i != 0) path.push_back(std::string(str, i));
763  str = &str[i + 1];
764  i = 0;
765  } else {
766  i++;
767  }
768  }
769 
770  // At the end, we have to create an entry for the last word
771  if (i != 0) path.push_back(std::string(str, i));
772 
773  return (path.size() != 0);
774 }
775 
777  GenericItem *result = item;
778  if (!result || !isValid()) return true;
779 
780  // Go back to the first creator object that matches or can contain the
781  // command hierarchy level
782  while (result && command < result->getType()) result = result->creator;
783 
784  // If we went to the root, we have to create a new hierarchy level and set
785  // it as the new root
786  if (!result) {
787  try {
788  result = new GroupElement(command);
789  } catch (std::exception &nex) {
790  memfail(nex, 1);
791  return false;
792  }
793  result->push(item);
794  }
795 
796  // change the current element as the new accessed element
797  item = result;
798  return true;
799 }
800 
802  try {
803  Command *result = nullptr;
804  switch (t) {
805  case PDMS_CREATE:
806  result = new ElementCreation;
807  break;
808  case PDMS_END:
809  case PDMS_LAST:
810  result = new ElementEnding(t);
811  break;
812  case PDMS_WRT:
813  case PDMS_OWNER:
814  result = new Reference(t);
815  break;
816  case PDMS_NAME:
817  result = new Name;
818  break;
819  // Attributes
820  case PDMS_DIAMETER:
821  case PDMS_HEIGHT:
822  case PDMS_RADIUS:
823  case PDMS_INSIDE_RADIUS:
824  case PDMS_OUTSIDE_RADIUS:
825  case PDMS_TOP_DIAMETER:
827  case PDMS_XLENGTH:
828  case PDMS_YLENGTH:
829  case PDMS_ZLENGTH:
830  case PDMS_X_OFF:
831  case PDMS_Y_OFF:
832  case PDMS_X_BOTTOM:
833  case PDMS_Y_BOTTOM:
834  case PDMS_X_TOP:
835  case PDMS_Y_TOP:
836  result = new DistanceValue(t);
837  break;
838  case PDMS_X_TOP_SHEAR:
839  case PDMS_X_BOTTOM_SHEAR:
840  case PDMS_Y_TOP_SHEAR:
841  case PDMS_Y_BOTTOM_SHEAR:
842  case PDMS_ANGLE:
843  result = new NumericalValue(t);
844  break;
845  case PDMS_POSITION:
846  result = new Position;
847  break;
848  case PDMS_ORIENTATION:
849  result = new Orientation;
850  break;
851  case PDMS_WORLD:
852  case PDMS_SITE:
853  case PDMS_ZONE:
854  case PDMS_EQUIPMENT:
855  case PDMS_STRUCTURE:
856  case PDMS_SUBSTRUCTURE:
857  result = new HierarchyNavigation(t);
858  break;
859  default:
860  break;
861  }
862  return result;
863  } catch (std::exception &nex) {
864  memfail(nex, 1);
865  return nullptr;
866  }
867 }
868 
870 // PDMS OBJECTS IMPLEMENTATION
872 
873 GenericItem::GenericItem()
874  : owner(nullptr),
875  creator(nullptr),
876  position(0, 0, 0),
877  isCoordinateSystemUpToDate(false),
878  positionReference(nullptr) {
880  orientationReferences[2] = nullptr;
881  orientation[0] = CCVector3(0, 0, 0);
882  orientation[0][0] = 1;
883  orientation[1] = CCVector3(0, 0, 0);
884  orientation[1][1] = 1;
885  orientation[2] = CCVector3(0, 0, 0);
886  orientation[2][2] = 1;
887  name[0] = '\0';
888 }
889 
891  position = p;
892  return true;
893 }
894 
896  const CCVector3 &y,
897  const CCVector3 &z) {
898  orientation[0] = x;
899  orientation[1] = y;
900  orientation[2] = z;
901  return true;
902 }
903 
904 bool GenericItem::isOrientationValid(unsigned i) const {
905  return cloudViewer::GreaterThanEpsilon(orientation[i].norm2());
906 }
907 
909  bool ok[3] = {isOrientationValid(0), isOrientationValid(1),
910  isOrientationValid(2)};
911 
912  unsigned nb = static_cast<unsigned>(ok[0]) + static_cast<unsigned>(ok[1]) +
913  static_cast<unsigned>(ok[2]);
914 
915  switch (nb) {
916  case 0:
917  return false;
918 
919  case 1:
920 
921  if (ok[0]) {
922  orientation[0].normalize();
925  break;
926  }
927  if (ok[1]) {
928  orientation[1].normalize();
931  break;
932  }
933  if (ok[2]) {
934  orientation[2].normalize();
937  break;
938  }
939 
940  case 2:
941 
942  if (!ok[0]) {
943  orientation[1].normalize();
944  orientation[2].normalize();
946  }
947  if (!ok[1]) {
948  orientation[0].normalize();
949  orientation[2].normalize();
951  }
952  if (!ok[2]) {
953  orientation[0].normalize();
954  orientation[1].normalize();
956  }
957  break;
958 
959  case 3:
960  break;
961 
962  default:
963  return false;
964  }
965 
966  return true;
967 }
968 
970  if (isCoordinateSystemUpToDate) return true;
972  // init orientationReferences
973  {
974  for (unsigned k = 0; k < 3; k++)
976  }
977  // Update position coordinates
978  if (positionReference) {
979  if (!positionReference->convertCoordinateSystem()) return false;
980  // New position is reference origin plus
981  // sum(reference_axis[i]*point_coordinate[i])
983  if (!ref->isCoordinateSystemUpToDate && ref->owner == this)
984  return false;
985  CCVector3 p = position;
986  for (unsigned i = 0; i < 3; i++)
987  position[i] = ref->orientation[0][i] * p[0] +
988  ref->orientation[1][i] * p[1] +
989  ref->orientation[2][i] * p[2];
990  position += ref->position;
991  }
992  // The same for orientation
993  for (unsigned k = 0; k < 3; k++) {
994  if (!isOrientationValid(k)) continue;
995  if (orientationReferences[k]) {
997  return false;
998  // New axis is sum(reference_axis[i]*axis[i])
1000  if (!ref->isCoordinateSystemUpToDate && ref->owner == this)
1001  return false;
1002 
1003  CCVector3 axis[3];
1004  {
1005  for (unsigned j = 0; j < 3; j++) axis[j] = orientation[j];
1006  }
1007  {
1008  for (unsigned j = 0; j < 3; j++)
1009  for (unsigned i = 0; i < 3; i++)
1010  orientation[j][i] =
1011  ref->orientation[0][i] * axis[j][0] +
1012  ref->orientation[1][i] * axis[j][1] +
1013  ref->orientation[2][i] * axis[j][2];
1014  }
1015  }
1016  }
1017 
1018  if (!completeOrientation()) return false;
1020 
1021  return true;
1022 }
1023 
1024 bool GenericItem::scan(Token t, std::vector<GenericItem *> &array) {
1025  if (getType() == t) {
1026  try {
1027  array.push_back(this);
1028  } catch (std::exception &pex) {
1029  memfail(pex, array.size());
1030  }
1031  return true;
1032  }
1033 
1034  return false;
1035 }
1036 
1038  for (std::list<DesignElement *>::iterator it = nelements.begin();
1039  it != nelements.end(); ++it) {
1040  GenericItem *item = *it;
1041  if (item) {
1042  Stack::Destroy(item);
1043  }
1044  }
1045  nelements.clear();
1046 }
1047 
1049  if (i->isDesignElement()) {
1050  DesignElement *element = static_cast<DesignElement *>(i);
1051  if (element->negative) {
1052  try {
1053  nelements.push_back(element);
1054  } catch (std::exception &pex) {
1055  memalert(pex, nelements.size());
1056  return false;
1057  }
1058  if (element->owner) element->owner->remove(element);
1059  element->owner = this;
1060  return true;
1061  }
1062  }
1063 
1064  // In most cases, design elements do not handle nested elements
1065  if (owner) return owner->push(i);
1066 
1067  return false;
1068 }
1069 
1071  for (std::list<DesignElement *>::iterator it = nelements.begin();
1072  it != nelements.end();) {
1073  if (*it == i)
1074  nelements.erase(it);
1075  else
1076  ++it;
1077  }
1078 }
1079 
1081  level = l;
1082  elements.clear();
1083  subhierarchy.clear();
1084  memset(name, 0, c_max_str_length);
1085 }
1086 
1088 
1089 void GroupElement::clear(bool del) {
1090  if (del) {
1091  for (std::list<DesignElement *>::iterator eit = elements.begin();
1092  eit != elements.end(); ++eit) {
1093  GenericItem *item = *eit;
1094  if (*eit) Stack::Destroy(item);
1095  }
1096  for (std::list<GroupElement *>::iterator hit = subhierarchy.begin();
1097  hit != subhierarchy.end(); ++hit) {
1098  GenericItem *item = *hit;
1099  if (*hit) Stack::Destroy(item);
1100  }
1101  }
1102  elements.clear();
1103  subhierarchy.clear();
1104 }
1105 
1107  // In each case, the insertion of a new element consists in finding the list
1108  // in which it should be added
1109 
1110  // If the request item is a group, we have to find its new place in the
1111  // hierarchy
1112  if (PdmsToken::isGroupElement(i->getType())) {
1113  // If this group can contain the request item, then insert it in the
1114  // group list
1115  GroupElement *group = dynamic_cast<GroupElement *>(i);
1116  if (group->level == PDMS_GROUP || group->level > level) {
1117  if (group->owner) group->owner->remove(group);
1118  group->owner = this;
1119 
1120  try {
1121  subhierarchy.push_back(group);
1122  } catch (std::exception &pex) {
1123  memalert(pex, subhierarchy.size());
1124  return false;
1125  }
1126  }
1127  // else the requested item should be inserted in this group owner
1128  else if (owner)
1129  owner->push(group);
1130  else
1131  return false;
1132  }
1133  // For design elements, insert it in the group' design element list
1134  else if (PdmsToken::isDesignElement(i->getType())) {
1135  if (i->owner) i->owner->remove(i);
1136  i->owner = this;
1137  try {
1138  elements.push_back(dynamic_cast<DesignElement *>(i));
1139  } catch (std::exception &pex) {
1140  memalert(pex, elements.size());
1141  return false;
1142  }
1143  return true;
1144  }
1145  return true;
1146 }
1147 
1149  for (std::list<GroupElement *>::iterator hit = subhierarchy.begin();
1150  hit != subhierarchy.end(); ++hit) {
1151  if (*hit == i) {
1152  subhierarchy.erase(hit);
1153  return;
1154  }
1155  }
1156 
1157  for (std::list<DesignElement *>::iterator eit = elements.begin();
1158  eit != elements.end(); ++eit) {
1159  if (*eit == i) {
1160  elements.erase(eit);
1161  return;
1162  }
1163  }
1164 }
1165 
1167  // Important : check that the object is not up to date, to avoid infinite
1168  // loops
1169  if (isCoordinateSystemUpToDate) return true;
1170 
1171  if (!GenericItem::convertCoordinateSystem()) return false;
1172  for (std::list<DesignElement *>::iterator eit = elements.begin();
1173  eit != elements.end(); ++eit)
1174  if (!(*eit)->convertCoordinateSystem()) return false;
1175  for (std::list<GroupElement *>::iterator hit = subhierarchy.begin();
1176  hit != subhierarchy.end(); ++hit)
1177  if (!(*hit)->convertCoordinateSystem()) return false;
1178  return true;
1179 }
1180 
1181 GenericItem *GroupElement::scan(const char *str) {
1182  // scan all elements contained in this group, beginning with this one, while
1183  // none matches the requested name
1184  GenericItem *item = GenericItem::scan(str);
1185  for (std::list<DesignElement *>::iterator eit = elements.begin();
1186  eit != elements.end() && !item; ++eit)
1187  item = (*eit)->scan(str);
1188  for (std::list<GroupElement *>::iterator hit = subhierarchy.begin();
1189  hit != subhierarchy.end() && !item; ++hit)
1190  item = (*hit)->scan(str);
1191  return item;
1192 }
1193 
1194 bool GroupElement::scan(Token t, std::vector<GenericItem *> &items) {
1195  GenericItem::scan(t, items);
1196  size_t size = items.size();
1197  for (std::list<DesignElement *>::iterator eit = elements.begin();
1198  eit != elements.end(); ++eit)
1199  (*eit)->scan(t, items);
1200  for (std::list<GroupElement *>::iterator hit = subhierarchy.begin();
1201  hit != subhierarchy.end(); ++hit)
1202  (*hit)->scan(t, items);
1203  return (items.size() > size);
1204 }
1205 
1206 std::pair<int, int> GroupElement::write(std::ostream &output,
1207  int nbtabs) const {
1208  {
1209  for (int i = 0; i < nbtabs; i++) output << "\t";
1210  }
1211  output << "NEW ";
1212 
1213  switch (level) {
1214  case PDMS_GROUP:
1215  output << "GROUP";
1216  break;
1217  case PDMS_WORLD:
1218  output << "WORLD";
1219  break;
1220  case PDMS_SITE:
1221  output << "SITE";
1222  break;
1223  case PDMS_ZONE:
1224  output << "ZONE";
1225  break;
1226  case PDMS_EQUIPMENT:
1227  output << "EQUIPMENT";
1228  break;
1229  case PDMS_STRUCTURE:
1230  output << "STRUCTURE";
1231  break;
1232  case PDMS_SUBSTRUCTURE:
1233  output << "SUBSTRUCTURE";
1234  break;
1235  default:
1236  std::cout << "Error : cannot write group " << level << std::endl;
1237  return std::pair<int, int>(0, 0);
1238  }
1239 
1240  if (strlen(name)) output << " /" << name;
1241  output << std::endl;
1242 
1243  std::pair<int, int> nb(1, 0);
1244 
1245  for (std::list<GroupElement *>::const_iterator hit = subhierarchy.begin();
1246  hit != subhierarchy.end(); ++hit) {
1247  std::pair<int, int> n = (*hit)->write(output, nbtabs + 1);
1248  nb.first += n.first;
1249  nb.second += n.second;
1250  }
1251 
1252  for (std::list<DesignElement *>::const_iterator eit = elements.begin();
1253  eit != elements.end(); ++eit) {
1254  std::pair<int, int> n = (*eit)->write(output, nbtabs + 1);
1255  nb.first += n.first;
1256  nb.second += n.second;
1257  }
1258 
1259  {
1260  for (int i = 0; i < nbtabs; i++) output << "\t";
1261  }
1262  output << "END" << std::endl;
1263  return nb;
1264 }
1265 
1267  switch (t) {
1268  case PDMS_DIAMETER:
1269  diameter = value;
1270  break;
1271  case PDMS_HEIGHT:
1272  height = value;
1273  break;
1274  case PDMS_X_TOP_SHEAR:
1275  xtshear = value;
1276  if (fabs(xtshear) > 90.) return false;
1277  break;
1278  case PDMS_Y_TOP_SHEAR:
1279  ytshear = value;
1280  if (fabs(ytshear) > 90.) return false;
1281  break;
1282  case PDMS_X_BOTTOM_SHEAR:
1283  xbshear = value;
1284  if (fabs(xbshear) > 90.) return false;
1285  break;
1286  case PDMS_Y_BOTTOM_SHEAR:
1287  ybshear = value;
1288  if (fabs(ybshear) > 90.) return false;
1289  break;
1290  default:
1291  return false;
1292  }
1293  return true;
1294 }
1295 
1297  return static_cast<PointCoordinateType>(M_PI) * diameter * height;
1298 }
1299 
1300 std::pair<int, int> SCylinder::write(std::ostream &output, int nbtabs) const {
1301  int i;
1302  for (i = 0; i < nbtabs; i++) output << "\t";
1303  output << "NEW SLCYLINDER";
1304  if (strlen(name)) output << " /" << name;
1305  output << std::endl;
1306 
1307  for (i = 0; i <= nbtabs; i++) output << "\t";
1308  output << "DIAMETER " << diameter << std::endl;
1309  for (i = 0; i <= nbtabs; i++) output << "\t";
1310  output << "HEIGHT " << height << std::endl;
1311  for (i = 0; i <= nbtabs; i++) output << "\t";
1312  output << "XTSHEAR " << cloudViewer::RadiansToDegrees(xtshear) << std::endl;
1313  for (i = 0; i <= nbtabs; i++) output << "\t";
1314  output << "XBSHEAR " << cloudViewer::RadiansToDegrees(xbshear) << std::endl;
1315  for (i = 0; i <= nbtabs; i++) output << "\t";
1316  output << "YTSHEAR " << cloudViewer::RadiansToDegrees(ytshear) << std::endl;
1317  for (i = 0; i <= nbtabs; i++) output << "\t";
1318  output << "YBSHEAR " << cloudViewer::RadiansToDegrees(ybshear) << std::endl;
1319  for (i = 0; i <= nbtabs; i++) output << "\t";
1320  output << "AT X " << position[0] << " Y " << position[1] << " Z "
1321  << position[2] << std::endl;
1322  for (i = 0; i <= nbtabs; i++) output << "\t";
1323  output << "ORI ";
1324  output << "X is X " << orientation[0][0] << " Y " << orientation[0][1]
1325  << " Z " << orientation[0][2];
1326  output << " AND Z is X " << orientation[2][0] << " Y " << orientation[2][1]
1327  << " Z " << orientation[2][2] << std::endl;
1328 
1329  for (i = 0; i < nbtabs; i++) output << "\t";
1330 
1331  output << "END" << std::endl;
1332 
1333  return std::pair<int, int>(0, 1);
1334 }
1335 
1337  switch (t) {
1338  case PDMS_ANGLE:
1339  angle = value;
1340  if (fabs(angle) > (2. * M_PI)) return false;
1341  break;
1342  case PDMS_INSIDE_RADIUS:
1343  inside_radius = value;
1344  break;
1345  case PDMS_OUTSIDE_RADIUS:
1346  outside_radius = value;
1347  break;
1348  default:
1349  return false;
1350  }
1351  return true;
1352 }
1353 
1355  PointCoordinateType r = static_cast<PointCoordinateType>(0.5) *
1358  return (angle / static_cast<PointCoordinateType>(2.0 * M_PI)) *
1359  (static_cast<PointCoordinateType>(4.0 * PDMS_SQR(M_PI)) * r * R);
1360 }
1361 
1362 std::pair<int, int> CTorus::write(std::ostream &output, int nbtabs) const {
1363  int i;
1364 
1365  for (i = 0; i < nbtabs; i++) output << "\t";
1366  output << "NEW CTORUS";
1367  if (strlen(name)) output << " /" << name;
1368  output << std::endl;
1369 
1370  for (i = 0; i <= nbtabs; i++) output << "\t";
1371  output << "RINSIDE " << inside_radius << std::endl;
1372  for (i = 0; i <= nbtabs; i++) output << "\t";
1373  output << "ROUTSIDE " << outside_radius << std::endl;
1374  for (i = 0; i <= nbtabs; i++) output << "\t";
1375  output << "ANGLE " << cloudViewer::RadiansToDegrees(angle) << std::endl;
1376  for (i = 0; i <= nbtabs; i++) output << "\t";
1377  output << "AT X " << position[0] << " Y " << position[1] << " Z "
1378  << position[2] << std::endl;
1379  for (i = 0; i <= nbtabs; i++) output << "\t";
1380  output << "ORI ";
1381  output << "X is X " << orientation[0][0] << " Y " << orientation[0][1]
1382  << " Z " << orientation[0][2];
1383  output << " AND Z is X " << orientation[2][0] << " Y " << orientation[2][1]
1384  << " Z " << orientation[2][2] << std::endl;
1385 
1386  for (i = 0; i < nbtabs; i++) output << "\t";
1387  output << "END" << std::endl;
1388 
1389  return std::pair<int, int>(0, 1);
1390 }
1391 
1393  switch (t) {
1394  case PDMS_ANGLE:
1395  angle = value;
1396  if (fabs(angle) > (2. * M_PI)) return false;
1397  break;
1398  case PDMS_INSIDE_RADIUS:
1399  inside_radius = value;
1400  break;
1401  case PDMS_OUTSIDE_RADIUS:
1402  outside_radius = value;
1403  break;
1404  case PDMS_HEIGHT:
1405  height = value;
1406  break;
1407  default:
1408  return false;
1409  }
1410  return true;
1411 }
1412 
1414  PointCoordinateType inside = static_cast<PointCoordinateType>(2.0 * M_PI) *
1416  PointCoordinateType outside = static_cast<PointCoordinateType>(2.0 * M_PI) *
1418  PointCoordinateType updown =
1419  static_cast<PointCoordinateType>(2.0 * M_PI) *
1421  return (angle / static_cast<PointCoordinateType>(2.0 * M_PI)) *
1422  (inside + outside + updown);
1423 }
1424 
1425 std::pair<int, int> RTorus::write(std::ostream &output, int nbtabs) const {
1426  int i;
1427 
1428  for (i = 0; i < nbtabs; i++) output << "\t";
1429  output << "NEW RTORUS";
1430  if (strlen(name)) output << " /" << name;
1431  output << std::endl;
1432 
1433  for (i = 0; i <= nbtabs; i++) output << "\t";
1434  output << "RINSIDE " << inside_radius << std::endl;
1435  for (i = 0; i <= nbtabs; i++) output << "\t";
1436  output << "ROUTSIDE " << outside_radius << std::endl;
1437  for (i = 0; i <= nbtabs; i++) output << "\t";
1438  output << "HEIGHT " << height << std::endl;
1439  for (i = 0; i <= nbtabs; i++) output << "\t";
1440  output << "ANGLE " << cloudViewer::RadiansToDegrees(angle) << std::endl;
1441  for (i = 0; i <= nbtabs; i++) output << "\t";
1442  output << "AT X " << position[0] << " Y " << position[1] << " Z "
1443  << position[2] << std::endl;
1444  for (i = 0; i <= nbtabs; i++) output << "\t";
1445  output << "ORI ";
1446  output << "X is X " << orientation[0][0] << " Y " << orientation[0][1]
1447  << " Z " << orientation[0][2];
1448  output << " AND Z is X " << orientation[2][0] << " Y " << orientation[2][1]
1449  << " Z " << orientation[2][2] << std::endl;
1450 
1451  for (i = 0; i < nbtabs; i++) output << "\t";
1452  output << "END" << std::endl;
1453 
1454  return std::pair<int, int>(0, 1);
1455 }
1456 
1457 Dish::Dish() : diameter(0), height(0), radius(0) {}
1458 
1460  switch (t) {
1461  case PDMS_HEIGHT:
1462  height = value;
1463  break;
1464  case PDMS_RADIUS:
1465  radius = value;
1466  break;
1467  case PDMS_DIAMETER:
1468  diameter = value;
1469  break;
1470  default:
1471  return false;
1472  }
1473  return true;
1474 }
1475 
1479  static_cast<PointCoordinateType>(0.5f * diameter);
1481  return static_cast<PointCoordinateType>(2.0 * M_PI) * PDMS_SQR(r);
1482  if (2 * height > diameter) {
1483  PointCoordinateType a = acos(r / height);
1484  return static_cast<PointCoordinateType>(M_PI) *
1485  (PDMS_SQR(r) + (a * r * height / sin(a)));
1486  } else {
1487  PointCoordinateType a = acos(height / r);
1488  return static_cast<PointCoordinateType>(M_PI) *
1489  (PDMS_SQR(r) +
1490  ((PDMS_SQR(height) / sin(a)) * log((1 + sin(a)) / cos(a))));
1491  }
1492  }
1493  return static_cast<PointCoordinateType>(M_PI) * diameter * height;
1494 }
1495 
1496 std::pair<int, int> Dish::write(std::ostream &output, int nbtabs) const {
1497  int i;
1498 
1499  for (i = 0; i < nbtabs; i++) output << "\t";
1500  output << "NEW DISH";
1501  if (strlen(name)) output << " /" << name;
1502  output << std::endl;
1503 
1504  for (i = 0; i <= nbtabs; i++) output << "\t";
1505  output << "HEIGHT " << height << std::endl;
1506  for (i = 0; i <= nbtabs; i++) output << "\t";
1507  output << "RADIUS " << radius << std::endl;
1508  for (i = 0; i <= nbtabs; i++) output << "\t";
1509  output << "DIAMETER " << diameter << std::endl;
1510  for (i = 0; i <= nbtabs; i++) output << "\t";
1511  output << "AT X " << position[0] << " Y " << position[1] << " Z "
1512  << position[2] << std::endl;
1513  for (i = 0; i <= nbtabs; i++) output << "\t";
1514  output << "ORI ";
1515  output << "X is X " << orientation[0][0] << " Y " << orientation[0][1]
1516  << " Z " << orientation[0][2];
1517  output << " AND Z is X " << orientation[2][0] << " Y " << orientation[2][1]
1518  << " Z " << orientation[2][2] << std::endl;
1519 
1520  for (i = 0; i < nbtabs; i++) output << "\t";
1521  output << "END" << std::endl;
1522 
1523  return std::pair<int, int>(0, 1);
1524 }
1525 
1527  switch (t) {
1528  case PDMS_TOP_DIAMETER:
1529  dtop = value;
1530  break;
1531  case PDMS_BOTTOM_DIAMETER:
1532  dbottom = value;
1533  break;
1534  case PDMS_HEIGHT:
1535  height = value;
1536  break;
1537  default:
1538  return false;
1539  }
1540  return true;
1541 }
1542 
1544  PointCoordinateType r1, r2;
1545  if (dtop < dbottom) {
1546  r1 = dtop;
1547  r2 = dbottom;
1548  } else {
1549  r1 = dbottom;
1550  r2 = dtop;
1551  }
1552 
1553  PointCoordinateType h1 = (r1 * height) / (r2 - r1);
1554  PointCoordinateType a1 = static_cast<PointCoordinateType>(M_PI) * r1 *
1555  sqrt(PDMS_SQR(r1) + PDMS_SQR(h1));
1556  PointCoordinateType a2 = static_cast<PointCoordinateType>(M_PI) * r2 *
1557  sqrt(PDMS_SQR(r2) + PDMS_SQR(h1 + height));
1558 
1559  return a2 - a1;
1560 }
1561 
1562 std::pair<int, int> Cone::write(std::ostream &output, int nbtabs) const {
1563  int i;
1564 
1565  for (i = 0; i < nbtabs; i++) output << "\t";
1566  output << "NEW CONE";
1567  if (strlen(name)) output << " /" << name;
1568  output << std::endl;
1569 
1570  for (i = 0; i <= nbtabs; i++) output << "\t";
1571  output << "HEIGHT " << height << std::endl;
1572  for (i = 0; i <= nbtabs; i++) output << "\t";
1573  output << "DBOTTOM " << dbottom << std::endl;
1574  for (i = 0; i <= nbtabs; i++) output << "\t";
1575  output << "DTOP " << dtop << std::endl;
1576  for (i = 0; i <= nbtabs; i++) output << "\t";
1577  output << "AT X " << position[0] << " Y " << position[1] << " Z "
1578  << position[2] << std::endl;
1579  for (i = 0; i <= nbtabs; i++) output << "\t";
1580  output << "ORI ";
1581  output << "X is X " << orientation[0][0] << " Y " << orientation[0][1]
1582  << " Z " << orientation[0][2];
1583  output << " AND Z is X " << orientation[2][0] << " Y " << orientation[2][1]
1584  << " Z " << orientation[2][2] << std::endl;
1585 
1586  for (i = 0; i < nbtabs; i++) output << "\t";
1587  output << "END" << std::endl;
1588 
1589  return std::pair<int, int>(0, 1);
1590 }
1591 
1592 Box::Box() : lengths(0, 0, 0) {}
1593 
1595  switch (t) {
1596  case PDMS_XLENGTH:
1597  lengths[0] = value;
1598  break;
1599  case PDMS_YLENGTH:
1600  lengths[1] = value;
1601  break;
1602  case PDMS_ZLENGTH:
1603  lengths[2] = value;
1604  break;
1605  default:
1606  return false;
1607  }
1608  return true;
1609 }
1610 
1612  return 2 * ((lengths[0] * lengths[1]) + (lengths[1] * lengths[2]) +
1613  (lengths[2] * lengths[0]));
1614 }
1615 
1616 std::pair<int, int> Box::write(std::ostream &output, int nbtabs) const {
1617  int i;
1618 
1619  for (i = 0; i < nbtabs; i++) output << "\t";
1620  if (negative)
1621  output << "NEW NBOX";
1622  else
1623  output << "NEW BOX";
1624  if (strlen(name)) output << " /" << name;
1625  output << std::endl;
1626 
1627  for (i = 0; i <= nbtabs; i++) output << "\t";
1628  output << "XLENGTH " << lengths[0] << std::endl;
1629  for (i = 0; i <= nbtabs; i++) output << "\t";
1630  output << "YLENGTH " << lengths[1] << std::endl;
1631  for (i = 0; i <= nbtabs; i++) output << "\t";
1632  output << "ZLENGTH " << lengths[2] << std::endl;
1633  for (i = 0; i <= nbtabs; i++) output << "\t";
1634  output << "AT X " << position[0] << " Y " << position[1] << " Z "
1635  << position[2] << std::endl;
1636  for (i = 0; i <= nbtabs; i++) output << "\t";
1637  output << "ORI ";
1638  output << "X is X " << orientation[0][0] << " Y " << orientation[0][1]
1639  << " Z " << orientation[0][2];
1640  output << " AND Z is X " << orientation[2][0] << " Y " << orientation[2][1]
1641  << " Z " << orientation[2][2] << std::endl;
1642 
1643  for (i = 0; i < nbtabs; i++) output << "\t";
1644  output << "END" << std::endl;
1645 
1646  return std::pair<int, int>(0, 1);
1647 }
1648 
1649 std::pair<int, int> Vertex::write(std::ostream &output, int nbtabs) const {
1650  return std::pair<int, int>(0, 0);
1651 }
1652 
1654  if (i->getType() == PDMS_VERTEX) {
1655  loop.push_back(dynamic_cast<Vertex *>(i));
1656  if (i->owner) i->owner->remove(i);
1657  i->owner = this;
1658  return true;
1659  }
1660  return false;
1661 }
1662 
1664  for (std::list<Vertex *>::iterator it = loop.begin(); it != loop.end();) {
1665  if ((*it) == i)
1666  loop.erase(it);
1667  else
1668  ++it;
1669  }
1670 }
1671 
1672 std::pair<int, int> Loop::write(std::ostream &output, int nbtabs) const {
1673  return std::pair<int, int>(0, 0);
1674 }
1675 
1677  if (l->getType() == PDMS_LOOP) {
1678  if (loop) return false;
1679  loop = dynamic_cast<Loop *>(l);
1680  if (l->owner) l->owner->remove(l);
1681  l->owner = this;
1682 
1683  return true;
1684  }
1685 
1686  return DesignElement::push(l);
1687 }
1688 
1690  PointCoordinateType p = 0;
1691  if (loop) {
1692  std::list<Vertex *>::const_iterator it1 = loop->loop.begin();
1693  std::list<Vertex *>::const_iterator it2 = it1;
1694  ++it2;
1695  while (it1 != loop->loop.end()) {
1696  if (it2 == loop->loop.end()) it2 = loop->loop.begin();
1697  p += ((*it1)->v - (*it2)->v).norm();
1698  ++it1;
1699  ++it2;
1700  }
1701  }
1702 
1703  return p * static_cast<PointCoordinateType>(height);
1704 }
1705 
1706 std::pair<int, int> Extrusion::write(std::ostream &output, int nbtabs) const {
1707  return std::pair<int, int>(0, 0);
1708 }
1709 
1711  switch (t) {
1712  case PDMS_X_BOTTOM:
1713  xbot = value;
1714  break;
1715  case PDMS_Y_BOTTOM:
1716  ybot = value;
1717  break;
1718  case PDMS_X_TOP:
1719  xtop = value;
1720  break;
1721  case PDMS_Y_TOP:
1722  ytop = value;
1723  break;
1724  case PDMS_X_OFF:
1725  xoff = value;
1726  break;
1727  case PDMS_Y_OFF:
1728  yoff = value;
1729  break;
1730  case PDMS_HEIGHT:
1731  height = value;
1732  break;
1733  default:
1734  return false;
1735  }
1736  return true;
1737 }
1738 
1740  // TODO
1741  return 0;
1742 }
1743 
1744 std::pair<int, int> Pyramid::write(std::ostream &output, int nbtabs) const {
1745  return std::pair<int, int>(0, 0);
1746 }
1747 
1749  switch (t) {
1750  case PDMS_BOTTOM_DIAMETER:
1751  dbottom = value;
1752  break;
1753  case PDMS_TOP_DIAMETER:
1754  dtop = value;
1755  break;
1756  case PDMS_X_OFF:
1757  xoff = value;
1758  break;
1759  case PDMS_Y_OFF:
1760  yoff = value;
1761  break;
1762  case PDMS_HEIGHT:
1763  height = value;
1764  break;
1765  default:
1766  return false;
1767  }
1768  return true;
1769 }
1770 
1772  // TODO
1773  return 0;
1774 }
1775 
1776 std::pair<int, int> Snout::write(std::ostream &output, int nbtabs) const {
1777  return std::pair<int, int>(0, 0);
1778 }
constexpr double M_PI
Pi.
Definition: CVConst.h:19
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
Definition: CVGeom.h:798
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Definition: CVTypes.h:16
int size
std::string name
int height
math::float3 position
static GroupElement defaultWorld(PDMS_WORLD)
#define memalert(e, s)
Definition: PdmsTools.cpp:28
#define memfail(e, s)
Definition: PdmsTools.cpp:31
QSet< PdmsObjects::GenericItem * > ElementsStack
Definition: PdmsTools.cpp:45
#define PDMS_SQR(a)
Definition: PdmsTools.cpp:36
static ElementsStack s_elementsStack
Definition: PdmsTools.cpp:46
core::Tensor result
Definition: VtkUtils.cpp:76
static Command * Create(Token t)
Factory.
Definition: PdmsTools.cpp:801
int getNbComponents(bool onlyset=false) const
Definition: PdmsTools.cpp:312
bool getVector(CCVector3 &u) const
Definition: PdmsTools.cpp:263
PointCoordinateType getValueInWorkingUnit() const
Definition: PdmsTools.cpp:114
virtual bool execute(PdmsObjects::GenericItem *&item) const
Definition: PdmsTools.cpp:123
virtual bool handle(const char *str)
Definition: PdmsTools.cpp:537
static const char * GetDefaultElementName(Token token)
Definition: PdmsTools.cpp:556
virtual bool execute(PdmsObjects::GenericItem *&item) const
Definition: PdmsTools.cpp:607
virtual bool execute(PdmsObjects::GenericItem *&item) const
Definition: PdmsTools.cpp:721
virtual bool execute(PdmsObjects::GenericItem *&item) const
Definition: PdmsTools.cpp:776
virtual bool execute(PdmsObjects::GenericItem *&item) const
Definition: PdmsTools.cpp:529
virtual bool handle(PointCoordinateType numvalue)
Definition: PdmsTools.cpp:82
virtual PointCoordinateType getValue() const
Definition: PdmsTools.cpp:90
virtual bool execute(PdmsObjects::GenericItem *&item) const
Definition: PdmsTools.cpp:103
static bool axisFromCoords(const Coordinates &coords, CCVector3 &u)
Definition: PdmsTools.cpp:488
bool getAxes(CCVector3 &x, CCVector3 &y, CCVector3 &z) const
Definition: PdmsTools.cpp:442
virtual bool execute(PdmsObjects::GenericItem *&item) const
Definition: PdmsTools.cpp:508
virtual bool isValid() const
Definition: PdmsTools.cpp:357
virtual bool handle(Token t)
Definition: PdmsTools.cpp:322
virtual bool execute(PdmsObjects::GenericItem *&item) const
Definition: PdmsTools.cpp:363
Reference & operator=(const Reference &ref)
Definition: PdmsTools.cpp:127
virtual bool isNameReference() const
Definition: PdmsTools.cpp:155
virtual bool isTokenReference() const
Definition: PdmsTools.cpp:157
virtual bool execute(PdmsObjects::GenericItem *&item) const
Definition: PdmsTools.cpp:166
char refname[c_max_str_length]
Definition: PdmsTools.h:527
virtual bool isValid() const
Definition: PdmsTools.cpp:151
virtual bool handle(Token t)
Definition: PdmsTools.cpp:135
virtual bool setValue(Token t, PointCoordinateType value)
Definition: PdmsTools.cpp:1594
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1616
virtual PointCoordinateType surface() const
Definition: PdmsTools.cpp:1611
Torus (circular section)
Definition: PdmsTools.h:283
PointCoordinateType angle
Definition: PdmsTools.h:287
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1362
PointCoordinateType outside_radius
Definition: PdmsTools.h:286
PointCoordinateType inside_radius
Definition: PdmsTools.h:285
virtual bool setValue(Token t, PointCoordinateType value)
Definition: PdmsTools.cpp:1336
virtual PointCoordinateType surface() const
Definition: PdmsTools.cpp:1354
PointCoordinateType dbottom
Definition: PdmsTools.h:337
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1562
PointCoordinateType height
Definition: PdmsTools.h:338
virtual bool setValue(Token t, PointCoordinateType value)
Definition: PdmsTools.cpp:1526
virtual PointCoordinateType surface() const
Definition: PdmsTools.cpp:1543
PointCoordinateType dtop
Definition: PdmsTools.h:336
virtual void remove(GenericItem *i)
Definition: PdmsTools.cpp:1070
std::list< DesignElement * > nelements
Definition: PdmsTools.h:213
virtual bool push(GenericItem *i)
Definition: PdmsTools.cpp:1048
PointCoordinateType height
Definition: PdmsTools.h:320
virtual PointCoordinateType surface() const
Definition: PdmsTools.cpp:1476
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1496
virtual bool setValue(Token t, PointCoordinateType value)
Definition: PdmsTools.cpp:1459
PointCoordinateType radius
Definition: PdmsTools.h:321
PointCoordinateType diameter
Definition: PdmsTools.h:319
PointCoordinateType height
Definition: PdmsTools.h:439
virtual bool push(GenericItem *l)
Definition: PdmsTools.cpp:1676
virtual PointCoordinateType surface() const
Definition: PdmsTools.cpp:1689
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1706
virtual GenericItem * getRoot()
Definition: PdmsTools.h:172
GenericItem * orientationReferences[3]
Reference(s) object(s) (orientation)
Definition: PdmsTools.h:154
GenericItem * positionReference
Reference object (position)
Definition: PdmsTools.h:152
virtual bool setValue(Token t, PointCoordinateType value)
Definition: PdmsTools.h:186
virtual void remove(GenericItem *i)
Definition: PdmsTools.h:178
char name[c_max_str_length]
Name.
Definition: PdmsTools.h:157
GenericItem * owner
Parent imte.
Definition: PdmsTools.h:140
virtual bool setOrientation(const CCVector3 &x, const CCVector3 &y, const CCVector3 &z)
Definition: PdmsTools.cpp:895
virtual bool push(GenericItem *i)=0
bool isOrientationValid(unsigned i) const
Definition: PdmsTools.cpp:904
GenericItem * creator
Creator item.
Definition: PdmsTools.h:142
virtual bool setPosition(const CCVector3 &p)
Definition: PdmsTools.cpp:890
virtual GenericItem * scan(const char *str)
Definition: PdmsTools.h:189
CCVector3 orientation[3]
Object orientation (X,Y and Z)
Definition: PdmsTools.h:147
CCVector3 position
Object position.
Definition: PdmsTools.h:145
bool isCoordinateSystemUpToDate
Coordinate system update flag.
Definition: PdmsTools.h:149
virtual Token getType() const
Definition: PdmsTools.h:183
std::list< DesignElement * > elements
Definition: PdmsTools.h:231
std::list< GroupElement * > subhierarchy
Definition: PdmsTools.h:232
virtual void remove(GenericItem *i)
Definition: PdmsTools.cpp:1148
virtual void clear(bool del=false)
Definition: PdmsTools.cpp:1089
virtual GenericItem * scan(const char *str)
Definition: PdmsTools.cpp:1181
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1206
virtual bool push(GenericItem *i)
Definition: PdmsTools.cpp:1106
virtual bool push(GenericItem *i)
Definition: PdmsTools.cpp:1653
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1672
virtual void remove(GenericItem *i)
Definition: PdmsTools.cpp:1663
std::list< Vertex * > loop
Definition: PdmsTools.h:416
PointCoordinateType xbot
Definition: PdmsTools.h:353
PointCoordinateType yoff
Definition: PdmsTools.h:353
PointCoordinateType height
Definition: PdmsTools.h:353
virtual PointCoordinateType surface() const
Definition: PdmsTools.cpp:1739
PointCoordinateType xtop
Definition: PdmsTools.h:353
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1744
PointCoordinateType ybot
Definition: PdmsTools.h:353
virtual bool setValue(Token t, PointCoordinateType value)
Definition: PdmsTools.cpp:1710
PointCoordinateType xoff
Definition: PdmsTools.h:353
PointCoordinateType ytop
Definition: PdmsTools.h:353
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1425
virtual bool setValue(Token t, PointCoordinateType value)
Definition: PdmsTools.cpp:1392
PointCoordinateType height
Definition: PdmsTools.h:304
virtual PointCoordinateType surface() const
Definition: PdmsTools.cpp:1413
virtual bool setValue(Token t, PointCoordinateType value)
Definition: PdmsTools.cpp:1266
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1300
virtual PointCoordinateType surface() const
Definition: PdmsTools.cpp:1296
PointCoordinateType xtshear
Definition: PdmsTools.h:259
PointCoordinateType height
Definition: PdmsTools.h:258
PointCoordinateType ybshear
Definition: PdmsTools.h:262
PointCoordinateType ytshear
Definition: PdmsTools.h:260
PointCoordinateType xbshear
Definition: PdmsTools.h:261
PointCoordinateType diameter
Definition: PdmsTools.h:257
virtual PointCoordinateType surface() const
Definition: PdmsTools.cpp:1771
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1776
PointCoordinateType xoff
Definition: PdmsTools.h:368
PointCoordinateType yoff
Definition: PdmsTools.h:368
virtual bool setValue(Token t, PointCoordinateType value)
Definition: PdmsTools.cpp:1748
static void Destroy(GenericItem *&item)
Definition: PdmsTools.cpp:70
virtual std::pair< int, int > write(std::ostream &output, int nbtabs=0) const
Definition: PdmsTools.cpp:1649
void normalize()
Sets vector norm to unity.
Definition: CVGeom.h:428
Vector3Tpl orthogonal() const
Returns a normalized vector which is orthogonal to this one.
Definition: CVGeom.h:433
Vector3Tpl cross(const Vector3Tpl &v) const
Cross product.
Definition: CVGeom.h:412
__host__ __device__ float2 fabs(float2 v)
Definition: cutil_math.h:1254
static bool isElement(Token t)
Definition: PdmsTools.h:120
static bool isDesignElement(Token t)
Definition: PdmsTools.h:114
static bool isCoordinate(Token t)
Definition: PdmsTools.h:123
static bool isGroupElement(Token t)
Definition: PdmsTools.h:117
static bool isUnit(Token t)
Definition: PdmsTools.h:130
const int c_max_str_length
Definition: PdmsTools.h:22
@ PDMS_NAME
Definition: PdmsTools.h:40
@ PDMS_X_BOTTOM_SHEAR
Definition: PdmsTools.h:86
@ PDMS_Y_TOP
Definition: PdmsTools.h:92
@ PDMS_Y_TOP_SHEAR
Definition: PdmsTools.h:87
@ PDMS_RADIUS
Definition: PdmsTools.h:99
@ PDMS_SOUTH
Definition: PdmsTools.h:54
@ PDMS_WEST
Definition: PdmsTools.h:53
@ PDMS_SCYLINDER
Definition: PdmsTools.h:69
@ PDMS_X_BOTTOM
Definition: PdmsTools.h:89
@ PDMS_DOWN
Definition: PdmsTools.h:55
@ PDMS_ZLENGTH
Definition: PdmsTools.h:97
@ PDMS_NORTH
Definition: PdmsTools.h:51
@ PDMS_Y_BOTTOM
Definition: PdmsTools.h:90
@ PDMS_SUBSTRUCTURE
Definition: PdmsTools.h:67
@ PDMS_OWNER
Definition: PdmsTools.h:41
@ PDMS_PYRAMID
Definition: PdmsTools.h:74
@ PDMS_HEIGHT
Definition: PdmsTools.h:84
@ PDMS_ORIENTATION
Definition: PdmsTools.h:106
@ PDMS_TOP_DIAMETER
Definition: PdmsTools.h:102
@ PDMS_END
Definition: PdmsTools.h:44
@ PDMS_STRUCTURE
Definition: PdmsTools.h:66
@ PDMS_METRE
Definition: PdmsTools.h:108
@ PDMS_OUTSIDE_RADIUS
Definition: PdmsTools.h:101
@ PDMS_WORLD
Definition: PdmsTools.h:62
@ PDMS_Y_BOTTOM_SHEAR
Definition: PdmsTools.h:88
@ PDMS_CONE
Definition: PdmsTools.h:73
@ PDMS_BOTTOM_DIAMETER
Definition: PdmsTools.h:103
@ PDMS_X_OFF
Definition: PdmsTools.h:93
@ PDMS_LAST
Definition: PdmsTools.h:46
@ PDMS_SITE
Definition: PdmsTools.h:63
@ PDMS_INVALID_TOKEN
Definition: PdmsTools.h:28
@ PDMS_CTORUS
Definition: PdmsTools.h:70
@ PDMS_EXTRU
Definition: PdmsTools.h:78
@ PDMS_AND
Definition: PdmsTools.h:37
@ PDMS_WRT
Definition: PdmsTools.h:42
@ PDMS_EST
Definition: PdmsTools.h:50
@ PDMS_CREATE
Definition: PdmsTools.h:43
@ PDMS_BOX
Definition: PdmsTools.h:76
@ PDMS_MILLIMETRE
Definition: PdmsTools.h:109
@ PDMS_DISH
Definition: PdmsTools.h:72
@ PDMS_VERTEX
Definition: PdmsTools.h:81
@ PDMS_POSITION
Definition: PdmsTools.h:105
@ PDMS_LOOP
Definition: PdmsTools.h:80
@ PDMS_X_TOP_SHEAR
Definition: PdmsTools.h:85
@ PDMS_DIAMETER
Definition: PdmsTools.h:83
@ PDMS_RTORUS
Definition: PdmsTools.h:71
@ PDMS_EQUIPMENT
Definition: PdmsTools.h:65
@ PDMS_SNOUT
Definition: PdmsTools.h:75
@ PDMS_GROUP
Definition: PdmsTools.h:60
@ PDMS_X_TOP
Definition: PdmsTools.h:91
@ PDMS_INSIDE_RADIUS
Definition: PdmsTools.h:100
@ PDMS_NBOX
Definition: PdmsTools.h:77
@ PDMS_Y_OFF
Definition: PdmsTools.h:94
@ PDMS_NEXTRU
Definition: PdmsTools.h:79
@ PDMS_ZONE
Definition: PdmsTools.h:64
@ PDMS_YLENGTH
Definition: PdmsTools.h:96
@ PDMS_XLENGTH
Definition: PdmsTools.h:95
@ PDMS_ANGLE
Definition: PdmsTools.h:98
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
static const std::string path
Definition: PointCloud.cpp:59
float RadiansToDegrees(int radians)
Convert radians to degrees.
Definition: CVMath.h:71
bool GreaterThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
Definition: CVMath.h:37
float DegreesToRadians(int degrees)
Convert degrees to radians.
Definition: CVMath.h:98
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
Definition: CVMath.h:23