EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4GDMLReadSolids.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4GDMLReadSolids.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // G4GDMLReadSolids implementation
27 //
28 // Author: Zoltan Torzsok, November 2007
29 // --------------------------------------------------------------------
30 
31 #include "G4GDMLReadSolids.hh"
32 #include "G4Box.hh"
33 #include "G4Cons.hh"
34 #include "G4Ellipsoid.hh"
35 #include "G4EllipticalCone.hh"
36 #include "G4EllipticalTube.hh"
37 #include "G4Hype.hh"
38 #include "G4IntersectionSolid.hh"
39 #include "G4Orb.hh"
40 #include "G4Para.hh"
41 #include "G4Paraboloid.hh"
42 #include "G4Polycone.hh"
43 #include "G4GenericPolycone.hh"
44 #include "G4Polyhedra.hh"
45 #include "G4QuadrangularFacet.hh"
46 #include "G4ReflectedSolid.hh"
47 #include "G4ScaledSolid.hh"
48 #include "G4Sphere.hh"
49 #include "G4SolidStore.hh"
50 #include "G4SubtractionSolid.hh"
51 #include "G4GenericTrap.hh"
52 #include "G4TessellatedSolid.hh"
53 #include "G4Tet.hh"
54 #include "G4Torus.hh"
55 #include "G4Transform3D.hh"
56 #include "G4Trap.hh"
57 #include "G4Trd.hh"
58 #include "G4TriangularFacet.hh"
59 #include "G4Tubs.hh"
60 #include "G4CutTubs.hh"
61 #include "G4TwistedBox.hh"
62 #include "G4TwistedTrap.hh"
63 #include "G4TwistedTrd.hh"
64 #include "G4TwistedTubs.hh"
65 #include "G4UnionSolid.hh"
66 #include "G4OpticalSurface.hh"
67 #include "G4UnitsTable.hh"
68 #include "G4SurfaceProperty.hh"
69 
70 // --------------------------------------------------------------------
71 G4GDMLReadSolids::G4GDMLReadSolids()
72  : G4GDMLReadMaterials()
73 {
74 }
75 
76 // --------------------------------------------------------------------
77 G4GDMLReadSolids::~G4GDMLReadSolids()
78 {
79 }
80 
81 // --------------------------------------------------------------------
82 void G4GDMLReadSolids::BooleanRead(
83  const xercesc::DOMElement* const booleanElement, const BooleanOp op)
84 {
85  G4String name;
86  G4String first;
87  G4String scnd;
88  G4ThreeVector position(0.0, 0.0, 0.0);
89  G4ThreeVector rotation(0.0, 0.0, 0.0);
90  G4ThreeVector firstposition(0.0, 0.0, 0.0);
91  G4ThreeVector firstrotation(0.0, 0.0, 0.0);
92 
93  const xercesc::DOMNamedNodeMap* const attributes =
94  booleanElement->getAttributes();
95  XMLSize_t attributeCount = attributes->getLength();
96 
97  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
98  ++attribute_index)
99  {
100  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
101 
102  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
103  {
104  continue;
105  }
106 
107  const xercesc::DOMAttr* const attribute =
108  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
109  if(attribute == nullptr)
110  {
111  G4Exception("G4GDMLReadSolids::BooleanRead()", "InvalidRead",
112  FatalException, "No attribute found!");
113  return;
114  }
115  const G4String attName = Transcode(attribute->getName());
116  const G4String attValue = Transcode(attribute->getValue());
117 
118  if(attName == "name")
119  {
120  name = GenerateName(attValue);
121  }
122  }
123 
124  for(xercesc::DOMNode* iter = booleanElement->getFirstChild(); iter != nullptr;
125  iter = iter->getNextSibling())
126  {
127  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
128  {
129  continue;
130  }
131 
132  const xercesc::DOMElement* const child =
133  dynamic_cast<xercesc::DOMElement*>(iter);
134  if(child == nullptr)
135  {
136  G4Exception("G4GDMLReadSolids::BooleanRead()", "InvalidRead",
137  FatalException, "No child found!");
138  return;
139  }
140  const G4String tag = Transcode(child->getTagName());
141 
142  if(tag == "first")
143  {
144  first = RefRead(child);
145  }
146  else if(tag == "second")
147  {
148  scnd = RefRead(child);
149  }
150  else if(tag == "position")
151  {
152  VectorRead(child, position);
153  }
154  else if(tag == "rotation")
155  {
156  VectorRead(child, rotation);
157  }
158  else if(tag == "positionref")
159  {
160  position = GetPosition(GenerateName(RefRead(child)));
161  }
162  else if(tag == "rotationref")
163  {
164  rotation = GetRotation(GenerateName(RefRead(child)));
165  }
166  else if(tag == "firstposition")
167  {
168  VectorRead(child, firstposition);
169  }
170  else if(tag == "firstrotation")
171  {
172  VectorRead(child, firstrotation);
173  }
174  else if(tag == "firstpositionref")
175  {
176  firstposition = GetPosition(GenerateName(RefRead(child)));
177  }
178  else if(tag == "firstrotationref")
179  {
180  firstrotation = GetRotation(GenerateName(RefRead(child)));
181  }
182  else
183  {
184  G4String error_msg = "Unknown tag in boolean solid: " + tag;
185  G4Exception("G4GDMLReadSolids::BooleanRead()", "ReadError",
186  FatalException, error_msg);
187  }
188  }
189 
190  G4VSolid* firstSolid = GetSolid(GenerateName(first));
191  G4VSolid* secondSolid = GetSolid(GenerateName(scnd));
192 
193  G4Transform3D transform(GetRotationMatrix(rotation), position);
194 
195  if(((firstrotation.x() != 0.0) || (firstrotation.y() != 0.0) ||
196  (firstrotation.z() != 0.0)) ||
197  ((firstposition.x() != 0.0) || (firstposition.y() != 0.0) ||
198  (firstposition.z() != 0.0)))
199  {
200  G4Transform3D firsttransform(GetRotationMatrix(firstrotation),
201  firstposition);
202  firstSolid = new G4DisplacedSolid(GenerateName("displaced_" + first),
203  firstSolid, firsttransform);
204  }
205 
206  if(op == UNION)
207  {
208  new G4UnionSolid(name, firstSolid, secondSolid, transform);
209  }
210  else if(op == SUBTRACTION)
211  {
212  new G4SubtractionSolid(name, firstSolid, secondSolid, transform);
213  }
214  else if(op == INTERSECTION)
215  {
216  new G4IntersectionSolid(name, firstSolid, secondSolid, transform);
217  }
218 }
219 
220 // --------------------------------------------------------------------
221 void G4GDMLReadSolids::BoxRead(const xercesc::DOMElement* const boxElement)
222 {
223  G4String name;
224  G4double lunit = 1.0;
225  G4double x = 0.0;
226  G4double y = 0.0;
227  G4double z = 0.0;
228 
229  const xercesc::DOMNamedNodeMap* const attributes =
230  boxElement->getAttributes();
231  XMLSize_t attributeCount = attributes->getLength();
232 
233  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
234  ++attribute_index)
235  {
236  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
237 
238  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
239  {
240  continue;
241  }
242 
243  const xercesc::DOMAttr* const attribute =
244  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
245  if(attribute == nullptr)
246  {
247  G4Exception("G4GDMLReadSolids::BoxRead()", "InvalidRead", FatalException,
248  "No attribute found!");
249  return;
250  }
251  const G4String attName = Transcode(attribute->getName());
252  const G4String attValue = Transcode(attribute->getValue());
253 
254  if(attName == "name")
255  {
256  name = GenerateName(attValue);
257  }
258  else if(attName == "lunit")
259  {
260  lunit = G4UnitDefinition::GetValueOf(attValue);
261  if(G4UnitDefinition::GetCategory(attValue) != "Length")
262  {
263  G4Exception("G4GDMLReadSolids::BoxRead()", "InvalidRead",
264  FatalException, "Invalid unit for length!");
265  }
266  }
267  else if(attName == "x")
268  {
269  x = eval.Evaluate(attValue);
270  }
271  else if(attName == "y")
272  {
273  y = eval.Evaluate(attValue);
274  }
275  else if(attName == "z")
276  {
277  z = eval.Evaluate(attValue);
278  }
279  }
280 
281  x *= 0.5 * lunit;
282  y *= 0.5 * lunit;
283  z *= 0.5 * lunit;
284 
285  new G4Box(name, x, y, z);
286 }
287 
288 // --------------------------------------------------------------------
289 void G4GDMLReadSolids::ConeRead(const xercesc::DOMElement* const coneElement)
290 {
291  G4String name;
292  G4double lunit = 1.0;
293  G4double aunit = 1.0;
294  G4double rmin1 = 0.0;
295  G4double rmax1 = 0.0;
296  G4double rmin2 = 0.0;
297  G4double rmax2 = 0.0;
298  G4double z = 0.0;
299  G4double startphi = 0.0;
300  G4double deltaphi = 0.0;
301 
302  const xercesc::DOMNamedNodeMap* const attributes =
303  coneElement->getAttributes();
304  XMLSize_t attributeCount = attributes->getLength();
305 
306  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
307  ++attribute_index)
308  {
309  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
310 
311  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
312  {
313  continue;
314  }
315 
316  const xercesc::DOMAttr* const attribute =
317  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
318  if(attribute == nullptr)
319  {
320  G4Exception("G4GDMLReadSolids::ConeRead()", "InvalidRead", FatalException,
321  "No attribute found!");
322  return;
323  }
324  const G4String attName = Transcode(attribute->getName());
325  const G4String attValue = Transcode(attribute->getValue());
326 
327  if(attName == "name")
328  {
329  name = GenerateName(attValue);
330  }
331  else if(attName == "lunit")
332  {
333  lunit = G4UnitDefinition::GetValueOf(attValue);
334  if(G4UnitDefinition::GetCategory(attValue) != "Length")
335  {
336  G4Exception("G4GDMLReadSolids::ConeRead()", "InvalidRead",
337  FatalException, "Invalid unit for length!");
338  }
339  }
340  else if(attName == "aunit")
341  {
342  aunit = G4UnitDefinition::GetValueOf(attValue);
343  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
344  {
345  G4Exception("G4GDMLReadSolids::ConeRead()", "InvalidRead",
346  FatalException, "Invalid unit for angle!");
347  }
348  }
349  else if(attName == "rmin1")
350  {
351  rmin1 = eval.Evaluate(attValue);
352  }
353  else if(attName == "rmax1")
354  {
355  rmax1 = eval.Evaluate(attValue);
356  }
357  else if(attName == "rmin2")
358  {
359  rmin2 = eval.Evaluate(attValue);
360  }
361  else if(attName == "rmax2")
362  {
363  rmax2 = eval.Evaluate(attValue);
364  }
365  else if(attName == "z")
366  {
367  z = eval.Evaluate(attValue);
368  }
369  else if(attName == "startphi")
370  {
371  startphi = eval.Evaluate(attValue);
372  }
373  else if(attName == "deltaphi")
374  {
375  deltaphi = eval.Evaluate(attValue);
376  }
377  }
378 
379  rmin1 *= lunit;
380  rmax1 *= lunit;
381  rmin2 *= lunit;
382  rmax2 *= lunit;
383  z *= 0.5 * lunit;
384  startphi *= aunit;
385  deltaphi *= aunit;
386 
387  new G4Cons(name, rmin1, rmax1, rmin2, rmax2, z, startphi, deltaphi);
388 }
389 
390 // --------------------------------------------------------------------
391 void G4GDMLReadSolids::ElconeRead(
392  const xercesc::DOMElement* const elconeElement)
393 {
394  G4String name;
395  G4double lunit = 1.0;
396  G4double dx = 0.0;
397  G4double dy = 0.0;
398  G4double zmax = 0.0;
399  G4double zcut = 0.0;
400 
401  const xercesc::DOMNamedNodeMap* const attributes =
402  elconeElement->getAttributes();
403  XMLSize_t attributeCount = attributes->getLength();
404 
405  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
406  ++attribute_index)
407  {
408  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
409 
410  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
411  {
412  continue;
413  }
414 
415  const xercesc::DOMAttr* const attribute =
416  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
417  if(attribute == nullptr)
418  {
419  G4Exception("G4GDMLReadSolids::ElconeRead()", "InvalidRead",
420  FatalException, "No attribute found!");
421  return;
422  }
423  const G4String attName = Transcode(attribute->getName());
424  const G4String attValue = Transcode(attribute->getValue());
425 
426  if(attName == "name")
427  {
428  name = GenerateName(attValue);
429  }
430  else if(attName == "lunit")
431  {
432  lunit = G4UnitDefinition::GetValueOf(attValue);
433  if(G4UnitDefinition::GetCategory(attValue) != "Length")
434  {
435  G4Exception("G4GDMLReadSolids::ElconeRead()", "InvalidRead",
436  FatalException, "Invalid unit for length!");
437  }
438  }
439  else if(attName == "dx")
440  {
441  dx = eval.Evaluate(attValue);
442  }
443  else if(attName == "dy")
444  {
445  dy = eval.Evaluate(attValue);
446  }
447  else if(attName == "zmax")
448  {
449  zmax = eval.Evaluate(attValue);
450  }
451  else if(attName == "zcut")
452  {
453  zcut = eval.Evaluate(attValue);
454  }
455  }
456 
457  zmax *= lunit;
458  zcut *= lunit;
459 
460  new G4EllipticalCone(name, dx, dy, zmax, zcut);
461 }
462 
463 // --------------------------------------------------------------------
464 void G4GDMLReadSolids::EllipsoidRead(
465  const xercesc::DOMElement* const ellipsoidElement)
466 {
467  G4String name;
468  G4double lunit = 1.0;
469  G4double ax = 0.0;
470  G4double by = 0.0;
471  G4double cz = 0.0;
472  G4double zcut1 = 0.0;
473  G4double zcut2 = 0.0;
474 
475  const xercesc::DOMNamedNodeMap* const attributes =
476  ellipsoidElement->getAttributes();
477  XMLSize_t attributeCount = attributes->getLength();
478 
479  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
480  ++attribute_index)
481  {
482  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
483 
484  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
485  {
486  continue;
487  }
488 
489  const xercesc::DOMAttr* const attribute =
490  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
491  if(attribute == nullptr)
492  {
493  G4Exception("G4GDMLReadSolids::EllipsoidRead()", "InvalidRead",
494  FatalException, "No attribute found!");
495  return;
496  }
497  const G4String attName = Transcode(attribute->getName());
498  const G4String attValue = Transcode(attribute->getValue());
499 
500  if(attName == "name")
501  {
502  name = GenerateName(attValue);
503  }
504  else if(attName == "lunit")
505  {
506  lunit = G4UnitDefinition::GetValueOf(attValue);
507  if(G4UnitDefinition::GetCategory(attValue) != "Length")
508  {
509  G4Exception("G4GDMLReadSolids::EllipsoidRead()", "InvalidRead",
510  FatalException, "Invalid unit for length!");
511  }
512  }
513  else if(attName == "ax")
514  {
515  ax = eval.Evaluate(attValue);
516  }
517  else if(attName == "by")
518  {
519  by = eval.Evaluate(attValue);
520  }
521  else if(attName == "cz")
522  {
523  cz = eval.Evaluate(attValue);
524  }
525  else if(attName == "zcut1")
526  {
527  zcut1 = eval.Evaluate(attValue);
528  }
529  else if(attName == "zcut2")
530  {
531  zcut2 = eval.Evaluate(attValue);
532  }
533  }
534 
535  ax *= lunit;
536  by *= lunit;
537  cz *= lunit;
538  zcut1 *= lunit;
539  zcut2 *= lunit;
540 
541  new G4Ellipsoid(name, ax, by, cz, zcut1, zcut2);
542 }
543 
544 // --------------------------------------------------------------------
545 void G4GDMLReadSolids::EltubeRead(
546  const xercesc::DOMElement* const eltubeElement)
547 {
548  G4String name;
549  G4double lunit = 1.0;
550  G4double dx = 0.0;
551  G4double dy = 0.0;
552  G4double dz = 0.0;
553 
554  const xercesc::DOMNamedNodeMap* const attributes =
555  eltubeElement->getAttributes();
556  XMLSize_t attributeCount = attributes->getLength();
557 
558  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
559  ++attribute_index)
560  {
561  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
562 
563  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
564  {
565  continue;
566  }
567 
568  const xercesc::DOMAttr* const attribute =
569  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
570  if(attribute == nullptr)
571  {
572  G4Exception("G4GDMLReadSolids::EltubeRead()", "InvalidRead",
573  FatalException, "No attribute found!");
574  return;
575  }
576  const G4String attName = Transcode(attribute->getName());
577  const G4String attValue = Transcode(attribute->getValue());
578 
579  if(attName == "name")
580  {
581  name = GenerateName(attValue);
582  }
583  else if(attName == "lunit")
584  {
585  lunit = G4UnitDefinition::GetValueOf(attValue);
586  if(G4UnitDefinition::GetCategory(attValue) != "Length")
587  {
588  G4Exception("G4GDMLReadSolids::EltubeRead()", "InvalidRead",
589  FatalException, "Invalid unit for length!");
590  }
591  }
592  else if(attName == "dx")
593  {
594  dx = eval.Evaluate(attValue);
595  }
596  else if(attName == "dy")
597  {
598  dy = eval.Evaluate(attValue);
599  }
600  else if(attName == "dz")
601  {
602  dz = eval.Evaluate(attValue);
603  }
604  }
605 
606  dx *= lunit;
607  dy *= lunit;
608  dz *= lunit;
609 
610  new G4EllipticalTube(name, dx, dy, dz);
611 }
612 
613 // --------------------------------------------------------------------
614 void G4GDMLReadSolids::XtruRead(const xercesc::DOMElement* const xtruElement)
615 {
616  G4String name;
617  G4double lunit = 1.0;
618 
619  const xercesc::DOMNamedNodeMap* const attributes =
620  xtruElement->getAttributes();
621  XMLSize_t attributeCount = attributes->getLength();
622 
623  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
624  ++attribute_index)
625  {
626  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
627 
628  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
629  {
630  continue;
631  }
632 
633  const xercesc::DOMAttr* const attribute =
634  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
635  if(attribute == nullptr)
636  {
637  G4Exception("G4GDMLReadSolids::XtruRead()", "InvalidRead", FatalException,
638  "No attribute found!");
639  return;
640  }
641  const G4String attName = Transcode(attribute->getName());
642  const G4String attValue = Transcode(attribute->getValue());
643 
644  if(attName == "name")
645  {
646  name = GenerateName(attValue);
647  }
648  else if(attName == "lunit")
649  {
650  lunit = G4UnitDefinition::GetValueOf(attValue);
651  if(G4UnitDefinition::GetCategory(attValue) != "Length")
652  {
653  G4Exception("G4GDMLReadSolids::XtruRead()", "InvalidRead",
654  FatalException, "Invalid unit for length!");
655  }
656  }
657  }
658 
659  std::vector<G4TwoVector> twoDimVertexList;
660  std::vector<G4ExtrudedSolid::ZSection> sectionList;
661 
662  for(xercesc::DOMNode* iter = xtruElement->getFirstChild(); iter != nullptr;
663  iter = iter->getNextSibling())
664  {
665  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
666  {
667  continue;
668  }
669 
670  const xercesc::DOMElement* const child =
671  dynamic_cast<xercesc::DOMElement*>(iter);
672  if(child == nullptr)
673  {
674  G4Exception("G4GDMLReadSolids::XtruRead()", "InvalidRead", FatalException,
675  "No child found!");
676  return;
677  }
678  const G4String tag = Transcode(child->getTagName());
679 
680  if(tag == "twoDimVertex")
681  {
682  twoDimVertexList.push_back(TwoDimVertexRead(child, lunit));
683  }
684  else if(tag == "section")
685  {
686  sectionList.push_back(SectionRead(child, lunit));
687  }
688  }
689 
690  new G4ExtrudedSolid(name, twoDimVertexList, sectionList);
691 }
692 
693 // --------------------------------------------------------------------
694 void G4GDMLReadSolids::HypeRead(const xercesc::DOMElement* const hypeElement)
695 {
696  G4String name;
697  G4double lunit = 1.0;
698  G4double aunit = 1.0;
699  G4double rmin = 0.0;
700  G4double rmax = 0.0;
701  G4double inst = 0.0;
702  G4double outst = 0.0;
703  G4double z = 0.0;
704 
705  const xercesc::DOMNamedNodeMap* const attributes =
706  hypeElement->getAttributes();
707  XMLSize_t attributeCount = attributes->getLength();
708 
709  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
710  ++attribute_index)
711  {
712  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
713 
714  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
715  {
716  continue;
717  }
718 
719  const xercesc::DOMAttr* const attribute =
720  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
721  if(attribute == nullptr)
722  {
723  G4Exception("G4GDMLReadSolids::HypeRead()", "InvalidRead", FatalException,
724  "No attribute found!");
725  return;
726  }
727  const G4String attName = Transcode(attribute->getName());
728  const G4String attValue = Transcode(attribute->getValue());
729 
730  if(attName == "name")
731  {
732  name = GenerateName(attValue);
733  }
734  else if(attName == "lunit")
735  {
736  lunit = G4UnitDefinition::GetValueOf(attValue);
737  if(G4UnitDefinition::GetCategory(attValue) != "Length")
738  {
739  G4Exception("G4GDMLReadSolids::HypeRead()", "InvalidRead",
740  FatalException, "Invalid unit for length!");
741  }
742  }
743  else if(attName == "aunit")
744  {
745  aunit = G4UnitDefinition::GetValueOf(attValue);
746  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
747  {
748  G4Exception("G4GDMLReadSolids::HypeRead()", "InvalidRead",
749  FatalException, "Invalid unit for angle!");
750  }
751  }
752  else if(attName == "rmin")
753  {
754  rmin = eval.Evaluate(attValue);
755  }
756  else if(attName == "rmax")
757  {
758  rmax = eval.Evaluate(attValue);
759  }
760  else if(attName == "inst")
761  {
762  inst = eval.Evaluate(attValue);
763  }
764  else if(attName == "outst")
765  {
766  outst = eval.Evaluate(attValue);
767  }
768  else if(attName == "z")
769  {
770  z = eval.Evaluate(attValue);
771  }
772  }
773 
774  rmin *= lunit;
775  rmax *= lunit;
776  inst *= aunit;
777  outst *= aunit;
778  z *= 0.5 * lunit;
779 
780  new G4Hype(name, rmin, rmax, inst, outst, z);
781 }
782 
783 // --------------------------------------------------------------------
784 void G4GDMLReadSolids::MultiUnionNodeRead(
785  const xercesc::DOMElement* const unionNodeElement,
786  G4MultiUnion* const multiUnionSolid)
787 {
788  G4String name;
789  G4String solid;
790  G4ThreeVector position(0.0, 0.0, 0.0);
791  G4ThreeVector rotation(0.0, 0.0, 0.0);
792 
793  const xercesc::DOMNamedNodeMap* const attributes =
794  unionNodeElement->getAttributes();
795  XMLSize_t attributeCount = attributes->getLength();
796 
797  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
798  ++attribute_index)
799  {
800  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
801 
802  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
803  {
804  continue;
805  }
806 
807  const xercesc::DOMAttr* const attribute =
808  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
809  if(attribute == nullptr)
810  {
811  G4Exception("G4GDMLReadSolids::MultiUnionNodeRead()", "InvalidRead",
812  FatalException, "No attribute found!");
813  return;
814  }
815  const G4String attName = Transcode(attribute->getName());
816  const G4String attValue = Transcode(attribute->getValue());
817 
818  if(attName == "name")
819  {
820  name = GenerateName(attValue);
821  }
822  }
823 
824  for(xercesc::DOMNode* iter = unionNodeElement->getFirstChild();
825  iter != nullptr; iter = iter->getNextSibling())
826  {
827  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
828  {
829  continue;
830  }
831 
832  const xercesc::DOMElement* const child =
833  dynamic_cast<xercesc::DOMElement*>(iter);
834  if(child == nullptr)
835  {
836  G4Exception("G4GDMLReadSolids::MultiUnionNodeRead()", "InvalidRead",
837  FatalException, "No child found!");
838  return;
839  }
840  const G4String tag = Transcode(child->getTagName());
841 
842  if(tag == "position")
843  {
844  VectorRead(child, position);
845  }
846  else if(tag == "rotation")
847  {
848  VectorRead(child, rotation);
849  }
850  else if(tag == "positionref")
851  {
852  position = GetPosition(GenerateName(RefRead(child)));
853  }
854  else if(tag == "rotationref")
855  {
856  rotation = GetRotation(GenerateName(RefRead(child)));
857  }
858  else if(tag == "solid")
859  {
860  solid = RefRead(child);
861  }
862  else
863  {
864  G4String error_msg = "Unknown tag in MultiUnion structure: " + tag;
865  G4Exception("G4GDMLReadSolids::MultiUnionNodeRead()", "ReadError",
866  FatalException, error_msg);
867  }
868  }
869  G4VSolid* solidNode = GetSolid(GenerateName(solid));
870  G4Transform3D transform(GetRotationMatrix(rotation), position);
871  multiUnionSolid->AddNode(*solidNode, transform);
872 }
873 
874 // --------------------------------------------------------------------
875 void G4GDMLReadSolids::MultiUnionRead(
876  const xercesc::DOMElement* const unionElement)
877 {
878  G4String name;
879 
880  const xercesc::DOMNamedNodeMap* const attributes =
881  unionElement->getAttributes();
882  XMLSize_t attributeCount = attributes->getLength();
883 
884  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
885  ++attribute_index)
886  {
887  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
888 
889  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
890  {
891  continue;
892  }
893 
894  const xercesc::DOMAttr* const attribute =
895  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
896  if(attribute == nullptr)
897  {
898  G4Exception("G4GDMLReadSolids::MultiUnionRead()", "InvalidRead",
899  FatalException, "No attribute found!");
900  return;
901  }
902  const G4String attName = Transcode(attribute->getName());
903  const G4String attValue = Transcode(attribute->getValue());
904 
905  if(attName == "name")
906  {
907  name = GenerateName(attValue);
908  }
909  }
910 
911  G4MultiUnion* multiUnion = new G4MultiUnion(name);
912 
913  for(xercesc::DOMNode* iter = unionElement->getFirstChild(); iter != nullptr;
914  iter = iter->getNextSibling())
915  {
916  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
917  {
918  continue;
919  }
920 
921  const xercesc::DOMElement* const child =
922  dynamic_cast<xercesc::DOMElement*>(iter);
923  if(child == nullptr)
924  {
925  G4Exception("G4GDMLReadSolids::MultiUnionRead()", "InvalidRead",
926  FatalException, "No child found!");
927  return;
928  }
929  const G4String tag = Transcode(child->getTagName());
930 
931  if(tag == "multiUnionNode")
932  {
933  MultiUnionNodeRead(child, multiUnion);
934  }
935  else
936  {
937  G4String error_msg = "Unknown tag in MultiUnion structure: " + tag;
938  G4Exception("G4GDMLReadSolids::MultiUnionRead()", "ReadError",
939  FatalException, error_msg);
940  }
941  }
942  multiUnion->Voxelize();
943 }
944 
945 // --------------------------------------------------------------------
946 void G4GDMLReadSolids::OrbRead(const xercesc::DOMElement* const orbElement)
947 {
948  G4String name;
949  G4double lunit = 1.0;
950  G4double r = 0.0;
951 
952  const xercesc::DOMNamedNodeMap* const attributes =
953  orbElement->getAttributes();
954  XMLSize_t attributeCount = attributes->getLength();
955 
956  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
957  ++attribute_index)
958  {
959  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
960 
961  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
962  {
963  continue;
964  }
965 
966  const xercesc::DOMAttr* const attribute =
967  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
968  if(attribute == nullptr)
969  {
970  G4Exception("G4GDMLReadSolids::OrbRead()", "InvalidRead", FatalException,
971  "No attribute found!");
972  return;
973  }
974  const G4String attName = Transcode(attribute->getName());
975  const G4String attValue = Transcode(attribute->getValue());
976 
977  if(attName == "name")
978  {
979  name = GenerateName(attValue);
980  }
981  else if(attName == "lunit")
982  {
983  lunit = G4UnitDefinition::GetValueOf(attValue);
984  if(G4UnitDefinition::GetCategory(attValue) != "Length")
985  {
986  G4Exception("G4GDMLReadSolids::OrbRead()", "InvalidRead",
987  FatalException, "Invalid unit for length!");
988  }
989  }
990  else if(attName == "r")
991  {
992  r = eval.Evaluate(attValue);
993  }
994  }
995 
996  r *= lunit;
997 
998  new G4Orb(name, r);
999 }
1000 
1001 // --------------------------------------------------------------------
1002 void G4GDMLReadSolids::ParaRead(const xercesc::DOMElement* const paraElement)
1003 {
1004  G4String name;
1005  G4double lunit = 1.0;
1006  G4double aunit = 1.0;
1007  G4double x = 0.0;
1008  G4double y = 0.0;
1009  G4double z = 0.0;
1010  G4double alpha = 0.0;
1011  G4double theta = 0.0;
1012  G4double phi = 0.0;
1013 
1014  const xercesc::DOMNamedNodeMap* const attributes =
1015  paraElement->getAttributes();
1016  XMLSize_t attributeCount = attributes->getLength();
1017 
1018  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1019  ++attribute_index)
1020  {
1021  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1022 
1023  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1024  {
1025  continue;
1026  }
1027 
1028  const xercesc::DOMAttr* const attribute =
1029  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1030  if(attribute == nullptr)
1031  {
1032  G4Exception("G4GDMLReadSolids::ParaRead()", "InvalidRead", FatalException,
1033  "No attribute found!");
1034  return;
1035  }
1036  const G4String attName = Transcode(attribute->getName());
1037  const G4String attValue = Transcode(attribute->getValue());
1038 
1039  if(attName == "name")
1040  {
1041  name = GenerateName(attValue);
1042  }
1043  else if(attName == "lunit")
1044  {
1045  lunit = G4UnitDefinition::GetValueOf(attValue);
1046  if(G4UnitDefinition::GetCategory(attValue) != "Length")
1047  {
1048  G4Exception("G4GDMLReadSolids::ParaRead()", "InvalidRead",
1049  FatalException, "Invalid unit for length!");
1050  }
1051  }
1052  else if(attName == "aunit")
1053  {
1054  aunit = G4UnitDefinition::GetValueOf(attValue);
1055  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
1056  {
1057  G4Exception("G4GDMLReadSolids::ParaRead()", "InvalidRead",
1058  FatalException, "Invalid unit for angle!");
1059  }
1060  }
1061  else if(attName == "x")
1062  {
1063  x = eval.Evaluate(attValue);
1064  }
1065  else if(attName == "y")
1066  {
1067  y = eval.Evaluate(attValue);
1068  }
1069  else if(attName == "z")
1070  {
1071  z = eval.Evaluate(attValue);
1072  }
1073  else if(attName == "alpha")
1074  {
1075  alpha = eval.Evaluate(attValue);
1076  }
1077  else if(attName == "theta")
1078  {
1079  theta = eval.Evaluate(attValue);
1080  }
1081  else if(attName == "phi")
1082  {
1083  phi = eval.Evaluate(attValue);
1084  }
1085  }
1086 
1087  x *= 0.5 * lunit;
1088  y *= 0.5 * lunit;
1089  z *= 0.5 * lunit;
1090  alpha *= aunit;
1091  theta *= aunit;
1092  phi *= aunit;
1093 
1094  new G4Para(name, x, y, z, alpha, theta, phi);
1095 }
1096 
1097 // --------------------------------------------------------------------
1098 void G4GDMLReadSolids::ParaboloidRead(
1099  const xercesc::DOMElement* const paraElement)
1100 {
1101  G4String name;
1102  G4double lunit = 1.0;
1103  G4double rlo = 0.0;
1104  G4double rhi = 0.0;
1105  G4double dz = 0.0;
1106 
1107  const xercesc::DOMNamedNodeMap* const attributes =
1108  paraElement->getAttributes();
1109  XMLSize_t attributeCount = attributes->getLength();
1110 
1111  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1112  ++attribute_index)
1113  {
1114  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1115 
1116  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1117  {
1118  continue;
1119  }
1120 
1121  const xercesc::DOMAttr* const attribute =
1122  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1123  if(attribute == nullptr)
1124  {
1125  G4Exception("G4GDMLReadSolids::ParaboloidRead()", "InvalidRead",
1126  FatalException, "No attribute found!");
1127  return;
1128  }
1129  const G4String attName = Transcode(attribute->getName());
1130  const G4String attValue = Transcode(attribute->getValue());
1131 
1132  if(attName == "name")
1133  {
1134  name = GenerateName(attValue);
1135  }
1136  else if(attName == "lunit")
1137  {
1138  lunit = G4UnitDefinition::GetValueOf(attValue);
1139  if(G4UnitDefinition::GetCategory(attValue) != "Length")
1140  {
1141  G4Exception("G4GDMLReadSolids::ParaboloidRead()", "InvalidRead",
1142  FatalException, "Invalid unit for length!");
1143  }
1144  }
1145  else if(attName == "rlo")
1146  {
1147  rlo = eval.Evaluate(attValue);
1148  }
1149  else if(attName == "rhi")
1150  {
1151  rhi = eval.Evaluate(attValue);
1152  }
1153  else if(attName == "dz")
1154  {
1155  dz = eval.Evaluate(attValue);
1156  }
1157  }
1158 
1159  rlo *= 1. * lunit;
1160  rhi *= 1. * lunit;
1161  dz *= 1. * lunit;
1162 
1163  new G4Paraboloid(name, dz, rlo, rhi);
1164 }
1165 
1166 // --------------------------------------------------------------------
1167 void G4GDMLReadSolids::PolyconeRead(
1168  const xercesc::DOMElement* const polyconeElement)
1169 {
1170  G4String name;
1171  G4double lunit = 1.0;
1172  G4double aunit = 1.0;
1173  G4double startphi = 0.0;
1174  G4double deltaphi = 0.0;
1175 
1176  const xercesc::DOMNamedNodeMap* const attributes =
1177  polyconeElement->getAttributes();
1178  XMLSize_t attributeCount = attributes->getLength();
1179 
1180  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1181  ++attribute_index)
1182  {
1183  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1184 
1185  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1186  {
1187  continue;
1188  }
1189 
1190  const xercesc::DOMAttr* const attribute =
1191  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1192  if(attribute == nullptr)
1193  {
1194  G4Exception("G4GDMLReadSolids::PolyconeRead()", "InvalidRead",
1195  FatalException, "No attribute found!");
1196  return;
1197  }
1198  const G4String attName = Transcode(attribute->getName());
1199  const G4String attValue = Transcode(attribute->getValue());
1200 
1201  if(attName == "name")
1202  {
1203  name = GenerateName(attValue);
1204  }
1205  else if(attName == "lunit")
1206  {
1207  lunit = G4UnitDefinition::GetValueOf(attValue);
1208  if(G4UnitDefinition::GetCategory(attValue) != "Length")
1209  {
1210  G4Exception("G4GDMLReadSolids::PolyconeRead()", "InvalidRead",
1211  FatalException, "Invalid unit for length!");
1212  }
1213  }
1214  else if(attName == "aunit")
1215  {
1216  aunit = G4UnitDefinition::GetValueOf(attValue);
1217  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
1218  {
1219  G4Exception("G4GDMLReadSolids::PolyconeRead()", "InvalidRead",
1220  FatalException, "Invalid unit for angle!");
1221  }
1222  }
1223  else if(attName == "startphi")
1224  {
1225  startphi = eval.Evaluate(attValue);
1226  }
1227  else if(attName == "deltaphi")
1228  {
1229  deltaphi = eval.Evaluate(attValue);
1230  }
1231  }
1232 
1233  startphi *= aunit;
1234  deltaphi *= aunit;
1235 
1236  std::vector<zplaneType> zplaneList;
1237 
1238  for(xercesc::DOMNode* iter = polyconeElement->getFirstChild(); iter!= nullptr;
1239  iter = iter->getNextSibling())
1240  {
1241  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
1242  {
1243  continue;
1244  }
1245 
1246  const xercesc::DOMElement* const child =
1247  dynamic_cast<xercesc::DOMElement*>(iter);
1248  if(child == nullptr)
1249  {
1250  G4Exception("G4GDMLReadSolids::PolyconeRead()", "InvalidRead",
1251  FatalException, "No child found!");
1252  return;
1253  }
1254  const G4String tag = Transcode(child->getTagName());
1255 
1256  if(tag == "zplane")
1257  {
1258  zplaneList.push_back(ZplaneRead(child));
1259  }
1260  }
1261 
1262  G4int numZPlanes = zplaneList.size();
1263 
1264  G4double* rmin_array = new G4double[numZPlanes];
1265  G4double* rmax_array = new G4double[numZPlanes];
1266  G4double* z_array = new G4double[numZPlanes];
1267 
1268  for(G4int i = 0; i < numZPlanes; ++i)
1269  {
1270  rmin_array[i] = zplaneList[i].rmin * lunit;
1271  rmax_array[i] = zplaneList[i].rmax * lunit;
1272  z_array[i] = zplaneList[i].z * lunit;
1273  }
1274 
1275  new G4Polycone(name, startphi, deltaphi, numZPlanes, z_array, rmin_array,
1276  rmax_array);
1277 
1278  delete[] rmin_array;
1279  delete[] rmax_array;
1280  delete[] z_array;
1281 }
1282 
1283 // --------------------------------------------------------------------
1284 void G4GDMLReadSolids::GenericPolyconeRead(
1285  const xercesc::DOMElement* const polyconeElement)
1286 {
1287  G4String name;
1288  G4double lunit = 1.0;
1289  G4double aunit = 1.0;
1290  G4double startphi = 0.0;
1291  G4double deltaphi = 0.0;
1292 
1293  const xercesc::DOMNamedNodeMap* const attributes =
1294  polyconeElement->getAttributes();
1295  XMLSize_t attributeCount = attributes->getLength();
1296 
1297  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1298  ++attribute_index)
1299  {
1300  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1301 
1302  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1303  {
1304  continue;
1305  }
1306 
1307  const xercesc::DOMAttr* const attribute =
1308  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1309  if(attribute == nullptr)
1310  {
1311  G4Exception("G4GDMLReadSolids::GenericPolyconeRead()", "InvalidRead",
1312  FatalException, "No attribute found!");
1313  return;
1314  }
1315  const G4String attName = Transcode(attribute->getName());
1316  const G4String attValue = Transcode(attribute->getValue());
1317 
1318  if(attName == "name")
1319  {
1320  name = GenerateName(attValue);
1321  }
1322  else if(attName == "lunit")
1323  {
1324  lunit = G4UnitDefinition::GetValueOf(attValue);
1325  if(G4UnitDefinition::GetCategory(attValue) != "Length")
1326  {
1327  G4Exception("G4GDMLReadSolids::GenericPolyconeRead()", "InvalidRead",
1328  FatalException, "Invalid unit for length!");
1329  }
1330  }
1331  else if(attName == "aunit")
1332  {
1333  aunit = G4UnitDefinition::GetValueOf(attValue);
1334  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
1335  {
1336  G4Exception("G4GDMLReadSolids::GenericPolyconeRead()", "InvalidRead",
1337  FatalException, "Invalid unit for angle!");
1338  }
1339  }
1340  else if(attName == "startphi")
1341  {
1342  startphi = eval.Evaluate(attValue);
1343  }
1344  else if(attName == "deltaphi")
1345  {
1346  deltaphi = eval.Evaluate(attValue);
1347  }
1348  }
1349 
1350  startphi *= aunit;
1351  deltaphi *= aunit;
1352 
1353  std::vector<rzPointType> rzPointList;
1354 
1355  for(xercesc::DOMNode* iter = polyconeElement->getFirstChild();
1356  iter != nullptr; iter = iter->getNextSibling())
1357  {
1358  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
1359  {
1360  continue;
1361  }
1362 
1363  const xercesc::DOMElement* const child =
1364  dynamic_cast<xercesc::DOMElement*>(iter);
1365  if(child == nullptr)
1366  {
1367  G4Exception("G4GDMLReadSolids::GenericPolyconeRead()", "InvalidRead",
1368  FatalException, "No child found!");
1369  return;
1370  }
1371  const G4String tag = Transcode(child->getTagName());
1372 
1373  if(tag == "rzpoint")
1374  {
1375  rzPointList.push_back(RZPointRead(child));
1376  }
1377  }
1378 
1379  G4int numRZPoints = rzPointList.size();
1380 
1381  G4double* r_array = new G4double[numRZPoints];
1382  G4double* z_array = new G4double[numRZPoints];
1383 
1384  for(G4int i = 0; i < numRZPoints; ++i)
1385  {
1386  r_array[i] = rzPointList[i].r * lunit;
1387  z_array[i] = rzPointList[i].z * lunit;
1388  }
1389  new G4GenericPolycone(name, startphi, deltaphi, numRZPoints, r_array,
1390  z_array);
1391  delete[] r_array;
1392  delete[] z_array;
1393 }
1394 
1395 // --------------------------------------------------------------------
1396 void G4GDMLReadSolids::PolyhedraRead(
1397  const xercesc::DOMElement* const polyhedraElement)
1398 {
1399  G4String name;
1400  G4double lunit = 1.0;
1401  G4double aunit = 1.0;
1402  G4double startphi = 0.0;
1403  G4double deltaphi = 0.0;
1404  G4int numsides = 0;
1405 
1406  const xercesc::DOMNamedNodeMap* const attributes =
1407  polyhedraElement->getAttributes();
1408  XMLSize_t attributeCount = attributes->getLength();
1409 
1410  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1411  ++attribute_index)
1412  {
1413  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1414 
1415  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1416  {
1417  continue;
1418  }
1419 
1420  const xercesc::DOMAttr* const attribute =
1421  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1422  if(attribute == nullptr)
1423  {
1424  G4Exception("G4GDMLReadSolids::PolyhedraRead()", "InvalidRead",
1425  FatalException, "No attribute found!");
1426  return;
1427  }
1428  const G4String attName = Transcode(attribute->getName());
1429  const G4String attValue = Transcode(attribute->getValue());
1430 
1431  if(attName == "name")
1432  {
1433  name = GenerateName(attValue);
1434  }
1435  else if(attName == "lunit")
1436  {
1437  lunit = G4UnitDefinition::GetValueOf(attValue);
1438  if(G4UnitDefinition::GetCategory(attValue) != "Length")
1439  {
1440  G4Exception("G4GDMLReadSolids::PolyhedraRead()", "InvalidRead",
1441  FatalException, "Invalid unit for length!");
1442  }
1443  }
1444  else if(attName == "aunit")
1445  {
1446  aunit = G4UnitDefinition::GetValueOf(attValue);
1447  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
1448  {
1449  G4Exception("G4GDMLReadSolids::PolyhedraRead()", "InvalidRead",
1450  FatalException, "Invalid unit for angle!");
1451  }
1452  }
1453  else if(attName == "startphi")
1454  {
1455  startphi = eval.Evaluate(attValue);
1456  }
1457  else if(attName == "deltaphi")
1458  {
1459  deltaphi = eval.Evaluate(attValue);
1460  }
1461  else if(attName == "numsides")
1462  {
1463  numsides = eval.EvaluateInteger(attValue);
1464  }
1465  }
1466 
1467  startphi *= aunit;
1468  deltaphi *= aunit;
1469 
1470  std::vector<zplaneType> zplaneList;
1471 
1472  for(xercesc::DOMNode* iter = polyhedraElement->getFirstChild();
1473  iter != nullptr; iter = iter->getNextSibling())
1474  {
1475  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
1476  {
1477  continue;
1478  }
1479 
1480  const xercesc::DOMElement* const child =
1481  dynamic_cast<xercesc::DOMElement*>(iter);
1482  if(child == nullptr)
1483  {
1484  G4Exception("G4GDMLReadSolids::PolyhedraRead()", "InvalidRead",
1485  FatalException, "No child found!");
1486  return;
1487  }
1488  const G4String tag = Transcode(child->getTagName());
1489 
1490  if(tag == "zplane")
1491  {
1492  zplaneList.push_back(ZplaneRead(child));
1493  }
1494  }
1495 
1496  G4int numZPlanes = zplaneList.size();
1497 
1498  G4double* rmin_array = new G4double[numZPlanes];
1499  G4double* rmax_array = new G4double[numZPlanes];
1500  G4double* z_array = new G4double[numZPlanes];
1501 
1502  for(G4int i = 0; i < numZPlanes; ++i)
1503  {
1504  rmin_array[i] = zplaneList[i].rmin * lunit;
1505  rmax_array[i] = zplaneList[i].rmax * lunit;
1506  z_array[i] = zplaneList[i].z * lunit;
1507  }
1508 
1509  new G4Polyhedra(name, startphi, deltaphi, numsides, numZPlanes, z_array,
1510  rmin_array, rmax_array);
1511 
1512  delete[] rmin_array;
1513  delete[] rmax_array;
1514  delete[] z_array;
1515 }
1516 
1517 // --------------------------------------------------------------------
1518 void G4GDMLReadSolids::GenericPolyhedraRead(
1519  const xercesc::DOMElement* const polyhedraElement)
1520 {
1521  G4String name;
1522  G4double lunit = 1.0;
1523  G4double aunit = 1.0;
1524  G4double startphi = 0.0;
1525  G4double deltaphi = 0.0;
1526  G4int numsides = 0;
1527 
1528  const xercesc::DOMNamedNodeMap* const attributes =
1529  polyhedraElement->getAttributes();
1530  XMLSize_t attributeCount = attributes->getLength();
1531 
1532  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1533  ++attribute_index)
1534  {
1535  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1536 
1537  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1538  {
1539  continue;
1540  }
1541 
1542  const xercesc::DOMAttr* const attribute =
1543  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1544  if(attribute == nullptr)
1545  {
1546  G4Exception("G4GDMLReadSolids::GenericPolyhedraRead()", "InvalidRead",
1547  FatalException, "No attribute found!");
1548  return;
1549  }
1550  const G4String attName = Transcode(attribute->getName());
1551  const G4String attValue = Transcode(attribute->getValue());
1552 
1553  if(attName == "name")
1554  {
1555  name = GenerateName(attValue);
1556  }
1557  else if(attName == "lunit")
1558  {
1559  lunit = G4UnitDefinition::GetValueOf(attValue);
1560  if(G4UnitDefinition::GetCategory(attValue) != "Length")
1561  {
1562  G4Exception("G4GDMLReadSolids::GenericPolyhedraRead()", "InvalidRead",
1563  FatalException, "Invalid unit for length!");
1564  }
1565  }
1566  else if(attName == "aunit")
1567  {
1568  aunit = G4UnitDefinition::GetValueOf(attValue);
1569  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
1570  {
1571  G4Exception("G4GDMLReadSolids::GenericPolyhedraRead()", "InvalidRead",
1572  FatalException, "Invalid unit for angle!");
1573  }
1574  }
1575  else if(attName == "startphi")
1576  {
1577  startphi = eval.Evaluate(attValue);
1578  }
1579  else if(attName == "deltaphi")
1580  {
1581  deltaphi = eval.Evaluate(attValue);
1582  }
1583  else if(attName == "numsides")
1584  {
1585  numsides = eval.EvaluateInteger(attValue);
1586  }
1587  }
1588 
1589  startphi *= aunit;
1590  deltaphi *= aunit;
1591 
1592  std::vector<rzPointType> rzpointList;
1593 
1594  for(xercesc::DOMNode* iter = polyhedraElement->getFirstChild();
1595  iter != nullptr; iter = iter->getNextSibling())
1596  {
1597  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
1598  {
1599  continue;
1600  }
1601 
1602  const xercesc::DOMElement* const child =
1603  dynamic_cast<xercesc::DOMElement*>(iter);
1604  if(child == nullptr)
1605  {
1606  G4Exception("G4GDMLReadSolids::GenericPolyhedraRead()", "InvalidRead",
1607  FatalException, "No child found!");
1608  return;
1609  }
1610  const G4String tag = Transcode(child->getTagName());
1611 
1612  if(tag == "rzpoint")
1613  {
1614  rzpointList.push_back(RZPointRead(child));
1615  }
1616  }
1617 
1618  G4int numRZPoints = rzpointList.size();
1619 
1620  G4double* r_array = new G4double[numRZPoints];
1621  G4double* z_array = new G4double[numRZPoints];
1622 
1623  for(G4int i = 0; i < numRZPoints; ++i)
1624  {
1625  r_array[i] = rzpointList[i].r * lunit;
1626  z_array[i] = rzpointList[i].z * lunit;
1627  }
1628 
1629  new G4Polyhedra(name, startphi, deltaphi, numsides, numRZPoints, r_array,
1630  z_array);
1631 
1632  delete[] r_array;
1633  delete[] z_array;
1634 }
1635 
1636 // --------------------------------------------------------------------
1637 G4QuadrangularFacet* G4GDMLReadSolids::QuadrangularRead(
1638  const xercesc::DOMElement* const quadrangularElement)
1639 {
1640  G4ThreeVector vertex1;
1641  G4ThreeVector vertex2;
1642  G4ThreeVector vertex3;
1643  G4ThreeVector vertex4;
1644  G4FacetVertexType type = ABSOLUTE;
1645  G4double lunit = 1.0;
1646 
1647  const xercesc::DOMNamedNodeMap* const attributes =
1648  quadrangularElement->getAttributes();
1649  XMLSize_t attributeCount = attributes->getLength();
1650 
1651  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1652  ++attribute_index)
1653  {
1654  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1655 
1656  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1657  {
1658  continue;
1659  }
1660 
1661  const xercesc::DOMAttr* const attribute =
1662  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1663  if(attribute == nullptr)
1664  {
1665  G4Exception("G4GDMLReadSolids::QuadrangularRead()", "InvalidRead",
1666  FatalException, "No attribute found!");
1667  return nullptr;
1668  }
1669  const G4String attName = Transcode(attribute->getName());
1670  const G4String attValue = Transcode(attribute->getValue());
1671 
1672  if(attName == "vertex1")
1673  {
1674  vertex1 = GetPosition(GenerateName(attValue));
1675  }
1676  else if(attName == "vertex2")
1677  {
1678  vertex2 = GetPosition(GenerateName(attValue));
1679  }
1680  else if(attName == "vertex3")
1681  {
1682  vertex3 = GetPosition(GenerateName(attValue));
1683  }
1684  else if(attName == "vertex4")
1685  {
1686  vertex4 = GetPosition(GenerateName(attValue));
1687  }
1688  else if(attName == "lunit")
1689  {
1690  lunit = G4UnitDefinition::GetValueOf(attValue);
1691  if(G4UnitDefinition::GetCategory(attValue) != "Length")
1692  {
1693  G4Exception("G4GDMLReadSolids::QuadrangularRead()", "InvalidRead",
1694  FatalException, "Invalid unit for length!");
1695  }
1696  }
1697  else if(attName == "type")
1698  {
1699  if(attValue == "RELATIVE")
1700  {
1701  type = RELATIVE;
1702  }
1703  }
1704  }
1705 
1706  return new G4QuadrangularFacet(vertex1 * lunit, vertex2 * lunit,
1707  vertex3 * lunit, vertex4 * lunit, type);
1708 }
1709 
1710 // --------------------------------------------------------------------
1711 void G4GDMLReadSolids::ReflectedSolidRead(
1712  const xercesc::DOMElement* const reflectedSolidElement)
1713 {
1714  G4String name;
1715  G4double lunit = 1.0;
1716  G4double aunit = 1.0;
1717  G4String solid;
1718  G4ThreeVector scale(1.0, 1.0, 1.0);
1719  G4ThreeVector rotation;
1720  G4ThreeVector position;
1721 
1722  const xercesc::DOMNamedNodeMap* const attributes =
1723  reflectedSolidElement->getAttributes();
1724  XMLSize_t attributeCount = attributes->getLength();
1725 
1726  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1727  ++attribute_index)
1728  {
1729  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1730 
1731  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1732  {
1733  continue;
1734  }
1735 
1736  const xercesc::DOMAttr* const attribute =
1737  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1738  if(attribute == nullptr)
1739  {
1740  G4Exception("G4GDMLReadSolids::ReflectedSolidRead()", "InvalidRead",
1741  FatalException, "No attribute found!");
1742  return;
1743  }
1744  const G4String attName = Transcode(attribute->getName());
1745  const G4String attValue = Transcode(attribute->getValue());
1746 
1747  if(attName == "name")
1748  {
1749  name = GenerateName(attValue);
1750  }
1751  else if(attName == "lunit")
1752  {
1753  lunit = G4UnitDefinition::GetValueOf(attValue);
1754  if(G4UnitDefinition::GetCategory(attValue) != "Length")
1755  {
1756  G4Exception("G4GDMLReadSolids::ReflectedSolidRead()", "InvalidRead",
1757  FatalException, "Invalid unit for length!");
1758  }
1759  }
1760  else if(attName == "aunit")
1761  {
1762  aunit = G4UnitDefinition::GetValueOf(attValue);
1763  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
1764  {
1765  G4Exception("G4GDMLReadSolids::ReflectedSolidRead()", "InvalidRead",
1766  FatalException, "Invalid unit for angle!");
1767  }
1768  }
1769  else if(attName == "solid")
1770  {
1771  solid = GenerateName(attValue);
1772  }
1773  else if(attName == "sx")
1774  {
1775  scale.setX(eval.Evaluate(attValue));
1776  }
1777  else if(attName == "sy")
1778  {
1779  scale.setY(eval.Evaluate(attValue));
1780  }
1781  else if(attName == "sz")
1782  {
1783  scale.setZ(eval.Evaluate(attValue));
1784  }
1785  else if(attName == "rx")
1786  {
1787  rotation.setX(eval.Evaluate(attValue));
1788  }
1789  else if(attName == "ry")
1790  {
1791  rotation.setY(eval.Evaluate(attValue));
1792  }
1793  else if(attName == "rz")
1794  {
1795  rotation.setZ(eval.Evaluate(attValue));
1796  }
1797  else if(attName == "dx")
1798  {
1799  position.setX(eval.Evaluate(attValue));
1800  }
1801  else if(attName == "dy")
1802  {
1803  position.setY(eval.Evaluate(attValue));
1804  }
1805  else if(attName == "dz")
1806  {
1807  position.setZ(eval.Evaluate(attValue));
1808  }
1809  }
1810 
1811  rotation *= aunit;
1812  position *= lunit;
1813 
1814  G4Transform3D transform(GetRotationMatrix(rotation), position);
1815  transform = transform * G4Scale3D(scale.x(), scale.y(), scale.z());
1816 
1817  new G4ReflectedSolid(name, GetSolid(solid), transform);
1818 }
1819 
1820 // --------------------------------------------------------------------
1821 void G4GDMLReadSolids::ScaledSolidRead(
1822  const xercesc::DOMElement* const scaledSolidElement)
1823 {
1824  G4String name;
1825  G4VSolid* solid = nullptr;
1826  G4ThreeVector scale(1.0, 1.0, 1.0);
1827 
1828  const xercesc::DOMNamedNodeMap* const attributes =
1829  scaledSolidElement->getAttributes();
1830  XMLSize_t attributeCount = attributes->getLength();
1831 
1832  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1833  ++attribute_index)
1834  {
1835  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1836 
1837  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1838  {
1839  continue;
1840  }
1841 
1842  const xercesc::DOMAttr* const attribute =
1843  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1844  if(attribute == nullptr)
1845  {
1846  G4Exception("G4GDMLReadSolids::ScaledSolidRead()", "InvalidRead",
1847  FatalException, "No attribute found!");
1848  return;
1849  }
1850  const G4String attName = Transcode(attribute->getName());
1851  const G4String attValue = Transcode(attribute->getValue());
1852 
1853  if(attName == "name")
1854  {
1855  name = GenerateName(attValue);
1856  }
1857  }
1858 
1859  for(xercesc::DOMNode* iter = scaledSolidElement->getFirstChild();
1860  iter != nullptr; iter = iter->getNextSibling())
1861  {
1862  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
1863  {
1864  continue;
1865  }
1866 
1867  const xercesc::DOMElement* const child =
1868  dynamic_cast<xercesc::DOMElement*>(iter);
1869  if(child == nullptr)
1870  {
1871  G4Exception("G4GDMLReadSolids::ScaledSolidRead()", "InvalidRead",
1872  FatalException, "No child found!");
1873  return;
1874  }
1875  const G4String tag = Transcode(child->getTagName());
1876 
1877  if(tag == "solidref")
1878  {
1879  solid = GetSolid(GenerateName(RefRead(child)));
1880  }
1881  else if(tag == "scale")
1882  {
1883  VectorRead(child, scale);
1884  }
1885  else if(tag == "scaleref")
1886  {
1887  scale = GetScale(GenerateName(RefRead(child)));
1888  }
1889  else
1890  {
1891  G4String error_msg = "Unknown tag in scaled solid: " + tag;
1892  G4Exception("G4GDMLReadSolids::ScaledSolidRead()", "ReadError",
1893  FatalException, error_msg);
1894  return;
1895  }
1896  }
1897 
1898  G4Scale3D transform = G4Scale3D(scale.x(), scale.y(), scale.z());
1899 
1900  new G4ScaledSolid(name, solid, transform);
1901 }
1902 
1903 // --------------------------------------------------------------------
1904 G4ExtrudedSolid::ZSection G4GDMLReadSolids::SectionRead(
1905  const xercesc::DOMElement* const sectionElement, G4double lunit)
1906 {
1907  G4double zPosition = 0.0;
1908  G4TwoVector Offset;
1909  G4double scalingFactor = 1.0;
1910 
1911  const xercesc::DOMNamedNodeMap* const attributes =
1912  sectionElement->getAttributes();
1913  XMLSize_t attributeCount = attributes->getLength();
1914 
1915  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1916  ++attribute_index)
1917  {
1918  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1919 
1920  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1921  {
1922  continue;
1923  }
1924 
1925  const xercesc::DOMAttr* const attribute =
1926  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1927  if(attribute == nullptr)
1928  {
1929  G4Exception("G4GDMLReadSolids::SectionRead()", "InvalidRead",
1930  FatalException, "No attribute found!");
1931  return G4ExtrudedSolid::ZSection(zPosition, Offset, scalingFactor);
1932  }
1933  const G4String attName = Transcode(attribute->getName());
1934  const G4String attValue = Transcode(attribute->getValue());
1935 
1936  if(attName == "zPosition")
1937  {
1938  zPosition = eval.Evaluate(attValue) * lunit;
1939  }
1940  else if(attName == "xOffset")
1941  {
1942  Offset.setX(eval.Evaluate(attValue) * lunit);
1943  }
1944  else if(attName == "yOffset")
1945  {
1946  Offset.setY(eval.Evaluate(attValue) * lunit);
1947  }
1948  else if(attName == "scalingFactor")
1949  {
1950  scalingFactor = eval.Evaluate(attValue);
1951  }
1952  }
1953 
1954  return G4ExtrudedSolid::ZSection(zPosition, Offset, scalingFactor);
1955 }
1956 
1957 // --------------------------------------------------------------------
1958 void G4GDMLReadSolids::SphereRead(
1959  const xercesc::DOMElement* const sphereElement)
1960 {
1961  G4String name;
1962  G4double lunit = 1.0;
1963  G4double aunit = 1.0;
1964  G4double rmin = 0.0;
1965  G4double rmax = 0.0;
1966  G4double startphi = 0.0;
1967  G4double deltaphi = 0.0;
1968  G4double starttheta = 0.0;
1969  G4double deltatheta = 0.0;
1970 
1971  const xercesc::DOMNamedNodeMap* const attributes =
1972  sphereElement->getAttributes();
1973  XMLSize_t attributeCount = attributes->getLength();
1974 
1975  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
1976  ++attribute_index)
1977  {
1978  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1979 
1980  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1981  {
1982  continue;
1983  }
1984 
1985  const xercesc::DOMAttr* const attribute =
1986  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1987  if(attribute == nullptr)
1988  {
1989  G4Exception("G4GDMLReadSolids::SphereRead()", "InvalidRead",
1990  FatalException, "No attribute found!");
1991  return;
1992  }
1993  const G4String attName = Transcode(attribute->getName());
1994  const G4String attValue = Transcode(attribute->getValue());
1995 
1996  if(attName == "name")
1997  {
1998  name = GenerateName(attValue);
1999  }
2000  else if(attName == "lunit")
2001  {
2002  lunit = G4UnitDefinition::GetValueOf(attValue);
2003  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2004  {
2005  G4Exception("G4GDMLReadSolids::SphereRead()", "InvalidRead",
2006  FatalException, "Invalid unit for length!");
2007  }
2008  }
2009  else if(attName == "aunit")
2010  {
2011  aunit = G4UnitDefinition::GetValueOf(attValue);
2012  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
2013  {
2014  G4Exception("G4GDMLReadSolids::SphereRead()", "InvalidRead",
2015  FatalException, "Invalid unit for angle!");
2016  }
2017  }
2018  else if(attName == "rmin")
2019  {
2020  rmin = eval.Evaluate(attValue);
2021  }
2022  else if(attName == "rmax")
2023  {
2024  rmax = eval.Evaluate(attValue);
2025  }
2026  else if(attName == "startphi")
2027  {
2028  startphi = eval.Evaluate(attValue);
2029  }
2030  else if(attName == "deltaphi")
2031  {
2032  deltaphi = eval.Evaluate(attValue);
2033  }
2034  else if(attName == "starttheta")
2035  {
2036  starttheta = eval.Evaluate(attValue);
2037  }
2038  else if(attName == "deltatheta")
2039  {
2040  deltatheta = eval.Evaluate(attValue);
2041  }
2042  }
2043 
2044  rmin *= lunit;
2045  rmax *= lunit;
2046  startphi *= aunit;
2047  deltaphi *= aunit;
2048  starttheta *= aunit;
2049  deltatheta *= aunit;
2050 
2051  new G4Sphere(name, rmin, rmax, startphi, deltaphi, starttheta, deltatheta);
2052 }
2053 
2054 // --------------------------------------------------------------------
2055 void G4GDMLReadSolids::TessellatedRead(
2056  const xercesc::DOMElement* const tessellatedElement)
2057 {
2058  G4String name;
2059 
2060  const xercesc::DOMNamedNodeMap* const attributes =
2061  tessellatedElement->getAttributes();
2062  XMLSize_t attributeCount = attributes->getLength();
2063 
2064  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2065  ++attribute_index)
2066  {
2067  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2068 
2069  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2070  {
2071  continue;
2072  }
2073 
2074  const xercesc::DOMAttr* const attribute =
2075  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2076  if(attribute == nullptr)
2077  {
2078  G4Exception("G4GDMLReadSolids::TessellatedRead()", "InvalidRead",
2079  FatalException, "No attribute found!");
2080  return;
2081  }
2082  const G4String attName = Transcode(attribute->getName());
2083  const G4String attValue = Transcode(attribute->getValue());
2084 
2085  if(attName == "name")
2086  {
2087  name = GenerateName(attValue);
2088  }
2089  }
2090 
2091  G4TessellatedSolid* tessellated = new G4TessellatedSolid(name);
2092 
2093  for(xercesc::DOMNode* iter = tessellatedElement->getFirstChild();
2094  iter != nullptr; iter = iter->getNextSibling())
2095  {
2096  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
2097  {
2098  continue;
2099  }
2100 
2101  const xercesc::DOMElement* const child =
2102  dynamic_cast<xercesc::DOMElement*>(iter);
2103  if(child == nullptr)
2104  {
2105  G4Exception("G4GDMLReadSolids::TessellatedRead()", "InvalidRead",
2106  FatalException, "No child found!");
2107  return;
2108  }
2109  const G4String tag = Transcode(child->getTagName());
2110 
2111  if(tag == "triangular")
2112  {
2113  tessellated->AddFacet(TriangularRead(child));
2114  }
2115  else if(tag == "quadrangular")
2116  {
2117  tessellated->AddFacet(QuadrangularRead(child));
2118  }
2119  }
2120 
2121  tessellated->SetSolidClosed(true);
2122 }
2123 
2124 // --------------------------------------------------------------------
2125 void G4GDMLReadSolids::TetRead(const xercesc::DOMElement* const tetElement)
2126 {
2127  G4String name;
2128  G4ThreeVector vertex1;
2129  G4ThreeVector vertex2;
2130  G4ThreeVector vertex3;
2131  G4ThreeVector vertex4;
2132  G4double lunit = 1.0;
2133 
2134  const xercesc::DOMNamedNodeMap* const attributes =
2135  tetElement->getAttributes();
2136  XMLSize_t attributeCount = attributes->getLength();
2137 
2138  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2139  ++attribute_index)
2140  {
2141  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2142 
2143  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2144  {
2145  continue;
2146  }
2147 
2148  const xercesc::DOMAttr* const attribute =
2149  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2150  if(attribute == nullptr)
2151  {
2152  G4Exception("G4GDMLReadSolids::TetRead()", "InvalidRead", FatalException,
2153  "No attribute found!");
2154  return;
2155  }
2156  const G4String attName = Transcode(attribute->getName());
2157  const G4String attValue = Transcode(attribute->getValue());
2158 
2159  if(attName == "name")
2160  {
2161  name = GenerateName(attValue);
2162  }
2163  else if(attName == "lunit")
2164  {
2165  lunit = G4UnitDefinition::GetValueOf(attValue);
2166  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2167  {
2168  G4Exception("G4GDMLReadSolids::TetRead()", "InvalidRead",
2169  FatalException, "Invalid unit for length!");
2170  }
2171  }
2172  else if(attName == "vertex1")
2173  {
2174  vertex1 = GetPosition(GenerateName(attValue));
2175  }
2176  else if(attName == "vertex2")
2177  {
2178  vertex2 = GetPosition(GenerateName(attValue));
2179  }
2180  else if(attName == "vertex3")
2181  {
2182  vertex3 = GetPosition(GenerateName(attValue));
2183  }
2184  else if(attName == "vertex4")
2185  {
2186  vertex4 = GetPosition(GenerateName(attValue));
2187  }
2188  }
2189 
2190  new G4Tet(name, vertex1 * lunit, vertex2 * lunit, vertex3 * lunit,
2191  vertex4 * lunit);
2192 }
2193 
2194 // --------------------------------------------------------------------
2195 void G4GDMLReadSolids::TorusRead(const xercesc::DOMElement* const torusElement)
2196 {
2197  G4String name;
2198  G4double lunit = 1.0;
2199  G4double aunit = 1.0;
2200  G4double rmin = 0.0;
2201  G4double rmax = 0.0;
2202  G4double rtor = 0.0;
2203  G4double startphi = 0.0;
2204  G4double deltaphi = 0.0;
2205 
2206  const xercesc::DOMNamedNodeMap* const attributes =
2207  torusElement->getAttributes();
2208  XMLSize_t attributeCount = attributes->getLength();
2209 
2210  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2211  ++attribute_index)
2212  {
2213  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2214 
2215  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2216  {
2217  continue;
2218  }
2219 
2220  const xercesc::DOMAttr* const attribute =
2221  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2222  if(attribute == nullptr)
2223  {
2224  G4Exception("G4GDMLReadSolids::TorusRead()", "InvalidRead",
2225  FatalException, "No attribute found!");
2226  return;
2227  }
2228  const G4String attName = Transcode(attribute->getName());
2229  const G4String attValue = Transcode(attribute->getValue());
2230 
2231  if(attName == "name")
2232  {
2233  name = GenerateName(attValue);
2234  }
2235  else if(attName == "lunit")
2236  {
2237  lunit = G4UnitDefinition::GetValueOf(attValue);
2238  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2239  {
2240  G4Exception("G4GDMLReadSolids::TorusRead()", "InvalidRead",
2241  FatalException, "Invalid unit for length!");
2242  }
2243  }
2244  else if(attName == "aunit")
2245  {
2246  aunit = G4UnitDefinition::GetValueOf(attValue);
2247  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
2248  {
2249  G4Exception("G4GDMLReadSolids::TorusRead()", "InvalidRead",
2250  FatalException, "Invalid unit for angle!");
2251  }
2252  }
2253  else if(attName == "rmin")
2254  {
2255  rmin = eval.Evaluate(attValue);
2256  }
2257  else if(attName == "rmax")
2258  {
2259  rmax = eval.Evaluate(attValue);
2260  }
2261  else if(attName == "rtor")
2262  {
2263  rtor = eval.Evaluate(attValue);
2264  }
2265  else if(attName == "startphi")
2266  {
2267  startphi = eval.Evaluate(attValue);
2268  }
2269  else if(attName == "deltaphi")
2270  {
2271  deltaphi = eval.Evaluate(attValue);
2272  }
2273  }
2274 
2275  rmin *= lunit;
2276  rmax *= lunit;
2277  rtor *= lunit;
2278  startphi *= aunit;
2279  deltaphi *= aunit;
2280 
2281  new G4Torus(name, rmin, rmax, rtor, startphi, deltaphi);
2282 }
2283 
2284 // --------------------------------------------------------------------
2285 void G4GDMLReadSolids::GenTrapRead(
2286  const xercesc::DOMElement* const gtrapElement)
2287 {
2288  G4String name;
2289  G4double lunit = 1.0;
2290  G4double dz = 0.0;
2291  G4double v1x = 0.0, v1y = 0.0, v2x = 0.0, v2y = 0.0, v3x = 0.0, v3y = 0.0,
2292  v4x = 0.0, v4y = 0.0, v5x = 0.0, v5y = 0.0, v6x = 0.0, v6y = 0.0,
2293  v7x = 0.0, v7y = 0.0, v8x = 0.0, v8y = 0.0;
2294 
2295  const xercesc::DOMNamedNodeMap* const attributes =
2296  gtrapElement->getAttributes();
2297  XMLSize_t attributeCount = attributes->getLength();
2298 
2299  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2300  ++attribute_index)
2301  {
2302  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2303 
2304  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2305  {
2306  continue;
2307  }
2308 
2309  const xercesc::DOMAttr* const attribute =
2310  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2311  if(attribute == nullptr)
2312  {
2313  G4Exception("G4GDMLReadSolids::GenTrapRead()", "InvalidRead",
2314  FatalException, "No attribute found!");
2315  return;
2316  }
2317  const G4String attName = Transcode(attribute->getName());
2318  const G4String attValue = Transcode(attribute->getValue());
2319 
2320  if(attName == "name")
2321  {
2322  name = GenerateName(attValue);
2323  }
2324  else if(attName == "lunit")
2325  {
2326  lunit = G4UnitDefinition::GetValueOf(attValue);
2327  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2328  {
2329  G4Exception("G4GDMLReadSolids::GenTrapRead()", "InvalidRead",
2330  FatalException, "Invalid unit for length!");
2331  }
2332  }
2333  else if(attName == "dz")
2334  {
2335  dz = eval.Evaluate(attValue);
2336  }
2337  else if(attName == "v1x")
2338  {
2339  v1x = eval.Evaluate(attValue);
2340  }
2341  else if(attName == "v1y")
2342  {
2343  v1y = eval.Evaluate(attValue);
2344  }
2345  else if(attName == "v2x")
2346  {
2347  v2x = eval.Evaluate(attValue);
2348  }
2349  else if(attName == "v2y")
2350  {
2351  v2y = eval.Evaluate(attValue);
2352  }
2353  else if(attName == "v3x")
2354  {
2355  v3x = eval.Evaluate(attValue);
2356  }
2357  else if(attName == "v3y")
2358  {
2359  v3y = eval.Evaluate(attValue);
2360  }
2361  else if(attName == "v4x")
2362  {
2363  v4x = eval.Evaluate(attValue);
2364  }
2365  else if(attName == "v4y")
2366  {
2367  v4y = eval.Evaluate(attValue);
2368  }
2369  else if(attName == "v5x")
2370  {
2371  v5x = eval.Evaluate(attValue);
2372  }
2373  else if(attName == "v5y")
2374  {
2375  v5y = eval.Evaluate(attValue);
2376  }
2377  else if(attName == "v6x")
2378  {
2379  v6x = eval.Evaluate(attValue);
2380  }
2381  else if(attName == "v6y")
2382  {
2383  v6y = eval.Evaluate(attValue);
2384  }
2385  else if(attName == "v7x")
2386  {
2387  v7x = eval.Evaluate(attValue);
2388  }
2389  else if(attName == "v7y")
2390  {
2391  v7y = eval.Evaluate(attValue);
2392  }
2393  else if(attName == "v8x")
2394  {
2395  v8x = eval.Evaluate(attValue);
2396  }
2397  else if(attName == "v8y")
2398  {
2399  v8y = eval.Evaluate(attValue);
2400  }
2401  }
2402 
2403  dz *= lunit;
2404  std::vector<G4TwoVector> vertices;
2405  vertices.push_back(G4TwoVector(v1x * lunit, v1y * lunit));
2406  vertices.push_back(G4TwoVector(v2x * lunit, v2y * lunit));
2407  vertices.push_back(G4TwoVector(v3x * lunit, v3y * lunit));
2408  vertices.push_back(G4TwoVector(v4x * lunit, v4y * lunit));
2409  vertices.push_back(G4TwoVector(v5x * lunit, v5y * lunit));
2410  vertices.push_back(G4TwoVector(v6x * lunit, v6y * lunit));
2411  vertices.push_back(G4TwoVector(v7x * lunit, v7y * lunit));
2412  vertices.push_back(G4TwoVector(v8x * lunit, v8y * lunit));
2413  new G4GenericTrap(name, dz, vertices);
2414 }
2415 
2416 // --------------------------------------------------------------------
2417 void G4GDMLReadSolids::TrapRead(const xercesc::DOMElement* const trapElement)
2418 {
2419  G4String name;
2420  G4double lunit = 1.0;
2421  G4double aunit = 1.0;
2422  G4double z = 0.0;
2423  G4double theta = 0.0;
2424  G4double phi = 0.0;
2425  G4double y1 = 0.0;
2426  G4double x1 = 0.0;
2427  G4double x2 = 0.0;
2428  G4double alpha1 = 0.0;
2429  G4double y2 = 0.0;
2430  G4double x3 = 0.0;
2431  G4double x4 = 0.0;
2432  G4double alpha2 = 0.0;
2433 
2434  const xercesc::DOMNamedNodeMap* const attributes =
2435  trapElement->getAttributes();
2436  XMLSize_t attributeCount = attributes->getLength();
2437 
2438  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2439  ++attribute_index)
2440  {
2441  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2442 
2443  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2444  {
2445  continue;
2446  }
2447 
2448  const xercesc::DOMAttr* const attribute =
2449  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2450  if(attribute == nullptr)
2451  {
2452  G4Exception("G4GDMLReadSolids::TrapRead()", "InvalidRead", FatalException,
2453  "No attribute found!");
2454  return;
2455  }
2456  const G4String attName = Transcode(attribute->getName());
2457  const G4String attValue = Transcode(attribute->getValue());
2458 
2459  if(attName == "name")
2460  {
2461  name = GenerateName(attValue);
2462  }
2463  else if(attName == "lunit")
2464  {
2465  lunit = G4UnitDefinition::GetValueOf(attValue);
2466  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2467  {
2468  G4Exception("G4GDMLReadSolids::TrapRead()", "InvalidRead",
2469  FatalException, "Invalid unit for length!");
2470  }
2471  }
2472  else if(attName == "aunit")
2473  {
2474  aunit = G4UnitDefinition::GetValueOf(attValue);
2475  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
2476  {
2477  G4Exception("G4GDMLReadSolids::TrapRead()", "InvalidRead",
2478  FatalException, "Invalid unit for angle!");
2479  }
2480  }
2481  else if(attName == "z")
2482  {
2483  z = eval.Evaluate(attValue);
2484  }
2485  else if(attName == "theta")
2486  {
2487  theta = eval.Evaluate(attValue);
2488  }
2489  else if(attName == "phi")
2490  {
2491  phi = eval.Evaluate(attValue);
2492  }
2493  else if(attName == "y1")
2494  {
2495  y1 = eval.Evaluate(attValue);
2496  }
2497  else if(attName == "x1")
2498  {
2499  x1 = eval.Evaluate(attValue);
2500  }
2501  else if(attName == "x2")
2502  {
2503  x2 = eval.Evaluate(attValue);
2504  }
2505  else if(attName == "alpha1")
2506  {
2507  alpha1 = eval.Evaluate(attValue);
2508  }
2509  else if(attName == "y2")
2510  {
2511  y2 = eval.Evaluate(attValue);
2512  }
2513  else if(attName == "x3")
2514  {
2515  x3 = eval.Evaluate(attValue);
2516  }
2517  else if(attName == "x4")
2518  {
2519  x4 = eval.Evaluate(attValue);
2520  }
2521  else if(attName == "alpha2")
2522  {
2523  alpha2 = eval.Evaluate(attValue);
2524  }
2525  }
2526 
2527  z *= 0.5 * lunit;
2528  theta *= aunit;
2529  phi *= aunit;
2530  y1 *= 0.5 * lunit;
2531  x1 *= 0.5 * lunit;
2532  x2 *= 0.5 * lunit;
2533  alpha1 *= aunit;
2534  y2 *= 0.5 * lunit;
2535  x3 *= 0.5 * lunit;
2536  x4 *= 0.5 * lunit;
2537  alpha2 *= aunit;
2538 
2539  new G4Trap(name, z, theta, phi, y1, x1, x2, alpha1, y2, x3, x4, alpha2);
2540 }
2541 
2542 // --------------------------------------------------------------------
2543 void G4GDMLReadSolids::TrdRead(const xercesc::DOMElement* const trdElement)
2544 {
2545  G4String name;
2546  G4double lunit = 1.0;
2547  G4double x1 = 0.0;
2548  G4double x2 = 0.0;
2549  G4double y1 = 0.0;
2550  G4double y2 = 0.0;
2551  G4double z = 0.0;
2552 
2553  const xercesc::DOMNamedNodeMap* const attributes =
2554  trdElement->getAttributes();
2555  XMLSize_t attributeCount = attributes->getLength();
2556 
2557  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2558  ++attribute_index)
2559  {
2560  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2561 
2562  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2563  {
2564  continue;
2565  }
2566 
2567  const xercesc::DOMAttr* const attribute =
2568  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2569  if(attribute == nullptr)
2570  {
2571  G4Exception("G4GDMLReadSolids::TrdRead()", "InvalidRead", FatalException,
2572  "No attribute found!");
2573  return;
2574  }
2575  const G4String attName = Transcode(attribute->getName());
2576  const G4String attValue = Transcode(attribute->getValue());
2577 
2578  if(attName == "name")
2579  {
2580  name = GenerateName(attValue);
2581  }
2582  else if(attName == "lunit")
2583  {
2584  lunit = G4UnitDefinition::GetValueOf(attValue);
2585  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2586  {
2587  G4Exception("G4GDMLReadSolids::TrdRead()", "InvalidRead",
2588  FatalException, "Invalid unit for length!");
2589  }
2590  }
2591  else if(attName == "x1")
2592  {
2593  x1 = eval.Evaluate(attValue);
2594  }
2595  else if(attName == "x2")
2596  {
2597  x2 = eval.Evaluate(attValue);
2598  }
2599  else if(attName == "y1")
2600  {
2601  y1 = eval.Evaluate(attValue);
2602  }
2603  else if(attName == "y2")
2604  {
2605  y2 = eval.Evaluate(attValue);
2606  }
2607  else if(attName == "z")
2608  {
2609  z = eval.Evaluate(attValue);
2610  }
2611  }
2612 
2613  x1 *= 0.5 * lunit;
2614  x2 *= 0.5 * lunit;
2615  y1 *= 0.5 * lunit;
2616  y2 *= 0.5 * lunit;
2617  z *= 0.5 * lunit;
2618 
2619  new G4Trd(name, x1, x2, y1, y2, z);
2620 }
2621 
2622 // --------------------------------------------------------------------
2623 G4TriangularFacet* G4GDMLReadSolids::TriangularRead(
2624  const xercesc::DOMElement* const triangularElement)
2625 {
2626  G4ThreeVector vertex1;
2627  G4ThreeVector vertex2;
2628  G4ThreeVector vertex3;
2629  G4FacetVertexType type = ABSOLUTE;
2630  G4double lunit = 1.0;
2631 
2632  const xercesc::DOMNamedNodeMap* const attributes =
2633  triangularElement->getAttributes();
2634  XMLSize_t attributeCount = attributes->getLength();
2635 
2636  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2637  ++attribute_index)
2638  {
2639  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2640 
2641  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2642  {
2643  continue;
2644  }
2645 
2646  const xercesc::DOMAttr* const attribute =
2647  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2648  if(attribute == nullptr)
2649  {
2650  G4Exception("G4GDMLReadSolids::TriangularRead()", "InvalidRead",
2651  FatalException, "No attribute found!");
2652  return nullptr;
2653  }
2654  const G4String attName = Transcode(attribute->getName());
2655  const G4String attValue = Transcode(attribute->getValue());
2656 
2657  if(attName == "vertex1")
2658  {
2659  vertex1 = GetPosition(GenerateName(attValue));
2660  }
2661  else if(attName == "vertex2")
2662  {
2663  vertex2 = GetPosition(GenerateName(attValue));
2664  }
2665  else if(attName == "vertex3")
2666  {
2667  vertex3 = GetPosition(GenerateName(attValue));
2668  }
2669  else if(attName == "lunit")
2670  {
2671  lunit = G4UnitDefinition::GetValueOf(attValue);
2672  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2673  {
2674  G4Exception("G4GDMLReadSolids::TriangularRead()", "InvalidRead",
2675  FatalException, "Invalid unit for length!");
2676  }
2677  }
2678  else if(attName == "type")
2679  {
2680  if(attValue == "RELATIVE")
2681  {
2682  type = RELATIVE;
2683  }
2684  }
2685  }
2686 
2687  return new G4TriangularFacet(vertex1 * lunit, vertex2 * lunit,
2688  vertex3 * lunit, type);
2689 }
2690 
2691 // --------------------------------------------------------------------
2692 void G4GDMLReadSolids::TubeRead(const xercesc::DOMElement* const tubeElement)
2693 {
2694  G4String name;
2695  G4double lunit = 1.0;
2696  G4double aunit = 1.0;
2697  G4double rmin = 0.0;
2698  G4double rmax = 0.0;
2699  G4double z = 0.0;
2700  G4double startphi = 0.0;
2701  G4double deltaphi = 0.0;
2702 
2703  const xercesc::DOMNamedNodeMap* const attributes =
2704  tubeElement->getAttributes();
2705  XMLSize_t attributeCount = attributes->getLength();
2706 
2707  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2708  ++attribute_index)
2709  {
2710  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2711 
2712  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2713  {
2714  continue;
2715  }
2716 
2717  const xercesc::DOMAttr* const attribute =
2718  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2719  if(attribute == nullptr)
2720  {
2721  G4Exception("G4GDMLReadSolids::TubeRead()", "InvalidRead", FatalException,
2722  "No attribute found!");
2723  return;
2724  }
2725  const G4String attName = Transcode(attribute->getName());
2726  const G4String attValue = Transcode(attribute->getValue());
2727 
2728  if(attName == "name")
2729  {
2730  name = GenerateName(attValue);
2731  }
2732  else if(attName == "lunit")
2733  {
2734  lunit = G4UnitDefinition::GetValueOf(attValue);
2735  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2736  {
2737  G4Exception("G4GDMLReadSolids::TubeRead()", "InvalidRead",
2738  FatalException, "Invalid unit for length!");
2739  }
2740  }
2741  else if(attName == "aunit")
2742  {
2743  aunit = G4UnitDefinition::GetValueOf(attValue);
2744  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
2745  {
2746  G4Exception("G4GDMLReadSolids::TubeRead()", "InvalidRead",
2747  FatalException, "Invalid unit for angle!");
2748  }
2749  }
2750  else if(attName == "rmin")
2751  {
2752  rmin = eval.Evaluate(attValue);
2753  }
2754  else if(attName == "rmax")
2755  {
2756  rmax = eval.Evaluate(attValue);
2757  }
2758  else if(attName == "z")
2759  {
2760  z = eval.Evaluate(attValue);
2761  }
2762  else if(attName == "startphi")
2763  {
2764  startphi = eval.Evaluate(attValue);
2765  }
2766  else if(attName == "deltaphi")
2767  {
2768  deltaphi = eval.Evaluate(attValue);
2769  }
2770  }
2771 
2772  rmin *= lunit;
2773  rmax *= lunit;
2774  z *= 0.5 * lunit;
2775  startphi *= aunit;
2776  deltaphi *= aunit;
2777 
2778  new G4Tubs(name, rmin, rmax, z, startphi, deltaphi);
2779 }
2780 
2781 // --------------------------------------------------------------------
2782 void G4GDMLReadSolids::CutTubeRead(
2783  const xercesc::DOMElement* const cuttubeElement)
2784 {
2785  G4String name;
2786  G4double lunit = 1.0;
2787  G4double aunit = 1.0;
2788  G4double rmin = 0.0;
2789  G4double rmax = 0.0;
2790  G4double z = 0.0;
2791  G4double startphi = 0.0;
2792  G4double deltaphi = 0.0;
2793  G4ThreeVector lowNorm(0);
2794  G4ThreeVector highNorm(0);
2795 
2796  const xercesc::DOMNamedNodeMap* const attributes =
2797  cuttubeElement->getAttributes();
2798  XMLSize_t attributeCount = attributes->getLength();
2799 
2800  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2801  ++attribute_index)
2802  {
2803  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2804 
2805  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2806  {
2807  continue;
2808  }
2809 
2810  const xercesc::DOMAttr* const attribute =
2811  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2812  if(attribute == nullptr)
2813  {
2814  G4Exception("G4GDMLReadSolids::CutTubeRead()", "InvalidRead",
2815  FatalException, "No attribute found!");
2816  return;
2817  }
2818  const G4String attName = Transcode(attribute->getName());
2819  const G4String attValue = Transcode(attribute->getValue());
2820 
2821  if(attName == "name")
2822  {
2823  name = GenerateName(attValue);
2824  }
2825  else if(attName == "lunit")
2826  {
2827  lunit = G4UnitDefinition::GetValueOf(attValue);
2828  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2829  {
2830  G4Exception("G4GDMLReadSolids::CutTubeRead()", "InvalidRead",
2831  FatalException, "Invalid unit for length!");
2832  }
2833  }
2834  else if(attName == "aunit")
2835  {
2836  aunit = G4UnitDefinition::GetValueOf(attValue);
2837  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
2838  {
2839  G4Exception("G4GDMLReadSolids::CutTubeRead()", "InvalidRead",
2840  FatalException, "Invalid unit for angle!");
2841  }
2842  }
2843  else if(attName == "rmin")
2844  {
2845  rmin = eval.Evaluate(attValue);
2846  }
2847  else if(attName == "rmax")
2848  {
2849  rmax = eval.Evaluate(attValue);
2850  }
2851  else if(attName == "z")
2852  {
2853  z = eval.Evaluate(attValue);
2854  }
2855  else if(attName == "startphi")
2856  {
2857  startphi = eval.Evaluate(attValue);
2858  }
2859  else if(attName == "deltaphi")
2860  {
2861  deltaphi = eval.Evaluate(attValue);
2862  }
2863  else if(attName == "lowX")
2864  {
2865  lowNorm.setX(eval.Evaluate(attValue));
2866  }
2867  else if(attName == "lowY")
2868  {
2869  lowNorm.setY(eval.Evaluate(attValue));
2870  }
2871  else if(attName == "lowZ")
2872  {
2873  lowNorm.setZ(eval.Evaluate(attValue));
2874  }
2875  else if(attName == "highX")
2876  {
2877  highNorm.setX(eval.Evaluate(attValue));
2878  }
2879  else if(attName == "highY")
2880  {
2881  highNorm.setY(eval.Evaluate(attValue));
2882  }
2883  else if(attName == "highZ")
2884  {
2885  highNorm.setZ(eval.Evaluate(attValue));
2886  }
2887  }
2888 
2889  rmin *= lunit;
2890  rmax *= lunit;
2891  z *= 0.5 * lunit;
2892  startphi *= aunit;
2893  deltaphi *= aunit;
2894 
2895  new G4CutTubs(name, rmin, rmax, z, startphi, deltaphi, lowNorm, highNorm);
2896 }
2897 
2898 // --------------------------------------------------------------------
2899 void G4GDMLReadSolids::TwistedboxRead(
2900  const xercesc::DOMElement* const twistedboxElement)
2901 {
2902  G4String name;
2903  G4double lunit = 1.0;
2904  G4double aunit = 1.0;
2905  G4double PhiTwist = 0.0;
2906  G4double x = 0.0;
2907  G4double y = 0.0;
2908  G4double z = 0.0;
2909 
2910  const xercesc::DOMNamedNodeMap* const attributes =
2911  twistedboxElement->getAttributes();
2912  XMLSize_t attributeCount = attributes->getLength();
2913 
2914  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
2915  ++attribute_index)
2916  {
2917  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2918 
2919  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2920  {
2921  continue;
2922  }
2923 
2924  const xercesc::DOMAttr* const attribute =
2925  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2926  if(attribute == nullptr)
2927  {
2928  G4Exception("G4GDMLReadSolids::TwistedboxRead()", "InvalidRead",
2929  FatalException, "No attribute found!");
2930  return;
2931  }
2932  const G4String attName = Transcode(attribute->getName());
2933  const G4String attValue = Transcode(attribute->getValue());
2934 
2935  if(attName == "name")
2936  {
2937  name = GenerateName(attValue);
2938  }
2939  else if(attName == "lunit")
2940  {
2941  lunit = G4UnitDefinition::GetValueOf(attValue);
2942  if(G4UnitDefinition::GetCategory(attValue) != "Length")
2943  {
2944  G4Exception("G4GDMLReadSolids::TwistedBoxRead()", "InvalidRead",
2945  FatalException, "Invalid unit for length!");
2946  }
2947  }
2948  else if(attName == "aunit")
2949  {
2950  aunit = G4UnitDefinition::GetValueOf(attValue);
2951  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
2952  {
2953  G4Exception("G4GDMLReadSolids::TwistedboxRead()", "InvalidRead",
2954  FatalException, "Invalid unit for angle!");
2955  }
2956  }
2957  else if(attName == "PhiTwist")
2958  {
2959  PhiTwist = eval.Evaluate(attValue);
2960  }
2961  else if(attName == "x")
2962  {
2963  x = eval.Evaluate(attValue);
2964  }
2965  else if(attName == "y")
2966  {
2967  y = eval.Evaluate(attValue);
2968  }
2969  else if(attName == "z")
2970  {
2971  z = eval.Evaluate(attValue);
2972  }
2973  }
2974 
2975  PhiTwist *= aunit;
2976  x *= 0.5 * lunit;
2977  y *= 0.5 * lunit;
2978  z *= 0.5 * lunit;
2979 
2980  new G4TwistedBox(name, PhiTwist, x, y, z);
2981 }
2982 
2983 // --------------------------------------------------------------------
2984 void G4GDMLReadSolids::TwistedtrapRead(
2985  const xercesc::DOMElement* const twistedtrapElement)
2986 {
2987  G4String name;
2988  G4double lunit = 1.0;
2989  G4double aunit = 1.0;
2990  G4double PhiTwist = 0.0;
2991  G4double z = 0.0;
2992  G4double Theta = 0.0;
2993  G4double Phi = 0.0;
2994  G4double y1 = 0.0;
2995  G4double x1 = 0.0;
2996  G4double x2 = 0.0;
2997  G4double y2 = 0.0;
2998  G4double x3 = 0.0;
2999  G4double x4 = 0.0;
3000  G4double Alph = 0.0;
3001 
3002  const xercesc::DOMNamedNodeMap* const attributes =
3003  twistedtrapElement->getAttributes();
3004  XMLSize_t attributeCount = attributes->getLength();
3005 
3006  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
3007  ++attribute_index)
3008  {
3009  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
3010 
3011  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
3012  {
3013  continue;
3014  }
3015 
3016  const xercesc::DOMAttr* const attribute =
3017  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
3018  if(attribute == nullptr)
3019  {
3020  G4Exception("G4GDMLReadSolids::TwistedtrapRead()", "InvalidRead",
3021  FatalException, "No attribute found!");
3022  return;
3023  }
3024  const G4String attName = Transcode(attribute->getName());
3025  const G4String attValue = Transcode(attribute->getValue());
3026 
3027  if(attName == "name")
3028  {
3029  name = GenerateName(attValue);
3030  }
3031  else if(attName == "lunit")
3032  {
3033  lunit = G4UnitDefinition::GetValueOf(attValue);
3034  if(G4UnitDefinition::GetCategory(attValue) != "Length")
3035  {
3036  G4Exception("G4GDMLReadSolids::TwistedtrapRead()", "InvalidRead",
3037  FatalException, "Invalid unit for length!");
3038  }
3039  }
3040  else if(attName == "aunit")
3041  {
3042  aunit = G4UnitDefinition::GetValueOf(attValue);
3043  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
3044  {
3045  G4Exception("G4GDMLReadSolids::TwistedtrapRead()", "InvalidRead",
3046  FatalException, "Invalid unit for angle!");
3047  }
3048  }
3049  else if(attName == "PhiTwist")
3050  {
3051  PhiTwist = eval.Evaluate(attValue);
3052  }
3053  else if(attName == "z")
3054  {
3055  z = eval.Evaluate(attValue);
3056  }
3057  else if(attName == "Theta")
3058  {
3059  Theta = eval.Evaluate(attValue);
3060  }
3061  else if(attName == "Phi")
3062  {
3063  Phi = eval.Evaluate(attValue);
3064  }
3065  else if(attName == "y1")
3066  {
3067  y1 = eval.Evaluate(attValue);
3068  }
3069  else if(attName == "x1")
3070  {
3071  x1 = eval.Evaluate(attValue);
3072  }
3073  else if(attName == "x2")
3074  {
3075  x2 = eval.Evaluate(attValue);
3076  }
3077  else if(attName == "y2")
3078  {
3079  y2 = eval.Evaluate(attValue);
3080  }
3081  else if(attName == "x3")
3082  {
3083  x3 = eval.Evaluate(attValue);
3084  }
3085  else if(attName == "x4")
3086  {
3087  x4 = eval.Evaluate(attValue);
3088  }
3089  else if(attName == "Alph")
3090  {
3091  Alph = eval.Evaluate(attValue);
3092  }
3093  }
3094 
3095  PhiTwist *= aunit;
3096  z *= 0.5 * lunit;
3097  Theta *= aunit;
3098  Phi *= aunit;
3099  Alph *= aunit;
3100  y1 *= 0.5 * lunit;
3101  x1 *= 0.5 * lunit;
3102  x2 *= 0.5 * lunit;
3103  y2 *= 0.5 * lunit;
3104  x3 *= 0.5 * lunit;
3105  x4 *= 0.5 * lunit;
3106 
3107  new G4TwistedTrap(name, PhiTwist, z, Theta, Phi, y1, x1, x2, y2, x3, x4,
3108  Alph);
3109 }
3110 
3111 // --------------------------------------------------------------------
3112 void G4GDMLReadSolids::TwistedtrdRead(
3113  const xercesc::DOMElement* const twistedtrdElement)
3114 {
3115  G4String name;
3116  G4double lunit = 1.0;
3117  G4double aunit = 1.0;
3118  G4double x1 = 0.0;
3119  G4double x2 = 0.0;
3120  G4double y1 = 0.0;
3121  G4double y2 = 0.0;
3122  G4double z = 0.0;
3123  G4double PhiTwist = 0.0;
3124 
3125  const xercesc::DOMNamedNodeMap* const attributes =
3126  twistedtrdElement->getAttributes();
3127  XMLSize_t attributeCount = attributes->getLength();
3128 
3129  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
3130  ++attribute_index)
3131  {
3132  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
3133 
3134  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
3135  {
3136  continue;
3137  }
3138 
3139  const xercesc::DOMAttr* const attribute =
3140  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
3141  if(attribute == nullptr)
3142  {
3143  G4Exception("G4GDMLReadSolids::TwistedtrdRead()", "InvalidRead",
3144  FatalException, "No attribute found!");
3145  return;
3146  }
3147  const G4String attName = Transcode(attribute->getName());
3148  const G4String attValue = Transcode(attribute->getValue());
3149 
3150  if(attName == "name")
3151  {
3152  name = GenerateName(attValue);
3153  }
3154  else if(attName == "lunit")
3155  {
3156  lunit = G4UnitDefinition::GetValueOf(attValue);
3157  if(G4UnitDefinition::GetCategory(attValue) != "Length")
3158  {
3159  G4Exception("G4GDMLReadSolids::TwistedtrdRead()", "InvalidRead",
3160  FatalException, "Invalid unit for length!");
3161  }
3162  }
3163  else if(attName == "aunit")
3164  {
3165  aunit = G4UnitDefinition::GetValueOf(attValue);
3166  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
3167  {
3168  G4Exception("G4GDMLReadSolids::TwistedtrdRead()", "InvalidRead",
3169  FatalException, "Invalid unit for angle!");
3170  }
3171  }
3172  else if(attName == "x1")
3173  {
3174  x1 = eval.Evaluate(attValue);
3175  }
3176  else if(attName == "x2")
3177  {
3178  x2 = eval.Evaluate(attValue);
3179  }
3180  else if(attName == "y1")
3181  {
3182  y1 = eval.Evaluate(attValue);
3183  }
3184  else if(attName == "y2")
3185  {
3186  y2 = eval.Evaluate(attValue);
3187  }
3188  else if(attName == "z")
3189  {
3190  z = eval.Evaluate(attValue);
3191  }
3192  else if(attName == "PhiTwist")
3193  {
3194  PhiTwist = eval.Evaluate(attValue);
3195  }
3196  }
3197 
3198  x1 *= 0.5 * lunit;
3199  x2 *= 0.5 * lunit;
3200  y1 *= 0.5 * lunit;
3201  y2 *= 0.5 * lunit;
3202  z *= 0.5 * lunit;
3203  PhiTwist *= aunit;
3204 
3205  new G4TwistedTrd(name, x1, x2, y1, y2, z, PhiTwist);
3206 }
3207 
3208 // --------------------------------------------------------------------
3209 void G4GDMLReadSolids::TwistedtubsRead(
3210  const xercesc::DOMElement* const twistedtubsElement)
3211 {
3212  G4String name;
3213  G4double lunit = 1.0;
3214  G4double aunit = 1.0;
3215  G4double twistedangle = 0.0;
3216  G4double endinnerrad = 0.0;
3217  G4double endouterrad = 0.0;
3218  G4double zlen = 0.0;
3219  G4double phi = 0.0;
3220  G4double totphi = 0.0;
3221  G4double midinnerrad = 0.0;
3222  G4double midouterrad = 0.0;
3223  G4double positiveEndz = 0.0;
3224  G4double negativeEndz = 0.0;
3225  G4int nseg = 0;
3226 
3227  const xercesc::DOMNamedNodeMap* const attributes =
3228  twistedtubsElement->getAttributes();
3229  XMLSize_t attributeCount = attributes->getLength();
3230 
3231  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
3232  ++attribute_index)
3233  {
3234  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
3235 
3236  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
3237  {
3238  continue;
3239  }
3240 
3241  const xercesc::DOMAttr* const attribute =
3242  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
3243  if(attribute == nullptr)
3244  {
3245  G4Exception("G4GDMLReadSolids::TwistedtubsRead()", "InvalidRead",
3246  FatalException, "No attribute found!");
3247  return;
3248  }
3249  const G4String attName = Transcode(attribute->getName());
3250  const G4String attValue = Transcode(attribute->getValue());
3251 
3252  if(attName == "name")
3253  {
3254  name = GenerateName(attValue);
3255  }
3256  else if(attName == "lunit")
3257  {
3258  lunit = G4UnitDefinition::GetValueOf(attValue);
3259  if(G4UnitDefinition::GetCategory(attValue) != "Length")
3260  {
3261  G4Exception("G4GDMLReadSolids::TwistedtubsRead()", "InvalidRead",
3262  FatalException, "Invalid unit for length!");
3263  }
3264  }
3265  else if(attName == "aunit")
3266  {
3267  aunit = G4UnitDefinition::GetValueOf(attValue);
3268  if(G4UnitDefinition::GetCategory(attValue) != "Angle")
3269  {
3270  G4Exception("G4GDMLReadSolids::TwistedtubsRead()", "InvalidRead",
3271  FatalException, "Invalid unit for angle!");
3272  }
3273  }
3274  else if(attName == "twistedangle")
3275  {
3276  twistedangle = eval.Evaluate(attValue);
3277  }
3278  else if(attName == "endinnerrad")
3279  {
3280  endinnerrad = eval.Evaluate(attValue);
3281  }
3282  else if(attName == "endouterrad")
3283  {
3284  endouterrad = eval.Evaluate(attValue);
3285  }
3286  else if(attName == "zlen")
3287  {
3288  zlen = eval.Evaluate(attValue);
3289  }
3290  else if(attName == "midinnerrad")
3291  {
3292  midinnerrad = eval.Evaluate(attValue);
3293  }
3294  else if(attName == "midouterrad")
3295  {
3296  midouterrad = eval.Evaluate(attValue);
3297  }
3298  else if(attName == "negativeEndz")
3299  {
3300  negativeEndz = eval.Evaluate(attValue);
3301  }
3302  else if(attName == "positiveEndz")
3303  {
3304  positiveEndz = eval.Evaluate(attValue);
3305  }
3306  else if(attName == "nseg")
3307  {
3308  nseg = eval.Evaluate(attValue);
3309  }
3310  else if(attName == "totphi")
3311  {
3312  totphi = eval.Evaluate(attValue);
3313  }
3314  else if(attName == "phi")
3315  {
3316  phi = eval.Evaluate(attValue);
3317  }
3318  }
3319 
3320  twistedangle *= aunit;
3321  endinnerrad *= lunit;
3322  endouterrad *= lunit;
3323  zlen *= 0.5 * lunit;
3324  midinnerrad *= lunit;
3325  midouterrad *= lunit;
3326  positiveEndz *= lunit;
3327  negativeEndz *= lunit;
3328  phi *= aunit;
3329  totphi *= aunit;
3330 
3331  if(zlen != 0.0)
3332  {
3333  if(nseg != 0)
3334  new G4TwistedTubs(name, twistedangle, endinnerrad, endouterrad, zlen,
3335  nseg, totphi);
3336  else
3337  new G4TwistedTubs(name, twistedangle, endinnerrad, endouterrad, zlen,
3338  phi);
3339  }
3340  else
3341  {
3342  if(nseg != 0)
3343  new G4TwistedTubs(name, twistedangle, midinnerrad, midouterrad,
3344  negativeEndz, positiveEndz, nseg, totphi);
3345  else
3346  new G4TwistedTubs(name, twistedangle, midinnerrad, midouterrad,
3347  negativeEndz, positiveEndz, phi);
3348  }
3349 }
3350 
3351 // --------------------------------------------------------------------
3352 G4TwoVector G4GDMLReadSolids::TwoDimVertexRead(
3353  const xercesc::DOMElement* const element, G4double lunit)
3354 {
3355  G4TwoVector vec;
3356 
3357  const xercesc::DOMNamedNodeMap* const attributes = element->getAttributes();
3358  XMLSize_t attributeCount = attributes->getLength();
3359 
3360  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
3361  ++attribute_index)
3362  {
3363  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
3364 
3365  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
3366  {
3367  continue;
3368  }
3369 
3370  const xercesc::DOMAttr* const attribute =
3371  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
3372  if(attribute == nullptr)
3373  {
3374  G4Exception("G4GDMLReadSolids::TwoDimVertexRead()", "InvalidRead",
3375  FatalException, "No attribute found!");
3376  return vec;
3377  }
3378  const G4String attName = Transcode(attribute->getName());
3379  const G4String attValue = Transcode(attribute->getValue());
3380 
3381  if(attName == "x")
3382  {
3383  vec.setX(eval.Evaluate(attValue) * lunit);
3384  }
3385  else if(attName == "y")
3386  {
3387  vec.setY(eval.Evaluate(attValue) * lunit);
3388  }
3389  }
3390 
3391  return vec;
3392 }
3393 
3394 // --------------------------------------------------------------------
3395 G4GDMLReadSolids::zplaneType G4GDMLReadSolids::ZplaneRead(
3396  const xercesc::DOMElement* const zplaneElement)
3397 {
3398  zplaneType zplane = { 0., 0., 0. };
3399 
3400  const xercesc::DOMNamedNodeMap* const attributes =
3401  zplaneElement->getAttributes();
3402  XMLSize_t attributeCount = attributes->getLength();
3403 
3404  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
3405  ++attribute_index)
3406  {
3407  xercesc::DOMNode* node = attributes->item(attribute_index);
3408 
3409  if(node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
3410  {
3411  continue;
3412  }
3413 
3414  const xercesc::DOMAttr* const attribute =
3415  dynamic_cast<xercesc::DOMAttr*>(node);
3416  if(attribute == nullptr)
3417  {
3418  G4Exception("G4GDMLReadSolids::ZplaneRead()", "InvalidRead",
3419  FatalException, "No attribute found!");
3420  return zplane;
3421  }
3422  const G4String attName = Transcode(attribute->getName());
3423  const G4String attValue = Transcode(attribute->getValue());
3424 
3425  if(attName == "rmin")
3426  {
3427  zplane.rmin = eval.Evaluate(attValue);
3428  }
3429  else if(attName == "rmax")
3430  {
3431  zplane.rmax = eval.Evaluate(attValue);
3432  }
3433  else if(attName == "z")
3434  {
3435  zplane.z = eval.Evaluate(attValue);
3436  }
3437  }
3438 
3439  return zplane;
3440 }
3441 
3442 // --------------------------------------------------------------------
3443 G4GDMLReadSolids::rzPointType G4GDMLReadSolids::RZPointRead(
3444  const xercesc::DOMElement* const zplaneElement)
3445 {
3446  rzPointType rzpoint = { 0., 0. };
3447 
3448  const xercesc::DOMNamedNodeMap* const attributes =
3449  zplaneElement->getAttributes();
3450  XMLSize_t attributeCount = attributes->getLength();
3451 
3452  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
3453  ++attribute_index)
3454  {
3455  xercesc::DOMNode* node = attributes->item(attribute_index);
3456 
3457  if(node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
3458  {
3459  continue;
3460  }
3461 
3462  const xercesc::DOMAttr* const attribute =
3463  dynamic_cast<xercesc::DOMAttr*>(node);
3464  if(attribute == nullptr)
3465  {
3466  G4Exception("G4GDMLReadSolids::RZPointRead()", "InvalidRead",
3467  FatalException, "No attribute found!");
3468  return rzpoint;
3469  }
3470  const G4String attName = Transcode(attribute->getName());
3471  const G4String attValue = Transcode(attribute->getValue());
3472 
3473  if(attName == "r")
3474  {
3475  rzpoint.r = eval.Evaluate(attValue);
3476  }
3477  else if(attName == "z")
3478  {
3479  rzpoint.z = eval.Evaluate(attValue);
3480  }
3481  }
3482 
3483  return rzpoint;
3484 }
3485 
3486 // --------------------------------------------------------------------
3487 void G4GDMLReadSolids::PropertyRead(
3488  const xercesc::DOMElement* const propertyElement,
3489  G4OpticalSurface* opticalsurface)
3490 {
3491  G4String name;
3492  G4String ref;
3494 
3495  const xercesc::DOMNamedNodeMap* const attributes =
3496  propertyElement->getAttributes();
3497  XMLSize_t attributeCount = attributes->getLength();
3498 
3499  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
3500  ++attribute_index)
3501  {
3502  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
3503 
3504  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
3505  {
3506  continue;
3507  }
3508 
3509  const xercesc::DOMAttr* const attribute =
3510  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
3511  if(attribute == nullptr)
3512  {
3513  G4Exception("G4GDMLReadSolids::PropertyRead()", "InvalidRead",
3514  FatalException, "No attribute found!");
3515  return;
3516  }
3517  const G4String attName = Transcode(attribute->getName());
3518  const G4String attValue = Transcode(attribute->getValue());
3519 
3520  if(attName == "name")
3521  {
3522  name = GenerateName(attValue);
3523  }
3524  else if(attName == "ref")
3525  {
3526  matrix = GetMatrix(ref = attValue);
3527  }
3528  }
3529 
3530  /*
3531  if (matrix.GetCols() != 2)
3532  {
3533  G4String error_msg = "Referenced matrix '" + ref
3534  + "' should have \n two columns as a property table for
3535  opticalsurface: "
3536  + opticalsurface->GetName();
3537  G4Exception("G4GDMLReadSolids::PropertyRead()", "InvalidRead",
3538  FatalException, error_msg);
3539  }
3540  */
3541 
3542  if(matrix.GetRows() == 0)
3543  {
3544  return;
3545  }
3546 
3547  G4MaterialPropertiesTable* matprop =
3548  opticalsurface->GetMaterialPropertiesTable();
3549  if(matprop == nullptr)
3550  {
3551  matprop = new G4MaterialPropertiesTable();
3552  opticalsurface->SetMaterialPropertiesTable(matprop);
3553  }
3554  if(matrix.GetCols() == 1) // constant property assumed
3555  {
3556  matprop->AddConstProperty(Strip(name), matrix.Get(0, 0), true);
3557  }
3558  else // build the material properties vector
3559  {
3560  G4MaterialPropertyVector* propvect;
3561  G4String temp = name + ref;
3562  // first check if it was already built
3563  if(mapOfMatPropVects.find(temp) == mapOfMatPropVects.end())
3564  {
3565  // if not create a new one
3566  propvect = new G4MaterialPropertyVector();
3567  for(size_t i = 0; i < matrix.GetRows(); i++)
3568  {
3569  propvect->InsertValues(matrix.Get(i, 0), matrix.Get(i, 1));
3570  }
3571  // and add it to the list for potential future reuse
3572  mapOfMatPropVects[temp] = propvect;
3573  }
3574  else
3575  {
3576  propvect = mapOfMatPropVects[temp];
3577  }
3578 
3579  matprop->AddProperty(Strip(name), propvect, true);
3580  }
3581 }
3582 
3583 // --------------------------------------------------------------------
3584 void G4GDMLReadSolids::OpticalSurfaceRead(
3585  const xercesc::DOMElement* const opticalsurfaceElement)
3586 {
3587  G4String name;
3588  G4String smodel;
3589  G4String sfinish;
3590  G4String stype;
3591  G4double value = 0.0;
3592 
3593  const xercesc::DOMNamedNodeMap* const attributes =
3594  opticalsurfaceElement->getAttributes();
3595  XMLSize_t attributeCount = attributes->getLength();
3596 
3597  for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
3598  ++attribute_index)
3599  {
3600  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
3601 
3602  if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
3603  {
3604  continue;
3605  }
3606 
3607  const xercesc::DOMAttr* const attribute =
3608  dynamic_cast<xercesc::DOMAttr*>(attribute_node);
3609  if(attribute == nullptr)
3610  {
3611  G4Exception("G4GDMLReadSolids::OpticalSurfaceRead()", "InvalidRead",
3612  FatalException, "No attribute found!");
3613  return;
3614  }
3615  const G4String attName = Transcode(attribute->getName());
3616  const G4String attValue = Transcode(attribute->getValue());
3617 
3618  if(attName == "name")
3619  {
3620  name = GenerateName(attValue);
3621  }
3622  else if(attName == "model")
3623  {
3624  smodel = attValue;
3625  }
3626  else if(attName == "finish")
3627  {
3628  sfinish = attValue;
3629  }
3630  else if(attName == "type")
3631  {
3632  stype = attValue;
3633  }
3634  else if(attName == "value")
3635  {
3636  value = eval.Evaluate(attValue);
3637  }
3638  }
3639 
3640  G4OpticalSurfaceModel model;
3641  G4OpticalSurfaceFinish finish;
3642  G4SurfaceType type;
3643 
3644  if((smodel == "glisur") || (smodel == "0"))
3645  {
3646  model = glisur;
3647  }
3648  else if((smodel == "unified") || (smodel == "1"))
3649  {
3650  model = unified;
3651  }
3652  else if((smodel == "LUT") || (smodel == "2"))
3653  {
3654  model = LUT;
3655  }
3656  else if((smodel == "DAVIS") || (smodel == "3"))
3657  {
3658  model = DAVIS;
3659  }
3660  else
3661  {
3662  model = dichroic;
3663  }
3664 
3665  if((sfinish == "polished") || (sfinish == "0"))
3666  {
3667  finish = polished;
3668  }
3669  else if((sfinish == "polishedfrontpainted") || (sfinish == "1"))
3670  {
3671  finish = polishedfrontpainted;
3672  }
3673  else if((sfinish == "polishedbackpainted") || (sfinish == "2"))
3674  {
3675  finish = polishedbackpainted;
3676  }
3677  else if((sfinish == "ground") || (sfinish == "3"))
3678  {
3679  finish = ground;
3680  }
3681  else if((sfinish == "groundfrontpainted") || (sfinish == "4"))
3682  {
3683  finish = groundfrontpainted;
3684  }
3685  else if((sfinish == "groundbackpainted") || (sfinish == "5"))
3686  {
3687  finish = groundbackpainted;
3688  }
3689  else if((sfinish == "polishedlumirrorair") || (sfinish == "6"))
3690  {
3691  finish = polishedlumirrorair;
3692  }
3693  else if((sfinish == "polishedlumirrorglue") || (sfinish == "7"))
3694  {
3695  finish = polishedlumirrorglue;
3696  }
3697  else if((sfinish == "polishedair") || (sfinish == "8"))
3698  {
3699  finish = polishedair;
3700  }
3701  else if((sfinish == "polishedteflonair") || (sfinish == "9"))
3702  {
3703  finish = polishedteflonair;
3704  }
3705  else if((sfinish == "polishedtioair") || (sfinish == "10"))
3706  {
3707  finish = polishedtioair;
3708  }
3709  else if((sfinish == "polishedtyvekair") || (sfinish == "11"))
3710  {
3711  finish = polishedtyvekair;
3712  }
3713  else if((sfinish == "polishedvm2000air") || (sfinish == "12"))
3714  {
3715  finish = polishedvm2000air;
3716  }
3717  else if((sfinish == "polishedvm2000glue") || (sfinish == "13"))
3718  {
3719  finish = polishedvm2000glue;
3720  }
3721  else if((sfinish == "etchedlumirrorair") || (sfinish == "14"))
3722  {
3723  finish = etchedlumirrorair;
3724  }
3725  else if((sfinish == "etchedlumirrorglue") || (sfinish == "15"))
3726  {
3727  finish = etchedlumirrorglue;
3728  }
3729  else if((sfinish == "etchedair") || (sfinish == "16"))
3730  {
3731  finish = etchedair;
3732  }
3733  else if((sfinish == "etchedteflonair") || (sfinish == "17"))
3734  {
3735  finish = etchedteflonair;
3736  }
3737  else if((sfinish == "etchedtioair") || (sfinish == "18"))
3738  {
3739  finish = etchedtioair;
3740  }
3741  else if((sfinish == "etchedtyvekair") || (sfinish == "19"))
3742  {
3743  finish = etchedtyvekair;
3744  }
3745  else if((sfinish == "etchedvm2000air") || (sfinish == "20"))
3746  {
3747  finish = etchedvm2000air;
3748  }
3749  else if((sfinish == "etchedvm2000glue") || (sfinish == "21"))
3750  {
3751  finish = etchedvm2000glue;
3752  }
3753  else if((sfinish == "groundlumirrorair") || (sfinish == "22"))
3754  {
3755  finish = groundlumirrorair;
3756  }
3757  else if((sfinish == "groundlumirrorglue") || (sfinish == "23"))
3758  {
3759  finish = groundlumirrorglue;
3760  }
3761  else if((sfinish == "groundair") || (sfinish == "24"))
3762  {
3763  finish = groundair;
3764  }
3765  else if((sfinish == "groundteflonair") || (sfinish == "25"))
3766  {
3767  finish = groundteflonair;
3768  }
3769  else if((sfinish == "groundtioair") || (sfinish == "26"))
3770  {
3771  finish = groundtioair;
3772  }
3773  else if((sfinish == "groundtyvekair") || (sfinish == "27"))
3774  {
3775  finish = groundtyvekair;
3776  }
3777  else if((sfinish == "groundvm2000air") || (sfinish == "28"))
3778  {
3779  finish = groundvm2000air;
3780  }
3781  else if((sfinish == "groundvm2000glue") || (sfinish == "29"))
3782  {
3783  finish = groundvm2000glue;
3784  }
3785  else if((sfinish == "Rough_LUT") || (sfinish == "30"))
3786  {
3787  finish = Rough_LUT;
3788  }
3789  else if((sfinish == "RoughTeflon_LUT") || (sfinish == "31"))
3790  {
3791  finish = RoughTeflon_LUT;
3792  }
3793  else if((sfinish == "RoughESR_LUT") || (sfinish == "32"))
3794  {
3795  finish = RoughESR_LUT;
3796  }
3797  else if((sfinish == "RoughESRGrease_LUT") || (sfinish == "33"))
3798  {
3799  finish = RoughESRGrease_LUT;
3800  }
3801  else if((sfinish == "Polished_LUT") || (sfinish == "34"))
3802  {
3803  finish = Polished_LUT;
3804  }
3805  else if((sfinish == "PolishedTeflon_LUT") || (sfinish == "35"))
3806  {
3807  finish = PolishedTeflon_LUT;
3808  }
3809  else if((sfinish == "PolishedESR_LUT") || (sfinish == "36"))
3810  {
3811  finish = PolishedESR_LUT;
3812  }
3813  else if((sfinish == "PolishedESRGrease_LUT") || (sfinish == "37"))
3814  {
3815  finish = PolishedESRGrease_LUT;
3816  }
3817  else
3818  {
3819  finish = Detector_LUT;
3820  }
3821 
3822  if((stype == "dielectric_metal") || (stype == "0"))
3823  {
3824  type = dielectric_metal;
3825  }
3826  else if((stype == "dielectric_dielectric") || (stype == "1"))
3827  {
3828  type = dielectric_dielectric;
3829  }
3830  else if((stype == "dielectric_LUT") || (stype == "2"))
3831  {
3832  type = dielectric_LUT;
3833  }
3834  else if((stype == "dielectric_LUTDAVIS") || (stype == "3"))
3835  {
3836  type = dielectric_LUTDAVIS;
3837  }
3838  else if((stype == "dielectric_dichroic") || (stype == "4"))
3839  {
3840  type = dielectric_dichroic;
3841  }
3842  else if((stype == "firsov") || (stype == "5"))
3843  {
3844  type = firsov;
3845  }
3846  else
3847  {
3848  type = x_ray;
3849  }
3850 
3851  G4OpticalSurface* opticalsurface =
3852  new G4OpticalSurface(name, model, finish, type, value);
3853 
3854  for(xercesc::DOMNode* iter = opticalsurfaceElement->getFirstChild();
3855  iter != nullptr; iter = iter->getNextSibling())
3856  {
3857  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
3858  {
3859  continue;
3860  }
3861 
3862  const xercesc::DOMElement* const child =
3863  dynamic_cast<xercesc::DOMElement*>(iter);
3864  if(child == nullptr)
3865  {
3866  G4Exception("G4GDMLReadSolids::OpticalSurfaceRead()", "InvalidRead",
3867  FatalException, "No child found!");
3868  return;
3869  }
3870  const G4String tag = Transcode(child->getTagName());
3871 
3872  if(tag == "property")
3873  {
3874  PropertyRead(child, opticalsurface);
3875  }
3876  }
3877 }
3878 
3879 // --------------------------------------------------------------------
3880 void G4GDMLReadSolids::SolidsRead(
3881  const xercesc::DOMElement* const solidsElement)
3882 {
3883 #ifdef G4VERBOSE
3884  G4cout << "G4GDML: Reading solids..." << G4endl;
3885 #endif
3886  for(xercesc::DOMNode* iter = solidsElement->getFirstChild(); iter != nullptr;
3887  iter = iter->getNextSibling())
3888  {
3889  if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
3890  {
3891  continue;
3892  }
3893 
3894  const xercesc::DOMElement* const child =
3895  dynamic_cast<xercesc::DOMElement*>(iter);
3896  if(child == nullptr)
3897  {
3898  G4Exception("G4GDMLReadSolids::SolidsRead()", "InvalidRead",
3899  FatalException, "No child found!");
3900  return;
3901  }
3902  const G4String tag = Transcode(child->getTagName());
3903  if(tag == "define")
3904  {
3905  DefineRead(child);
3906  }
3907  else if(tag == "box")
3908  {
3909  BoxRead(child);
3910  }
3911  else if(tag == "cone")
3912  {
3913  ConeRead(child);
3914  }
3915  else if(tag == "elcone")
3916  {
3917  ElconeRead(child);
3918  }
3919  else if(tag == "ellipsoid")
3920  {
3921  EllipsoidRead(child);
3922  }
3923  else if(tag == "eltube")
3924  {
3925  EltubeRead(child);
3926  }
3927  else if(tag == "xtru")
3928  {
3929  XtruRead(child);
3930  }
3931  else if(tag == "hype")
3932  {
3933  HypeRead(child);
3934  }
3935  else if(tag == "intersection")
3936  {
3937  BooleanRead(child, INTERSECTION);
3938  }
3939  else if(tag == "multiUnion")
3940  {
3941  MultiUnionRead(child);
3942  }
3943  else if(tag == "orb")
3944  {
3945  OrbRead(child);
3946  }
3947  else if(tag == "para")
3948  {
3949  ParaRead(child);
3950  }
3951  else if(tag == "paraboloid")
3952  {
3953  ParaboloidRead(child);
3954  }
3955  else if(tag == "polycone")
3956  {
3957  PolyconeRead(child);
3958  }
3959  else if(tag == "genericPolycone")
3960  {
3961  GenericPolyconeRead(child);
3962  }
3963  else if(tag == "polyhedra")
3964  {
3965  PolyhedraRead(child);
3966  }
3967  else if(tag == "genericPolyhedra")
3968  {
3969  GenericPolyhedraRead(child);
3970  }
3971  else if(tag == "reflectedSolid")
3972  {
3973  ReflectedSolidRead(child);
3974  }
3975  else if(tag == "scaledSolid")
3976  {
3977  ScaledSolidRead(child);
3978  }
3979  else if(tag == "sphere")
3980  {
3981  SphereRead(child);
3982  }
3983  else if(tag == "subtraction")
3984  {
3985  BooleanRead(child, SUBTRACTION);
3986  }
3987  else if(tag == "tessellated")
3988  {
3989  TessellatedRead(child);
3990  }
3991  else if(tag == "tet")
3992  {
3993  TetRead(child);
3994  }
3995  else if(tag == "torus")
3996  {
3997  TorusRead(child);
3998  }
3999  else if(tag == "arb8")
4000  {
4001  GenTrapRead(child);
4002  }
4003  else if(tag == "trap")
4004  {
4005  TrapRead(child);
4006  }
4007  else if(tag == "trd")
4008  {
4009  TrdRead(child);
4010  }
4011  else if(tag == "tube")
4012  {
4013  TubeRead(child);
4014  }
4015  else if(tag == "cutTube")
4016  {
4017  CutTubeRead(child);
4018  }
4019  else if(tag == "twistedbox")
4020  {
4021  TwistedboxRead(child);
4022  }
4023  else if(tag == "twistedtrap")
4024  {
4025  TwistedtrapRead(child);
4026  }
4027  else if(tag == "twistedtrd")
4028  {
4029  TwistedtrdRead(child);
4030  }
4031  else if(tag == "twistedtubs")
4032  {
4033  TwistedtubsRead(child);
4034  }
4035  else if(tag == "union")
4036  {
4037  BooleanRead(child, UNION);
4038  }
4039  else if(tag == "opticalsurface")
4040  {
4041  OpticalSurfaceRead(child);
4042  }
4043  else if(tag == "loop")
4044  {
4045  LoopRead(child, &G4GDMLRead::SolidsRead);
4046  }
4047  else
4048  {
4049  G4String error_msg = "Unknown tag in solids: " + tag;
4050  G4Exception("G4GDMLReadSolids::SolidsRead()", "ReadError", FatalException,
4051  error_msg);
4052  }
4053  }
4054 }
4055 
4056 // --------------------------------------------------------------------
4057 G4VSolid* G4GDMLReadSolids::GetSolid(const G4String& ref) const
4058 {
4059  G4VSolid* solidPtr = G4SolidStore::GetInstance()
4060  ->GetSolid(ref,false,reverseSearch);
4061 
4062  if(solidPtr == nullptr)
4063  {
4064  G4String error_msg = "Referenced solid '" + ref + "' was not found!";
4065  G4Exception("G4GDMLReadSolids::GetSolid()", "ReadError", FatalException,
4066  error_msg);
4067  }
4068 
4069  return solidPtr;
4070 }
4071 
4072 // --------------------------------------------------------------------
4073 G4SurfaceProperty* G4GDMLReadSolids::GetSurfaceProperty(
4074  const G4String& ref) const
4075 {
4076  const G4SurfacePropertyTable* surfaceList =
4077  G4SurfaceProperty::GetSurfacePropertyTable();
4078  const std::size_t surfaceCount = surfaceList->size();
4079 
4080  for(std::size_t i = 0; i < surfaceCount; ++i)
4081  {
4082  if((*surfaceList)[i]->GetName() == ref)
4083  {
4084  return (*surfaceList)[i];
4085  }
4086  }
4087 
4088  G4String error_msg =
4089  "Referenced optical surface '" + ref + "' was not found!";
4090  G4Exception("G4GDMLReadSolids::GetSurfaceProperty()", "ReadError",
4091  FatalException, error_msg);
4092 
4093  return nullptr;
4094 }