ECCE @ 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 //
27 // class G4GDMLReadSolids Implementation
28 //
29 // Original author: Zoltan Torzsok, November 2007
30 //
31 // --------------------------------------------------------------------
32 
33 #include "G4GDMLReadSolids.hh"
34 #include "G4Box.hh"
35 #include "G4Cons.hh"
36 #include "G4Ellipsoid.hh"
37 #include "G4EllipticalCone.hh"
38 #include "G4EllipticalTube.hh"
39 #include "G4Hype.hh"
40 #include "G4IntersectionSolid.hh"
41 #include "G4Orb.hh"
42 #include "G4Para.hh"
43 #include "G4Paraboloid.hh"
44 #include "G4Polycone.hh"
45 #include "G4GenericPolycone.hh"
46 #include "G4Polyhedra.hh"
47 #include "G4QuadrangularFacet.hh"
48 #include "G4ReflectedSolid.hh"
49 #include "G4ScaledSolid.hh"
50 #include "G4Sphere.hh"
51 #include "G4SolidStore.hh"
52 #include "G4SubtractionSolid.hh"
53 #include "G4GenericTrap.hh"
54 #include "G4TessellatedSolid.hh"
55 #include "G4Tet.hh"
56 #include "G4Torus.hh"
57 #include "G4Transform3D.hh"
58 #include "G4Trap.hh"
59 #include "G4Trd.hh"
60 #include "G4TriangularFacet.hh"
61 #include "G4Tubs.hh"
62 #include "G4CutTubs.hh"
63 #include "G4TwistedBox.hh"
64 #include "G4TwistedTrap.hh"
65 #include "G4TwistedTrd.hh"
66 #include "G4TwistedTubs.hh"
67 #include "G4UnionSolid.hh"
68 #include "G4OpticalSurface.hh"
69 #include "G4UnitsTable.hh"
70 #include "G4SurfaceProperty.hh"
71 
73 {
74 }
75 
77 {
78 }
79 
81 BooleanRead(const xercesc::DOMElement* const booleanElement, const BooleanOp op)
82 {
83  G4String name;
84  G4String first;
85  G4String scnd;
86  G4ThreeVector position(0.0,0.0,0.0);
87  G4ThreeVector rotation(0.0,0.0,0.0);
88  G4ThreeVector firstposition(0.0,0.0,0.0);
89  G4ThreeVector firstrotation(0.0,0.0,0.0);
90 
91  const xercesc::DOMNamedNodeMap* const attributes
92  = booleanElement->getAttributes();
93  XMLSize_t attributeCount = attributes->getLength();
94 
95  for (XMLSize_t attribute_index=0;
96  attribute_index<attributeCount; attribute_index++)
97  {
98  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
99 
100  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
101  { continue; }
102 
103  const xercesc::DOMAttr* const attribute
104  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
105  if (!attribute)
106  {
107  G4Exception("G4GDMLReadSolids::BooleanRead()",
108  "InvalidRead", FatalException, "No attribute found!");
109  return;
110  }
111  const G4String attName = Transcode(attribute->getName());
112  const G4String attValue = Transcode(attribute->getValue());
113 
114  if (attName=="name") { name = GenerateName(attValue); }
115  }
116 
117  for (xercesc::DOMNode* iter = booleanElement->getFirstChild();
118  iter != 0;iter = iter->getNextSibling())
119  {
120  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
121 
122  const xercesc::DOMElement* const child
123  = dynamic_cast<xercesc::DOMElement*>(iter);
124  if (!child)
125  {
126  G4Exception("G4GDMLReadSolids::BooleanRead()",
127  "InvalidRead", FatalException, "No child found!");
128  return;
129  }
130  const G4String tag = Transcode(child->getTagName());
131 
132  if (tag=="first") { first = RefRead(child); } else
133  if (tag=="second") { scnd = RefRead(child); } else
134  if (tag=="position") { VectorRead(child,position); } else
135  if (tag=="rotation") { VectorRead(child,rotation); } else
136  if (tag=="positionref")
137  { position = GetPosition(GenerateName(RefRead(child))); } else
138  if (tag=="rotationref")
139  { rotation = GetRotation(GenerateName(RefRead(child))); } else
140  if (tag=="firstposition") { VectorRead(child,firstposition); } else
141  if (tag=="firstrotation") { VectorRead(child,firstrotation); } else
142  if (tag=="firstpositionref")
143  { firstposition = GetPosition(GenerateName(RefRead(child))); } else
144  if (tag=="firstrotationref")
145  { firstrotation = GetRotation(GenerateName(RefRead(child))); }
146  else
147  {
148  G4String error_msg = "Unknown tag in boolean solid: " + tag;
149  G4Exception("G4GDMLReadSolids::BooleanRead()", "ReadError",
150  FatalException, error_msg);
151  }
152  }
153 
154  G4VSolid* firstSolid = GetSolid(GenerateName(first));
155  G4VSolid* secondSolid = GetSolid(GenerateName(scnd));
156 
157  G4Transform3D transform(GetRotationMatrix(rotation),position);
158 
159  if (( (firstrotation.x()!=0.0) || (firstrotation.y()!=0.0)
160  || (firstrotation.z()!=0.0))
161  || ( (firstposition.x()!=0.0) || (firstposition.y()!=0.0)
162  || (firstposition.z()!=0.0)))
163  {
164  G4Transform3D firsttransform(GetRotationMatrix(firstrotation),
165  firstposition);
166  firstSolid = new G4DisplacedSolid(GenerateName("displaced_"+first),
167  firstSolid, firsttransform);
168  }
169 
170  if (op==UNION)
171  { new G4UnionSolid(name,firstSolid,secondSolid,transform); } else
172  if (op==SUBTRACTION)
173  { new G4SubtractionSolid(name,firstSolid,secondSolid,transform); } else
174  if (op==INTERSECTION)
175  { new G4IntersectionSolid(name,firstSolid,secondSolid,transform); }
176 }
177 
178 void G4GDMLReadSolids::BoxRead(const xercesc::DOMElement* const boxElement)
179 {
180  G4String name;
181  G4double lunit = 1.0;
182  G4double x = 0.0;
183  G4double y = 0.0;
184  G4double z = 0.0;
185 
186  const xercesc::DOMNamedNodeMap* const attributes
187  = boxElement->getAttributes();
188  XMLSize_t attributeCount = attributes->getLength();
189 
190  for (XMLSize_t attribute_index=0;
191  attribute_index<attributeCount; attribute_index++)
192  {
193  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
194 
195  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
196  { continue; }
197 
198  const xercesc::DOMAttr* const attribute
199  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
200  if (!attribute)
201  {
202  G4Exception("G4GDMLReadSolids::BoxRead()",
203  "InvalidRead", FatalException, "No attribute found!");
204  return;
205  }
206  const G4String attName = Transcode(attribute->getName());
207  const G4String attValue = Transcode(attribute->getValue());
208 
209  if (attName=="name") { name = GenerateName(attValue); } else
210  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
211  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
212  G4Exception("G4GDMLReadSolids::BoxRead()", "InvalidRead",
213  FatalException, "Invalid unit for length!"); }
214  }
215  else
216  if (attName=="x") { x = eval.Evaluate(attValue); } else
217  if (attName=="y") { y = eval.Evaluate(attValue); } else
218  if (attName=="z") { z = eval.Evaluate(attValue); }
219  }
220 
221  x *= 0.5*lunit;
222  y *= 0.5*lunit;
223  z *= 0.5*lunit;
224 
225  new G4Box(name,x,y,z);
226 }
227 
228 void G4GDMLReadSolids::ConeRead(const xercesc::DOMElement* const coneElement)
229 {
230  G4String name;
231  G4double lunit = 1.0;
232  G4double aunit = 1.0;
233  G4double rmin1 = 0.0;
234  G4double rmax1 = 0.0;
235  G4double rmin2 = 0.0;
236  G4double rmax2 = 0.0;
237  G4double z = 0.0;
238  G4double startphi = 0.0;
239  G4double deltaphi = 0.0;
240 
241  const xercesc::DOMNamedNodeMap* const attributes
242  = coneElement->getAttributes();
243  XMLSize_t attributeCount = attributes->getLength();
244 
245  for (XMLSize_t attribute_index=0;
246  attribute_index<attributeCount; attribute_index++)
247  {
248  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
249 
250  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
251  { continue; }
252 
253  const xercesc::DOMAttr* const attribute
254  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
255  if (!attribute)
256  {
257  G4Exception("G4GDMLReadSolids::ConeRead()",
258  "InvalidRead", FatalException, "No attribute found!");
259  return;
260  }
261  const G4String attName = Transcode(attribute->getName());
262  const G4String attValue = Transcode(attribute->getValue());
263 
264  if (attName=="name") { name = GenerateName(attValue); } else
265  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
266  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
267  G4Exception("G4GDMLReadSolids::ConeRead()", "InvalidRead",
268  FatalException, "Invalid unit for length!"); }
269  } else
270  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
271  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
272  G4Exception("G4GDMLReadSolids::ConeRead()", "InvalidRead",
273  FatalException, "Invalid unit for angle!"); }
274  } else
275  if (attName=="rmin1") { rmin1 = eval.Evaluate(attValue); } else
276  if (attName=="rmax1") { rmax1 = eval.Evaluate(attValue); } else
277  if (attName=="rmin2") { rmin2 = eval.Evaluate(attValue); } else
278  if (attName=="rmax2") { rmax2 = eval.Evaluate(attValue); } else
279  if (attName=="z") { z = eval.Evaluate(attValue); } else
280  if (attName=="startphi") { startphi = eval.Evaluate(attValue); } else
281  if (attName=="deltaphi") { deltaphi = eval.Evaluate(attValue); }
282  }
283 
284  rmin1 *= lunit;
285  rmax1 *= lunit;
286  rmin2 *= lunit;
287  rmax2 *= lunit;
288  z *= 0.5*lunit;
289  startphi *= aunit;
290  deltaphi *= aunit;
291 
292  new G4Cons(name,rmin1,rmax1,rmin2,rmax2,z,startphi,deltaphi);
293 }
294 
296 ElconeRead(const xercesc::DOMElement* const elconeElement)
297 {
298  G4String name;
299  G4double lunit = 1.0;
300  G4double dx = 0.0;
301  G4double dy = 0.0;
302  G4double zmax = 0.0;
303  G4double zcut = 0.0;
304 
305  const xercesc::DOMNamedNodeMap* const attributes
306  = elconeElement->getAttributes();
307  XMLSize_t attributeCount = attributes->getLength();
308 
309  for (XMLSize_t attribute_index=0;
310  attribute_index<attributeCount; attribute_index++)
311  {
312  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
313 
314  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
315  { continue; }
316 
317  const xercesc::DOMAttr* const attribute
318  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
319  if (!attribute)
320  {
321  G4Exception("G4GDMLReadSolids::ElconeRead()",
322  "InvalidRead", FatalException, "No attribute found!");
323  return;
324  }
325  const G4String attName = Transcode(attribute->getName());
326  const G4String attValue = Transcode(attribute->getValue());
327 
328  if (attName=="name") { name = GenerateName(attValue); } else
329  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
330  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
331  G4Exception("G4GDMLReadSolids::ElconeRead()", "InvalidRead",
332  FatalException, "Invalid unit for length!"); }
333  } else
334  if (attName=="dx") { dx = eval.Evaluate(attValue); } else
335  if (attName=="dy") { dy = eval.Evaluate(attValue); } else
336  if (attName=="zmax") { zmax = eval.Evaluate(attValue); } else
337  if (attName=="zcut") { zcut = eval.Evaluate(attValue); }
338  }
339 
340  zmax *= lunit;
341  zcut *= lunit;
342 
343  new G4EllipticalCone(name,dx,dy,zmax,zcut);
344 }
345 
347 EllipsoidRead(const xercesc::DOMElement* const ellipsoidElement)
348 {
349  G4String name;
350  G4double lunit = 1.0;
351  G4double ax = 0.0;
352  G4double by = 0.0;
353  G4double cz = 0.0;
354  G4double zcut1 = 0.0;
355  G4double zcut2 = 0.0;
356 
357  const xercesc::DOMNamedNodeMap* const attributes
358  = ellipsoidElement->getAttributes();
359  XMLSize_t attributeCount = attributes->getLength();
360 
361  for (XMLSize_t attribute_index=0;
362  attribute_index<attributeCount; attribute_index++)
363  {
364  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
365 
366  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
367  { continue; }
368 
369  const xercesc::DOMAttr* const attribute
370  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
371  if (!attribute)
372  {
373  G4Exception("G4GDMLReadSolids::EllipsoidRead()",
374  "InvalidRead", FatalException, "No attribute found!");
375  return;
376  }
377  const G4String attName = Transcode(attribute->getName());
378  const G4String attValue = Transcode(attribute->getValue());
379 
380  if (attName=="name") { name = GenerateName(attValue); } else
381  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
382  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
383  G4Exception("G4GDMLReadSolids::EllipsoidRead()", "InvalidRead",
384  FatalException, "Invalid unit for length!"); }
385  } else
386  if (attName=="ax") { ax = eval.Evaluate(attValue); } else
387  if (attName=="by") { by = eval.Evaluate(attValue); } else
388  if (attName=="cz") { cz = eval.Evaluate(attValue); } else
389  if (attName=="zcut1") { zcut1 = eval.Evaluate(attValue); } else
390  if (attName=="zcut2") { zcut2 = eval.Evaluate(attValue); }
391  }
392 
393  ax *= lunit;
394  by *= lunit;
395  cz *= lunit;
396  zcut1 *= lunit;
397  zcut2 *= lunit;
398 
399  new G4Ellipsoid(name,ax,by,cz,zcut1,zcut2);
400 }
401 
403 EltubeRead(const xercesc::DOMElement* const eltubeElement)
404 {
405  G4String name;
406  G4double lunit = 1.0;
407  G4double dx = 0.0;
408  G4double dy = 0.0;
409  G4double dz = 0.0;
410 
411  const xercesc::DOMNamedNodeMap* const attributes
412  = eltubeElement->getAttributes();
413  XMLSize_t attributeCount = attributes->getLength();
414 
415  for (XMLSize_t attribute_index=0;
416  attribute_index<attributeCount; attribute_index++)
417  {
418  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
419 
420  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
421  { continue; }
422 
423  const xercesc::DOMAttr* const attribute
424  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
425  if (!attribute)
426  {
427  G4Exception("G4GDMLReadSolids::EltubeRead()",
428  "InvalidRead", FatalException, "No attribute found!");
429  return;
430  }
431  const G4String attName = Transcode(attribute->getName());
432  const G4String attValue = Transcode(attribute->getValue());
433 
434  if (attName=="name") { name = GenerateName(attValue); } else
435  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
436  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
437  G4Exception("G4GDMLReadSolids::EltubeRead()", "InvalidRead",
438  FatalException, "Invalid unit for length!"); }
439  } else
440  if (attName=="dx") { dx = eval.Evaluate(attValue); } else
441  if (attName=="dy") { dy = eval.Evaluate(attValue); } else
442  if (attName=="dz") { dz = eval.Evaluate(attValue); }
443  }
444 
445  dx *= lunit;
446  dy *= lunit;
447  dz *= lunit;
448 
449  new G4EllipticalTube(name,dx,dy,dz);
450 }
451 
452 void G4GDMLReadSolids::XtruRead(const xercesc::DOMElement* const xtruElement)
453 {
454  G4String name;
455  G4double lunit = 1.0;
456 
457  const xercesc::DOMNamedNodeMap* const attributes
458  = xtruElement->getAttributes();
459  XMLSize_t attributeCount = attributes->getLength();
460 
461  for (XMLSize_t attribute_index=0;
462  attribute_index<attributeCount; attribute_index++)
463  {
464  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
465 
466  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
467  { continue; }
468 
469  const xercesc::DOMAttr* const attribute
470  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
471  if (!attribute)
472  {
473  G4Exception("G4GDMLReadSolids::XtruRead()",
474  "InvalidRead", FatalException, "No attribute found!");
475  return;
476  }
477  const G4String attName = Transcode(attribute->getName());
478  const G4String attValue = Transcode(attribute->getValue());
479 
480  if (attName=="name") { name = GenerateName(attValue); } else
481  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
482  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
483  G4Exception("G4GDMLReadSolids::XtruRead()", "InvalidRead",
484  FatalException, "Invalid unit for length!"); }
485  }
486  }
487 
488  std::vector<G4TwoVector> twoDimVertexList;
489  std::vector<G4ExtrudedSolid::ZSection> sectionList;
490 
491  for (xercesc::DOMNode* iter = xtruElement->getFirstChild();
492  iter != 0; iter = iter->getNextSibling())
493  {
494  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
495 
496  const xercesc::DOMElement* const child
497  = dynamic_cast<xercesc::DOMElement*>(iter);
498  if (!child)
499  {
500  G4Exception("G4GDMLReadSolids::XtruRead()",
501  "InvalidRead", FatalException, "No child found!");
502  return;
503  }
504  const G4String tag = Transcode(child->getTagName());
505 
506  if (tag=="twoDimVertex")
507  { twoDimVertexList.push_back(TwoDimVertexRead(child,lunit)); } else
508  if (tag=="section")
509  { sectionList.push_back(SectionRead(child,lunit)); }
510  }
511 
512  new G4ExtrudedSolid(name,twoDimVertexList,sectionList);
513 }
514 
515 void G4GDMLReadSolids::HypeRead(const xercesc::DOMElement* const hypeElement)
516 {
517  G4String name;
518  G4double lunit = 1.0;
519  G4double aunit = 1.0;
520  G4double rmin = 0.0;
521  G4double rmax = 0.0;
522  G4double inst = 0.0;
523  G4double outst = 0.0;
524  G4double z = 0.0;
525 
526  const xercesc::DOMNamedNodeMap* const attributes
527  = hypeElement->getAttributes();
528  XMLSize_t attributeCount = attributes->getLength();
529 
530  for (XMLSize_t attribute_index=0;
531  attribute_index<attributeCount; attribute_index++)
532  {
533  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
534 
535  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
536  { continue; }
537 
538  const xercesc::DOMAttr* const attribute
539  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
540  if (!attribute)
541  {
542  G4Exception("G4GDMLReadSolids::HypeRead()",
543  "InvalidRead", FatalException, "No attribute found!");
544  return;
545  }
546  const G4String attName = Transcode(attribute->getName());
547  const G4String attValue = Transcode(attribute->getValue());
548 
549  if (attName=="name") { name = GenerateName(attValue); } else
550  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
551  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
552  G4Exception("G4GDMLReadSolids::HypeRead()", "InvalidRead",
553  FatalException, "Invalid unit for length!"); }
554  } else
555  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
556  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
557  G4Exception("G4GDMLReadSolids::HypeRead()", "InvalidRead",
558  FatalException, "Invalid unit for angle!"); }
559  } else
560  if (attName=="rmin") { rmin = eval.Evaluate(attValue); } else
561  if (attName=="rmax") { rmax = eval.Evaluate(attValue); } else
562  if (attName=="inst") { inst = eval.Evaluate(attValue); } else
563  if (attName=="outst") { outst = eval.Evaluate(attValue); } else
564  if (attName=="z") { z = eval.Evaluate(attValue); }
565  }
566 
567  rmin *= lunit;
568  rmax *= lunit;
569  inst *= aunit;
570  outst *= aunit;
571  z *= 0.5*lunit;
572 
573  new G4Hype(name,rmin,rmax,inst,outst,z);
574 }
575 
577 MultiUnionNodeRead(const xercesc::DOMElement* const unionNodeElement,
578  G4MultiUnion* const multiUnionSolid)
579 {
580  G4String name;
581  G4String solid;
582  G4ThreeVector position(0.0,0.0,0.0);
583  G4ThreeVector rotation(0.0,0.0,0.0);
584 
585  const xercesc::DOMNamedNodeMap* const attributes
586  = unionNodeElement->getAttributes();
587  XMLSize_t attributeCount = attributes->getLength();
588 
589  for (XMLSize_t attribute_index=0;
590  attribute_index<attributeCount; attribute_index++)
591  {
592  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
593 
594  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
595  { continue; }
596 
597  const xercesc::DOMAttr* const attribute
598  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
599  if (!attribute)
600  {
601  G4Exception("G4GDMLReadSolids::MultiUnionNodeRead()",
602  "InvalidRead", FatalException, "No attribute found!");
603  return;
604  }
605  const G4String attName = Transcode(attribute->getName());
606  const G4String attValue = Transcode(attribute->getValue());
607 
608  if (attName=="name") { name = GenerateName(attValue); }
609  }
610 
611  for (xercesc::DOMNode* iter = unionNodeElement->getFirstChild();
612  iter != 0;iter = iter->getNextSibling())
613  {
614  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
615 
616  const xercesc::DOMElement* const child
617  = dynamic_cast<xercesc::DOMElement*>(iter);
618  if (!child)
619  {
620  G4Exception("G4GDMLReadSolids::MultiUnionNodeRead()",
621  "InvalidRead", FatalException, "No child found!");
622  return;
623  }
624  const G4String tag = Transcode(child->getTagName());
625 
626  if (tag=="position") { VectorRead(child,position); } else
627  if (tag=="rotation") { VectorRead(child,rotation); } else
628  if (tag=="positionref")
629  { position = GetPosition(GenerateName(RefRead(child))); } else
630  if (tag=="rotationref")
631  { rotation = GetRotation(GenerateName(RefRead(child))); } else
632  if (tag=="solid") { solid = RefRead(child); }
633  else
634  {
635  G4String error_msg = "Unknown tag in MultiUnion structure: " + tag;
636  G4Exception("G4GDMLReadSolids::MultiUnionNodeRead()", "ReadError",
637  FatalException, error_msg);
638  }
639  }
640  G4VSolid* solidNode = GetSolid(GenerateName(solid));
641  G4Transform3D transform(GetRotationMatrix(rotation),position);
642  multiUnionSolid->AddNode(*solidNode, transform);
643 }
644 
646 MultiUnionRead(const xercesc::DOMElement* const unionElement)
647 {
648  G4String name;
649 
650  const xercesc::DOMNamedNodeMap* const attributes
651  = unionElement->getAttributes();
652  XMLSize_t attributeCount = attributes->getLength();
653 
654  for (XMLSize_t attribute_index=0;
655  attribute_index<attributeCount; attribute_index++)
656  {
657  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
658 
659  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
660  { continue; }
661 
662  const xercesc::DOMAttr* const attribute
663  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
664  if (!attribute)
665  {
666  G4Exception("G4GDMLReadSolids::MultiUnionRead()",
667  "InvalidRead", FatalException, "No attribute found!");
668  return;
669  }
670  const G4String attName = Transcode(attribute->getName());
671  const G4String attValue = Transcode(attribute->getValue());
672 
673  if (attName=="name") { name = GenerateName(attValue); }
674  }
675 
676  G4MultiUnion* multiUnion = new G4MultiUnion(name);
677 
678  for (xercesc::DOMNode* iter = unionElement->getFirstChild();
679  iter != 0;iter = iter->getNextSibling())
680  {
681  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
682 
683  const xercesc::DOMElement* const child
684  = dynamic_cast<xercesc::DOMElement*>(iter);
685  if (!child)
686  {
687  G4Exception("G4GDMLReadSolids::MultiUnionRead()",
688  "InvalidRead", FatalException, "No child found!");
689  return;
690  }
691  const G4String tag = Transcode(child->getTagName());
692 
693  if (tag=="multiUnionNode") { MultiUnionNodeRead(child, multiUnion); }
694  else
695  {
696  G4String error_msg = "Unknown tag in MultiUnion structure: " + tag;
697  G4Exception("G4GDMLReadSolids::MultiUnionRead()", "ReadError",
698  FatalException, error_msg);
699  }
700  }
701  multiUnion->Voxelize();
702 }
703 
704 void G4GDMLReadSolids::OrbRead(const xercesc::DOMElement* const orbElement)
705 {
706  G4String name;
707  G4double lunit = 1.0;
708  G4double r = 0.0;
709 
710  const xercesc::DOMNamedNodeMap* const attributes
711  = orbElement->getAttributes();
712  XMLSize_t attributeCount = attributes->getLength();
713 
714  for (XMLSize_t attribute_index=0;
715  attribute_index<attributeCount; attribute_index++)
716  {
717  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
718 
719  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
720  { continue; }
721 
722  const xercesc::DOMAttr* const attribute
723  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
724  if (!attribute)
725  {
726  G4Exception("G4GDMLReadSolids::OrbRead()",
727  "InvalidRead", FatalException, "No attribute found!");
728  return;
729  }
730  const G4String attName = Transcode(attribute->getName());
731  const G4String attValue = Transcode(attribute->getValue());
732 
733  if (attName=="name") { name = GenerateName(attValue); } else
734  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
735  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
736  G4Exception("G4GDMLReadSolids::OrbRead()", "InvalidRead",
737  FatalException, "Invalid unit for length!"); }
738  } else
739  if (attName=="r") { r = eval.Evaluate(attValue); }
740  }
741 
742  r *= lunit;
743 
744  new G4Orb(name,r);
745 }
746 
747 void G4GDMLReadSolids::ParaRead(const xercesc::DOMElement* const paraElement)
748 {
749  G4String name;
750  G4double lunit = 1.0;
751  G4double aunit = 1.0;
752  G4double x = 0.0;
753  G4double y = 0.0;
754  G4double z = 0.0;
755  G4double alpha = 0.0;
756  G4double theta = 0.0;
757  G4double phi = 0.0;
758 
759  const xercesc::DOMNamedNodeMap* const attributes
760  = paraElement->getAttributes();
761  XMLSize_t attributeCount = attributes->getLength();
762 
763  for (XMLSize_t attribute_index=0;
764  attribute_index<attributeCount; attribute_index++)
765  {
766  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
767 
768  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
769  { continue; }
770 
771  const xercesc::DOMAttr* const attribute
772  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
773  if (!attribute)
774  {
775  G4Exception("G4GDMLReadSolids::ParaRead()",
776  "InvalidRead", FatalException, "No attribute found!");
777  return;
778  }
779  const G4String attName = Transcode(attribute->getName());
780  const G4String attValue = Transcode(attribute->getValue());
781 
782  if (attName=="name") { name = GenerateName(attValue); } else
783  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
784  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
785  G4Exception("G4GDMLReadSolids::ParaRead()", "InvalidRead",
786  FatalException, "Invalid unit for length!"); }
787  } else
788  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
789  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
790  G4Exception("G4GDMLReadSolids::ParaRead()", "InvalidRead",
791  FatalException, "Invalid unit for angle!"); }
792  } else
793  if (attName=="x") { x = eval.Evaluate(attValue); } else
794  if (attName=="y") { y = eval.Evaluate(attValue); } else
795  if (attName=="z") { z = eval.Evaluate(attValue); } else
796  if (attName=="alpha") { alpha = eval.Evaluate(attValue); } else
797  if (attName=="theta") { theta = eval.Evaluate(attValue); } else
798  if (attName=="phi") { phi = eval.Evaluate(attValue); }
799  }
800 
801  x *= 0.5*lunit;
802  y *= 0.5*lunit;
803  z *= 0.5*lunit;
804  alpha *= aunit;
805  theta *= aunit;
806  phi *= aunit;
807 
808  new G4Para(name,x,y,z,alpha,theta,phi);
809 }
810 
812 ParaboloidRead(const xercesc::DOMElement* const paraElement)
813 {
814  G4String name;
815  G4double lunit = 1.0;
816  G4double rlo = 0.0;
817  G4double rhi = 0.0;
818  G4double dz = 0.0;
819 
820  const xercesc::DOMNamedNodeMap* const attributes
821  = paraElement->getAttributes();
822  XMLSize_t attributeCount = attributes->getLength();
823 
824  for (XMLSize_t attribute_index=0;
825  attribute_index<attributeCount; attribute_index++)
826  {
827  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
828 
829  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
830  { continue; }
831 
832  const xercesc::DOMAttr* const attribute
833  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
834  if (!attribute)
835  {
836  G4Exception("G4GDMLReadSolids::ParaboloidRead()",
837  "InvalidRead", FatalException, "No attribute found!");
838  return;
839  }
840  const G4String attName = Transcode(attribute->getName());
841  const G4String attValue = Transcode(attribute->getValue());
842 
843  if (attName=="name") { name = GenerateName(attValue); } else
844  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
845  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
846  G4Exception("G4GDMLReadSolids::ParaboloidRead()", "InvalidRead",
847  FatalException, "Invalid unit for length!"); }
848  } else
849  if (attName=="rlo") { rlo = eval.Evaluate(attValue); } else
850  if (attName=="rhi") { rhi = eval.Evaluate(attValue); } else
851  if (attName=="dz") { dz = eval.Evaluate(attValue); }
852  }
853 
854  rlo *= 1.*lunit;
855  rhi *= 1.*lunit;
856  dz *= 1.*lunit;
857 
858  new G4Paraboloid(name,dz,rlo,rhi);
859 }
860 
862 PolyconeRead(const xercesc::DOMElement* const polyconeElement)
863 {
864  G4String name;
865  G4double lunit = 1.0;
866  G4double aunit = 1.0;
867  G4double startphi = 0.0;
868  G4double deltaphi = 0.0;
869 
870  const xercesc::DOMNamedNodeMap* const attributes
871  = polyconeElement->getAttributes();
872  XMLSize_t attributeCount = attributes->getLength();
873 
874  for (XMLSize_t attribute_index=0;
875  attribute_index<attributeCount; attribute_index++)
876  {
877  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
878 
879  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
880  { continue; }
881 
882  const xercesc::DOMAttr* const attribute
883  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
884  if (!attribute)
885  {
886  G4Exception("G4GDMLReadSolids::PolyconeRead()",
887  "InvalidRead", FatalException, "No attribute found!");
888  return;
889  }
890  const G4String attName = Transcode(attribute->getName());
891  const G4String attValue = Transcode(attribute->getValue());
892 
893  if (attName=="name") { name = GenerateName(attValue); } else
894  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
895  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
896  G4Exception("G4GDMLReadSolids::PolyconeRead()", "InvalidRead",
897  FatalException, "Invalid unit for length!"); }
898  } else
899  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
900  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
901  G4Exception("G4GDMLReadSolids::PolyconeRead()", "InvalidRead",
902  FatalException, "Invalid unit for angle!"); }
903  } else
904  if (attName=="startphi") { startphi = eval.Evaluate(attValue); }else
905  if (attName=="deltaphi") { deltaphi = eval.Evaluate(attValue); }
906  }
907 
908  startphi *= aunit;
909  deltaphi *= aunit;
910 
911  std::vector<zplaneType> zplaneList;
912 
913  for (xercesc::DOMNode* iter = polyconeElement->getFirstChild();
914  iter != 0; iter = iter->getNextSibling())
915  {
916  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
917 
918  const xercesc::DOMElement* const child
919  = dynamic_cast<xercesc::DOMElement*>(iter);
920  if (!child)
921  {
922  G4Exception("G4GDMLReadSolids::PolyconeRead()",
923  "InvalidRead", FatalException, "No child found!");
924  return;
925  }
926  const G4String tag = Transcode(child->getTagName());
927 
928  if (tag=="zplane") { zplaneList.push_back(ZplaneRead(child)); }
929  }
930 
931  G4int numZPlanes = zplaneList.size();
932 
933  G4double* rmin_array = new G4double[numZPlanes];
934  G4double* rmax_array = new G4double[numZPlanes];
935  G4double* z_array = new G4double[numZPlanes];
936 
937  for (G4int i=0; i<numZPlanes; i++)
938  {
939  rmin_array[i] = zplaneList[i].rmin*lunit;
940  rmax_array[i] = zplaneList[i].rmax*lunit;
941  z_array[i] = zplaneList[i].z*lunit;
942  }
943 
944  new G4Polycone(name,startphi,deltaphi,numZPlanes,
945  z_array,rmin_array,rmax_array);
946 
947  delete [] rmin_array;
948  delete [] rmax_array;
949  delete [] z_array;
950 }
951 
953 GenericPolyconeRead(const xercesc::DOMElement* const polyconeElement)
954 {
955  G4String name;
956  G4double lunit = 1.0;
957  G4double aunit = 1.0;
958  G4double startphi = 0.0;
959  G4double deltaphi = 0.0;
960 
961  const xercesc::DOMNamedNodeMap* const attributes
962  = polyconeElement->getAttributes();
963  XMLSize_t attributeCount = attributes->getLength();
964 
965  for (XMLSize_t attribute_index=0;
966  attribute_index<attributeCount; attribute_index++)
967  {
968  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
969 
970  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
971  { continue; }
972 
973  const xercesc::DOMAttr* const attribute
974  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
975  if (!attribute)
976  {
977  G4Exception("G4GDMLReadSolids::GenericPolyconeRead()",
978  "InvalidRead", FatalException, "No attribute found!");
979  return;
980  }
981  const G4String attName = Transcode(attribute->getName());
982  const G4String attValue = Transcode(attribute->getValue());
983 
984  if (attName=="name") { name = GenerateName(attValue); } else
985  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
986  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
987  G4Exception("G4GDMLReadSolids::GenericPolyconeRead()", "InvalidRead",
988  FatalException, "Invalid unit for length!"); }
989  } else
990  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
991  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
992  G4Exception("G4GDMLReadSolids::GenericPolyconeRead()", "InvalidRead",
993  FatalException, "Invalid unit for angle!"); }
994  } else
995  if (attName=="startphi") { startphi = eval.Evaluate(attValue); }else
996  if (attName=="deltaphi") { deltaphi = eval.Evaluate(attValue); }
997  }
998 
999  startphi *= aunit;
1000  deltaphi *= aunit;
1001 
1002  std::vector<rzPointType> rzPointList;
1003 
1004  for (xercesc::DOMNode* iter = polyconeElement->getFirstChild();
1005  iter != 0; iter = iter->getNextSibling())
1006  {
1007  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
1008 
1009  const xercesc::DOMElement* const child
1010  = dynamic_cast<xercesc::DOMElement*>(iter);
1011  if (!child)
1012  {
1013  G4Exception("G4GDMLReadSolids::GenericPolyconeRead()",
1014  "InvalidRead", FatalException, "No child found!");
1015  return;
1016  }
1017  const G4String tag = Transcode(child->getTagName());
1018 
1019  if (tag=="rzpoint") { rzPointList.push_back(RZPointRead(child)); }
1020  }
1021 
1022  G4int numRZPoints = rzPointList.size();
1023 
1024  G4double* r_array = new G4double[numRZPoints];
1025  G4double* z_array = new G4double[numRZPoints];
1026 
1027  for (G4int i=0; i<numRZPoints; i++)
1028  {
1029  r_array[i] = rzPointList[i].r*lunit;
1030  z_array[i] = rzPointList[i].z*lunit;
1031  }
1032  new G4GenericPolycone(name,startphi,deltaphi,numRZPoints,
1033  r_array,z_array);
1034  delete [] r_array;
1035  delete [] z_array;
1036 }
1037 
1038 void G4GDMLReadSolids::
1039 PolyhedraRead(const xercesc::DOMElement* const polyhedraElement)
1040 {
1041  G4String name;
1042  G4double lunit = 1.0;
1043  G4double aunit = 1.0;
1044  G4double startphi = 0.0;
1045  G4double deltaphi = 0.0;
1046  G4int numsides = 0;
1047 
1048  const xercesc::DOMNamedNodeMap* const attributes
1049  = polyhedraElement->getAttributes();
1050  XMLSize_t attributeCount = attributes->getLength();
1051 
1052  for (XMLSize_t attribute_index=0;
1053  attribute_index<attributeCount; attribute_index++)
1054  {
1055  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1056 
1057  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1058  { continue; }
1059 
1060  const xercesc::DOMAttr* const attribute
1061  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1062  if (!attribute)
1063  {
1064  G4Exception("G4GDMLReadSolids::PolyhedraRead()",
1065  "InvalidRead", FatalException, "No attribute found!");
1066  return;
1067  }
1068  const G4String attName = Transcode(attribute->getName());
1069  const G4String attValue = Transcode(attribute->getValue());
1070 
1071  if (attName=="name") { name = GenerateName(attValue); } else
1072  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
1073  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1074  G4Exception("G4GDMLReadSolids::PolyhedraRead()", "InvalidRead",
1075  FatalException, "Invalid unit for length!"); }
1076  } else
1077  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
1078  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
1079  G4Exception("G4GDMLReadSolids::PolyhedraRead()", "InvalidRead",
1080  FatalException, "Invalid unit for angle!"); }
1081  } else
1082  if (attName=="startphi") { startphi = eval.Evaluate(attValue); } else
1083  if (attName=="deltaphi") { deltaphi = eval.Evaluate(attValue); } else
1084  if (attName=="numsides") { numsides = eval.EvaluateInteger(attValue); }
1085  }
1086 
1087  startphi *= aunit;
1088  deltaphi *= aunit;
1089 
1090  std::vector<zplaneType> zplaneList;
1091 
1092  for (xercesc::DOMNode* iter = polyhedraElement->getFirstChild();
1093  iter != 0; iter = iter->getNextSibling())
1094  {
1095  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
1096 
1097  const xercesc::DOMElement* const child
1098  = dynamic_cast<xercesc::DOMElement*>(iter);
1099  if (!child)
1100  {
1101  G4Exception("G4GDMLReadSolids::PolyhedraRead()",
1102  "InvalidRead", FatalException, "No child found!");
1103  return;
1104  }
1105  const G4String tag = Transcode(child->getTagName());
1106 
1107  if (tag=="zplane") { zplaneList.push_back(ZplaneRead(child)); }
1108  }
1109 
1110  G4int numZPlanes = zplaneList.size();
1111 
1112  G4double* rmin_array = new G4double[numZPlanes];
1113  G4double* rmax_array = new G4double[numZPlanes];
1114  G4double* z_array = new G4double[numZPlanes];
1115 
1116  for (G4int i=0; i<numZPlanes; i++)
1117  {
1118  rmin_array[i] = zplaneList[i].rmin*lunit;
1119  rmax_array[i] = zplaneList[i].rmax*lunit;
1120  z_array[i] = zplaneList[i].z*lunit;
1121  }
1122 
1123  new G4Polyhedra(name,startphi,deltaphi,numsides,numZPlanes,
1124  z_array,rmin_array,rmax_array);
1125 
1126  delete [] rmin_array;
1127  delete [] rmax_array;
1128  delete [] z_array;
1129 }
1130 
1131 void G4GDMLReadSolids::
1132 GenericPolyhedraRead(const xercesc::DOMElement* const polyhedraElement)
1133 {
1134  G4String name;
1135  G4double lunit = 1.0;
1136  G4double aunit = 1.0;
1137  G4double startphi = 0.0;
1138  G4double deltaphi = 0.0;
1139  G4int numsides = 0;
1140 
1141  const xercesc::DOMNamedNodeMap* const attributes
1142  = polyhedraElement->getAttributes();
1143  XMLSize_t attributeCount = attributes->getLength();
1144 
1145  for (XMLSize_t attribute_index=0;
1146  attribute_index<attributeCount; attribute_index++)
1147  {
1148  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1149 
1150  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1151  { continue; }
1152 
1153  const xercesc::DOMAttr* const attribute
1154  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1155  if (!attribute)
1156  {
1157  G4Exception("G4GDMLReadSolids::GenericPolyhedraRead()",
1158  "InvalidRead", FatalException, "No attribute found!");
1159  return;
1160  }
1161  const G4String attName = Transcode(attribute->getName());
1162  const G4String attValue = Transcode(attribute->getValue());
1163 
1164  if (attName=="name") { name = GenerateName(attValue); } else
1165  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
1166  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1167  G4Exception("G4GDMLReadSolids::GenericPolyhedraRead()", "InvalidRead",
1168  FatalException, "Invalid unit for length!"); }
1169  } else
1170  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
1171  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
1172  G4Exception("G4GDMLReadSolids::GenericPolyhedraRead()", "InvalidRead",
1173  FatalException, "Invalid unit for angle!"); }
1174  } else
1175  if (attName=="startphi") { startphi = eval.Evaluate(attValue); } else
1176  if (attName=="deltaphi") { deltaphi = eval.Evaluate(attValue); } else
1177  if (attName=="numsides") { numsides = eval.EvaluateInteger(attValue); }
1178  }
1179 
1180  startphi *= aunit;
1181  deltaphi *= aunit;
1182 
1183  std::vector<rzPointType> rzpointList;
1184 
1185  for (xercesc::DOMNode* iter = polyhedraElement->getFirstChild();
1186  iter != 0; iter = iter->getNextSibling())
1187  {
1188  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
1189 
1190  const xercesc::DOMElement* const child
1191  = dynamic_cast<xercesc::DOMElement*>(iter);
1192  if (!child)
1193  {
1194  G4Exception("G4GDMLReadSolids::GenericPolyhedraRead()",
1195  "InvalidRead", FatalException, "No child found!");
1196  return;
1197  }
1198  const G4String tag = Transcode(child->getTagName());
1199 
1200  if (tag=="rzpoint") { rzpointList.push_back(RZPointRead(child)); }
1201  }
1202 
1203  G4int numRZPoints = rzpointList.size();
1204 
1205  G4double* r_array = new G4double[numRZPoints];
1206  G4double* z_array = new G4double[numRZPoints];
1207 
1208  for (G4int i=0; i<numRZPoints; i++)
1209  {
1210  r_array[i] = rzpointList[i].r*lunit;
1211  z_array[i] = rzpointList[i].z*lunit;
1212  }
1213 
1214  new G4Polyhedra(name,startphi,deltaphi,numsides,numRZPoints,
1215  r_array,z_array);
1216 
1217  delete [] r_array;
1218  delete [] z_array;
1219 }
1220 
1222 QuadrangularRead(const xercesc::DOMElement* const quadrangularElement)
1223 {
1224  G4ThreeVector vertex1;
1225  G4ThreeVector vertex2;
1226  G4ThreeVector vertex3;
1227  G4ThreeVector vertex4;
1228  G4FacetVertexType type = ABSOLUTE;
1229  G4double lunit = 1.0;
1230 
1231  const xercesc::DOMNamedNodeMap* const attributes
1232  = quadrangularElement->getAttributes();
1233  XMLSize_t attributeCount = attributes->getLength();
1234 
1235  for (XMLSize_t attribute_index=0;
1236  attribute_index<attributeCount; attribute_index++)
1237  {
1238  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1239 
1240  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1241  { continue; }
1242 
1243  const xercesc::DOMAttr* const attribute
1244  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1245  if (!attribute)
1246  {
1247  G4Exception("G4GDMLReadSolids::QuadrangularRead()",
1248  "InvalidRead", FatalException, "No attribute found!");
1249  return 0;
1250  }
1251  const G4String attName = Transcode(attribute->getName());
1252  const G4String attValue = Transcode(attribute->getValue());
1253 
1254  if (attName=="vertex1")
1255  { vertex1 = GetPosition(GenerateName(attValue)); } else
1256  if (attName=="vertex2")
1257  { vertex2 = GetPosition(GenerateName(attValue)); } else
1258  if (attName=="vertex3")
1259  { vertex3 = GetPosition(GenerateName(attValue)); } else
1260  if (attName=="vertex4")
1261  { vertex4 = GetPosition(GenerateName(attValue)); } else
1262  if (attName=="lunit")
1263  { lunit = G4UnitDefinition::GetValueOf(attValue);
1264  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1265  G4Exception("G4GDMLReadSolids::QuadrangularRead()", "InvalidRead",
1266  FatalException, "Invalid unit for length!"); }
1267  } else
1268  if (attName=="type")
1269  { if (attValue=="RELATIVE") { type = RELATIVE; } }
1270  }
1271 
1272  return new G4QuadrangularFacet(vertex1*lunit,vertex2*lunit,
1273  vertex3*lunit,vertex4*lunit,type);
1274 }
1275 
1276 void G4GDMLReadSolids::
1277 ReflectedSolidRead(const xercesc::DOMElement* const reflectedSolidElement)
1278 {
1279  G4String name;
1280  G4double lunit = 1.0;
1281  G4double aunit = 1.0;
1282  G4String solid;
1283  G4ThreeVector scale(1.0,1.0,1.0);
1284  G4ThreeVector rotation;
1286 
1287  const xercesc::DOMNamedNodeMap* const attributes
1288  = reflectedSolidElement->getAttributes();
1289  XMLSize_t attributeCount = attributes->getLength();
1290 
1291  for (XMLSize_t attribute_index=0;
1292  attribute_index<attributeCount; attribute_index++)
1293  {
1294  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1295 
1296  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1297  { continue; }
1298 
1299  const xercesc::DOMAttr* const attribute
1300  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1301  if (!attribute)
1302  {
1303  G4Exception("G4GDMLReadSolids::ReflectedSolidRead()",
1304  "InvalidRead", FatalException, "No attribute found!");
1305  return;
1306  }
1307  const G4String attName = Transcode(attribute->getName());
1308  const G4String attValue = Transcode(attribute->getValue());
1309 
1310  if (attName=="name") { name = GenerateName(attValue); } else
1311  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
1312  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1313  G4Exception("G4GDMLReadSolids::ReflectedSolidRead()", "InvalidRead",
1314  FatalException, "Invalid unit for length!"); }
1315  } else
1316  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
1317  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
1318  G4Exception("G4GDMLReadSolids::ReflectedSolidRead()", "InvalidRead",
1319  FatalException, "Invalid unit for angle!"); }
1320  } else
1321  if (attName=="solid") { solid = GenerateName(attValue); } else
1322  if (attName=="sx") { scale.setX(eval.Evaluate(attValue)); } else
1323  if (attName=="sy") { scale.setY(eval.Evaluate(attValue)); } else
1324  if (attName=="sz") { scale.setZ(eval.Evaluate(attValue)); } else
1325  if (attName=="rx") { rotation.setX(eval.Evaluate(attValue)); } else
1326  if (attName=="ry") { rotation.setY(eval.Evaluate(attValue)); } else
1327  if (attName=="rz") { rotation.setZ(eval.Evaluate(attValue)); } else
1328  if (attName=="dx") { position.setX(eval.Evaluate(attValue)); } else
1329  if (attName=="dy") { position.setY(eval.Evaluate(attValue)); } else
1330  if (attName=="dz") { position.setZ(eval.Evaluate(attValue)); }
1331  }
1332 
1333  rotation *= aunit;
1334  position *= lunit;
1335 
1336  G4Transform3D transform(GetRotationMatrix(rotation),position);
1337  transform = transform*G4Scale3D(scale.x(),scale.y(),scale.z());
1338 
1339  new G4ReflectedSolid(name,GetSolid(solid),transform);
1340 }
1341 
1342 void G4GDMLReadSolids::
1343 ScaledSolidRead(const xercesc::DOMElement* const scaledSolidElement)
1344 {
1345  G4String name;
1346  G4VSolid* solid=0;
1347  G4ThreeVector scale(1.0,1.0,1.0);
1348 
1349  const xercesc::DOMNamedNodeMap* const attributes
1350  = scaledSolidElement->getAttributes();
1351  XMLSize_t attributeCount = attributes->getLength();
1352 
1353  for (XMLSize_t attribute_index=0;
1354  attribute_index<attributeCount; attribute_index++)
1355  {
1356  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1357 
1358  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1359  { continue; }
1360 
1361  const xercesc::DOMAttr* const attribute
1362  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1363  if (!attribute)
1364  {
1365  G4Exception("G4GDMLReadSolids::ScaledSolidRead()",
1366  "InvalidRead", FatalException, "No attribute found!");
1367  return;
1368  }
1369  const G4String attName = Transcode(attribute->getName());
1370  const G4String attValue = Transcode(attribute->getValue());
1371 
1372  if (attName=="name") { name = GenerateName(attValue); }
1373  }
1374 
1375  for (xercesc::DOMNode* iter = scaledSolidElement->getFirstChild();
1376  iter != 0; iter = iter->getNextSibling())
1377  {
1378  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
1379 
1380  const xercesc::DOMElement* const child
1381  = dynamic_cast<xercesc::DOMElement*>(iter);
1382  if (!child)
1383  {
1384  G4Exception("G4GDMLReadSolids::ScaledSolidRead()",
1385  "InvalidRead", FatalException, "No child found!");
1386  return;
1387  }
1388  const G4String tag = Transcode(child->getTagName());
1389 
1390  if (tag=="solidref")
1391  { solid = GetSolid(GenerateName(RefRead(child))); }
1392  else if (tag=="scale")
1393  { VectorRead(child,scale); }
1394  else if (tag=="scaleref")
1395  { scale = GetScale(GenerateName(RefRead(child))); }
1396  else
1397  {
1398  G4String error_msg = "Unknown tag in scaled solid: " + tag;
1399  G4Exception("G4GDMLReadSolids::ScaledSolidRead()", "ReadError",
1400  FatalException, error_msg);
1401  return;
1402  }
1403  }
1404 
1405  G4Scale3D transform = G4Scale3D(scale.x(),scale.y(),scale.z());
1406 
1407  new G4ScaledSolid(name, solid ,transform);
1408 }
1409 
1411 SectionRead(const xercesc::DOMElement* const sectionElement,G4double lunit)
1412 {
1413  G4double zPosition = 0.0;
1414  G4TwoVector Offset;
1415  G4double scalingFactor = 1.0;
1416 
1417  const xercesc::DOMNamedNodeMap* const attributes
1418  = sectionElement->getAttributes();
1419  XMLSize_t attributeCount = attributes->getLength();
1420 
1421  for (XMLSize_t attribute_index=0;
1422  attribute_index<attributeCount; attribute_index++)
1423  {
1424  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1425 
1426  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1427  { continue; }
1428 
1429  const xercesc::DOMAttr* const attribute
1430  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1431  if (!attribute)
1432  {
1433  G4Exception("G4GDMLReadSolids::SectionRead()",
1434  "InvalidRead", FatalException, "No attribute found!");
1435  return G4ExtrudedSolid::ZSection(zPosition,Offset,scalingFactor);
1436  }
1437  const G4String attName = Transcode(attribute->getName());
1438  const G4String attValue = Transcode(attribute->getValue());
1439 
1440  if (attName=="zPosition")
1441  { zPosition = eval.Evaluate(attValue)*lunit; } else
1442  if (attName=="xOffset")
1443  { Offset.setX(eval.Evaluate(attValue)*lunit); } else
1444  if (attName=="yOffset")
1445  { Offset.setY(eval.Evaluate(attValue)*lunit); } else
1446  if (attName=="scalingFactor")
1447  { scalingFactor = eval.Evaluate(attValue); }
1448  }
1449 
1450  return G4ExtrudedSolid::ZSection(zPosition,Offset,scalingFactor);
1451 }
1452 
1453 void G4GDMLReadSolids::
1454 SphereRead(const xercesc::DOMElement* const sphereElement)
1455 {
1456  G4String name;
1457  G4double lunit = 1.0;
1458  G4double aunit = 1.0;
1459  G4double rmin = 0.0;
1460  G4double rmax = 0.0;
1461  G4double startphi = 0.0;
1462  G4double deltaphi = 0.0;
1463  G4double starttheta = 0.0;
1464  G4double deltatheta = 0.0;
1465 
1466  const xercesc::DOMNamedNodeMap* const attributes
1467  = sphereElement->getAttributes();
1468  XMLSize_t attributeCount = attributes->getLength();
1469 
1470  for (XMLSize_t attribute_index=0;
1471  attribute_index<attributeCount; attribute_index++)
1472  {
1473  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1474 
1475  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1476  { continue; }
1477 
1478  const xercesc::DOMAttr* const attribute
1479  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1480  if (!attribute)
1481  {
1482  G4Exception("G4GDMLReadSolids::SphereRead()",
1483  "InvalidRead", FatalException, "No attribute found!");
1484  return;
1485  }
1486  const G4String attName = Transcode(attribute->getName());
1487  const G4String attValue = Transcode(attribute->getValue());
1488 
1489  if (attName=="name") { name = GenerateName(attValue); } else
1490  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
1491  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1492  G4Exception("G4GDMLReadSolids::SphereRead()", "InvalidRead",
1493  FatalException, "Invalid unit for length!"); }
1494  } else
1495  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
1496  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
1497  G4Exception("G4GDMLReadSolids::SphereRead()", "InvalidRead",
1498  FatalException, "Invalid unit for angle!"); }
1499  } else
1500  if (attName=="rmin") { rmin = eval.Evaluate(attValue); } else
1501  if (attName=="rmax") { rmax = eval.Evaluate(attValue); } else
1502  if (attName=="startphi") { startphi = eval.Evaluate(attValue); } else
1503  if (attName=="deltaphi") { deltaphi = eval.Evaluate(attValue); } else
1504  if (attName=="starttheta") { starttheta = eval.Evaluate(attValue); } else
1505  if (attName=="deltatheta") { deltatheta = eval.Evaluate(attValue); }
1506  }
1507 
1508  rmin *= lunit;
1509  rmax *= lunit;
1510  startphi *= aunit;
1511  deltaphi *= aunit;
1512  starttheta *= aunit;
1513  deltatheta *= aunit;
1514 
1515  new G4Sphere(name,rmin,rmax,startphi,deltaphi,starttheta,deltatheta);
1516 }
1517 
1518 void G4GDMLReadSolids::
1519 TessellatedRead(const xercesc::DOMElement* const tessellatedElement)
1520 {
1521  G4String name;
1522 
1523  const xercesc::DOMNamedNodeMap* const attributes
1524  = tessellatedElement->getAttributes();
1525  XMLSize_t attributeCount = attributes->getLength();
1526 
1527  for (XMLSize_t attribute_index=0;
1528  attribute_index<attributeCount; attribute_index++)
1529  {
1530  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1531 
1532  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1533  { continue; }
1534 
1535  const xercesc::DOMAttr* const attribute
1536  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1537  if (!attribute)
1538  {
1539  G4Exception("G4GDMLReadSolids::TessellatedRead()",
1540  "InvalidRead", FatalException, "No attribute found!");
1541  return;
1542  }
1543  const G4String attName = Transcode(attribute->getName());
1544  const G4String attValue = Transcode(attribute->getValue());
1545 
1546  if (attName=="name") { name = GenerateName(attValue); }
1547  }
1548 
1549  G4TessellatedSolid *tessellated = new G4TessellatedSolid(name);
1550 
1551  for (xercesc::DOMNode* iter = tessellatedElement->getFirstChild();
1552  iter != 0; iter = iter->getNextSibling())
1553  {
1554  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
1555 
1556  const xercesc::DOMElement* const child
1557  = dynamic_cast<xercesc::DOMElement*>(iter);
1558  if (!child)
1559  {
1560  G4Exception("G4GDMLReadSolids::TessellatedRead()",
1561  "InvalidRead", FatalException, "No child found!");
1562  return;
1563  }
1564  const G4String tag = Transcode(child->getTagName());
1565 
1566  if (tag=="triangular")
1567  { tessellated->AddFacet(TriangularRead(child)); } else
1568  if (tag=="quadrangular")
1569  { tessellated->AddFacet(QuadrangularRead(child)); }
1570  }
1571 
1572  tessellated->SetSolidClosed(true);
1573 }
1574 
1575 void G4GDMLReadSolids::TetRead(const xercesc::DOMElement* const tetElement)
1576 {
1577  G4String name;
1578  G4ThreeVector vertex1;
1579  G4ThreeVector vertex2;
1580  G4ThreeVector vertex3;
1581  G4ThreeVector vertex4;
1582  G4double lunit = 1.0;
1583 
1584  const xercesc::DOMNamedNodeMap* const attributes
1585  = tetElement->getAttributes();
1586  XMLSize_t attributeCount = attributes->getLength();
1587 
1588  for (XMLSize_t attribute_index=0;
1589  attribute_index<attributeCount;attribute_index++)
1590  {
1591  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1592 
1593  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1594  { continue; }
1595 
1596  const xercesc::DOMAttr* const attribute
1597  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1598  if (!attribute)
1599  {
1600  G4Exception("G4GDMLReadSolids::TetRead()",
1601  "InvalidRead", FatalException, "No attribute found!");
1602  return;
1603  }
1604  const G4String attName = Transcode(attribute->getName());
1605  const G4String attValue = Transcode(attribute->getValue());
1606 
1607  if (attName=="name")
1608  { name = GenerateName(attValue); } else
1609  if (attName=="lunit")
1610  { lunit = G4UnitDefinition::GetValueOf(attValue);
1611  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1612  G4Exception("G4GDMLReadSolids::TetRead()", "InvalidRead",
1613  FatalException, "Invalid unit for length!"); }
1614  } else
1615  if (attName=="vertex1")
1616  { vertex1 = GetPosition(GenerateName(attValue)); } else
1617  if (attName=="vertex2")
1618  { vertex2 = GetPosition(GenerateName(attValue)); } else
1619  if (attName=="vertex3")
1620  { vertex3 = GetPosition(GenerateName(attValue)); } else
1621  if (attName=="vertex4")
1622  { vertex4 = GetPosition(GenerateName(attValue)); }
1623  }
1624 
1625  new G4Tet(name,vertex1*lunit,vertex2*lunit,vertex3*lunit,vertex4*lunit);
1626 }
1627 
1628 void G4GDMLReadSolids::TorusRead(const xercesc::DOMElement* const torusElement)
1629 {
1630  G4String name;
1631  G4double lunit = 1.0;
1632  G4double aunit = 1.0;
1633  G4double rmin = 0.0;
1634  G4double rmax = 0.0;
1635  G4double rtor = 0.0;
1636  G4double startphi = 0.0;
1637  G4double deltaphi = 0.0;
1638 
1639  const xercesc::DOMNamedNodeMap* const attributes
1640  = torusElement->getAttributes();
1641  XMLSize_t attributeCount = attributes->getLength();
1642 
1643  for (XMLSize_t attribute_index=0;
1644  attribute_index<attributeCount; attribute_index++)
1645  {
1646  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1647 
1648  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1649  { continue; }
1650 
1651  const xercesc::DOMAttr* const attribute
1652  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1653  if (!attribute)
1654  {
1655  G4Exception("G4GDMLReadSolids::TorusRead()",
1656  "InvalidRead", FatalException, "No attribute found!");
1657  return;
1658  }
1659  const G4String attName = Transcode(attribute->getName());
1660  const G4String attValue = Transcode(attribute->getValue());
1661 
1662  if (attName=="name") { name = GenerateName(attValue); } else
1663  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
1664  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1665  G4Exception("G4GDMLReadSolids::TorusRead()", "InvalidRead",
1666  FatalException, "Invalid unit for length!"); }
1667  } else
1668  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
1669  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
1670  G4Exception("G4GDMLReadSolids::TorusRead()", "InvalidRead",
1671  FatalException, "Invalid unit for angle!"); }
1672  } else
1673  if (attName=="rmin") { rmin = eval.Evaluate(attValue); } else
1674  if (attName=="rmax") { rmax = eval.Evaluate(attValue); } else
1675  if (attName=="rtor") { rtor = eval.Evaluate(attValue); } else
1676  if (attName=="startphi") { startphi = eval.Evaluate(attValue); } else
1677  if (attName=="deltaphi") { deltaphi = eval.Evaluate(attValue); }
1678  }
1679 
1680  rmin *= lunit;
1681  rmax *= lunit;
1682  rtor *= lunit;
1683  startphi *= aunit;
1684  deltaphi *= aunit;
1685 
1686  new G4Torus(name,rmin,rmax,rtor,startphi,deltaphi);
1687 }
1688 
1689 void G4GDMLReadSolids::
1690 GenTrapRead(const xercesc::DOMElement* const gtrapElement)
1691 {
1692  G4String name;
1693  G4double lunit = 1.0;
1694  G4double dz =0.0;
1695  G4double v1x=0.0, v1y=0.0, v2x=0.0, v2y=0.0, v3x=0.0, v3y=0.0,
1696  v4x=0.0, v4y=0.0, v5x=0.0, v5y=0.0, v6x=0.0, v6y=0.0,
1697  v7x=0.0, v7y=0.0, v8x=0.0, v8y=0.0;
1698 
1699  const xercesc::DOMNamedNodeMap* const attributes
1700  = gtrapElement->getAttributes();
1701  XMLSize_t attributeCount = attributes->getLength();
1702 
1703  for (XMLSize_t attribute_index=0;
1704  attribute_index<attributeCount; attribute_index++)
1705  {
1706  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1707 
1708  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1709  { continue; }
1710 
1711  const xercesc::DOMAttr* const attribute
1712  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1713  if (!attribute)
1714  {
1715  G4Exception("G4GDMLReadSolids::GenTrapRead()",
1716  "InvalidRead", FatalException, "No attribute found!");
1717  return;
1718  }
1719  const G4String attName = Transcode(attribute->getName());
1720  const G4String attValue = Transcode(attribute->getValue());
1721 
1722  if (attName=="name") { name = GenerateName(attValue); } else
1723  if (attName=="lunit") { G4UnitDefinition::GetValueOf(attValue);
1724  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1725  G4Exception("G4GDMLReadSolids::GenTrapRead()", "InvalidRead",
1726  FatalException, "Invalid unit for length!"); }
1727  } else
1728  if (attName=="dz") { dz = eval.Evaluate(attValue); } else
1729  if (attName=="v1x") { v1x = eval.Evaluate(attValue); } else
1730  if (attName=="v1y") { v1y = eval.Evaluate(attValue); } else
1731  if (attName=="v2x") { v2x = eval.Evaluate(attValue); } else
1732  if (attName=="v2y") { v2y = eval.Evaluate(attValue); } else
1733  if (attName=="v3x") { v3x = eval.Evaluate(attValue); } else
1734  if (attName=="v3y") { v3y = eval.Evaluate(attValue); } else
1735  if (attName=="v4x") { v4x = eval.Evaluate(attValue); } else
1736  if (attName=="v4y") { v4y = eval.Evaluate(attValue); } else
1737  if (attName=="v5x") { v5x = eval.Evaluate(attValue); } else
1738  if (attName=="v5y") { v5y = eval.Evaluate(attValue); } else
1739  if (attName=="v6x") { v6x = eval.Evaluate(attValue); } else
1740  if (attName=="v6y") { v6y = eval.Evaluate(attValue); } else
1741  if (attName=="v7x") { v7x = eval.Evaluate(attValue); } else
1742  if (attName=="v7y") { v7y = eval.Evaluate(attValue); } else
1743  if (attName=="v8x") { v8x = eval.Evaluate(attValue); } else
1744  if (attName=="v8y") { v8y = eval.Evaluate(attValue); }
1745  }
1746 
1747  dz *= lunit;
1748  std::vector<G4TwoVector> vertices;
1749  vertices.push_back(G4TwoVector(v1x*lunit,v1y*lunit));
1750  vertices.push_back(G4TwoVector(v2x*lunit,v2y*lunit));
1751  vertices.push_back(G4TwoVector(v3x*lunit,v3y*lunit));
1752  vertices.push_back(G4TwoVector(v4x*lunit,v4y*lunit));
1753  vertices.push_back(G4TwoVector(v5x*lunit,v5y*lunit));
1754  vertices.push_back(G4TwoVector(v6x*lunit,v6y*lunit));
1755  vertices.push_back(G4TwoVector(v7x*lunit,v7y*lunit));
1756  vertices.push_back(G4TwoVector(v8x*lunit,v8y*lunit));
1757  new G4GenericTrap(name,dz,vertices);
1758 }
1759 
1760 void G4GDMLReadSolids::TrapRead(const xercesc::DOMElement* const trapElement)
1761 {
1762  G4String name;
1763  G4double lunit = 1.0;
1764  G4double aunit = 1.0;
1765  G4double z = 0.0;
1766  G4double theta = 0.0;
1767  G4double phi = 0.0;
1768  G4double y1 = 0.0;
1769  G4double x1 = 0.0;
1770  G4double x2 = 0.0;
1771  G4double alpha1 = 0.0;
1772  G4double y2 = 0.0;
1773  G4double x3 = 0.0;
1774  G4double x4 = 0.0;
1775  G4double alpha2 = 0.0;
1776 
1777  const xercesc::DOMNamedNodeMap* const attributes
1778  = trapElement->getAttributes();
1779  XMLSize_t attributeCount = attributes->getLength();
1780 
1781  for (XMLSize_t attribute_index=0;
1782  attribute_index<attributeCount; attribute_index++)
1783  {
1784  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1785 
1786  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1787  { continue; }
1788 
1789  const xercesc::DOMAttr* const attribute
1790  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1791  if (!attribute)
1792  {
1793  G4Exception("G4GDMLReadSolids::TrapRead()",
1794  "InvalidRead", FatalException, "No attribute found!");
1795  return;
1796  }
1797  const G4String attName = Transcode(attribute->getName());
1798  const G4String attValue = Transcode(attribute->getValue());
1799 
1800  if (attName=="name") { name = GenerateName(attValue); } else
1801  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
1802  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1803  G4Exception("G4GDMLReadSolids::TrapRead()", "InvalidRead",
1804  FatalException, "Invalid unit for length!"); }
1805  } else
1806  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
1807  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
1808  G4Exception("G4GDMLReadSolids::TrapRead()", "InvalidRead",
1809  FatalException, "Invalid unit for angle!"); }
1810  } else
1811  if (attName=="z") { z = eval.Evaluate(attValue); } else
1812  if (attName=="theta") { theta = eval.Evaluate(attValue); } else
1813  if (attName=="phi") { phi = eval.Evaluate(attValue); } else
1814  if (attName=="y1") { y1 = eval.Evaluate(attValue); } else
1815  if (attName=="x1") { x1 = eval.Evaluate(attValue); } else
1816  if (attName=="x2") { x2 = eval.Evaluate(attValue); } else
1817  if (attName=="alpha1") { alpha1 = eval.Evaluate(attValue); } else
1818  if (attName=="y2") { y2 = eval.Evaluate(attValue); } else
1819  if (attName=="x3") { x3 = eval.Evaluate(attValue); } else
1820  if (attName=="x4") { x4 = eval.Evaluate(attValue); } else
1821  if (attName=="alpha2") { alpha2 = eval.Evaluate(attValue); }
1822  }
1823 
1824  z *= 0.5*lunit;
1825  theta *= aunit;
1826  phi *= aunit;
1827  y1 *= 0.5*lunit;
1828  x1 *= 0.5*lunit;
1829  x2 *= 0.5*lunit;
1830  alpha1 *= aunit;
1831  y2 *= 0.5*lunit;
1832  x3 *= 0.5*lunit;
1833  x4 *= 0.5*lunit;
1834  alpha2 *= aunit;
1835 
1836  new G4Trap(name,z,theta,phi,y1,x1,x2,alpha1,y2,x3,x4,alpha2);
1837 }
1838 
1839 void G4GDMLReadSolids::TrdRead(const xercesc::DOMElement* const trdElement)
1840 {
1841  G4String name;
1842  G4double lunit = 1.0;
1843  G4double x1 = 0.0;
1844  G4double x2 = 0.0;
1845  G4double y1 = 0.0;
1846  G4double y2 = 0.0;
1847  G4double z = 0.0;
1848 
1849  const xercesc::DOMNamedNodeMap* const attributes = trdElement->getAttributes();
1850  XMLSize_t attributeCount = attributes->getLength();
1851 
1852  for (XMLSize_t attribute_index=0;
1853  attribute_index<attributeCount; attribute_index++)
1854  {
1855  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1856 
1857  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1858  { continue; }
1859 
1860  const xercesc::DOMAttr* const attribute
1861  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1862  if (!attribute)
1863  {
1864  G4Exception("G4GDMLReadSolids::TrdRead()",
1865  "InvalidRead", FatalException, "No attribute found!");
1866  return;
1867  }
1868  const G4String attName = Transcode(attribute->getName());
1869  const G4String attValue = Transcode(attribute->getValue());
1870 
1871  if (attName=="name") { name = GenerateName(attValue); } else
1872  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
1873  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1874  G4Exception("G4GDMLReadSolids::TrdRead()", "InvalidRead",
1875  FatalException, "Invalid unit for length!"); }
1876  } else
1877  if (attName=="x1") { x1 = eval.Evaluate(attValue); } else
1878  if (attName=="x2") { x2 = eval.Evaluate(attValue); } else
1879  if (attName=="y1") { y1 = eval.Evaluate(attValue); } else
1880  if (attName=="y2") { y2 = eval.Evaluate(attValue); } else
1881  if (attName=="z") { z = eval.Evaluate(attValue); }
1882  }
1883 
1884  x1 *= 0.5*lunit;
1885  x2 *= 0.5*lunit;
1886  y1 *= 0.5*lunit;
1887  y2 *= 0.5*lunit;
1888  z *= 0.5*lunit;
1889 
1890  new G4Trd(name,x1,x2,y1,y2,z);
1891 }
1892 
1894 TriangularRead(const xercesc::DOMElement* const triangularElement)
1895 {
1896  G4ThreeVector vertex1;
1897  G4ThreeVector vertex2;
1898  G4ThreeVector vertex3;
1899  G4FacetVertexType type = ABSOLUTE;
1900  G4double lunit = 1.0;
1901 
1902  const xercesc::DOMNamedNodeMap* const attributes
1903  = triangularElement->getAttributes();
1904  XMLSize_t attributeCount = attributes->getLength();
1905 
1906  for (XMLSize_t attribute_index=0;
1907  attribute_index<attributeCount; attribute_index++)
1908  {
1909  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1910 
1911  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1912  { continue; }
1913 
1914  const xercesc::DOMAttr* const attribute
1915  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1916  if (!attribute)
1917  {
1918  G4Exception("G4GDMLReadSolids::TriangularRead()",
1919  "InvalidRead", FatalException, "No attribute found!");
1920  return 0;
1921  }
1922  const G4String attName = Transcode(attribute->getName());
1923  const G4String attValue = Transcode(attribute->getValue());
1924 
1925  if (attName=="vertex1")
1926  { vertex1 = GetPosition(GenerateName(attValue)); } else
1927  if (attName=="vertex2")
1928  { vertex2 = GetPosition(GenerateName(attValue)); } else
1929  if (attName=="vertex3")
1930  { vertex3 = GetPosition(GenerateName(attValue)); } else
1931  if (attName=="lunit")
1932  { lunit = G4UnitDefinition::GetValueOf(attValue);
1933  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1934  G4Exception("G4GDMLReadSolids::TriangularRead()", "InvalidRead",
1935  FatalException, "Invalid unit for length!"); }
1936  } else
1937  if (attName=="type")
1938  { if (attValue=="RELATIVE") { type = RELATIVE; } }
1939  }
1940 
1941  return new G4TriangularFacet(vertex1*lunit,vertex2*lunit,vertex3*lunit,type);
1942 }
1943 
1944 void G4GDMLReadSolids::TubeRead(const xercesc::DOMElement* const tubeElement)
1945 {
1946  G4String name;
1947  G4double lunit = 1.0;
1948  G4double aunit = 1.0;
1949  G4double rmin = 0.0;
1950  G4double rmax = 0.0;
1951  G4double z = 0.0;
1952  G4double startphi = 0.0;
1953  G4double deltaphi = 0.0;
1954 
1955  const xercesc::DOMNamedNodeMap* const attributes
1956  = tubeElement->getAttributes();
1957  XMLSize_t attributeCount = attributes->getLength();
1958 
1959  for (XMLSize_t attribute_index=0;
1960  attribute_index<attributeCount; attribute_index++)
1961  {
1962  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
1963 
1964  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
1965  { continue; }
1966 
1967  const xercesc::DOMAttr* const attribute
1968  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
1969  if (!attribute)
1970  {
1971  G4Exception("G4GDMLReadSolids::TubeRead()",
1972  "InvalidRead", FatalException, "No attribute found!");
1973  return;
1974  }
1975  const G4String attName = Transcode(attribute->getName());
1976  const G4String attValue = Transcode(attribute->getValue());
1977 
1978  if (attName=="name") { name = GenerateName(attValue); } else
1979  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
1980  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
1981  G4Exception("G4GDMLReadSolids::TubeRead()", "InvalidRead",
1982  FatalException, "Invalid unit for length!"); }
1983  } else
1984  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
1985  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
1986  G4Exception("G4GDMLReadSolids::TubeRead()", "InvalidRead",
1987  FatalException, "Invalid unit for angle!"); }
1988  } else
1989  if (attName=="rmin") { rmin = eval.Evaluate(attValue); } else
1990  if (attName=="rmax") { rmax = eval.Evaluate(attValue); } else
1991  if (attName=="z") { z = eval.Evaluate(attValue); } else
1992  if (attName=="startphi") { startphi = eval.Evaluate(attValue); } else
1993  if (attName=="deltaphi") { deltaphi = eval.Evaluate(attValue); }
1994  }
1995 
1996  rmin *= lunit;
1997  rmax *= lunit;
1998  z *= 0.5*lunit;
1999  startphi *= aunit;
2000  deltaphi *= aunit;
2001 
2002  new G4Tubs(name,rmin,rmax,z,startphi,deltaphi);
2003 }
2004 
2005 void G4GDMLReadSolids::CutTubeRead(const xercesc::DOMElement* const cuttubeElement)
2006 {
2007  G4String name;
2008  G4double lunit = 1.0;
2009  G4double aunit = 1.0;
2010  G4double rmin = 0.0;
2011  G4double rmax = 0.0;
2012  G4double z = 0.0;
2013  G4double startphi = 0.0;
2014  G4double deltaphi = 0.0;
2015  G4ThreeVector lowNorm(0);
2016  G4ThreeVector highNorm(0);
2017 
2018  const xercesc::DOMNamedNodeMap* const attributes
2019  = cuttubeElement->getAttributes();
2020  XMLSize_t attributeCount = attributes->getLength();
2021 
2022  for (XMLSize_t attribute_index=0;
2023  attribute_index<attributeCount; attribute_index++)
2024  {
2025  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2026 
2027  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2028  { continue; }
2029 
2030  const xercesc::DOMAttr* const attribute
2031  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2032  if (!attribute)
2033  {
2034  G4Exception("G4GDMLReadSolids::CutTubeRead()",
2035  "InvalidRead", FatalException, "No attribute found!");
2036  return;
2037  }
2038  const G4String attName = Transcode(attribute->getName());
2039  const G4String attValue = Transcode(attribute->getValue());
2040 
2041  if (attName=="name") { name = GenerateName(attValue); } else
2042  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
2043  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
2044  G4Exception("G4GDMLReadSolids::CutTubeRead()", "InvalidRead",
2045  FatalException, "Invalid unit for length!"); }
2046  } else
2047  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
2048  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
2049  G4Exception("G4GDMLReadSolids::CutTubeRead()", "InvalidRead",
2050  FatalException, "Invalid unit for angle!"); }
2051  } else
2052  if (attName=="rmin") { rmin = eval.Evaluate(attValue); } else
2053  if (attName=="rmax") { rmax = eval.Evaluate(attValue); } else
2054  if (attName=="z") { z = eval.Evaluate(attValue); } else
2055  if (attName=="startphi") { startphi = eval.Evaluate(attValue); } else
2056  if (attName=="deltaphi") { deltaphi = eval.Evaluate(attValue); } else
2057  if (attName=="lowX") { lowNorm.setX (eval.Evaluate(attValue)); } else
2058  if (attName=="lowY") { lowNorm.setY (eval.Evaluate(attValue)); } else
2059  if (attName=="lowZ") { lowNorm.setZ (eval.Evaluate(attValue)); } else
2060  if (attName=="highX") { highNorm.setX (eval.Evaluate(attValue)); } else
2061  if (attName=="highY") { highNorm.setY (eval.Evaluate(attValue)); } else
2062  if (attName=="highZ") { highNorm.setZ (eval.Evaluate(attValue)); }
2063 
2064  }
2065 
2066  rmin *= lunit;
2067  rmax *= lunit;
2068  z *= 0.5*lunit;
2069  startphi *= aunit;
2070  deltaphi *= aunit;
2071 
2072  new G4CutTubs(name,rmin,rmax,z,startphi,deltaphi,lowNorm,highNorm);
2073 }
2074 
2075 void G4GDMLReadSolids::
2076 TwistedboxRead(const xercesc::DOMElement* const twistedboxElement)
2077 {
2078  G4String name;
2079  G4double lunit = 1.0;
2080  G4double aunit = 1.0;
2081  G4double PhiTwist = 0.0;
2082  G4double x = 0.0;
2083  G4double y = 0.0;
2084  G4double z = 0.0;
2085 
2086  const xercesc::DOMNamedNodeMap* const attributes
2087  = twistedboxElement->getAttributes();
2088  XMLSize_t attributeCount = attributes->getLength();
2089 
2090  for (XMLSize_t attribute_index=0;
2091  attribute_index<attributeCount; attribute_index++)
2092  {
2093  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2094 
2095  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2096  { continue; }
2097 
2098  const xercesc::DOMAttr* const attribute
2099  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2100  if (!attribute)
2101  {
2102  G4Exception("G4GDMLReadSolids::TwistedboxRead()",
2103  "InvalidRead", FatalException, "No attribute found!");
2104  return;
2105  }
2106  const G4String attName = Transcode(attribute->getName());
2107  const G4String attValue = Transcode(attribute->getValue());
2108 
2109  if (attName=="name") { name = GenerateName(attValue); } else
2110  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
2111  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
2112  G4Exception("G4GDMLReadSolids::TwistedBoxRead()", "InvalidRead",
2113  FatalException, "Invalid unit for length!"); }
2114  } else
2115  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
2116  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
2117  G4Exception("G4GDMLReadSolids::TwistedboxRead()", "InvalidRead",
2118  FatalException, "Invalid unit for angle!"); }
2119  } else
2120  if (attName=="PhiTwist") { PhiTwist = eval.Evaluate(attValue); } else
2121  if (attName=="x") { x = eval.Evaluate(attValue); } else
2122  if (attName=="y") { y = eval.Evaluate(attValue); } else
2123  if (attName=="z") { z = eval.Evaluate(attValue); }
2124  }
2125 
2126  PhiTwist *= aunit;
2127  x *= 0.5*lunit;
2128  y *= 0.5*lunit;
2129  z *= 0.5*lunit;
2130 
2131  new G4TwistedBox(name,PhiTwist,x,y,z);
2132 }
2133 
2134 void G4GDMLReadSolids::
2135 TwistedtrapRead(const xercesc::DOMElement* const twistedtrapElement)
2136 {
2137  G4String name;
2138  G4double lunit = 1.0;
2139  G4double aunit = 1.0;
2140  G4double PhiTwist = 0.0;
2141  G4double z = 0.0;
2142  G4double Theta = 0.0;
2143  G4double Phi = 0.0;
2144  G4double y1 = 0.0;
2145  G4double x1 = 0.0;
2146  G4double x2 = 0.0;
2147  G4double y2 = 0.0;
2148  G4double x3 = 0.0;
2149  G4double x4 = 0.0;
2150  G4double Alph = 0.0;
2151 
2152  const xercesc::DOMNamedNodeMap* const attributes
2153  = twistedtrapElement->getAttributes();
2154  XMLSize_t attributeCount = attributes->getLength();
2155 
2156  for (XMLSize_t attribute_index=0;
2157  attribute_index<attributeCount; attribute_index++)
2158  {
2159  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2160 
2161  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2162  { continue; }
2163 
2164  const xercesc::DOMAttr* const attribute
2165  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2166  if (!attribute)
2167  {
2168  G4Exception("G4GDMLReadSolids::TwistedtrapRead()",
2169  "InvalidRead", FatalException, "No attribute found!");
2170  return;
2171  }
2172  const G4String attName = Transcode(attribute->getName());
2173  const G4String attValue = Transcode(attribute->getValue());
2174 
2175  if (attName=="name") { name = GenerateName(attValue); } else
2176  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
2177  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
2178  G4Exception("G4GDMLReadSolids::TwistedtrapRead()", "InvalidRead",
2179  FatalException, "Invalid unit for length!"); }
2180  } else
2181  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
2182  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
2183  G4Exception("G4GDMLReadSolids::TwistedtrapRead()", "InvalidRead",
2184  FatalException, "Invalid unit for angle!"); }
2185  } else
2186  if (attName=="PhiTwist") { PhiTwist = eval.Evaluate(attValue); } else
2187  if (attName=="z") { z = eval.Evaluate(attValue); } else
2188  if (attName=="Theta") { Theta = eval.Evaluate(attValue); } else
2189  if (attName=="Phi") { Phi = eval.Evaluate(attValue); } else
2190  if (attName=="y1") { y1 = eval.Evaluate(attValue); } else
2191  if (attName=="x1") { x1 = eval.Evaluate(attValue); } else
2192  if (attName=="x2") { x2 = eval.Evaluate(attValue); } else
2193  if (attName=="y2") { y2 = eval.Evaluate(attValue); } else
2194  if (attName=="x3") { x3 = eval.Evaluate(attValue); } else
2195  if (attName=="x4") { x4 = eval.Evaluate(attValue); } else
2196  if (attName=="Alph") { Alph = eval.Evaluate(attValue); }
2197  }
2198 
2199 
2200  PhiTwist *= aunit;
2201  z *= 0.5*lunit;
2202  Theta *= aunit;
2203  Phi *= aunit;
2204  Alph *= aunit;
2205  y1 *= 0.5*lunit;
2206  x1 *= 0.5*lunit;
2207  x2 *= 0.5*lunit;
2208  y2 *= 0.5*lunit;
2209  x3 *= 0.5*lunit;
2210  x4 *= 0.5*lunit;
2211 
2212  new G4TwistedTrap(name,PhiTwist,z,Theta,Phi,y1,x1,x2,y2,x3,x4,Alph);
2213 }
2214 
2215 void G4GDMLReadSolids::
2216 TwistedtrdRead(const xercesc::DOMElement* const twistedtrdElement)
2217 {
2218  G4String name;
2219  G4double lunit = 1.0;
2220  G4double aunit = 1.0;
2221  G4double x1 = 0.0;
2222  G4double x2 = 0.0;
2223  G4double y1 = 0.0;
2224  G4double y2 = 0.0;
2225  G4double z = 0.0;
2226  G4double PhiTwist = 0.0;
2227 
2228  const xercesc::DOMNamedNodeMap* const attributes
2229  = twistedtrdElement->getAttributes();
2230  XMLSize_t attributeCount = attributes->getLength();
2231 
2232  for (XMLSize_t attribute_index=0;
2233  attribute_index<attributeCount; attribute_index++)
2234  {
2235  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2236 
2237  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2238  { continue; }
2239 
2240  const xercesc::DOMAttr* const attribute
2241  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2242  if (!attribute)
2243  {
2244  G4Exception("G4GDMLReadSolids::TwistedtrdRead()",
2245  "InvalidRead", FatalException, "No attribute found!");
2246  return;
2247  }
2248  const G4String attName = Transcode(attribute->getName());
2249  const G4String attValue = Transcode(attribute->getValue());
2250 
2251  if (attName=="name") { name = GenerateName(attValue); } else
2252  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
2253  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
2254  G4Exception("G4GDMLReadSolids::TwistedtrdRead()", "InvalidRead",
2255  FatalException, "Invalid unit for length!"); }
2256  } else
2257  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
2258  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
2259  G4Exception("G4GDMLReadSolids::TwistedtrdRead()", "InvalidRead",
2260  FatalException, "Invalid unit for angle!"); }
2261  } else
2262  if (attName=="x1") { x1 = eval.Evaluate(attValue); } else
2263  if (attName=="x2") { x2 = eval.Evaluate(attValue); } else
2264  if (attName=="y1") { y1 = eval.Evaluate(attValue); } else
2265  if (attName=="y2") { y2 = eval.Evaluate(attValue); } else
2266  if (attName=="z") { z = eval.Evaluate(attValue); } else
2267  if (attName=="PhiTwist") { PhiTwist = eval.Evaluate(attValue); }
2268  }
2269 
2270  x1 *= 0.5*lunit;
2271  x2 *= 0.5*lunit;
2272  y1 *= 0.5*lunit;
2273  y2 *= 0.5*lunit;
2274  z *= 0.5*lunit;
2275  PhiTwist *= aunit;
2276 
2277  new G4TwistedTrd(name,x1,x2,y1,y2,z,PhiTwist);
2278 }
2279 
2280 void G4GDMLReadSolids::
2281 TwistedtubsRead(const xercesc::DOMElement* const twistedtubsElement)
2282 {
2283  G4String name;
2284  G4double lunit = 1.0;
2285  G4double aunit = 1.0;
2286  G4double twistedangle = 0.0;
2287  G4double endinnerrad = 0.0;
2288  G4double endouterrad = 0.0;
2289  G4double zlen = 0.0;
2290  G4double phi = 0.0;
2291  G4double totphi = 0.0;
2292  G4double midinnerrad = 0.0;
2293  G4double midouterrad = 0.0;
2294  G4double positiveEndz = 0.0;
2295  G4double negativeEndz = 0.0;
2296  G4int nseg = 0;
2297 
2298  const xercesc::DOMNamedNodeMap* const attributes
2299  = twistedtubsElement->getAttributes();
2300  XMLSize_t attributeCount = attributes->getLength();
2301 
2302  for (XMLSize_t attribute_index=0;
2303  attribute_index<attributeCount; attribute_index++)
2304  {
2305  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2306 
2307  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2308  { continue; }
2309 
2310  const xercesc::DOMAttr* const attribute
2311  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2312  if (!attribute)
2313  {
2314  G4Exception("G4GDMLReadSolids::TwistedtubsRead()",
2315  "InvalidRead", FatalException, "No attribute found!");
2316  return;
2317  }
2318  const G4String attName = Transcode(attribute->getName());
2319  const G4String attValue = Transcode(attribute->getValue());
2320 
2321  if (attName=="name") { name = GenerateName(attValue); } else
2322  if (attName=="lunit") { lunit = G4UnitDefinition::GetValueOf(attValue);
2323  if (G4UnitDefinition::GetCategory(attValue)!="Length") {
2324  G4Exception("G4GDMLReadSolids::TwistedtubsRead()", "InvalidRead",
2325  FatalException, "Invalid unit for length!"); }
2326  } else
2327  if (attName=="aunit") { aunit = G4UnitDefinition::GetValueOf(attValue);
2328  if (G4UnitDefinition::GetCategory(attValue)!="Angle") {
2329  G4Exception("G4GDMLReadSolids::TwistedtubsRead()", "InvalidRead",
2330  FatalException, "Invalid unit for angle!"); }
2331  } else
2332  if (attName=="twistedangle") { twistedangle=eval.Evaluate(attValue); } else
2333  if (attName=="endinnerrad") { endinnerrad=eval.Evaluate(attValue); } else
2334  if (attName=="endouterrad") { endouterrad=eval.Evaluate(attValue); } else
2335  if (attName=="zlen") { zlen = eval.Evaluate(attValue); } else
2336  if (attName=="midinnerrad") { midinnerrad=eval.Evaluate(attValue); } else
2337  if (attName=="midouterrad") { midouterrad=eval.Evaluate(attValue); } else
2338  if (attName=="negativeEndz") { negativeEndz = eval.Evaluate(attValue); } else
2339  if (attName=="positiveEndz") { positiveEndz = eval.Evaluate(attValue); } else
2340  if (attName=="nseg") { nseg = eval.Evaluate(attValue); } else
2341  if (attName=="totphi") { totphi = eval.Evaluate(attValue); } else
2342  if (attName=="phi") { phi = eval.Evaluate(attValue); }
2343  }
2344 
2345  twistedangle *= aunit;
2346  endinnerrad *= lunit;
2347  endouterrad *= lunit;
2348  zlen *= 0.5*lunit;
2349  midinnerrad *= lunit;
2350  midouterrad *= lunit;
2351  positiveEndz *= lunit;
2352  negativeEndz *= lunit;
2353  phi *= aunit;
2354  totphi *= aunit;
2355 
2356  if (zlen != 0.0)
2357  {
2358  if (nseg != 0)
2359  new G4TwistedTubs(name,twistedangle,endinnerrad,endouterrad,zlen,nseg,totphi);
2360  else
2361  new G4TwistedTubs(name,twistedangle,endinnerrad,endouterrad,zlen,phi);
2362  }
2363  else
2364  {
2365  if (nseg != 0)
2366  new G4TwistedTubs(name,twistedangle,midinnerrad,midouterrad,
2367  negativeEndz,positiveEndz,nseg,totphi);
2368  else
2369  new G4TwistedTubs(name,twistedangle,midinnerrad,midouterrad,
2370  negativeEndz,positiveEndz,phi);
2371  }
2372 }
2373 
2375 TwoDimVertexRead(const xercesc::DOMElement* const element, G4double lunit)
2376 {
2377  G4TwoVector vec;
2378 
2379  const xercesc::DOMNamedNodeMap* const attributes = element->getAttributes();
2380  XMLSize_t attributeCount = attributes->getLength();
2381 
2382  for (XMLSize_t attribute_index=0;
2383  attribute_index<attributeCount; attribute_index++)
2384  {
2385  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2386 
2387  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2388  { continue; }
2389 
2390  const xercesc::DOMAttr* const attribute
2391  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2392  if (!attribute)
2393  {
2394  G4Exception("G4GDMLReadSolids::TwoDimVertexRead()",
2395  "InvalidRead", FatalException, "No attribute found!");
2396  return vec;
2397  }
2398  const G4String attName = Transcode(attribute->getName());
2399  const G4String attValue = Transcode(attribute->getValue());
2400 
2401  if (attName=="x") { vec.setX(eval.Evaluate(attValue)*lunit); } else
2402  if (attName=="y") { vec.setY(eval.Evaluate(attValue)*lunit); }
2403  }
2404 
2405  return vec;
2406 }
2407 
2409 ZplaneRead(const xercesc::DOMElement* const zplaneElement)
2410 {
2411  zplaneType zplane = {0.,0.,0.};
2412 
2413  const xercesc::DOMNamedNodeMap* const attributes
2414  = zplaneElement->getAttributes();
2415  XMLSize_t attributeCount = attributes->getLength();
2416 
2417  for (XMLSize_t attribute_index=0;
2418  attribute_index<attributeCount; attribute_index++)
2419  {
2420  xercesc::DOMNode* node = attributes->item(attribute_index);
2421 
2422  if (node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE) { continue; }
2423 
2424  const xercesc::DOMAttr* const attribute
2425  = dynamic_cast<xercesc::DOMAttr*>(node);
2426  if (!attribute)
2427  {
2428  G4Exception("G4GDMLReadSolids::ZplaneRead()",
2429  "InvalidRead", FatalException, "No attribute found!");
2430  return zplane;
2431  }
2432  const G4String attName = Transcode(attribute->getName());
2433  const G4String attValue = Transcode(attribute->getValue());
2434 
2435  if (attName=="rmin") { zplane.rmin = eval.Evaluate(attValue); } else
2436  if (attName=="rmax") { zplane.rmax = eval.Evaluate(attValue); } else
2437  if (attName=="z") { zplane.z = eval.Evaluate(attValue); }
2438  }
2439 
2440  return zplane;
2441 }
2443 RZPointRead(const xercesc::DOMElement* const zplaneElement)
2444 {
2445  rzPointType rzpoint = {0.,0.};
2446 
2447  const xercesc::DOMNamedNodeMap* const attributes
2448  = zplaneElement->getAttributes();
2449  XMLSize_t attributeCount = attributes->getLength();
2450 
2451  for (XMLSize_t attribute_index=0;
2452  attribute_index<attributeCount; attribute_index++)
2453  {
2454  xercesc::DOMNode* node = attributes->item(attribute_index);
2455 
2456  if (node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE) { continue; }
2457 
2458  const xercesc::DOMAttr* const attribute
2459  = dynamic_cast<xercesc::DOMAttr*>(node);
2460  if (!attribute)
2461  {
2462  G4Exception("G4GDMLReadSolids::RZPointRead()",
2463  "InvalidRead", FatalException, "No attribute found!");
2464  return rzpoint;
2465  }
2466  const G4String attName = Transcode(attribute->getName());
2467  const G4String attValue = Transcode(attribute->getValue());
2468 
2469  if (attName=="r") { rzpoint.r = eval.Evaluate(attValue); } else
2470  if (attName=="z") { rzpoint.z = eval.Evaluate(attValue); }
2471  }
2472 
2473  return rzpoint;
2474 
2475 }
2476 
2477 void G4GDMLReadSolids::
2478 PropertyRead(const xercesc::DOMElement* const propertyElement,
2479  G4OpticalSurface* opticalsurface)
2480 {
2481  G4String name;
2482  G4String ref;
2483  G4GDMLMatrix matrix;
2484 
2485  const xercesc::DOMNamedNodeMap* const attributes
2486  = propertyElement->getAttributes();
2487  XMLSize_t attributeCount = attributes->getLength();
2488 
2489  for (XMLSize_t attribute_index=0;
2490  attribute_index<attributeCount; attribute_index++)
2491  {
2492  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2493 
2494  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2495  { continue; }
2496 
2497  const xercesc::DOMAttr* const attribute
2498  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2499  if (!attribute)
2500  {
2501  G4Exception("G4GDMLReadSolids::PropertyRead()", "InvalidRead",
2502  FatalException, "No attribute found!");
2503  return;
2504  }
2505  const G4String attName = Transcode(attribute->getName());
2506  const G4String attValue = Transcode(attribute->getValue());
2507 
2508  if (attName=="name") { name = GenerateName(attValue); } else
2509  if (attName=="ref") { matrix = GetMatrix(ref=attValue); }
2510  }
2511 
2512  /*
2513  if (matrix.GetCols() != 2)
2514  {
2515  G4String error_msg = "Referenced matrix '" + ref
2516  + "' should have \n two columns as a property table for opticalsurface: "
2517  + opticalsurface->GetName();
2518  G4Exception("G4GDMLReadSolids::PropertyRead()", "InvalidRead",
2519  FatalException, error_msg);
2520  }
2521  */
2522 
2523  if (matrix.GetRows() == 0) { return; }
2524 
2525  G4MaterialPropertiesTable* matprop=opticalsurface->GetMaterialPropertiesTable();
2526  if (!matprop)
2527  {
2528  matprop = new G4MaterialPropertiesTable();
2529  opticalsurface->SetMaterialPropertiesTable(matprop);
2530  }
2531  if (matrix.GetCols() == 1) // constant property assumed
2532  {
2533  matprop->AddConstProperty(Strip(name), matrix.Get(0,0));
2534  }
2535  else // build the material properties vector
2536  {
2537  G4MaterialPropertyVector* propvect;
2538  // first check if it was already built
2539  if ( mapOfMatPropVects.find(Strip(name)) == mapOfMatPropVects.end())
2540  {
2541  // if not create a new one
2542  propvect = new G4MaterialPropertyVector();
2543  for (size_t i=0; i<matrix.GetRows(); i++)
2544  {
2545  propvect->InsertValues(matrix.Get(i,0),matrix.Get(i,1));
2546  }
2547  // and add it to the list for potential future reuse
2548  mapOfMatPropVects[Strip(name)] = propvect;
2549  }
2550  else
2551  {
2552  propvect = mapOfMatPropVects[Strip(name)];
2553  }
2554 
2555  matprop->AddProperty(Strip(name),propvect);
2556  }
2557 }
2558 
2559 void G4GDMLReadSolids::
2560 OpticalSurfaceRead(const xercesc::DOMElement* const opticalsurfaceElement)
2561 {
2562  G4String name;
2563  G4String smodel;
2564  G4String sfinish;
2565  G4String stype;
2566  G4double value = 0.0;
2567 
2568  const xercesc::DOMNamedNodeMap* const attributes
2569  = opticalsurfaceElement->getAttributes();
2570  XMLSize_t attributeCount = attributes->getLength();
2571 
2572  for (XMLSize_t attribute_index=0;
2573  attribute_index<attributeCount; attribute_index++)
2574  {
2575  xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
2576 
2577  if (attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
2578  { continue; }
2579 
2580  const xercesc::DOMAttr* const attribute
2581  = dynamic_cast<xercesc::DOMAttr*>(attribute_node);
2582  if (!attribute)
2583  {
2584  G4Exception("G4GDMLReadSolids::OpticalSurfaceRead()",
2585  "InvalidRead", FatalException, "No attribute found!");
2586  return;
2587  }
2588  const G4String attName = Transcode(attribute->getName());
2589  const G4String attValue = Transcode(attribute->getValue());
2590 
2591  if (attName=="name") { name = GenerateName(attValue); } else
2592  if (attName=="model") { smodel = attValue; } else
2593  if (attName=="finish") { sfinish = attValue; } else
2594  if (attName=="type") { stype = attValue; } else
2595  if (attName=="value") { value = eval.Evaluate(attValue); }
2596  }
2597 
2599  G4OpticalSurfaceFinish finish;
2600  G4SurfaceType type;
2601 
2602  if ((smodel=="glisur") || (smodel=="0")) { model = glisur; } else
2603  if ((smodel=="unified") || (smodel=="1")) { model = unified; } else
2604  if ((smodel=="LUT") || (smodel=="2")) { model = LUT; }
2605  else { model = dichroic; }
2606 
2607  if ((sfinish=="polished") || (sfinish=="0"))
2608  { finish = polished; } else
2609  if ((sfinish=="polishedfrontpainted") || (sfinish=="1"))
2610  { finish = polishedfrontpainted; } else
2611  if ((sfinish=="polishedbackpainted") || (sfinish=="2"))
2612  { finish = polishedbackpainted; } else
2613  if ((sfinish=="ground") || (sfinish=="3"))
2614  { finish = ground; } else
2615  if ((sfinish=="groundfrontpainted") || (sfinish=="4"))
2616  { finish = groundfrontpainted; } else
2617  if ((sfinish=="groundbackpainted") || (sfinish=="5"))
2618  { finish = groundbackpainted; } else
2619  if ((sfinish=="polishedlumirrorair") || (sfinish=="6"))
2620  { finish = polishedlumirrorair; } else
2621  if ((sfinish=="polishedlumirrorglue") || (sfinish=="7"))
2622  { finish = polishedlumirrorglue; } else
2623  if ((sfinish=="polishedair") || (sfinish=="8"))
2624  { finish = polishedair; } else
2625  if ((sfinish=="polishedteflonair") || (sfinish=="9"))
2626  { finish = polishedteflonair; } else
2627  if ((sfinish=="polishedtioair") || (sfinish=="10"))
2628  { finish = polishedtioair; } else
2629  if ((sfinish=="polishedtyvekair") || (sfinish=="11"))
2630  { finish = polishedtyvekair; } else
2631  if ((sfinish=="polishedvm2000air") || (sfinish=="12"))
2632  { finish = polishedvm2000air; } else
2633  if ((sfinish=="polishedvm2000glue") || (sfinish=="13"))
2634  { finish = polishedvm2000glue; } else
2635  if ((sfinish=="etchedlumirrorair") || (sfinish=="14"))
2636  { finish = etchedlumirrorair; } else
2637  if ((sfinish=="etchedlumirrorglue") || (sfinish=="15"))
2638  { finish = etchedlumirrorglue; } else
2639  if ((sfinish=="etchedair") || (sfinish=="16"))
2640  { finish = etchedair; } else
2641  if ((sfinish=="etchedteflonair") || (sfinish=="17"))
2642  { finish = etchedteflonair; } else
2643  if ((sfinish=="etchedtioair") || (sfinish=="18"))
2644  { finish = etchedtioair; } else
2645  if ((sfinish=="etchedtyvekair") || (sfinish=="19"))
2646  { finish = etchedtyvekair; } else
2647  if ((sfinish=="etchedvm2000air") || (sfinish=="20"))
2648  { finish = etchedvm2000air; } else
2649  if ((sfinish=="etchedvm2000glue") || (sfinish=="21"))
2650  { finish = etchedvm2000glue; } else
2651  if ((sfinish=="groundlumirrorair") || (sfinish=="22"))
2652  { finish = groundlumirrorair; } else
2653  if ((sfinish=="groundlumirrorglue") || (sfinish=="23"))
2654  { finish = groundlumirrorglue; } else
2655  if ((sfinish=="groundair") || (sfinish=="24"))
2656  { finish = groundair; } else
2657  if ((sfinish=="groundteflonair") || (sfinish=="25"))
2658  { finish = groundteflonair; } else
2659  if ((sfinish=="groundtioair") || (sfinish=="26"))
2660  { finish = groundtioair; } else
2661  if ((sfinish=="groundtyvekair") || (sfinish=="27"))
2662  { finish = groundtyvekair; } else
2663  if ((sfinish=="groundvm2000air") || (sfinish=="28"))
2664  { finish = groundvm2000air; }
2665  else { finish = groundvm2000glue; }
2666 
2667  if ((stype=="dielectric_metal") || (stype=="0"))
2668  { type = dielectric_metal; } else
2669  if ((stype=="dielectric_dielectric") || (stype=="1"))
2670  { type = dielectric_dielectric; } else
2671  if ((stype=="dielectric_LUT") || (stype=="2"))
2672  { type = dielectric_LUT; } else
2673  if ((stype=="dielectric_dichroic") || (stype=="3"))
2674  { type = dielectric_dichroic; } else
2675  if ((stype=="firsov") || (stype=="4"))
2676  { type = firsov; }
2677  else { type = x_ray; }
2678 
2679  G4OpticalSurface* opticalsurface
2680  = new G4OpticalSurface(name,model,finish,type,value);
2681 
2682  for (xercesc::DOMNode* iter = opticalsurfaceElement->getFirstChild();
2683  iter != 0;iter = iter->getNextSibling())
2684  {
2685  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
2686 
2687  const xercesc::DOMElement* const child
2688  = dynamic_cast<xercesc::DOMElement*>(iter);
2689  if (!child)
2690  {
2691  G4Exception("G4GDMLReadSolids::OpticalSurfaceRead()",
2692  "InvalidRead", FatalException, "No child found!");
2693  return;
2694  }
2695  const G4String tag = Transcode(child->getTagName());
2696 
2697  if (tag=="property") { PropertyRead(child,opticalsurface); }
2698  }
2699 }
2700 
2701 void G4GDMLReadSolids::SolidsRead(const xercesc::DOMElement* const solidsElement)
2702 {
2703 #ifdef G4VERBOSE
2704  G4cout << "G4GDML: Reading solids..." << G4endl;
2705 #endif
2706  for (xercesc::DOMNode* iter = solidsElement->getFirstChild();
2707  iter != 0; iter = iter->getNextSibling())
2708  {
2709  if (iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) { continue; }
2710 
2711  const xercesc::DOMElement* const child
2712  = dynamic_cast<xercesc::DOMElement*>(iter);
2713  if (!child)
2714  {
2715  G4Exception("G4GDMLReadSolids::SolidsRead()",
2716  "InvalidRead", FatalException, "No child found!");
2717  return;
2718  }
2719  const G4String tag = Transcode(child->getTagName());
2720  if (tag=="define") { DefineRead(child); } else
2721  if (tag=="box") { BoxRead(child); } else
2722  if (tag=="cone") { ConeRead(child); } else
2723  if (tag=="elcone") { ElconeRead(child); } else
2724  if (tag=="ellipsoid") { EllipsoidRead(child); }else
2725  if (tag=="eltube") { EltubeRead(child); } else
2726  if (tag=="xtru") { XtruRead(child); } else
2727  if (tag=="hype") { HypeRead(child); } else
2728  if (tag=="intersection") { BooleanRead(child,INTERSECTION); } else
2729  if (tag=="multiUnion") { MultiUnionRead(child); } else
2730  if (tag=="orb") { OrbRead(child); } else
2731  if (tag=="para") { ParaRead(child); } else
2732  if (tag=="paraboloid") { ParaboloidRead(child); } else
2733  if (tag=="polycone") { PolyconeRead(child); } else
2734  if (tag=="genericPolycone") { GenericPolyconeRead(child); } else
2735  if (tag=="polyhedra") { PolyhedraRead(child); } else
2736  if (tag=="genericPolyhedra") { GenericPolyhedraRead(child); } else
2737  if (tag=="reflectedSolid") { ReflectedSolidRead(child); } else
2738  if (tag=="scaledSolid") { ScaledSolidRead(child); } else
2739  if (tag=="sphere") { SphereRead(child); } else
2740  if (tag=="subtraction") { BooleanRead(child,SUBTRACTION); } else
2741  if (tag=="tessellated") { TessellatedRead(child); } else
2742  if (tag=="tet") { TetRead(child); } else
2743  if (tag=="torus") { TorusRead(child); } else
2744  if (tag=="arb8") { GenTrapRead(child); } else
2745  if (tag=="trap") { TrapRead(child); } else
2746  if (tag=="trd") { TrdRead(child); } else
2747  if (tag=="tube") { TubeRead(child); } else
2748  if (tag=="cutTube") { CutTubeRead(child); } else
2749  if (tag=="twistedbox") { TwistedboxRead(child); } else
2750  if (tag=="twistedtrap") { TwistedtrapRead(child); } else
2751  if (tag=="twistedtrd") { TwistedtrdRead(child); } else
2752  if (tag=="twistedtubs") { TwistedtubsRead(child); } else
2753  if (tag=="union") { BooleanRead(child,UNION); } else
2754  if (tag=="opticalsurface") { OpticalSurfaceRead(child); } else
2755  if (tag=="loop") { LoopRead(child,&G4GDMLRead::SolidsRead); }
2756  else
2757  {
2758  G4String error_msg = "Unknown tag in solids: " + tag;
2759  G4Exception("G4GDMLReadSolids::SolidsRead()", "ReadError",
2760  FatalException, error_msg);
2761  }
2762  }
2763 }
2764 
2766 {
2767  G4VSolid* solidPtr = G4SolidStore::GetInstance()->GetSolid(ref,false);
2768 
2769  if (!solidPtr)
2770  {
2771  G4String error_msg = "Referenced solid '" + ref + "' was not found!";
2772  G4Exception("G4GDMLReadSolids::GetSolid()", "ReadError",
2773  FatalException, error_msg);
2774  }
2775 
2776  return solidPtr;
2777 }
2778 
2780 GetSurfaceProperty(const G4String& ref) const
2781 {
2782  const G4SurfacePropertyTable* surfaceList
2784  const size_t surfaceCount = surfaceList->size();
2785 
2786  for (size_t i=0; i<surfaceCount; i++)
2787  {
2788  if ((*surfaceList)[i]->GetName() == ref) { return (*surfaceList)[i]; }
2789  }
2790 
2791  G4String error_msg = "Referenced optical surface '" + ref + "' was not found!";
2792  G4Exception("G4GDMLReadSolids::GetSurfaceProperty()", "ReadError",
2793  FatalException, error_msg);
2794 
2795  return 0;
2796 }