source: trunk/source/persistency/gdml/src/G4GDMLWriteSolids.cc @ 1315

Last change on this file since 1315 was 1315, checked in by garnier, 14 years ago

update geant4-09-04-beta-cand-01 interfaces-V09-03-09 vis-V09-03-08

File size: 40.1 KB
Line 
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// $Id: G4GDMLWriteSolids.cc,v 1.68 2010/06/03 14:19:49 gcosmo Exp $
28// GEANT4 tag $Name: geant4-09-04-beta-cand-01 $
29//
30// class G4GDMLWriteSolids Implementation
31//
32// Original author: Zoltan Torzsok, November 2007
33//
34// --------------------------------------------------------------------
35
36#include "G4GDMLWriteSolids.hh"
37
38#include "G4BooleanSolid.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 "G4Polyhedra.hh"
52#include "G4ReflectedSolid.hh"
53#include "G4Sphere.hh"
54#include "G4SubtractionSolid.hh"
55#include "G4GenericTrap.hh"
56#include "G4TessellatedSolid.hh"
57#include "G4Tet.hh"
58#include "G4Torus.hh"
59#include "G4Trap.hh"
60#include "G4Trd.hh"
61#include "G4Tubs.hh"
62#include "G4TwistedBox.hh"
63#include "G4TwistedTrap.hh"
64#include "G4TwistedTrd.hh"
65#include "G4TwistedTubs.hh"
66#include "G4UnionSolid.hh"
67#include "G4OpticalSurface.hh"
68#include "G4SurfaceProperty.hh"
69
70G4GDMLWriteSolids::
71G4GDMLWriteSolids() : G4GDMLWriteMaterials()
72{
73}
74
75G4GDMLWriteSolids::
76~G4GDMLWriteSolids()
77{
78}
79
80void G4GDMLWriteSolids::
81BooleanWrite(xercesc::DOMElement* solidsElement,
82             const G4BooleanSolid* const boolean)
83{
84   G4int displaced=0;
85
86   G4String tag("undefined");
87   if (dynamic_cast<const G4IntersectionSolid*>(boolean))
88     { tag = "intersection"; } else
89   if (dynamic_cast<const G4SubtractionSolid*>(boolean))
90     { tag = "subtraction"; } else
91   if (dynamic_cast<const G4UnionSolid*>(boolean))
92     { tag = "union"; }
93   
94   G4VSolid* firstPtr = const_cast<G4VSolid*>(boolean->GetConstituentSolid(0));
95   G4VSolid* secondPtr = const_cast<G4VSolid*>(boolean->GetConstituentSolid(1));
96   
97   G4ThreeVector firstpos,firstrot,pos,rot;
98
99   // Solve possible displacement of referenced solids!
100   //
101   while (true)
102   {
103      if ( displaced>8 )
104      {
105        G4String ErrorMessage = "The referenced solid '"
106                              + firstPtr->GetName() +
107                              + "in the Boolean shape '" +
108                              + boolean->GetName() +
109                              + "' was displaced too many times!";
110        G4Exception("G4GDMLWriteSolids::BooleanWrite()",
111                    "InvalidSetup", FatalException, ErrorMessage);
112      }
113
114      if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(firstPtr))
115      {
116         firstpos += disp->GetObjectTranslation();
117         firstrot += firstrot + GetAngles(disp->GetObjectRotation());
118         firstPtr = disp->GetConstituentMovedSolid();
119         displaced++;
120         continue;
121      }
122      break;
123   }
124   displaced = 0;
125   while (true)
126   {
127      if ( displaced>maxTransforms )
128      {
129        G4String ErrorMessage = "The referenced solid '"
130                              + secondPtr->GetName() +
131                              + "in the Boolean shape '" +
132                              + boolean->GetName() +
133                              + "' was displaced too many times!";
134        G4Exception("G4GDMLWriteSolids::BooleanWrite()",
135                    "InvalidSetup", FatalException, ErrorMessage);
136      }
137
138      if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(secondPtr))
139      {
140         pos += disp->GetObjectTranslation();
141         rot += GetAngles(disp->GetObjectRotation());
142         secondPtr = disp->GetConstituentMovedSolid();
143         displaced++;
144         continue;
145      }
146      break;
147   }
148
149   AddSolid(firstPtr);   // At first add the constituent solids!
150   AddSolid(secondPtr);
151
152   const G4String& name = GenerateName(boolean->GetName(),boolean);
153   const G4String& firstref = GenerateName(firstPtr->GetName(),firstPtr);
154   const G4String& secondref = GenerateName(secondPtr->GetName(),secondPtr);
155
156   xercesc::DOMElement* booleanElement = NewElement(tag);
157   booleanElement->setAttributeNode(NewAttribute("name",name));
158   xercesc::DOMElement* firstElement = NewElement("first");
159   firstElement->setAttributeNode(NewAttribute("ref",firstref));
160   booleanElement->appendChild(firstElement);
161   xercesc::DOMElement* secondElement = NewElement("second");
162   secondElement->setAttributeNode(NewAttribute("ref",secondref));
163   booleanElement->appendChild(secondElement);
164   solidsElement->appendChild(booleanElement);
165     // Add the boolean solid AFTER the constituent solids!
166
167   if ( (std::fabs(pos.x()) > kLinearPrecision)
168     || (std::fabs(pos.y()) > kLinearPrecision)
169     || (std::fabs(pos.z()) > kLinearPrecision) )
170   {
171     PositionWrite(booleanElement,name+"_pos",pos);
172   }
173
174   if ( (std::fabs(rot.x()) > kAngularPrecision)
175     || (std::fabs(rot.y()) > kAngularPrecision)
176     || (std::fabs(rot.z()) > kAngularPrecision) )
177   {
178     RotationWrite(booleanElement,name+"_rot",rot);
179   }
180
181   if ( (std::fabs(firstpos.x()) > kLinearPrecision)
182     || (std::fabs(firstpos.y()) > kLinearPrecision)
183     || (std::fabs(firstpos.z()) > kLinearPrecision) )
184   {
185     FirstpositionWrite(booleanElement,name+"_fpos",firstpos);
186   }
187
188   if ( (std::fabs(firstrot.x()) > kAngularPrecision)
189     || (std::fabs(firstrot.y()) > kAngularPrecision)
190     || (std::fabs(firstrot.z()) > kAngularPrecision) )
191   {
192     FirstrotationWrite(booleanElement,name+"_frot",firstrot);
193   }
194}
195
196void G4GDMLWriteSolids::
197BoxWrite(xercesc::DOMElement* solidsElement, const G4Box* const box)
198{
199   const G4String& name = GenerateName(box->GetName(),box);
200
201   xercesc::DOMElement* boxElement = NewElement("box");
202   boxElement->setAttributeNode(NewAttribute("name",name));
203   boxElement->setAttributeNode(NewAttribute("x",2.0*box->GetXHalfLength()/mm));
204   boxElement->setAttributeNode(NewAttribute("y",2.0*box->GetYHalfLength()/mm));
205   boxElement->setAttributeNode(NewAttribute("z",2.0*box->GetZHalfLength()/mm));
206   boxElement->setAttributeNode(NewAttribute("lunit","mm"));
207   solidsElement->appendChild(boxElement);
208}
209
210void G4GDMLWriteSolids::
211ConeWrite(xercesc::DOMElement* solidsElement, const G4Cons* const cone)
212{
213   const G4String& name = GenerateName(cone->GetName(),cone);
214
215   xercesc::DOMElement* coneElement = NewElement("cone");
216   coneElement->setAttributeNode(NewAttribute("name",name));
217   coneElement->
218     setAttributeNode(NewAttribute("rmin1",cone->GetInnerRadiusMinusZ()/mm));
219   coneElement->
220     setAttributeNode(NewAttribute("rmax1",cone->GetOuterRadiusMinusZ()/mm));
221   coneElement->
222     setAttributeNode(NewAttribute("rmin2",cone->GetInnerRadiusPlusZ()/mm));
223   coneElement->
224     setAttributeNode(NewAttribute("rmax2",cone->GetOuterRadiusPlusZ()/mm));
225   coneElement->
226     setAttributeNode(NewAttribute("z",2.0*cone->GetZHalfLength()/mm));
227   coneElement->
228     setAttributeNode(NewAttribute("startphi",cone->GetStartPhiAngle()/degree));
229   coneElement->
230     setAttributeNode(NewAttribute("deltaphi",cone->GetDeltaPhiAngle()/degree));
231   coneElement->setAttributeNode(NewAttribute("aunit","deg"));
232   coneElement->setAttributeNode(NewAttribute("lunit","mm"));
233   solidsElement->appendChild(coneElement);
234}
235
236void G4GDMLWriteSolids::
237ElconeWrite(xercesc::DOMElement* solidsElement,
238            const G4EllipticalCone* const elcone)
239{
240   const G4String& name = GenerateName(elcone->GetName(),elcone);
241
242   xercesc::DOMElement* elconeElement = NewElement("elcone");
243   elconeElement->setAttributeNode(NewAttribute("name",name));
244   elconeElement->setAttributeNode(NewAttribute("dx",elcone->GetSemiAxisX()/mm));
245   elconeElement->setAttributeNode(NewAttribute("dy",elcone->GetSemiAxisY()/mm));
246   elconeElement->setAttributeNode(NewAttribute("zmax",elcone->GetZMax()/mm));
247   elconeElement->setAttributeNode(NewAttribute("zcut",elcone->GetZTopCut()/mm));
248   elconeElement->setAttributeNode(NewAttribute("lunit","mm"));
249   solidsElement->appendChild(elconeElement);
250}
251
252void G4GDMLWriteSolids::
253EllipsoidWrite(xercesc::DOMElement* solidsElement,
254               const G4Ellipsoid* const ellipsoid)
255{
256   const G4String& name = GenerateName(ellipsoid->GetName(),ellipsoid);
257
258   xercesc::DOMElement* ellipsoidElement = NewElement("ellipsoid");
259   ellipsoidElement->setAttributeNode(NewAttribute("name",name));
260   ellipsoidElement->
261     setAttributeNode(NewAttribute("ax",ellipsoid->GetSemiAxisMax(0)/mm));
262   ellipsoidElement->
263     setAttributeNode(NewAttribute("by",ellipsoid->GetSemiAxisMax(1)/mm));
264   ellipsoidElement->
265     setAttributeNode(NewAttribute("cz",ellipsoid->GetSemiAxisMax(2)/mm));
266   ellipsoidElement->
267     setAttributeNode(NewAttribute("zcut1",ellipsoid->GetZBottomCut()/mm));
268   ellipsoidElement->
269     setAttributeNode(NewAttribute("zcut2",ellipsoid->GetZTopCut()/mm));
270   ellipsoidElement->
271     setAttributeNode(NewAttribute("lunit","mm"));
272   solidsElement->appendChild(ellipsoidElement);
273}
274
275void G4GDMLWriteSolids::
276EltubeWrite(xercesc::DOMElement* solidsElement,
277            const G4EllipticalTube* const eltube)
278{
279   const G4String& name = GenerateName(eltube->GetName(),eltube);
280
281   xercesc::DOMElement* eltubeElement = NewElement("eltube");
282   eltubeElement->setAttributeNode(NewAttribute("name",name));
283   eltubeElement->setAttributeNode(NewAttribute("dx",eltube->GetDx()/mm));
284   eltubeElement->setAttributeNode(NewAttribute("dy",eltube->GetDy()/mm));
285   eltubeElement->setAttributeNode(NewAttribute("dz",eltube->GetDz()/mm));
286   eltubeElement->setAttributeNode(NewAttribute("lunit","mm"));
287   solidsElement->appendChild(eltubeElement);
288}
289
290void G4GDMLWriteSolids::
291XtruWrite(xercesc::DOMElement* solidsElement,
292          const G4ExtrudedSolid* const xtru)
293{
294   const G4String& name = GenerateName(xtru->GetName(),xtru);
295
296   xercesc::DOMElement* xtruElement = NewElement("xtru");
297   xtruElement->setAttributeNode(NewAttribute("name",name));
298   xtruElement->setAttributeNode(NewAttribute("lunit","mm"));
299   solidsElement->appendChild(xtruElement);
300
301   const G4int NumVertex = xtru->GetNofVertices();
302   
303   for (G4int i=0;i<NumVertex;i++)
304   {
305      xercesc::DOMElement* twoDimVertexElement = NewElement("twoDimVertex");
306      xtruElement->appendChild(twoDimVertexElement);
307
308      const G4TwoVector& vertex = xtru->GetVertex(i);
309
310      twoDimVertexElement->setAttributeNode(NewAttribute("x",vertex.x()/mm));
311      twoDimVertexElement->setAttributeNode(NewAttribute("y",vertex.y()/mm));
312   }
313
314   const G4int NumSection = xtru->GetNofZSections();
315
316   for (G4int i=0;i<NumSection;i++)
317   {
318      xercesc::DOMElement* sectionElement = NewElement("section");
319      xtruElement->appendChild(sectionElement);
320
321      const G4ExtrudedSolid::ZSection section = xtru->GetZSection(i);
322
323      sectionElement->setAttributeNode(NewAttribute("zOrder",i));
324      sectionElement->setAttributeNode(NewAttribute("zPosition",section.fZ/mm));
325      sectionElement->
326        setAttributeNode(NewAttribute("xOffset",section.fOffset.x()/mm));
327      sectionElement->
328        setAttributeNode(NewAttribute("yOffset",section.fOffset.y()/mm));
329      sectionElement->
330        setAttributeNode(NewAttribute("scalingFactor",section.fScale));
331   }
332}
333
334void G4GDMLWriteSolids::
335HypeWrite(xercesc::DOMElement* solidsElement, const G4Hype* const hype)
336{
337   const G4String& name = GenerateName(hype->GetName(),hype);
338
339   xercesc::DOMElement* hypeElement = NewElement("hype");
340   hypeElement->setAttributeNode(NewAttribute("name",name));
341   hypeElement->setAttributeNode(NewAttribute("rmin",
342                hype->GetInnerRadius()/mm));
343   hypeElement->setAttributeNode(NewAttribute("rmax",
344                hype->GetOuterRadius()/mm));
345   hypeElement->setAttributeNode(NewAttribute("inst",
346                hype->GetInnerStereo()/degree));
347   hypeElement->setAttributeNode(NewAttribute("outst",
348                hype->GetOuterStereo()/degree));
349   hypeElement->setAttributeNode(NewAttribute("z",
350                2.0*hype->GetZHalfLength()/mm));
351   hypeElement->setAttributeNode(NewAttribute("aunit","deg"));
352   hypeElement->setAttributeNode(NewAttribute("lunit","mm"));
353   solidsElement->appendChild(hypeElement);
354}
355
356void G4GDMLWriteSolids::
357OrbWrite(xercesc::DOMElement* solidsElement, const G4Orb* const orb)
358{
359   const G4String& name = GenerateName(orb->GetName(),orb);
360
361   xercesc::DOMElement* orbElement = NewElement("orb");
362   orbElement->setAttributeNode(NewAttribute("name",name));
363   orbElement->setAttributeNode(NewAttribute("r",orb->GetRadius()/mm));
364   orbElement->setAttributeNode(NewAttribute("lunit","mm"));
365   solidsElement->appendChild(orbElement);
366}
367
368void G4GDMLWriteSolids::
369ParaWrite(xercesc::DOMElement* solidsElement, const G4Para* const para)
370{
371   const G4String& name = GenerateName(para->GetName(),para);
372
373   const G4ThreeVector simaxis = para->GetSymAxis();
374   const G4double alpha = std::atan(para->GetTanAlpha());
375   const G4double theta = std::acos(simaxis.z());
376   const G4double phi = (simaxis.z() != 1.0)
377                      ? (std::atan(simaxis.y()/simaxis.x())) : (0.0);
378
379   xercesc::DOMElement* paraElement = NewElement("para");
380   paraElement->setAttributeNode(NewAttribute("name",name));
381   paraElement->setAttributeNode(NewAttribute("x",
382                2.0*para->GetXHalfLength()/mm));
383   paraElement->setAttributeNode(NewAttribute("y",
384                2.0*para->GetYHalfLength()/mm));
385   paraElement->setAttributeNode(NewAttribute("z",
386                2.0*para->GetZHalfLength()/mm));
387   paraElement->setAttributeNode(NewAttribute("alpha",alpha/degree));
388   paraElement->setAttributeNode(NewAttribute("theta",theta/degree));
389   paraElement->setAttributeNode(NewAttribute("phi",phi/degree));
390   paraElement->setAttributeNode(NewAttribute("aunit","deg"));
391   paraElement->setAttributeNode(NewAttribute("lunit","mm"));
392   solidsElement->appendChild(paraElement);
393}
394
395void G4GDMLWriteSolids::
396ParaboloidWrite(xercesc::DOMElement* solidsElement,
397                const G4Paraboloid* const paraboloid)
398{
399   const G4String& name = GenerateName(paraboloid->GetName(),paraboloid);
400
401   xercesc::DOMElement* paraboloidElement = NewElement("paraboloid");
402   paraboloidElement->setAttributeNode(NewAttribute("name",name));
403   paraboloidElement->setAttributeNode(NewAttribute("rlo",
404                      paraboloid->GetRadiusMinusZ()/mm));
405   paraboloidElement->setAttributeNode(NewAttribute("rhi",
406                      paraboloid->GetRadiusPlusZ()/mm));
407   paraboloidElement->setAttributeNode(NewAttribute("dz",
408                      paraboloid->GetZHalfLength()/mm));
409   paraboloidElement->setAttributeNode(NewAttribute("lunit","mm"));
410   solidsElement->appendChild(paraboloidElement);
411}
412
413void G4GDMLWriteSolids::
414PolyconeWrite(xercesc::DOMElement* solidsElement,
415              const G4Polycone* const polycone)
416{
417   const G4String& name = GenerateName(polycone->GetName(),polycone);
418
419   xercesc::DOMElement* polyconeElement = NewElement("polycone");
420   polyconeElement->setAttributeNode(NewAttribute("name",name));
421   polyconeElement->setAttributeNode(NewAttribute("startphi",
422                    polycone->GetOriginalParameters()->Start_angle/degree));
423   polyconeElement->setAttributeNode(NewAttribute("deltaphi",
424                    polycone->GetOriginalParameters()->Opening_angle/degree));
425   polyconeElement->setAttributeNode(NewAttribute("aunit","deg"));
426   polyconeElement->setAttributeNode(NewAttribute("lunit","mm"));
427   solidsElement->appendChild(polyconeElement);
428
429   const size_t num_zplanes = polycone->GetOriginalParameters()->Num_z_planes;
430   const G4double* z_array = polycone->GetOriginalParameters()->Z_values;
431   const G4double* rmin_array = polycone->GetOriginalParameters()->Rmin;
432   const G4double* rmax_array = polycone->GetOriginalParameters()->Rmax;
433
434   for (size_t i=0; i<num_zplanes; i++)
435   {
436      ZplaneWrite(polyconeElement,z_array[i],rmin_array[i],rmax_array[i]);
437   }
438}
439
440void G4GDMLWriteSolids::
441PolyhedraWrite(xercesc::DOMElement* solidsElement,
442               const G4Polyhedra* const polyhedra)
443{
444   const G4String& name = GenerateName(polyhedra->GetName(),polyhedra);
445
446   xercesc::DOMElement* polyhedraElement = NewElement("polyhedra");
447   polyhedraElement->setAttributeNode(NewAttribute("name",name));
448   polyhedraElement->setAttributeNode(NewAttribute("startphi",
449                     polyhedra->GetOriginalParameters()->Start_angle/degree));
450   polyhedraElement->setAttributeNode(NewAttribute("deltaphi",
451                     polyhedra->GetOriginalParameters()->Opening_angle/degree));
452   polyhedraElement->setAttributeNode(NewAttribute("numsides",
453                     polyhedra->GetOriginalParameters()->numSide));
454   polyhedraElement->setAttributeNode(NewAttribute("aunit","deg"));
455   polyhedraElement->setAttributeNode(NewAttribute("lunit","mm"));
456   solidsElement->appendChild(polyhedraElement);
457
458   const size_t num_zplanes = polyhedra->GetOriginalParameters()->Num_z_planes;
459   const G4double* z_array = polyhedra->GetOriginalParameters()->Z_values;
460   const G4double* rmin_array = polyhedra->GetOriginalParameters()->Rmin;
461   const G4double* rmax_array = polyhedra->GetOriginalParameters()->Rmax;
462
463   const G4double convertRad =
464         std::cos(0.5*polyhedra->GetOriginalParameters()->Opening_angle
465       / polyhedra->GetOriginalParameters()->numSide);
466
467   for (size_t i=0;i<num_zplanes;i++)
468   {
469      ZplaneWrite(polyhedraElement,z_array[i],
470                  rmin_array[i]*convertRad, rmax_array[i]*convertRad);
471   }
472}
473
474void G4GDMLWriteSolids::
475SphereWrite(xercesc::DOMElement* solidsElement, const G4Sphere* const sphere)
476{
477   const G4String& name = GenerateName(sphere->GetName(),sphere);
478
479   xercesc::DOMElement* sphereElement = NewElement("sphere");
480   sphereElement->setAttributeNode(NewAttribute("name",name));
481   sphereElement->setAttributeNode(NewAttribute("rmin",
482                  sphere->GetInsideRadius()/mm));
483   sphereElement->setAttributeNode(NewAttribute("rmax",
484                  sphere->GetOuterRadius()/mm));
485   sphereElement->setAttributeNode(NewAttribute("startphi",
486                  sphere->GetStartPhiAngle()/degree));
487   sphereElement->setAttributeNode(NewAttribute("deltaphi",
488                  sphere->GetDeltaPhiAngle()/degree));
489   sphereElement->setAttributeNode(NewAttribute("starttheta",
490                  sphere->GetStartThetaAngle()/degree));
491   sphereElement->setAttributeNode(NewAttribute("deltatheta",
492                  sphere->GetDeltaThetaAngle()/degree));
493   sphereElement->setAttributeNode(NewAttribute("aunit","deg"));
494   sphereElement->setAttributeNode(NewAttribute("lunit","mm"));
495   solidsElement->appendChild(sphereElement);
496}
497
498void G4GDMLWriteSolids::
499TessellatedWrite(xercesc::DOMElement* solidsElement,
500                 const G4TessellatedSolid* const tessellated)
501{
502   const G4String& solid_name = tessellated->GetName();
503   const G4String& name = GenerateName(solid_name, tessellated);
504
505   xercesc::DOMElement* tessellatedElement = NewElement("tessellated");
506   tessellatedElement->setAttributeNode(NewAttribute("name",name));
507   tessellatedElement->setAttributeNode(NewAttribute("aunit","deg"));
508   tessellatedElement->setAttributeNode(NewAttribute("lunit","mm"));
509   solidsElement->appendChild(tessellatedElement);
510
511   std::map<G4ThreeVector, G4String> vertexMap;
512
513   const size_t NumFacets = tessellated->GetNumberOfFacets();
514   size_t NumVertex = 0;
515   
516   for (size_t i=0;i<NumFacets;i++)
517   {
518      const G4VFacet* facet = tessellated->GetFacet(i);
519      const size_t NumVertexPerFacet = facet->GetNumberOfVertices();
520
521      G4String FacetTag;
522     
523      if (NumVertexPerFacet==3) { FacetTag="triangular"; } else
524      if (NumVertexPerFacet==4) { FacetTag="quadrangular"; }
525      else
526      {
527        G4Exception("G4GDMLWriteSolids::TessellatedWrite()", "InvalidSetup",
528                    FatalException, "Facet should contain 3 or 4 vertices!");
529      }
530
531      xercesc::DOMElement* facetElement = NewElement(FacetTag);
532      tessellatedElement->appendChild(facetElement);
533
534      for (size_t j=0; j<NumVertexPerFacet; j++)
535      {
536         std::stringstream name_stream;
537         std::stringstream ref_stream;
538
539         name_stream << "vertex" << (j+1);
540         ref_stream << solid_name << "_v" << NumVertex;
541
542         const G4String& name = name_stream.str();  // facet's tag variable
543         G4String ref = ref_stream.str();     // vertex tag to be associated
544
545         // Now search for the existance of the current vertex in the
546         // map of cached vertices. If existing, do NOT store it as
547         // position in the GDML file, so avoiding duplication; otherwise
548         // cache it in the local map and add it as position in the
549         // "define" section of the GDML file.
550
551         const G4ThreeVector& vertex = facet->GetVertex(j);
552
553         if(vertexMap.find(vertex) != vertexMap.end())  // Vertex is cached
554         {
555           ref = vertexMap[vertex];     // Set the proper tag for it
556         }
557         else                                           // Vertex not found
558         {
559           vertexMap.insert(std::make_pair(vertex,ref)); // Cache vertex and ...
560           AddPosition(ref, vertex);    // ... add it to define section!
561           NumVertex++;
562         }
563
564         // Now create association of the vertex with its facet
565         //
566         facetElement->setAttributeNode(NewAttribute(name,ref));
567      }
568   }
569}
570
571void G4GDMLWriteSolids::
572TetWrite(xercesc::DOMElement* solidsElement, const G4Tet* const tet)
573{
574   const G4String& solid_name = tet->GetName();
575   const G4String& name = GenerateName(solid_name, tet);
576
577   std::vector<G4ThreeVector> vertexList = tet->GetVertices();
578
579   xercesc::DOMElement* tetElement = NewElement("tet");
580   tetElement->setAttributeNode(NewAttribute("name",name));
581   tetElement->setAttributeNode(NewAttribute("vertex1",solid_name+"_v1"));
582   tetElement->setAttributeNode(NewAttribute("vertex2",solid_name+"_v2"));
583   tetElement->setAttributeNode(NewAttribute("vertex3",solid_name+"_v3"));
584   tetElement->setAttributeNode(NewAttribute("vertex4",solid_name+"_v4"));
585   tetElement->setAttributeNode(NewAttribute("lunit","mm"));
586   solidsElement->appendChild(tetElement);
587
588   AddPosition(solid_name+"_v1",vertexList[0]);
589   AddPosition(solid_name+"_v2",vertexList[1]);
590   AddPosition(solid_name+"_v3",vertexList[2]);
591   AddPosition(solid_name+"_v4",vertexList[3]);
592}
593
594void G4GDMLWriteSolids::
595TorusWrite(xercesc::DOMElement* solidsElement, const G4Torus* const torus)
596{
597   const G4String& name = GenerateName(torus->GetName(),torus);
598
599   xercesc::DOMElement* torusElement = NewElement("torus");
600   torusElement->setAttributeNode(NewAttribute("name",name));
601   torusElement->setAttributeNode(NewAttribute("rmin",torus->GetRmin()/mm));
602   torusElement->setAttributeNode(NewAttribute("rmax",torus->GetRmax()/mm));
603   torusElement->setAttributeNode(NewAttribute("rtor",torus->GetRtor()/mm));
604   torusElement->
605     setAttributeNode(NewAttribute("startphi",torus->GetSPhi()/degree));
606   torusElement->
607     setAttributeNode(NewAttribute("deltaphi",torus->GetDPhi()/degree));
608   torusElement->setAttributeNode(NewAttribute("aunit","deg"));
609   torusElement->setAttributeNode(NewAttribute("lunit","mm"));
610   solidsElement->appendChild(torusElement);
611}
612
613void G4GDMLWriteSolids::
614GenTrapWrite(xercesc::DOMElement* solidsElement,
615             const G4GenericTrap* const gtrap)
616{
617   const G4String& name = GenerateName(gtrap->GetName(),gtrap);
618
619   std::vector<G4TwoVector> vertices = gtrap->GetVertices();
620
621   xercesc::DOMElement* gtrapElement = NewElement("arb8");
622   gtrapElement->setAttributeNode(NewAttribute("name",name));
623   gtrapElement->setAttributeNode(NewAttribute("dz",
624                                           gtrap->GetZHalfLength()/mm));
625   gtrapElement->setAttributeNode(NewAttribute("v1x", vertices[0].x()));
626   gtrapElement->setAttributeNode(NewAttribute("v1y", vertices[0].y()));
627   gtrapElement->setAttributeNode(NewAttribute("v2x", vertices[1].x()));
628   gtrapElement->setAttributeNode(NewAttribute("v2y", vertices[1].y()));
629   gtrapElement->setAttributeNode(NewAttribute("v3x", vertices[2].x()));
630   gtrapElement->setAttributeNode(NewAttribute("v3y", vertices[2].y()));
631   gtrapElement->setAttributeNode(NewAttribute("v4x", vertices[3].x()));
632   gtrapElement->setAttributeNode(NewAttribute("v4y", vertices[3].y()));
633   gtrapElement->setAttributeNode(NewAttribute("v5x", vertices[4].x()));
634   gtrapElement->setAttributeNode(NewAttribute("v5y", vertices[4].y()));
635   gtrapElement->setAttributeNode(NewAttribute("v6x", vertices[5].x()));
636   gtrapElement->setAttributeNode(NewAttribute("v6y", vertices[5].y()));
637   gtrapElement->setAttributeNode(NewAttribute("v7x", vertices[6].x()));
638   gtrapElement->setAttributeNode(NewAttribute("v7y", vertices[6].y()));
639   gtrapElement->setAttributeNode(NewAttribute("v8x", vertices[7].x()));
640   gtrapElement->setAttributeNode(NewAttribute("v8y", vertices[7].y()));
641   gtrapElement->setAttributeNode(NewAttribute("lunit","mm"));
642   solidsElement->appendChild(gtrapElement);
643}
644
645void G4GDMLWriteSolids::
646TrapWrite(xercesc::DOMElement* solidsElement, const G4Trap* const trap)
647{
648   const G4String& name = GenerateName(trap->GetName(),trap);
649
650   const G4ThreeVector& simaxis = trap->GetSymAxis();
651   const G4double phi = (simaxis.z() != 1.0)
652                      ? (std::atan(simaxis.y()/simaxis.x())) : (0.0);
653   const G4double theta = std::acos(simaxis.z());
654   const G4double alpha1 = std::atan(trap->GetTanAlpha1());
655   const G4double alpha2 = std::atan(trap->GetTanAlpha2());
656
657   xercesc::DOMElement* trapElement = NewElement("trap");
658   trapElement->setAttributeNode(NewAttribute("name",name));
659   trapElement->setAttributeNode(NewAttribute("z",
660                2.0*trap->GetZHalfLength()/mm));
661   trapElement->setAttributeNode(NewAttribute("theta",theta/degree));
662   trapElement->setAttributeNode(NewAttribute("phi",phi/degree));
663   trapElement->setAttributeNode(NewAttribute("y1",
664                2.0*trap->GetYHalfLength1()/mm));
665   trapElement->setAttributeNode(NewAttribute("x1",
666                2.0*trap->GetXHalfLength1()/mm));
667   trapElement->setAttributeNode(NewAttribute("x2",
668                2.0*trap->GetXHalfLength2()/mm));
669   trapElement->setAttributeNode(NewAttribute("alpha1",alpha1/degree));
670   trapElement->setAttributeNode(NewAttribute("y2",
671                2.0*trap->GetYHalfLength2()/mm));
672   trapElement->setAttributeNode(NewAttribute("x3",
673                2.0*trap->GetXHalfLength3()/mm));
674   trapElement->setAttributeNode(NewAttribute("x4",
675                2.0*trap->GetXHalfLength4()/mm));
676   trapElement->setAttributeNode(NewAttribute("alpha2",alpha2/degree));
677   trapElement->setAttributeNode(NewAttribute("aunit","deg"));
678   trapElement->setAttributeNode(NewAttribute("lunit","mm"));
679   solidsElement->appendChild(trapElement);
680}
681
682void G4GDMLWriteSolids::
683TrdWrite(xercesc::DOMElement* solidsElement, const G4Trd* const trd)
684{
685   const G4String& name = GenerateName(trd->GetName(),trd);
686
687   xercesc::DOMElement* trdElement = NewElement("trd");
688   trdElement->setAttributeNode(NewAttribute("name",name));
689   trdElement->setAttributeNode(NewAttribute("x1",
690               2.0*trd->GetXHalfLength1()/mm));
691   trdElement->setAttributeNode(NewAttribute("x2",
692               2.0*trd->GetXHalfLength2()/mm));
693   trdElement->setAttributeNode(NewAttribute("y1",
694               2.0*trd->GetYHalfLength1()/mm));
695   trdElement->setAttributeNode(NewAttribute("y2",
696               2.0*trd->GetYHalfLength2()/mm));
697   trdElement->setAttributeNode(NewAttribute("z",
698               2.0*trd->GetZHalfLength()/mm));
699   trdElement->setAttributeNode(NewAttribute("lunit","mm"));
700   solidsElement->appendChild(trdElement);
701}
702
703void G4GDMLWriteSolids::
704TubeWrite(xercesc::DOMElement* solidsElement, const G4Tubs* const tube)
705{
706   const G4String& name = GenerateName(tube->GetName(),tube);
707
708   xercesc::DOMElement* tubeElement = NewElement("tube");
709   tubeElement->setAttributeNode(NewAttribute("name",name));
710   tubeElement->setAttributeNode(NewAttribute("rmin",
711                tube->GetInnerRadius()/mm));
712   tubeElement->setAttributeNode(NewAttribute("rmax",
713                tube->GetOuterRadius()/mm));
714   tubeElement->setAttributeNode(NewAttribute("z",
715                2.0*tube->GetZHalfLength()/mm));
716   tubeElement->setAttributeNode(NewAttribute("startphi",
717                tube->GetStartPhiAngle()/degree));
718   tubeElement->setAttributeNode(NewAttribute("deltaphi",
719                tube->GetDeltaPhiAngle()/degree));
720   tubeElement->setAttributeNode(NewAttribute("aunit","deg"));
721   tubeElement->setAttributeNode(NewAttribute("lunit","mm"));
722   solidsElement->appendChild(tubeElement);
723}
724
725void G4GDMLWriteSolids::
726TwistedboxWrite(xercesc::DOMElement* solidsElement,
727                const G4TwistedBox* const twistedbox)
728{
729   const G4String& name = GenerateName(twistedbox->GetName(),twistedbox);
730
731   xercesc::DOMElement* twistedboxElement = NewElement("twistedbox");
732   twistedboxElement->setAttributeNode(NewAttribute("name",name));
733   twistedboxElement->setAttributeNode(NewAttribute("x",
734                      2.0*twistedbox->GetXHalfLength()/mm));
735   twistedboxElement->setAttributeNode(NewAttribute("y",
736                      2.0*twistedbox->GetYHalfLength()/mm));
737   twistedboxElement->setAttributeNode(NewAttribute("z",
738                      2.0*twistedbox->GetZHalfLength()/mm));
739   twistedboxElement->setAttributeNode(NewAttribute("PhiTwist",
740                      twistedbox->GetPhiTwist()/degree));
741   twistedboxElement->setAttributeNode(NewAttribute("aunit","deg"));
742   twistedboxElement->setAttributeNode(NewAttribute("lunit","mm"));
743   solidsElement->appendChild(twistedboxElement);
744}
745
746void G4GDMLWriteSolids::
747TwistedtrapWrite(xercesc::DOMElement* solidsElement,
748                 const G4TwistedTrap* const twistedtrap)
749{
750   const G4String& name = GenerateName(twistedtrap->GetName(),twistedtrap);
751
752   xercesc::DOMElement* twistedtrapElement = NewElement("twistedtrap");
753   twistedtrapElement->setAttributeNode(NewAttribute("name",name));
754   twistedtrapElement->setAttributeNode(NewAttribute("y1",
755                       2.0*twistedtrap->GetY1HalfLength()/mm));
756   twistedtrapElement->setAttributeNode(NewAttribute("x1",
757                       2.0*twistedtrap->GetX1HalfLength()/mm));
758   twistedtrapElement->setAttributeNode(NewAttribute("x2",
759                       2.0*twistedtrap->GetX2HalfLength()/mm));
760   twistedtrapElement->setAttributeNode(NewAttribute("y2",
761                       2.0*twistedtrap->GetY2HalfLength()/mm));
762   twistedtrapElement->setAttributeNode(NewAttribute("x3",
763                       2.0*twistedtrap->GetX3HalfLength()/mm));
764   twistedtrapElement->setAttributeNode(NewAttribute("x4",
765                       2.0*twistedtrap->GetX4HalfLength()/mm));
766   twistedtrapElement->setAttributeNode(NewAttribute("z",
767                       2.0*twistedtrap->GetZHalfLength()/mm));
768   twistedtrapElement->setAttributeNode(NewAttribute("Alph",
769                       twistedtrap->GetTiltAngleAlpha()/degree));
770   twistedtrapElement->setAttributeNode(NewAttribute("Theta",
771                       twistedtrap->GetPolarAngleTheta()/degree));
772   twistedtrapElement->setAttributeNode(NewAttribute("Phi",
773                       twistedtrap->GetAzimuthalAnglePhi()/degree));
774   twistedtrapElement->setAttributeNode(NewAttribute("PhiTwist",
775                       twistedtrap->GetPhiTwist()/degree));
776   twistedtrapElement->setAttributeNode(NewAttribute("aunit","deg"));
777   twistedtrapElement->setAttributeNode(NewAttribute("lunit","mm"));
778   
779   solidsElement->appendChild(twistedtrapElement);
780}
781
782void G4GDMLWriteSolids::
783TwistedtrdWrite(xercesc::DOMElement* solidsElement,
784                const G4TwistedTrd* const twistedtrd)
785{
786   const G4String& name = GenerateName(twistedtrd->GetName(),twistedtrd);
787
788   xercesc::DOMElement* twistedtrdElement = NewElement("twistedtrd");
789   twistedtrdElement->setAttributeNode(NewAttribute("name",name));
790   twistedtrdElement->setAttributeNode(NewAttribute("x1",
791                      2.0*twistedtrd->GetX1HalfLength()/mm));
792   twistedtrdElement->setAttributeNode(NewAttribute("x2",
793                      2.0*twistedtrd->GetX2HalfLength()/mm));
794   twistedtrdElement->setAttributeNode(NewAttribute("y1",
795                      2.0*twistedtrd->GetY1HalfLength()/mm));
796   twistedtrdElement->setAttributeNode(NewAttribute("y2",
797                      2.0*twistedtrd->GetY2HalfLength()/mm));
798   twistedtrdElement->setAttributeNode(NewAttribute("z",
799                      2.0*twistedtrd->GetZHalfLength()/mm));
800   twistedtrdElement->setAttributeNode(NewAttribute("PhiTwist",
801                      twistedtrd->GetPhiTwist()/degree));
802   twistedtrdElement->setAttributeNode(NewAttribute("aunit","deg"));
803   twistedtrdElement->setAttributeNode(NewAttribute("lunit","mm"));
804   solidsElement->appendChild(twistedtrdElement);
805}
806
807void G4GDMLWriteSolids::
808TwistedtubsWrite(xercesc::DOMElement* solidsElement,
809                 const G4TwistedTubs* const twistedtubs)
810{
811   const G4String& name = GenerateName(twistedtubs->GetName(),twistedtubs);
812
813   xercesc::DOMElement* twistedtubsElement = NewElement("twistedtubs");
814   twistedtubsElement->setAttributeNode(NewAttribute("name",name));
815   twistedtubsElement->setAttributeNode(NewAttribute("twistedangle",
816                       twistedtubs->GetPhiTwist()/degree));
817   twistedtubsElement->setAttributeNode(NewAttribute("endinnerrad",
818                       twistedtubs->GetInnerRadius()/mm));
819   twistedtubsElement->setAttributeNode(NewAttribute("endouterrad",
820                       twistedtubs->GetOuterRadius()/mm));
821   twistedtubsElement->setAttributeNode(NewAttribute("zlen",
822                       2.0*twistedtubs->GetZHalfLength()/mm));
823   twistedtubsElement->setAttributeNode(NewAttribute("phi",
824                       twistedtubs->GetDPhi()/degree));
825   twistedtubsElement->setAttributeNode(NewAttribute("aunit","deg"));
826   twistedtubsElement->setAttributeNode(NewAttribute("lunit","mm"));
827   solidsElement->appendChild(twistedtubsElement);
828}
829
830void G4GDMLWriteSolids::
831ZplaneWrite(xercesc::DOMElement* element, const G4double& z,
832            const G4double& rmin, const G4double& rmax)
833{
834   xercesc::DOMElement* zplaneElement = NewElement("zplane");
835   zplaneElement->setAttributeNode(NewAttribute("z",z/mm));
836   zplaneElement->setAttributeNode(NewAttribute("rmin",rmin/mm));
837   zplaneElement->setAttributeNode(NewAttribute("rmax",rmax/mm));
838   element->appendChild(zplaneElement);
839}
840
841void G4GDMLWriteSolids::
842OpticalSurfaceWrite(xercesc::DOMElement* solidsElement,
843                    const G4OpticalSurface* const surf)
844{
845   xercesc::DOMElement* optElement = NewElement("opticalsurface");
846   G4OpticalSurfaceModel smodel = surf->GetModel();
847   G4double sval = (smodel==glisur) ? surf->GetPolish() : surf->GetSigmaAlpha();
848
849   optElement->setAttributeNode(NewAttribute("name", surf->GetName()));
850   optElement->setAttributeNode(NewAttribute("model", smodel));
851   optElement->setAttributeNode(NewAttribute("finish", surf->GetFinish()));
852   optElement->setAttributeNode(NewAttribute("type", surf->GetType()));
853   optElement->setAttributeNode(NewAttribute("value", sval));
854
855   solidsElement->appendChild(optElement);
856}
857
858void G4GDMLWriteSolids::SolidsWrite(xercesc::DOMElement* gdmlElement)
859{
860   G4cout << "G4GDML: Writing solids..." << G4endl;
861
862   solidsElement = NewElement("solids");
863   gdmlElement->appendChild(solidsElement);
864
865   solidList.clear();
866}
867
868void G4GDMLWriteSolids::AddSolid(const G4VSolid* const solidPtr)
869{
870   for (size_t i=0; i<solidList.size(); i++)   // Check if solid is
871   {                                           // already in the list!
872      if (solidList[i] == solidPtr)  { return; }
873   }
874
875   solidList.push_back(solidPtr);
876
877   if (const G4BooleanSolid* const booleanPtr
878     = dynamic_cast<const G4BooleanSolid*>(solidPtr))
879     { BooleanWrite(solidsElement,booleanPtr); } else
880   if (const G4Box* const boxPtr
881     = dynamic_cast<const G4Box*>(solidPtr))
882     { BoxWrite(solidsElement,boxPtr); } else
883   if (const G4Cons* const conePtr
884     = dynamic_cast<const G4Cons*>(solidPtr))
885     { ConeWrite(solidsElement,conePtr); } else
886   if (const G4EllipticalCone* const elconePtr
887     = dynamic_cast<const G4EllipticalCone*>(solidPtr))
888     { ElconeWrite(solidsElement,elconePtr); } else
889   if (const G4Ellipsoid* const ellipsoidPtr
890     = dynamic_cast<const G4Ellipsoid*>(solidPtr))
891     { EllipsoidWrite(solidsElement,ellipsoidPtr); } else
892   if (const G4EllipticalTube* const eltubePtr
893     = dynamic_cast<const G4EllipticalTube*>(solidPtr))
894     { EltubeWrite(solidsElement,eltubePtr); } else
895   if (const G4ExtrudedSolid* const xtruPtr
896     = dynamic_cast<const G4ExtrudedSolid*>(solidPtr))
897     { XtruWrite(solidsElement,xtruPtr); } else
898   if (const G4Hype* const hypePtr
899     = dynamic_cast<const G4Hype*>(solidPtr))
900     { HypeWrite(solidsElement,hypePtr); } else
901   if (const G4Orb* const orbPtr
902     = dynamic_cast<const G4Orb*>(solidPtr))
903     { OrbWrite(solidsElement,orbPtr); } else
904   if (const G4Para* const paraPtr
905     = dynamic_cast<const G4Para*>(solidPtr))
906     { ParaWrite(solidsElement,paraPtr); } else
907   if (const G4Paraboloid* const paraboloidPtr
908     = dynamic_cast<const G4Paraboloid*>(solidPtr))
909     { ParaboloidWrite(solidsElement,paraboloidPtr); } else
910   if (const G4Polycone* const polyconePtr
911     = dynamic_cast<const G4Polycone*>(solidPtr))
912     { PolyconeWrite(solidsElement,polyconePtr); } else
913   if (const G4Polyhedra* const polyhedraPtr
914     = dynamic_cast<const G4Polyhedra*>(solidPtr))
915     { PolyhedraWrite(solidsElement,polyhedraPtr); } else
916   if (const G4Sphere* const spherePtr
917     = dynamic_cast<const G4Sphere*>(solidPtr))
918     { SphereWrite(solidsElement,spherePtr); } else
919   if (const G4TessellatedSolid* const tessellatedPtr
920     = dynamic_cast<const G4TessellatedSolid*>(solidPtr))
921     { TessellatedWrite(solidsElement,tessellatedPtr); } else
922   if (const G4Tet* const tetPtr
923     = dynamic_cast<const G4Tet*>(solidPtr))
924     { TetWrite(solidsElement,tetPtr); } else
925   if (const G4Torus* const torusPtr
926     = dynamic_cast<const G4Torus*>(solidPtr))
927     { TorusWrite(solidsElement,torusPtr); } else
928   if (const G4GenericTrap* const gtrapPtr
929     = dynamic_cast<const G4GenericTrap*>(solidPtr))
930     { GenTrapWrite(solidsElement,gtrapPtr); } else
931   if (const G4Trap* const trapPtr
932     = dynamic_cast<const G4Trap*>(solidPtr))
933     { TrapWrite(solidsElement,trapPtr); } else
934   if (const G4Trd* const trdPtr
935     = dynamic_cast<const G4Trd*>(solidPtr))
936     { TrdWrite(solidsElement,trdPtr); } else
937   if (const G4Tubs* const tubePtr
938     = dynamic_cast<const G4Tubs*>(solidPtr))
939     { TubeWrite(solidsElement,tubePtr); } else
940   if (const G4TwistedBox* const twistedboxPtr
941     = dynamic_cast<const G4TwistedBox*>(solidPtr))
942     { TwistedboxWrite(solidsElement,twistedboxPtr); } else
943   if (const G4TwistedTrap* const twistedtrapPtr
944     = dynamic_cast<const G4TwistedTrap*>(solidPtr))
945     { TwistedtrapWrite(solidsElement,twistedtrapPtr); } else
946   if (const G4TwistedTrd* const twistedtrdPtr
947     = dynamic_cast<const G4TwistedTrd*>(solidPtr))
948     { TwistedtrdWrite(solidsElement,twistedtrdPtr); } else
949   if (const G4TwistedTubs* const twistedtubsPtr
950     = dynamic_cast<const G4TwistedTubs*>(solidPtr))
951     { TwistedtubsWrite(solidsElement,twistedtubsPtr); }
952   else
953   {
954     G4String error_msg = "Unknown solid: " + solidPtr->GetName()
955                        + "; Type: " + solidPtr->GetEntityType();
956     G4Exception("G4GDMLWriteSolids::AddSolid()", "WriteError",
957                 FatalException, error_msg);
958   }
959}
Note: See TracBrowser for help on using the repository browser.