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

Last change on this file since 1330 was 1315, checked in by garnier, 15 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.