ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4GDMLWriteSolids.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4GDMLWriteSolids.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 //
28 // class G4GDMLWriteSolids Implementation
29 //
30 // Original author: Zoltan Torzsok, November 2007
31 //
32 // --------------------------------------------------------------------
33 
34 #include "G4GDMLWriteSolids.hh"
35 
36 #include "G4SystemOfUnits.hh"
37 #include "G4BooleanSolid.hh"
38 #include "G4ScaledSolid.hh"
39 #include "G4Box.hh"
40 #include "G4Cons.hh"
41 #include "G4Ellipsoid.hh"
42 #include "G4EllipticalCone.hh"
43 #include "G4EllipticalTube.hh"
44 #include "G4ExtrudedSolid.hh"
45 #include "G4Hype.hh"
46 #include "G4Orb.hh"
47 #include "G4Para.hh"
48 #include "G4Paraboloid.hh"
49 #include "G4IntersectionSolid.hh"
50 #include "G4Polycone.hh"
51 #include "G4GenericPolycone.hh"
52 #include "G4Polyhedra.hh"
53 #include "G4ReflectedSolid.hh"
54 #include "G4Sphere.hh"
55 #include "G4SubtractionSolid.hh"
56 #include "G4GenericTrap.hh"
57 #include "G4TessellatedSolid.hh"
58 #include "G4Tet.hh"
59 #include "G4Torus.hh"
60 #include "G4Trap.hh"
61 #include "G4Trd.hh"
62 #include "G4Tubs.hh"
63 #include "G4CutTubs.hh"
64 #include "G4TwistedBox.hh"
65 #include "G4TwistedTrap.hh"
66 #include "G4TwistedTrd.hh"
67 #include "G4TwistedTubs.hh"
68 #include "G4UnionSolid.hh"
69 #include "G4OpticalSurface.hh"
70 #include "G4SurfaceProperty.hh"
72 
74  : G4GDMLWriteMaterials(), solidsElement(0)
75 {
76 }
77 
79 {
80 }
81 
83 MultiUnionWrite(xercesc::DOMElement* solElement,
84  const G4MultiUnion* const munionSolid)
85 {
86  G4int numSolids=munionSolid->GetNumberOfSolids();
87  G4String tag("multiUnion");
88 
89  G4VSolid* solid;
91 
92  const G4String& name = GenerateName(munionSolid->GetName(),munionSolid);
93  xercesc::DOMElement* multiUnionElement = NewElement(tag);
94  multiUnionElement->setAttributeNode(NewAttribute("name",name));
95 
96  for (G4int i=0; i<numSolids; ++i)
97  {
98  solid = munionSolid->GetSolid(i);
99  transform = munionSolid->GetTransformation(i);
100 
101  HepGeom::Rotate3D rot3d;
102  HepGeom::Translate3D transl ;
104  transform.getDecomposition(scale,rot3d,transl);
105 
106  G4ThreeVector pos = transl.getTranslation();
108  rotm(CLHEP::HepRep3x3(rot3d.xx(), rot3d.xy(), rot3d.xz(),
109  rot3d.yx(), rot3d.yy(), rot3d.yz(),
110  rot3d.zx(), rot3d.zy(), rot3d.zz()));
111  G4ThreeVector rot = GetAngles(rotm);
112 
113  AddSolid(solid);
114  const G4String& solidref = GenerateName(solid->GetName(),solid);
115  std::ostringstream os; os << i+1;
116  const G4String& nodeName = "Node-" + G4String(os.str());
117  xercesc::DOMElement* solidElement = NewElement("solid");
118  solidElement->setAttributeNode(NewAttribute("ref",solidref));
119  xercesc::DOMElement* multiUnionNodeElement = NewElement("multiUnionNode");
120  multiUnionNodeElement->setAttributeNode(NewAttribute("name", nodeName));
121  multiUnionNodeElement->appendChild(solidElement); // Append solid to node
122  if ( (std::fabs(pos.x()) > kLinearPrecision)
123  || (std::fabs(pos.y()) > kLinearPrecision)
124  || (std::fabs(pos.z()) > kLinearPrecision) )
125  {
126  PositionWrite(multiUnionNodeElement,name+"_pos",pos);
127  }
128  if ( (std::fabs(rot.x()) > kAngularPrecision)
129  || (std::fabs(rot.y()) > kAngularPrecision)
130  || (std::fabs(rot.z()) > kAngularPrecision) )
131  {
132  RotationWrite(multiUnionNodeElement,name+"_rot",rot);
133  }
134  multiUnionElement->appendChild(multiUnionNodeElement); // Append node
135  }
136 
137  solElement->appendChild(multiUnionElement);
138  // Add the multiUnion solid AFTER the constituent nodes!
139 }
140 
142 BooleanWrite(xercesc::DOMElement* solElement,
143  const G4BooleanSolid* const boolean)
144 {
145  G4int displaced=0;
146 
147  G4String tag("undefined");
148  if (dynamic_cast<const G4IntersectionSolid*>(boolean))
149  { tag = "intersection"; } else
150  if (dynamic_cast<const G4SubtractionSolid*>(boolean))
151  { tag = "subtraction"; } else
152  if (dynamic_cast<const G4UnionSolid*>(boolean))
153  { tag = "union"; }
154 
155  G4VSolid* firstPtr = const_cast<G4VSolid*>(boolean->GetConstituentSolid(0));
156  G4VSolid* secondPtr = const_cast<G4VSolid*>(boolean->GetConstituentSolid(1));
157 
158  G4ThreeVector firstpos,firstrot,pos,rot;
159 
160  // Solve possible displacement of referenced solids!
161  //
162  while (true)
163  {
164  if ( displaced>8 )
165  {
166  G4String ErrorMessage = "The referenced solid '"
167  + firstPtr->GetName() +
168  + "in the Boolean shape '" +
169  + boolean->GetName() +
170  + "' was displaced too many times!";
171  G4Exception("G4GDMLWriteSolids::BooleanWrite()",
172  "InvalidSetup", FatalException, ErrorMessage);
173  }
174 
175  if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(firstPtr))
176  {
177  firstpos += disp->GetObjectTranslation();
178  firstrot += GetAngles(disp->GetObjectRotation());
179  firstPtr = disp->GetConstituentMovedSolid();
180  displaced++;
181  continue;
182  }
183  break;
184  }
185  displaced = 0;
186  while (true)
187  {
188  if ( displaced>maxTransforms )
189  {
190  G4String ErrorMessage = "The referenced solid '"
191  + secondPtr->GetName() +
192  + "in the Boolean shape '" +
193  + boolean->GetName() +
194  + "' was displaced too many times!";
195  G4Exception("G4GDMLWriteSolids::BooleanWrite()",
196  "InvalidSetup", FatalException, ErrorMessage);
197  }
198 
199  if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(secondPtr))
200  {
201  pos += disp->GetObjectTranslation();
202  rot += GetAngles(disp->GetObjectRotation());
203  secondPtr = disp->GetConstituentMovedSolid();
204  displaced++;
205  continue;
206  }
207  break;
208  }
209 
210  AddSolid(firstPtr); // At first add the constituent solids!
211  AddSolid(secondPtr);
212 
213  const G4String& name = GenerateName(boolean->GetName(),boolean);
214  const G4String& firstref = GenerateName(firstPtr->GetName(),firstPtr);
215  const G4String& secondref = GenerateName(secondPtr->GetName(),secondPtr);
216 
217  xercesc::DOMElement* booleanElement = NewElement(tag);
218  booleanElement->setAttributeNode(NewAttribute("name",name));
219  xercesc::DOMElement* firstElement = NewElement("first");
220  firstElement->setAttributeNode(NewAttribute("ref",firstref));
221  booleanElement->appendChild(firstElement);
222  xercesc::DOMElement* secondElement = NewElement("second");
223  secondElement->setAttributeNode(NewAttribute("ref",secondref));
224  booleanElement->appendChild(secondElement);
225  solElement->appendChild(booleanElement);
226  // Add the boolean solid AFTER the constituent solids!
227 
228  if ( (std::fabs(pos.x()) > kLinearPrecision)
229  || (std::fabs(pos.y()) > kLinearPrecision)
230  || (std::fabs(pos.z()) > kLinearPrecision) )
231  {
232  PositionWrite(booleanElement,name+"_pos",pos);
233  }
234 
235  if ( (std::fabs(rot.x()) > kAngularPrecision)
236  || (std::fabs(rot.y()) > kAngularPrecision)
237  || (std::fabs(rot.z()) > kAngularPrecision) )
238  {
239  RotationWrite(booleanElement,name+"_rot",rot);
240  }
241 
242  if ( (std::fabs(firstpos.x()) > kLinearPrecision)
243  || (std::fabs(firstpos.y()) > kLinearPrecision)
244  || (std::fabs(firstpos.z()) > kLinearPrecision) )
245  {
246  FirstpositionWrite(booleanElement,name+"_fpos",firstpos);
247  }
248 
249  if ( (std::fabs(firstrot.x()) > kAngularPrecision)
250  || (std::fabs(firstrot.y()) > kAngularPrecision)
251  || (std::fabs(firstrot.z()) > kAngularPrecision) )
252  {
253  FirstrotationWrite(booleanElement,name+"_frot",firstrot);
254  }
255 }
256 
258 ScaledWrite(xercesc::DOMElement* solElement,
259  const G4ScaledSolid* const scaled)
260 {
261  G4String tag("scaledSolid");
262 
263  G4VSolid* solid = const_cast<G4VSolid*>(scaled->GetUnscaledSolid());
264  G4Scale3D scale = scaled->GetScaleTransform();
265  G4ThreeVector sclVector = G4ThreeVector(scale.xx(), scale.yy(), scale.zz());
266 
267  AddSolid(solid); // Add the constituent solid!
268 
269  const G4String& name = GenerateName(scaled->GetName(),scaled);
270  const G4String& solidref = GenerateName(solid->GetName(),solid);
271 
272  xercesc::DOMElement* scaledElement = NewElement(tag);
273  scaledElement->setAttributeNode(NewAttribute("name",name));
274 
275  xercesc::DOMElement* solidElement = NewElement("solidref");
276  solidElement->setAttributeNode(NewAttribute("ref",solidref));
277  scaledElement->appendChild(solidElement);
278 
279  if ( (std::fabs(scale.xx()) > kLinearPrecision)
280  && (std::fabs(scale.yy()) > kLinearPrecision)
281  && (std::fabs(scale.zz()) > kLinearPrecision) )
282  {
283  ScaleWrite(scaledElement, name+"_scl", sclVector);
284  }
285 
286  solElement->appendChild(scaledElement);
287  // Add the scaled solid AFTER its constituent solid!
288 }
289 
291 BoxWrite(xercesc::DOMElement* solElement, const G4Box* const box)
292 {
293  const G4String& name = GenerateName(box->GetName(),box);
294 
295  xercesc::DOMElement* boxElement = NewElement("box");
296  boxElement->setAttributeNode(NewAttribute("name",name));
297  boxElement->setAttributeNode(NewAttribute("x",2.0*box->GetXHalfLength()/mm));
298  boxElement->setAttributeNode(NewAttribute("y",2.0*box->GetYHalfLength()/mm));
299  boxElement->setAttributeNode(NewAttribute("z",2.0*box->GetZHalfLength()/mm));
300  boxElement->setAttributeNode(NewAttribute("lunit","mm"));
301  solElement->appendChild(boxElement);
302 }
303 
305 ConeWrite(xercesc::DOMElement* solElement, const G4Cons* const cone)
306 {
307  const G4String& name = GenerateName(cone->GetName(),cone);
308 
309  xercesc::DOMElement* coneElement = NewElement("cone");
310  coneElement->setAttributeNode(NewAttribute("name",name));
311  coneElement->
312  setAttributeNode(NewAttribute("rmin1",cone->GetInnerRadiusMinusZ()/mm));
313  coneElement->
314  setAttributeNode(NewAttribute("rmax1",cone->GetOuterRadiusMinusZ()/mm));
315  coneElement->
316  setAttributeNode(NewAttribute("rmin2",cone->GetInnerRadiusPlusZ()/mm));
317  coneElement->
318  setAttributeNode(NewAttribute("rmax2",cone->GetOuterRadiusPlusZ()/mm));
319  coneElement->
320  setAttributeNode(NewAttribute("z",2.0*cone->GetZHalfLength()/mm));
321  coneElement->
322  setAttributeNode(NewAttribute("startphi",cone->GetStartPhiAngle()/degree));
323  coneElement->
324  setAttributeNode(NewAttribute("deltaphi",cone->GetDeltaPhiAngle()/degree));
325  coneElement->setAttributeNode(NewAttribute("aunit","deg"));
326  coneElement->setAttributeNode(NewAttribute("lunit","mm"));
327  solElement->appendChild(coneElement);
328 }
329 
331 ElconeWrite(xercesc::DOMElement* solElement,
332  const G4EllipticalCone* const elcone)
333 {
334  const G4String& name = GenerateName(elcone->GetName(),elcone);
335 
336  xercesc::DOMElement* elconeElement = NewElement("elcone");
337  elconeElement->setAttributeNode(NewAttribute("name",name));
338  elconeElement->setAttributeNode(NewAttribute("dx",elcone->GetSemiAxisX()/mm));
339  elconeElement->setAttributeNode(NewAttribute("dy",elcone->GetSemiAxisY()/mm));
340  elconeElement->setAttributeNode(NewAttribute("zmax",elcone->GetZMax()/mm));
341  elconeElement->setAttributeNode(NewAttribute("zcut",elcone->GetZTopCut()/mm));
342  elconeElement->setAttributeNode(NewAttribute("lunit","mm"));
343  solElement->appendChild(elconeElement);
344 }
345 
347 EllipsoidWrite(xercesc::DOMElement* solElement,
348  const G4Ellipsoid* const ellipsoid)
349 {
350  const G4String& name = GenerateName(ellipsoid->GetName(),ellipsoid);
351 
352  xercesc::DOMElement* ellipsoidElement = NewElement("ellipsoid");
353  ellipsoidElement->setAttributeNode(NewAttribute("name",name));
354  ellipsoidElement->
355  setAttributeNode(NewAttribute("ax",ellipsoid->GetSemiAxisMax(0)/mm));
356  ellipsoidElement->
357  setAttributeNode(NewAttribute("by",ellipsoid->GetSemiAxisMax(1)/mm));
358  ellipsoidElement->
359  setAttributeNode(NewAttribute("cz",ellipsoid->GetSemiAxisMax(2)/mm));
360  ellipsoidElement->
361  setAttributeNode(NewAttribute("zcut1",ellipsoid->GetZBottomCut()/mm));
362  ellipsoidElement->
363  setAttributeNode(NewAttribute("zcut2",ellipsoid->GetZTopCut()/mm));
364  ellipsoidElement->
365  setAttributeNode(NewAttribute("lunit","mm"));
366  solElement->appendChild(ellipsoidElement);
367 }
368 
370 EltubeWrite(xercesc::DOMElement* solElement,
371  const G4EllipticalTube* const eltube)
372 {
373  const G4String& name = GenerateName(eltube->GetName(),eltube);
374 
375  xercesc::DOMElement* eltubeElement = NewElement("eltube");
376  eltubeElement->setAttributeNode(NewAttribute("name",name));
377  eltubeElement->setAttributeNode(NewAttribute("dx",eltube->GetDx()/mm));
378  eltubeElement->setAttributeNode(NewAttribute("dy",eltube->GetDy()/mm));
379  eltubeElement->setAttributeNode(NewAttribute("dz",eltube->GetDz()/mm));
380  eltubeElement->setAttributeNode(NewAttribute("lunit","mm"));
381  solElement->appendChild(eltubeElement);
382 }
383 
385 XtruWrite(xercesc::DOMElement* solElement,
386  const G4ExtrudedSolid* const xtru)
387 {
388  const G4String& name = GenerateName(xtru->GetName(),xtru);
389 
390  xercesc::DOMElement* xtruElement = NewElement("xtru");
391  xtruElement->setAttributeNode(NewAttribute("name",name));
392  xtruElement->setAttributeNode(NewAttribute("lunit","mm"));
393  solElement->appendChild(xtruElement);
394 
395  const G4int NumVertex = xtru->GetNofVertices();
396 
397  for (G4int i=0;i<NumVertex;i++)
398  {
399  xercesc::DOMElement* twoDimVertexElement = NewElement("twoDimVertex");
400  xtruElement->appendChild(twoDimVertexElement);
401 
402  const G4TwoVector& vertex = xtru->GetVertex(i);
403 
404  twoDimVertexElement->setAttributeNode(NewAttribute("x",vertex.x()/mm));
405  twoDimVertexElement->setAttributeNode(NewAttribute("y",vertex.y()/mm));
406  }
407 
408  const G4int NumSection = xtru->GetNofZSections();
409 
410  for (G4int i=0;i<NumSection;i++)
411  {
412  xercesc::DOMElement* sectionElement = NewElement("section");
413  xtruElement->appendChild(sectionElement);
414 
415  const G4ExtrudedSolid::ZSection section = xtru->GetZSection(i);
416 
417  sectionElement->setAttributeNode(NewAttribute("zOrder",i));
418  sectionElement->setAttributeNode(NewAttribute("zPosition",section.fZ/mm));
419  sectionElement->
420  setAttributeNode(NewAttribute("xOffset",section.fOffset.x()/mm));
421  sectionElement->
422  setAttributeNode(NewAttribute("yOffset",section.fOffset.y()/mm));
423  sectionElement->
424  setAttributeNode(NewAttribute("scalingFactor",section.fScale));
425  }
426 }
427 
429 HypeWrite(xercesc::DOMElement* solElement, const G4Hype* const hype)
430 {
431  const G4String& name = GenerateName(hype->GetName(),hype);
432 
433  xercesc::DOMElement* hypeElement = NewElement("hype");
434  hypeElement->setAttributeNode(NewAttribute("name",name));
435  hypeElement->setAttributeNode(NewAttribute("rmin",
436  hype->GetInnerRadius()/mm));
437  hypeElement->setAttributeNode(NewAttribute("rmax",
438  hype->GetOuterRadius()/mm));
439  hypeElement->setAttributeNode(NewAttribute("inst",
440  hype->GetInnerStereo()/degree));
441  hypeElement->setAttributeNode(NewAttribute("outst",
442  hype->GetOuterStereo()/degree));
443  hypeElement->setAttributeNode(NewAttribute("z",
444  2.0*hype->GetZHalfLength()/mm));
445  hypeElement->setAttributeNode(NewAttribute("aunit","deg"));
446  hypeElement->setAttributeNode(NewAttribute("lunit","mm"));
447  solElement->appendChild(hypeElement);
448 }
449 
451 OrbWrite(xercesc::DOMElement* solElement, const G4Orb* const orb)
452 {
453  const G4String& name = GenerateName(orb->GetName(),orb);
454 
455  xercesc::DOMElement* orbElement = NewElement("orb");
456  orbElement->setAttributeNode(NewAttribute("name",name));
457  orbElement->setAttributeNode(NewAttribute("r",orb->GetRadius()/mm));
458  orbElement->setAttributeNode(NewAttribute("lunit","mm"));
459  solElement->appendChild(orbElement);
460 }
461 
463 ParaWrite(xercesc::DOMElement* solElement, const G4Para* const para)
464 {
465  const G4String& name = GenerateName(para->GetName(),para);
466 
467  const G4ThreeVector simaxis = para->GetSymAxis();
468  const G4double alpha = std::atan(para->GetTanAlpha());
469  const G4double phi = simaxis.phi();
470  const G4double theta = simaxis.theta();
471 
472  xercesc::DOMElement* paraElement = NewElement("para");
473  paraElement->setAttributeNode(NewAttribute("name",name));
474  paraElement->setAttributeNode(NewAttribute("x",
475  2.0*para->GetXHalfLength()/mm));
476  paraElement->setAttributeNode(NewAttribute("y",
477  2.0*para->GetYHalfLength()/mm));
478  paraElement->setAttributeNode(NewAttribute("z",
479  2.0*para->GetZHalfLength()/mm));
480  paraElement->setAttributeNode(NewAttribute("alpha",alpha/degree));
481  paraElement->setAttributeNode(NewAttribute("theta",theta/degree));
482  paraElement->setAttributeNode(NewAttribute("phi",phi/degree));
483  paraElement->setAttributeNode(NewAttribute("aunit","deg"));
484  paraElement->setAttributeNode(NewAttribute("lunit","mm"));
485  solElement->appendChild(paraElement);
486 }
487 
489 ParaboloidWrite(xercesc::DOMElement* solElement,
490  const G4Paraboloid* const paraboloid)
491 {
492  const G4String& name = GenerateName(paraboloid->GetName(),paraboloid);
493 
494  xercesc::DOMElement* paraboloidElement = NewElement("paraboloid");
495  paraboloidElement->setAttributeNode(NewAttribute("name",name));
496  paraboloidElement->setAttributeNode(NewAttribute("rlo",
497  paraboloid->GetRadiusMinusZ()/mm));
498  paraboloidElement->setAttributeNode(NewAttribute("rhi",
499  paraboloid->GetRadiusPlusZ()/mm));
500  paraboloidElement->setAttributeNode(NewAttribute("dz",
501  paraboloid->GetZHalfLength()/mm));
502  paraboloidElement->setAttributeNode(NewAttribute("lunit","mm"));
503  solElement->appendChild(paraboloidElement);
504 }
506 PolyconeWrite(xercesc::DOMElement* solElement,
507  const G4Polycone* const polycone)
508 {
509  const G4String& name = GenerateName(polycone->GetName(),polycone);
510 
511  xercesc::DOMElement* polyconeElement = NewElement("polycone");
512  polyconeElement->setAttributeNode(NewAttribute("name",name));
513  polyconeElement->setAttributeNode(NewAttribute("startphi",
515  polyconeElement->setAttributeNode(NewAttribute("deltaphi",
517  polyconeElement->setAttributeNode(NewAttribute("aunit","deg"));
518  polyconeElement->setAttributeNode(NewAttribute("lunit","mm"));
519  solElement->appendChild(polyconeElement);
520 
521  const size_t num_zplanes = polycone->GetOriginalParameters()->Num_z_planes;
522  const G4double* z_array = polycone->GetOriginalParameters()->Z_values;
523  const G4double* rmin_array = polycone->GetOriginalParameters()->Rmin;
524  const G4double* rmax_array = polycone->GetOriginalParameters()->Rmax;
525 
526  for (size_t i=0; i<num_zplanes; i++)
527  {
528  ZplaneWrite(polyconeElement,z_array[i],rmin_array[i],rmax_array[i]);
529  }
530 
531 
532 }
533 
535 GenericPolyconeWrite(xercesc::DOMElement* solElement,
536  const G4GenericPolycone* const polycone)
537 {
538  const G4String& name = GenerateName(polycone->GetName(),polycone);
539  xercesc::DOMElement* polyconeElement = NewElement("genericPolycone");
540  const G4double startPhi=polycone->GetStartPhi();
541  polyconeElement->setAttributeNode(NewAttribute("name",name));
542  polyconeElement->setAttributeNode(NewAttribute("startphi",
543  startPhi/degree));
544  polyconeElement->setAttributeNode(NewAttribute("deltaphi",
545  (polycone->GetEndPhi()-startPhi)/degree));
546  polyconeElement->setAttributeNode(NewAttribute("aunit","deg"));
547  polyconeElement->setAttributeNode(NewAttribute("lunit","mm"));
548  solElement->appendChild(polyconeElement);
549 
550  const size_t num_rzpoints = polycone->GetNumRZCorner();
551  for (size_t i=0; i<num_rzpoints; i++)
552  {
553  const G4double r_point=polycone->GetCorner(i).r;
554  const G4double z_point=polycone->GetCorner(i).z;
555  RZPointWrite(polyconeElement,r_point,z_point);
556  }
557 }
558 
560 PolyhedraWrite(xercesc::DOMElement* solElement,
561  const G4Polyhedra* const polyhedra)
562 {
563  const G4String& name = GenerateName(polyhedra->GetName(),polyhedra);
564  if(polyhedra->IsGeneric() == false)
565  {
566  xercesc::DOMElement* polyhedraElement = NewElement("polyhedra");
567  polyhedraElement->setAttributeNode(NewAttribute("name",name));
568  polyhedraElement->setAttributeNode(NewAttribute("startphi",
569  polyhedra->GetOriginalParameters()->Start_angle/degree));
570  polyhedraElement->setAttributeNode(NewAttribute("deltaphi",
572  polyhedraElement->setAttributeNode(NewAttribute("numsides",
573  polyhedra->GetOriginalParameters()->numSide));
574  polyhedraElement->setAttributeNode(NewAttribute("aunit","deg"));
575  polyhedraElement->setAttributeNode(NewAttribute("lunit","mm"));
576  solElement->appendChild(polyhedraElement);
577 
578  const size_t num_zplanes =
579  polyhedra->GetOriginalParameters()->Num_z_planes;
580  const G4double* z_array =
581  polyhedra->GetOriginalParameters()->Z_values;
582  const G4double* rmin_array = polyhedra->GetOriginalParameters()->Rmin;
583  const G4double* rmax_array = polyhedra->GetOriginalParameters()->Rmax;
584 
585  const G4double convertRad =
586  std::cos(0.5*polyhedra->GetOriginalParameters()->Opening_angle
587  / polyhedra->GetOriginalParameters()->numSide);
588 
589  for (size_t i=0;i<num_zplanes;i++)
590  {
591  ZplaneWrite(polyhedraElement,z_array[i],
592  rmin_array[i]*convertRad, rmax_array[i]*convertRad);
593  }
594  }
595  else // generic polyhedra
596  {
597  xercesc::DOMElement* polyhedraElement = NewElement("genericPolyhedra");
598  polyhedraElement->setAttributeNode(NewAttribute("name",name));
599  polyhedraElement->setAttributeNode(NewAttribute("startphi",
600  polyhedra->GetOriginalParameters()->Start_angle/degree));
601  polyhedraElement->setAttributeNode(NewAttribute("deltaphi",
603  polyhedraElement->setAttributeNode(NewAttribute("numsides",
604  polyhedra->GetOriginalParameters()->numSide));
605  polyhedraElement->setAttributeNode(NewAttribute("aunit","deg"));
606  polyhedraElement->setAttributeNode(NewAttribute("lunit","mm"));
607  solElement->appendChild(polyhedraElement);
608 
609  const size_t num_rzpoints = polyhedra->GetNumRZCorner();
610 
611  for (size_t i=0;i<num_rzpoints;i++)
612  {
613  const G4double r_point = polyhedra->GetCorner(i).r;
614  const G4double z_point = polyhedra->GetCorner(i).z;
615  RZPointWrite(polyhedraElement,r_point,z_point);
616  }
617  }
618 }
619 
621 SphereWrite(xercesc::DOMElement* solElement, const G4Sphere* const sphere)
622 {
623  const G4String& name = GenerateName(sphere->GetName(),sphere);
624 
625  xercesc::DOMElement* sphereElement = NewElement("sphere");
626  sphereElement->setAttributeNode(NewAttribute("name",name));
627  sphereElement->setAttributeNode(NewAttribute("rmin",
628  sphere->GetInnerRadius()/mm));
629  sphereElement->setAttributeNode(NewAttribute("rmax",
630  sphere->GetOuterRadius()/mm));
631  sphereElement->setAttributeNode(NewAttribute("startphi",
632  sphere->GetStartPhiAngle()/degree));
633  sphereElement->setAttributeNode(NewAttribute("deltaphi",
634  sphere->GetDeltaPhiAngle()/degree));
635  sphereElement->setAttributeNode(NewAttribute("starttheta",
636  sphere->GetStartThetaAngle()/degree));
637  sphereElement->setAttributeNode(NewAttribute("deltatheta",
638  sphere->GetDeltaThetaAngle()/degree));
639  sphereElement->setAttributeNode(NewAttribute("aunit","deg"));
640  sphereElement->setAttributeNode(NewAttribute("lunit","mm"));
641  solElement->appendChild(sphereElement);
642 }
643 
645 TessellatedWrite(xercesc::DOMElement* solElement,
646  const G4TessellatedSolid* const tessellated)
647 {
648  const G4String& solid_name = tessellated->GetName();
649  const G4String& name = GenerateName(solid_name, tessellated);
650 
651  xercesc::DOMElement* tessellatedElement = NewElement("tessellated");
652  tessellatedElement->setAttributeNode(NewAttribute("name",name));
653  tessellatedElement->setAttributeNode(NewAttribute("aunit","deg"));
654  tessellatedElement->setAttributeNode(NewAttribute("lunit","mm"));
655  solElement->appendChild(tessellatedElement);
656 
657  std::map<G4ThreeVector, G4String, G4ThreeVectorCompare> vertexMap;
658 
659  const size_t NumFacets = tessellated->GetNumberOfFacets();
660  size_t NumVertex = 0;
661 
662  for (size_t i=0;i<NumFacets;i++)
663  {
664  const G4VFacet* facet = tessellated->GetFacet(i);
665  const size_t NumVertexPerFacet = facet->GetNumberOfVertices();
666 
667  G4String FacetTag;
668 
669  if (NumVertexPerFacet==3) { FacetTag="triangular"; } else
670  if (NumVertexPerFacet==4) { FacetTag="quadrangular"; }
671  else
672  {
673  G4Exception("G4GDMLWriteSolids::TessellatedWrite()", "InvalidSetup",
674  FatalException, "Facet should contain 3 or 4 vertices!");
675  }
676 
677  xercesc::DOMElement* facetElement = NewElement(FacetTag);
678  tessellatedElement->appendChild(facetElement);
679 
680  for (size_t j=0; j<NumVertexPerFacet; j++)
681  {
682  std::stringstream name_stream;
683  std::stringstream ref_stream;
684 
685  name_stream << "vertex" << (j+1);
686  ref_stream << solid_name << "_v" << NumVertex;
687 
688  const G4String& fname = name_stream.str(); // facet's tag variable
689  G4String ref = ref_stream.str(); // vertex tag to be associated
690 
691  // Now search for the existance of the current vertex in the
692  // map of cached vertices. If existing, do NOT store it as
693  // position in the GDML file, so avoiding duplication; otherwise
694  // cache it in the local map and add it as position in the
695  // "define" section of the GDML file.
696 
697  const G4ThreeVector& vertex = facet->GetVertex(j);
698 
699  if(vertexMap.find(vertex) != vertexMap.end()) // Vertex is cached
700  {
701  ref = vertexMap[vertex]; // Set the proper tag for it
702  }
703  else // Vertex not found
704  {
705  vertexMap.insert(std::make_pair(vertex,ref)); // Cache vertex and ...
706  AddPosition(ref, vertex); // ... add it to define section!
707  NumVertex++;
708  }
709 
710  // Now create association of the vertex with its facet
711  //
712  facetElement->setAttributeNode(NewAttribute(fname,ref));
713  }
714  }
715 }
716 
718 TetWrite(xercesc::DOMElement* solElement, const G4Tet* const tet)
719 {
720  const G4String& solid_name = tet->GetName();
721  const G4String& name = GenerateName(solid_name, tet);
722 
723  std::vector<G4ThreeVector> vertexList = tet->GetVertices();
724 
725  xercesc::DOMElement* tetElement = NewElement("tet");
726  tetElement->setAttributeNode(NewAttribute("name",name));
727  tetElement->setAttributeNode(NewAttribute("vertex1",solid_name+"_v1"));
728  tetElement->setAttributeNode(NewAttribute("vertex2",solid_name+"_v2"));
729  tetElement->setAttributeNode(NewAttribute("vertex3",solid_name+"_v3"));
730  tetElement->setAttributeNode(NewAttribute("vertex4",solid_name+"_v4"));
731  tetElement->setAttributeNode(NewAttribute("lunit","mm"));
732  solElement->appendChild(tetElement);
733 
734  AddPosition(solid_name+"_v1",vertexList[0]);
735  AddPosition(solid_name+"_v2",vertexList[1]);
736  AddPosition(solid_name+"_v3",vertexList[2]);
737  AddPosition(solid_name+"_v4",vertexList[3]);
738 }
739 
741 TorusWrite(xercesc::DOMElement* solElement, const G4Torus* const torus)
742 {
743  const G4String& name = GenerateName(torus->GetName(),torus);
744 
745  xercesc::DOMElement* torusElement = NewElement("torus");
746  torusElement->setAttributeNode(NewAttribute("name",name));
747  torusElement->setAttributeNode(NewAttribute("rmin",torus->GetRmin()/mm));
748  torusElement->setAttributeNode(NewAttribute("rmax",torus->GetRmax()/mm));
749  torusElement->setAttributeNode(NewAttribute("rtor",torus->GetRtor()/mm));
750  torusElement->
751  setAttributeNode(NewAttribute("startphi",torus->GetSPhi()/degree));
752  torusElement->
753  setAttributeNode(NewAttribute("deltaphi",torus->GetDPhi()/degree));
754  torusElement->setAttributeNode(NewAttribute("aunit","deg"));
755  torusElement->setAttributeNode(NewAttribute("lunit","mm"));
756  solElement->appendChild(torusElement);
757 }
758 
760 GenTrapWrite(xercesc::DOMElement* solElement,
761  const G4GenericTrap* const gtrap)
762 {
763  const G4String& name = GenerateName(gtrap->GetName(),gtrap);
764 
765  std::vector<G4TwoVector> vertices = gtrap->GetVertices();
766 
767  xercesc::DOMElement* gtrapElement = NewElement("arb8");
768  gtrapElement->setAttributeNode(NewAttribute("name",name));
769  gtrapElement->setAttributeNode(NewAttribute("dz",
770  gtrap->GetZHalfLength()/mm));
771  gtrapElement->setAttributeNode(NewAttribute("v1x", vertices[0].x()));
772  gtrapElement->setAttributeNode(NewAttribute("v1y", vertices[0].y()));
773  gtrapElement->setAttributeNode(NewAttribute("v2x", vertices[1].x()));
774  gtrapElement->setAttributeNode(NewAttribute("v2y", vertices[1].y()));
775  gtrapElement->setAttributeNode(NewAttribute("v3x", vertices[2].x()));
776  gtrapElement->setAttributeNode(NewAttribute("v3y", vertices[2].y()));
777  gtrapElement->setAttributeNode(NewAttribute("v4x", vertices[3].x()));
778  gtrapElement->setAttributeNode(NewAttribute("v4y", vertices[3].y()));
779  gtrapElement->setAttributeNode(NewAttribute("v5x", vertices[4].x()));
780  gtrapElement->setAttributeNode(NewAttribute("v5y", vertices[4].y()));
781  gtrapElement->setAttributeNode(NewAttribute("v6x", vertices[5].x()));
782  gtrapElement->setAttributeNode(NewAttribute("v6y", vertices[5].y()));
783  gtrapElement->setAttributeNode(NewAttribute("v7x", vertices[6].x()));
784  gtrapElement->setAttributeNode(NewAttribute("v7y", vertices[6].y()));
785  gtrapElement->setAttributeNode(NewAttribute("v8x", vertices[7].x()));
786  gtrapElement->setAttributeNode(NewAttribute("v8y", vertices[7].y()));
787  gtrapElement->setAttributeNode(NewAttribute("lunit","mm"));
788  solElement->appendChild(gtrapElement);
789 }
790 
792 TrapWrite(xercesc::DOMElement* solElement, const G4Trap* const trap)
793 {
794  const G4String& name = GenerateName(trap->GetName(),trap);
795 
796  const G4ThreeVector& simaxis = trap->GetSymAxis();
797  const G4double phi = simaxis.phi();
798  const G4double theta = simaxis.theta();
799  const G4double alpha1 = std::atan(trap->GetTanAlpha1());
800  const G4double alpha2 = std::atan(trap->GetTanAlpha2());
801 
802  xercesc::DOMElement* trapElement = NewElement("trap");
803  trapElement->setAttributeNode(NewAttribute("name",name));
804  trapElement->setAttributeNode(NewAttribute("z",
805  2.0*trap->GetZHalfLength()/mm));
806  trapElement->setAttributeNode(NewAttribute("theta",theta/degree));
807  trapElement->setAttributeNode(NewAttribute("phi",phi/degree));
808  trapElement->setAttributeNode(NewAttribute("y1",
809  2.0*trap->GetYHalfLength1()/mm));
810  trapElement->setAttributeNode(NewAttribute("x1",
811  2.0*trap->GetXHalfLength1()/mm));
812  trapElement->setAttributeNode(NewAttribute("x2",
813  2.0*trap->GetXHalfLength2()/mm));
814  trapElement->setAttributeNode(NewAttribute("alpha1",alpha1/degree));
815  trapElement->setAttributeNode(NewAttribute("y2",
816  2.0*trap->GetYHalfLength2()/mm));
817  trapElement->setAttributeNode(NewAttribute("x3",
818  2.0*trap->GetXHalfLength3()/mm));
819  trapElement->setAttributeNode(NewAttribute("x4",
820  2.0*trap->GetXHalfLength4()/mm));
821  trapElement->setAttributeNode(NewAttribute("alpha2",alpha2/degree));
822  trapElement->setAttributeNode(NewAttribute("aunit","deg"));
823  trapElement->setAttributeNode(NewAttribute("lunit","mm"));
824  solElement->appendChild(trapElement);
825 }
826 
828 TrdWrite(xercesc::DOMElement* solElement, const G4Trd* const trd)
829 {
830  const G4String& name = GenerateName(trd->GetName(),trd);
831 
832  xercesc::DOMElement* trdElement = NewElement("trd");
833  trdElement->setAttributeNode(NewAttribute("name",name));
834  trdElement->setAttributeNode(NewAttribute("x1",
835  2.0*trd->GetXHalfLength1()/mm));
836  trdElement->setAttributeNode(NewAttribute("x2",
837  2.0*trd->GetXHalfLength2()/mm));
838  trdElement->setAttributeNode(NewAttribute("y1",
839  2.0*trd->GetYHalfLength1()/mm));
840  trdElement->setAttributeNode(NewAttribute("y2",
841  2.0*trd->GetYHalfLength2()/mm));
842  trdElement->setAttributeNode(NewAttribute("z",
843  2.0*trd->GetZHalfLength()/mm));
844  trdElement->setAttributeNode(NewAttribute("lunit","mm"));
845  solElement->appendChild(trdElement);
846 }
847 
849 TubeWrite(xercesc::DOMElement* solElement, const G4Tubs* const tube)
850 {
851  const G4String& name = GenerateName(tube->GetName(),tube);
852 
853  xercesc::DOMElement* tubeElement = NewElement("tube");
854  tubeElement->setAttributeNode(NewAttribute("name",name));
855  tubeElement->setAttributeNode(NewAttribute("rmin",
856  tube->GetInnerRadius()/mm));
857  tubeElement->setAttributeNode(NewAttribute("rmax",
858  tube->GetOuterRadius()/mm));
859  tubeElement->setAttributeNode(NewAttribute("z",
860  2.0*tube->GetZHalfLength()/mm));
861  tubeElement->setAttributeNode(NewAttribute("startphi",
862  tube->GetStartPhiAngle()/degree));
863  tubeElement->setAttributeNode(NewAttribute("deltaphi",
864  tube->GetDeltaPhiAngle()/degree));
865  tubeElement->setAttributeNode(NewAttribute("aunit","deg"));
866  tubeElement->setAttributeNode(NewAttribute("lunit","mm"));
867  solElement->appendChild(tubeElement);
868 }
869 
871 CutTubeWrite(xercesc::DOMElement* solElement, const G4CutTubs* const cuttube)
872 {
873  const G4String& name = GenerateName(cuttube->GetName(),cuttube);
874 
875  xercesc::DOMElement* cuttubeElement = NewElement("cutTube");
876  cuttubeElement->setAttributeNode(NewAttribute("name",name));
877  cuttubeElement->setAttributeNode(NewAttribute("rmin",
878  cuttube->GetInnerRadius()/mm));
879  cuttubeElement->setAttributeNode(NewAttribute("rmax",
880  cuttube->GetOuterRadius()/mm));
881  cuttubeElement->setAttributeNode(NewAttribute("z",
882  2.0*cuttube->GetZHalfLength()/mm));
883  cuttubeElement->setAttributeNode(NewAttribute("startphi",
884  cuttube->GetStartPhiAngle()/degree));
885  cuttubeElement->setAttributeNode(NewAttribute("deltaphi",
886  cuttube->GetDeltaPhiAngle()/degree));
887  cuttubeElement->setAttributeNode(NewAttribute("lowX",
888  cuttube->GetLowNorm().getX()/mm));
889  cuttubeElement->setAttributeNode(NewAttribute("lowY",
890  cuttube->GetLowNorm().getY()/mm));
891  cuttubeElement->setAttributeNode(NewAttribute("lowZ",
892  cuttube->GetLowNorm().getZ()/mm));
893  cuttubeElement->setAttributeNode(NewAttribute("highX",
894  cuttube->GetHighNorm().getX()/mm));
895  cuttubeElement->setAttributeNode(NewAttribute("highY",
896  cuttube->GetHighNorm().getY()/mm));
897  cuttubeElement->setAttributeNode(NewAttribute("highZ",
898  cuttube->GetHighNorm().getZ()/mm));
899  cuttubeElement->setAttributeNode(NewAttribute("aunit","deg"));
900  cuttubeElement->setAttributeNode(NewAttribute("lunit","mm"));
901  solElement->appendChild(cuttubeElement);
902 }
903 
905 TwistedboxWrite(xercesc::DOMElement* solElement,
906  const G4TwistedBox* const twistedbox)
907 {
908  const G4String& name = GenerateName(twistedbox->GetName(),twistedbox);
909 
910  xercesc::DOMElement* twistedboxElement = NewElement("twistedbox");
911  twistedboxElement->setAttributeNode(NewAttribute("name",name));
912  twistedboxElement->setAttributeNode(NewAttribute("x",
913  2.0*twistedbox->GetXHalfLength()/mm));
914  twistedboxElement->setAttributeNode(NewAttribute("y",
915  2.0*twistedbox->GetYHalfLength()/mm));
916  twistedboxElement->setAttributeNode(NewAttribute("z",
917  2.0*twistedbox->GetZHalfLength()/mm));
918  twistedboxElement->setAttributeNode(NewAttribute("PhiTwist",
919  twistedbox->GetPhiTwist()/degree));
920  twistedboxElement->setAttributeNode(NewAttribute("aunit","deg"));
921  twistedboxElement->setAttributeNode(NewAttribute("lunit","mm"));
922  solElement->appendChild(twistedboxElement);
923 }
924 
926 TwistedtrapWrite(xercesc::DOMElement* solElement,
927  const G4TwistedTrap* const twistedtrap)
928 {
929  const G4String& name = GenerateName(twistedtrap->GetName(),twistedtrap);
930 
931  xercesc::DOMElement* twistedtrapElement = NewElement("twistedtrap");
932  twistedtrapElement->setAttributeNode(NewAttribute("name",name));
933  twistedtrapElement->setAttributeNode(NewAttribute("y1",
934  2.0*twistedtrap->GetY1HalfLength()/mm));
935  twistedtrapElement->setAttributeNode(NewAttribute("x1",
936  2.0*twistedtrap->GetX1HalfLength()/mm));
937  twistedtrapElement->setAttributeNode(NewAttribute("x2",
938  2.0*twistedtrap->GetX2HalfLength()/mm));
939  twistedtrapElement->setAttributeNode(NewAttribute("y2",
940  2.0*twistedtrap->GetY2HalfLength()/mm));
941  twistedtrapElement->setAttributeNode(NewAttribute("x3",
942  2.0*twistedtrap->GetX3HalfLength()/mm));
943  twistedtrapElement->setAttributeNode(NewAttribute("x4",
944  2.0*twistedtrap->GetX4HalfLength()/mm));
945  twistedtrapElement->setAttributeNode(NewAttribute("z",
946  2.0*twistedtrap->GetZHalfLength()/mm));
947  twistedtrapElement->setAttributeNode(NewAttribute("Alph",
948  twistedtrap->GetTiltAngleAlpha()/degree));
949  twistedtrapElement->setAttributeNode(NewAttribute("Theta",
950  twistedtrap->GetPolarAngleTheta()/degree));
951  twistedtrapElement->setAttributeNode(NewAttribute("Phi",
952  twistedtrap->GetAzimuthalAnglePhi()/degree));
953  twistedtrapElement->setAttributeNode(NewAttribute("PhiTwist",
954  twistedtrap->GetPhiTwist()/degree));
955  twistedtrapElement->setAttributeNode(NewAttribute("aunit","deg"));
956  twistedtrapElement->setAttributeNode(NewAttribute("lunit","mm"));
957 
958  solElement->appendChild(twistedtrapElement);
959 }
960 
962 TwistedtrdWrite(xercesc::DOMElement* solElement,
963  const G4TwistedTrd* const twistedtrd)
964 {
965  const G4String& name = GenerateName(twistedtrd->GetName(),twistedtrd);
966 
967  xercesc::DOMElement* twistedtrdElement = NewElement("twistedtrd");
968  twistedtrdElement->setAttributeNode(NewAttribute("name",name));
969  twistedtrdElement->setAttributeNode(NewAttribute("x1",
970  2.0*twistedtrd->GetX1HalfLength()/mm));
971  twistedtrdElement->setAttributeNode(NewAttribute("x2",
972  2.0*twistedtrd->GetX2HalfLength()/mm));
973  twistedtrdElement->setAttributeNode(NewAttribute("y1",
974  2.0*twistedtrd->GetY1HalfLength()/mm));
975  twistedtrdElement->setAttributeNode(NewAttribute("y2",
976  2.0*twistedtrd->GetY2HalfLength()/mm));
977  twistedtrdElement->setAttributeNode(NewAttribute("z",
978  2.0*twistedtrd->GetZHalfLength()/mm));
979  twistedtrdElement->setAttributeNode(NewAttribute("PhiTwist",
980  twistedtrd->GetPhiTwist()/degree));
981  twistedtrdElement->setAttributeNode(NewAttribute("aunit","deg"));
982  twistedtrdElement->setAttributeNode(NewAttribute("lunit","mm"));
983  solElement->appendChild(twistedtrdElement);
984 }
985 
987 TwistedtubsWrite(xercesc::DOMElement* solElement,
988  const G4TwistedTubs* const twistedtubs)
989 {
990  const G4String& name = GenerateName(twistedtubs->GetName(),twistedtubs);
991 
992  xercesc::DOMElement* twistedtubsElement = NewElement("twistedtubs");
993  twistedtubsElement->setAttributeNode(NewAttribute("name",name));
994  twistedtubsElement->setAttributeNode(NewAttribute("twistedangle",
995  twistedtubs->GetPhiTwist()/degree));
996  twistedtubsElement->setAttributeNode(NewAttribute("midinnerrad",
997  twistedtubs->GetInnerRadius()/mm));
998  twistedtubsElement->setAttributeNode(NewAttribute("midouterrad",
999  twistedtubs->GetOuterRadius()/mm));
1000  twistedtubsElement->setAttributeNode(NewAttribute("negativeEndz",
1001  twistedtubs->GetEndZ(0)/mm));
1002  twistedtubsElement->setAttributeNode(NewAttribute("positiveEndz",
1003  twistedtubs->GetEndZ(1)/mm));
1004  twistedtubsElement->setAttributeNode(NewAttribute("phi",
1005  twistedtubs->GetDPhi()/degree));
1006  twistedtubsElement->setAttributeNode(NewAttribute("aunit","deg"));
1007  twistedtubsElement->setAttributeNode(NewAttribute("lunit","mm"));
1008  solElement->appendChild(twistedtubsElement);
1009 }
1010 
1012 ZplaneWrite(xercesc::DOMElement* element, const G4double& z,
1013  const G4double& rmin, const G4double& rmax)
1014 {
1015  xercesc::DOMElement* zplaneElement = NewElement("zplane");
1016  zplaneElement->setAttributeNode(NewAttribute("z",z/mm));
1017  zplaneElement->setAttributeNode(NewAttribute("rmin",rmin/mm));
1018  zplaneElement->setAttributeNode(NewAttribute("rmax",rmax/mm));
1019  element->appendChild(zplaneElement);
1020 }
1021 
1023 RZPointWrite(xercesc::DOMElement* element, const G4double& r,
1024  const G4double& z)
1025 {
1026  xercesc::DOMElement* rzpointElement = NewElement("rzpoint");
1027  rzpointElement->setAttributeNode(NewAttribute("r",r/mm));
1028  rzpointElement->setAttributeNode(NewAttribute("z",z/mm));
1029  element->appendChild(rzpointElement);
1030 }
1031 
1033 OpticalSurfaceWrite(xercesc::DOMElement* solElement,
1034  const G4OpticalSurface* const surf)
1035 {
1036  xercesc::DOMElement* optElement = NewElement("opticalsurface");
1037  G4OpticalSurfaceModel smodel = surf->GetModel();
1038  G4double sval = (smodel==glisur) ? surf->GetPolish() : surf->GetSigmaAlpha();
1039  const G4String& name = GenerateName(surf->GetName(), surf);
1040 
1041  optElement->setAttributeNode(NewAttribute("name", name));
1042  optElement->setAttributeNode(NewAttribute("model", smodel));
1043  optElement->setAttributeNode(NewAttribute("finish", surf->GetFinish()));
1044  optElement->setAttributeNode(NewAttribute("type", surf->GetType()));
1045  optElement->setAttributeNode(NewAttribute("value", sval));
1046 
1047  // Write any property attached to the optical surface...
1048  //
1049  if (surf->GetMaterialPropertiesTable())
1050  {
1051  PropertyWrite(optElement, surf);
1052  }
1053 
1054  solElement->appendChild(optElement);
1055 }
1056 
1057 void G4GDMLWriteSolids::PropertyWrite(xercesc::DOMElement* optElement,
1058  const G4OpticalSurface* const surf)
1059 {
1060  xercesc::DOMElement* propElement;
1062  const std::map< G4int, G4PhysicsOrderedFreeVector*,
1063  std::less<G4int> >* pmap = ptable->GetPropertyMap();
1064  const std::map< G4int, G4double,
1065  std::less<G4int> >* cmap = ptable->GetConstPropertyMap();
1066  std::map< G4int, G4PhysicsOrderedFreeVector*,
1067  std::less<G4int> >::const_iterator mpos;
1068  std::map< G4int, G4double,
1069  std::less<G4int> >::const_iterator cpos;
1070  for (mpos=pmap->begin(); mpos!=pmap->end(); mpos++)
1071  {
1072  propElement = NewElement("property");
1073  propElement->setAttributeNode(NewAttribute("name",
1074  ptable->GetMaterialPropertyNames()[mpos->first]));
1075  propElement->setAttributeNode(NewAttribute("ref",
1076  GenerateName(ptable->GetMaterialPropertyNames()[mpos->first],
1077  mpos->second)));
1078  if (mpos->second)
1079  {
1080  PropertyVectorWrite(ptable->GetMaterialPropertyNames()[mpos->first],
1081  mpos->second);
1082  optElement->appendChild(propElement);
1083  }
1084  else
1085  {
1086  G4String warn_message = "Null pointer for material property -"
1087  + ptable->GetMaterialPropertyNames()[mpos->first]
1088  + "- of optical surface -" + surf->GetName() + "- !";
1089  G4Exception("G4GDMLWriteSolids::PropertyWrite()", "NullPointer",
1090  JustWarning, warn_message);
1091  continue;
1092  }
1093  }
1094  for (cpos=cmap->begin(); cpos!=cmap->end(); cpos++)
1095  {
1096  propElement = NewElement("property");
1097  propElement->setAttributeNode(NewAttribute("name",
1098  ptable->GetMaterialConstPropertyNames()[cpos->first]));
1099  propElement->setAttributeNode(NewAttribute("ref",
1100  ptable->GetMaterialConstPropertyNames()[cpos->first]));
1101  xercesc::DOMElement* constElement = NewElement("constant");
1102  constElement->setAttributeNode(NewAttribute("name",
1103  ptable->GetMaterialConstPropertyNames()[cpos->first]));
1104  constElement->setAttributeNode(NewAttribute("value", cpos->second));
1105  defineElement->appendChild(constElement);
1106  optElement->appendChild(propElement);
1107  }
1108 }
1109 
1110 void G4GDMLWriteSolids::SolidsWrite(xercesc::DOMElement* gdmlElement)
1111 {
1112 #ifdef G4VERBOSE
1113  G4cout << "G4GDML: Writing solids..." << G4endl;
1114 #endif
1115  solidsElement = NewElement("solids");
1116  gdmlElement->appendChild(solidsElement);
1117 
1118  solidList.clear();
1119 }
1120 
1121 void G4GDMLWriteSolids::AddSolid(const G4VSolid* const solidPtr)
1122 {
1123  for (size_t i=0; i<solidList.size(); i++) // Check if solid is
1124  { // already in the list!
1125  if (solidList[i] == solidPtr) { return; }
1126  }
1127 
1128  solidList.push_back(solidPtr);
1129 
1130  if (const G4BooleanSolid* const booleanPtr
1131  = dynamic_cast<const G4BooleanSolid*>(solidPtr))
1132  { BooleanWrite(solidsElement,booleanPtr); } else
1133  if (const G4ScaledSolid* const scaledPtr
1134  = dynamic_cast<const G4ScaledSolid*>(solidPtr))
1135  { ScaledWrite(solidsElement,scaledPtr); } else
1136  if (solidPtr->GetEntityType()=="G4MultiUnion")
1137  { const G4MultiUnion* const munionPtr
1138  = static_cast<const G4MultiUnion*>(solidPtr);
1139  MultiUnionWrite(solidsElement,munionPtr); } else
1140  if (solidPtr->GetEntityType()=="G4Box")
1141  { const G4Box* const boxPtr
1142  = static_cast<const G4Box*>(solidPtr);
1143  BoxWrite(solidsElement,boxPtr); } else
1144  if (solidPtr->GetEntityType()=="G4Cons")
1145  { const G4Cons* const conePtr
1146  = static_cast<const G4Cons*>(solidPtr);
1147  ConeWrite(solidsElement,conePtr); } else
1148  if (solidPtr->GetEntityType()=="G4EllipticalCone")
1149  { const G4EllipticalCone* const elconePtr
1150  = static_cast<const G4EllipticalCone*>(solidPtr);
1151  ElconeWrite(solidsElement,elconePtr); } else
1152  if (solidPtr->GetEntityType()=="G4Ellipsoid")
1153  { const G4Ellipsoid* const ellipsoidPtr
1154  = static_cast<const G4Ellipsoid*>(solidPtr);
1155  EllipsoidWrite(solidsElement,ellipsoidPtr); } else
1156  if (solidPtr->GetEntityType()=="G4EllipticalTube")
1157  { const G4EllipticalTube* const eltubePtr
1158  = static_cast<const G4EllipticalTube*>(solidPtr);
1159  EltubeWrite(solidsElement,eltubePtr); } else
1160  if (solidPtr->GetEntityType()=="G4ExtrudedSolid")
1161  { const G4ExtrudedSolid* const xtruPtr
1162  = static_cast<const G4ExtrudedSolid*>(solidPtr);
1163  XtruWrite(solidsElement,xtruPtr); } else
1164  if (solidPtr->GetEntityType()=="G4Hype")
1165  { const G4Hype* const hypePtr
1166  = static_cast<const G4Hype*>(solidPtr);
1167  HypeWrite(solidsElement,hypePtr); } else
1168  if (solidPtr->GetEntityType()=="G4Orb")
1169  { const G4Orb* const orbPtr
1170  = static_cast<const G4Orb*>(solidPtr);
1171  OrbWrite(solidsElement,orbPtr); } else
1172  if (solidPtr->GetEntityType()=="G4Para")
1173  { const G4Para* const paraPtr
1174  = static_cast<const G4Para*>(solidPtr);
1175  ParaWrite(solidsElement,paraPtr); } else
1176  if (solidPtr->GetEntityType()=="G4Paraboloid")
1177  { const G4Paraboloid* const paraboloidPtr
1178  = static_cast<const G4Paraboloid*>(solidPtr);
1179  ParaboloidWrite(solidsElement,paraboloidPtr); } else
1180  if (solidPtr->GetEntityType()=="G4Polycone")
1181  { const G4Polycone* const polyconePtr
1182  = static_cast<const G4Polycone*>(solidPtr);
1183  PolyconeWrite(solidsElement,polyconePtr); } else
1184  if (solidPtr->GetEntityType()=="G4GenericPolycone")
1185  { const G4GenericPolycone* const genpolyconePtr
1186  = static_cast<const G4GenericPolycone*>(solidPtr);
1187  GenericPolyconeWrite(solidsElement,genpolyconePtr); } else
1188  if (solidPtr->GetEntityType()=="G4Polyhedra")
1189  { const G4Polyhedra* const polyhedraPtr
1190  = static_cast<const G4Polyhedra*>(solidPtr);
1191  PolyhedraWrite(solidsElement,polyhedraPtr); } else
1192  if (solidPtr->GetEntityType()=="G4Sphere")
1193  { const G4Sphere* const spherePtr
1194  = static_cast<const G4Sphere*>(solidPtr);
1195  SphereWrite(solidsElement,spherePtr); } else
1196  if (solidPtr->GetEntityType()=="G4TessellatedSolid")
1197  { const G4TessellatedSolid* const tessellatedPtr
1198  = static_cast<const G4TessellatedSolid*>(solidPtr);
1199  TessellatedWrite(solidsElement,tessellatedPtr); } else
1200  if (solidPtr->GetEntityType()=="G4Tet")
1201  { const G4Tet* const tetPtr
1202  = static_cast<const G4Tet*>(solidPtr);
1203  TetWrite(solidsElement,tetPtr); } else
1204  if (solidPtr->GetEntityType()=="G4Torus")
1205  { const G4Torus* const torusPtr
1206  = static_cast<const G4Torus*>(solidPtr);
1207  TorusWrite(solidsElement,torusPtr); } else
1208  if (solidPtr->GetEntityType()=="G4GenericTrap")
1209  { const G4GenericTrap* const gtrapPtr
1210  = static_cast<const G4GenericTrap*>(solidPtr);
1211  GenTrapWrite(solidsElement,gtrapPtr); } else
1212  if (solidPtr->GetEntityType()=="G4Trap")
1213  { const G4Trap* const trapPtr
1214  = static_cast<const G4Trap*>(solidPtr);
1215  TrapWrite(solidsElement,trapPtr); } else
1216  if (solidPtr->GetEntityType()=="G4Trd")
1217  { const G4Trd* const trdPtr
1218  = static_cast<const G4Trd*>(solidPtr);
1219  TrdWrite(solidsElement,trdPtr); } else
1220  if (solidPtr->GetEntityType()=="G4Tubs")
1221  { const G4Tubs* const tubePtr
1222  = static_cast<const G4Tubs*>(solidPtr);
1223  TubeWrite(solidsElement,tubePtr); } else
1224  if (solidPtr->GetEntityType()=="G4CutTubs")
1225  { const G4CutTubs* const cuttubePtr
1226  = static_cast<const G4CutTubs*>(solidPtr);
1227  CutTubeWrite(solidsElement,cuttubePtr); } else
1228  if (solidPtr->GetEntityType()=="G4TwistedBox")
1229  { const G4TwistedBox* const twistedboxPtr
1230  = static_cast<const G4TwistedBox*>(solidPtr);
1231  TwistedboxWrite(solidsElement,twistedboxPtr); } else
1232  if (solidPtr->GetEntityType()=="G4TwistedTrap")
1233  { const G4TwistedTrap* const twistedtrapPtr
1234  = static_cast<const G4TwistedTrap*>(solidPtr);
1235  TwistedtrapWrite(solidsElement,twistedtrapPtr); } else
1236  if (solidPtr->GetEntityType()=="G4TwistedTrd")
1237  { const G4TwistedTrd* const twistedtrdPtr
1238  = static_cast<const G4TwistedTrd*>(solidPtr);
1239  TwistedtrdWrite(solidsElement,twistedtrdPtr); } else
1240  if (solidPtr->GetEntityType()=="G4TwistedTubs")
1241  { const G4TwistedTubs* const twistedtubsPtr
1242  = static_cast<const G4TwistedTubs*>(solidPtr);
1243  TwistedtubsWrite(solidsElement,twistedtubsPtr); }
1244  else
1245  {
1246  G4String error_msg = "Unknown solid: " + solidPtr->GetName()
1247  + "; Type: " + solidPtr->GetEntityType();
1248  G4Exception("G4GDMLWriteSolids::AddSolid()", "WriteError",
1249  FatalException, error_msg);
1250  }
1251 }