VGM Version 5.3
Loading...
Searching...
No Matches
VExporter.cxx
Go to the documentation of this file.
1// $Id$
2
3// -----------------------------------------------------------------------
4// The XmlVGM package of the Virtual Geometry Model
5// Copyright (C) 2007, Ivana Hrivnacova
6// All rights reserved.
7//
8// For the licensing terms see vgm/LICENSE.
9// Contact: ivana@ipno.in2p3.fr
10// -----------------------------------------------------------------------
11
12//
13// Class VExporter
14// --------------------
15// Class for generation of geometry data files in XML,
16// the XML format is independent from the geometry object model.
17//
18// Author: I. Hrivnacova, 19.1.2004
19
25#include "VGM/solids/ISolid.h"
29#include "VGM/volumes/IVolume.h"
30
31#include "ClhepVGM/transform.h"
32
33#include "XmlVGM/IWriter.h"
34#include "XmlVGM/VExporter.h"
35
36#include <iomanip>
37#include <sstream>
38#include <stdlib.h>
39#include <vector>
40
41const std::string XmlVGM::VExporter::fgkUndefinedFileName = "Undefined";
42
43//_____________________________________________________________________________
45 : fFactory(factory),
46 fWriter(writer),
47 fFileName(fgkUndefinedFileName),
48 fVolumeNames(),
49 fDebug(1),
50 fMaps(writer->GetNumPrecision(), writer->AngleUnit(), writer->LengthUnit())
51{
55}
56
57//_____________________________________________________________________________
59 : fFactory(0),
60 fWriter(0),
61 fFileName(fgkUndefinedFileName),
62 fVolumeNames(),
63 fDebug(1),
64 fMaps(0, 1., 1.)
65{
67
68 std::cerr << " XmlVGM::VExporter::VExporter:" << std::endl;
69 std::cerr << " Not allowed constructor." << std::endl;
70 std::cerr << "*** Error: Aborting execution +++" << std::endl;
71 exit(1);
72}
73
74//_____________________________________________________________________________
76 : fWriter(0),
77 fFileName(fgkUndefinedFileName),
78 fVolumeNames(),
79 fDebug(0),
80 fMaps(0, 1., 1.)
81{
83
84 std::cerr << " XmlVGM::VExporter::VExporter:" << std::endl;
85 std::cerr << " Copy constructor not implemented." << std::endl;
86 std::cerr << "** Exception: Aborting execution **" << std::endl;
87 exit(1);
88}
89
90//_____________________________________________________________________________
92{
93 //
94 delete fWriter;
95}
96
97//
98// operators
99//
100
101//_____________________________________________________________________________
103{
105
106 // check assignement to self
107 if (this == &right) return *this;
108
109 std::cerr << " XmlVGM::VExporter::operator=:" << std::endl;
110 std::cerr << " Assignement operator not implemented." << std::endl;
111 std::cerr << "** Exception: Aborting execution **" << std::endl;
112 exit(1);
113
114 return *this;
115}
116
117//
118// private methods
119//
120
121//_____________________________________________________________________________
122void XmlVGM::VExporter::ProcessPositions(VGM::IVolume* volume)
123{
125
126 std::string volumeName = volume->Name();
127
128 // store the name of logical volume in the set
129 fVolumeNames.insert(fVolumeNames.begin(), volumeName);
130
131 int nofDaughters = volume->NofDaughters();
132
133 if (nofDaughters > 0) {
134 for (int i = 0; i < nofDaughters; i++) {
135
136 // Simple placement positions
137 //
138 VGM::IPlacement* dPlacement = volume->Daughter(i);
139 if (dPlacement->Type() == VGM::kSimplePlacement) {
140
141 VGM::Transform transform = dPlacement->Transformation();
142 std::string name = fMaps.AddPosition(transform);
143
144 if (name != "") fWriter->WritePosition(name, transform);
145 }
146
147 // Parameterised placement positions
148 //
149 if (dPlacement->Type() == VGM::kParameterised) {
150
151 // get parameters
152 std::vector<VGM::Transform> transforms;
153 std::vector<VGM::IVolume*> volumes;
154 dPlacement->ParameterisedPlacementData(transforms, volumes);
155
156
157 for (size_t i=0; i<transforms.size(); ++i) {
158 auto transform = transforms[i];
159 std::string name = fMaps.AddPosition(transform);
160 if (name != "") fWriter->WritePosition(name, transform);
161 }
162 }
163
164 // Positions in tessellated solids
165 //
166 VGM::ISolid* dSolid = dPlacement->Volume()->Solid();
167 if (dSolid->Type() == VGM::kTessellated) {
168
169 ProcessPositionsInTessellated(dSolid);
170 }
171
172 // Positions in multi union solids
173 //
174 if (dSolid->Type() == VGM::kMultiUnion) {
175
176 ProcessPositionsInMultiUnion(dSolid);
177 }
178 /*
179 // Displacemnt positions in Boolean solids
180 //
181 VGM::ISolid* dSolid = dPlacement->Volume()->Solid();
182 if (dSolid->Type() == VGM::kBoolean) {
183
184 ProcessPositionsInBoolean(dSolid);
185 }
186 */
187
188 std::string dVolumeName = dPlacement->Volume()->Name();
189 if (fVolumeNames.find(dVolumeName) == fVolumeNames.end()) {
190 // process volumed only if it was not yet processed
191 ProcessPositions(dPlacement->Volume());
192 }
193 }
194 }
195}
196
197//_____________________________________________________________________________
198void XmlVGM::VExporter::ProcessPositionsInBoolean(VGM::ISolid* solid)
199{
202
203 if (solid->Type() != VGM::kBoolean) return;
204
205 VGM::IBooleanSolid* boolSolid = dynamic_cast<VGM::IBooleanSolid*>(solid);
206
207 VGM::Transform transform = boolSolid->Displacement();
208 std::string name = fMaps.AddPosition(transform);
209
210 // if (name != "")
211 // fWriter->WritePosition(name, transform);
212
213 // Process constituents
214 VGM::ISolid* solidA = boolSolid->ConstituentSolidA();
215 VGM::ISolid* solidB = boolSolid->ConstituentSolidB();
216
217 if (solidA->Type() == VGM::kBoolean) ProcessPositionsInBoolean(solidA);
218 if (solidB->Type() == VGM::kBoolean) ProcessPositionsInBoolean(solidB);
219}
220
221//_____________________________________________________________________________
222void XmlVGM::VExporter::ProcessPositionsInTessellated(VGM::ISolid* solid)
223{
226
227 if (solid->Type() != VGM::kTessellated) return;
228
229 VGM::ITessellatedSolid* tessellatedSolid =
230 dynamic_cast<VGM::ITessellatedSolid*>(solid);
231
232 for (int i = 0; i < tessellatedSolid->NofFacets(); ++i) {
233 for (int j = 0; j < tessellatedSolid->NofVertices(i); ++j) {
234
235 VGM::ThreeVector vertex = tessellatedSolid->Vertex(i, j);
236 std::string name = fMaps.AddPosition(vertex);
237
238 if (name != "") fWriter->WritePosition(name, vertex);
239 }
240 }
241}
242
243//_____________________________________________________________________________
244void XmlVGM::VExporter::ProcessPositionsInMultiUnion(VGM::ISolid* solid)
245{
247
248 if (solid->Type() != VGM::kMultiUnion) return;
249
250 VGM::IMultiUnion* multiUnion = dynamic_cast<VGM::IMultiUnion*>(solid);
251
252 for (int i = 0; i < multiUnion->NofSolids(); ++i) {
253 std::string posName = fMaps.AddPosition(multiUnion->Transformation(i));
254 if (posName != "")
255 fWriter->WritePosition(posName, multiUnion->Transformation(i));
256 }
257}
258
259//_____________________________________________________________________________
260void XmlVGM::VExporter::ProcessRotations(VGM::IVolume* volume)
261{
264
265 std::string volumeName = volume->Name();
266
267 // store the name of logical volume in the set
268 fVolumeNames.insert(fVolumeNames.begin(), volumeName);
269
270 int nofDaughters = volume->NofDaughters();
271
272 if (nofDaughters > 0) {
273 for (int i = 0; i < nofDaughters; i++) {
274
275 // Simple placement rotations
276 //
277 VGM::IPlacement* dPlacement = volume->Daughter(i);
278 if (dPlacement->Type() == VGM::kSimplePlacement) {
279
280 VGM::Transform transform = dPlacement->Transformation();
281 std::string name = fMaps.AddRotation(transform);
282
283 if (name != "") fWriter->WriteRotation(name, transform);
284 }
285
286 if (dPlacement->Type() == VGM::kParameterised) {
287
288 std::vector<VGM::Transform> transforms;
289 std::vector<VGM::IVolume*> volumes;
290 dPlacement->ParameterisedPlacementData(transforms, volumes);
291
292 for (auto transform : transforms) {
293 std::string name = fMaps.AddRotation(transform);
294 if (name != "") fWriter->WriteRotation(name, transform);
295 }
296 }
297
298 /*
299 // Displacemnt rotations in Boolean solids
300 //
301 VGM::ISolid* dSolid = dPlacement->Volume()->Solid();
302 if (dSolid->Type() == VGM::kBoolean) {
303
304 ProcessRotationsInBoolean(dSolid);
305 }
306 */
307
308 // Rotations in multi union solids
309 //
310 VGM::ISolid* dSolid = dPlacement->Volume()->Solid();
311 if (dSolid->Type() == VGM::kMultiUnion) {
312 ProcessRotationsInMultiUnion(dSolid);
313 }
314
315 std::string dVolumeName = dPlacement->Volume()->Name();
316 if (fVolumeNames.find(dVolumeName) == fVolumeNames.end()) {
317 // process volumed only if it was not yet processed
318 ProcessRotations(dPlacement->Volume());
319 }
320 }
321 }
322}
323
324//_____________________________________________________________________________
325void XmlVGM::VExporter::ProcessRotationsInBoolean(VGM::ISolid* solid)
326{
329
330 if (solid->Type() != VGM::kBoolean) return;
331
332 VGM::IBooleanSolid* boolSolid = dynamic_cast<VGM::IBooleanSolid*>(solid);
333
334 VGM::Transform transform = boolSolid->Displacement();
335 std::string name = fMaps.AddRotation(transform);
336
337 // if (name != "")
338 // fWriter->WriteRotation(name, transform);
339
340 // Process constituents
341 VGM::ISolid* solidA = boolSolid->ConstituentSolidA();
342 VGM::ISolid* solidB = boolSolid->ConstituentSolidB();
343
344 if (solidA->Type() == VGM::kBoolean) ProcessRotationsInBoolean(solidA);
345 if (solidB->Type() == VGM::kBoolean) ProcessPositionsInBoolean(solidB);
346}
347
348//_____________________________________________________________________________
349void XmlVGM::VExporter::ProcessRotationsInMultiUnion(VGM::ISolid* solid)
350{
352
353 if (solid->Type() != VGM::kMultiUnion) return;
354
355 VGM::IMultiUnion* multiUnion = dynamic_cast<VGM::IMultiUnion*>(solid);
356
357 for (int i = 0; i < multiUnion->NofSolids(); ++i) {
358 std::string rotName = fMaps.AddRotation(multiUnion->Transformation(i));
359 if (rotName != "")
360 fWriter->WriteRotation(rotName, multiUnion->Transformation(i));
361 }
362}
363
364//_____________________________________________________________________________
365void XmlVGM::VExporter::ProcessMaterials(VGM::IVolume* volume)
366{
368
369 std::string volumeName = volume->Name();
370
371 // Material
372 const VGM::IMaterial* volumeMaterial =
373 fFactory->MaterialFactory()->Material(volume->MaterialName());
374
375 if (!volumeMaterial) {
376 std::cerr << "XmlVGM::VExporter::ProcessMaterials: " << std::endl;
377 std::cerr << " Material " << volume->MaterialName() << "not found."
378 << std::endl;
379 exit(1);
380 }
381
382 const VGM::IMaterial* material = fMaps.AddMaterial(volumeMaterial);
383
384 // Elements
385 if (material) {
386 for (int j = 0; j < int(material->NofElements()); j++) {
387 VGM::IElement* element = material->Element(j);
388 fMaps.AddElement(element);
389
390 // Isotopes
391 for (int k = 0; k < int(element->NofIsotopes()); k++)
392 fMaps.AddIsotope(element->Isotope(k));
393 }
394 }
395
396 // store the name of logical volume in the set
397 fVolumeNames.insert(fVolumeNames.begin(), volumeName);
398
399 int nofDaughters = volume->NofDaughters();
400
401 if (nofDaughters > 0) {
402 for (int i = 0; i < nofDaughters; i++) {
403
404 VGM::IPlacement* dPlacement = volume->Daughter(i);
405
406 std::string dVolumeName = dPlacement->Volume()->Name();
407 if (fVolumeNames.find(dVolumeName) == fVolumeNames.end()) {
408 // process volume only if it was not yet processed
409 ProcessMaterials(dPlacement->Volume());
410 }
411 }
412 }
413}
414
415//_____________________________________________________________________________
416void XmlVGM::VExporter::ProcessMedia(VGM::IVolume* volume)
417{
419
420 std::string volumeName = volume->Name();
421
422 // Medium
423 const VGM::IMedium* volumeMedium =
424 fFactory->MaterialFactory()->Medium(volume->MediumName());
425
426 if (!volumeMedium) {
427 std::cerr << "XmlVGM::VExporter::ProcessMedia: " << std::endl;
428 std::cerr << " Medium " << volume->MediumName() << " not found."
429 << std::endl;
430 // exit(1);
431 }
432 else
433 fMaps.AddMedium(volumeMedium);
434
435 // store the name of logical volume in the set
436 fVolumeNames.insert(fVolumeNames.begin(), volumeName);
437
438 int nofDaughters = volume->NofDaughters();
439
440 if (nofDaughters > 0) {
441 for (int i = 0; i < nofDaughters; i++) {
442
443 VGM::IPlacement* dPlacement = volume->Daughter(i);
444
445 std::string dVolumeName = dPlacement->Volume()->Name();
446 if (fVolumeNames.find(dVolumeName) == fVolumeNames.end()) {
447 // process volume only if it was not yet processed
448 ProcessMedia(dPlacement->Volume());
449 }
450 }
451 }
452}
453
454//_____________________________________________________________________________
455void XmlVGM::VExporter::ProcessSolids(VGM::IVolume* volume)
456{
458
459 VGM::ISolid* solid = volume->Solid();
460 std::string volumeName = volume->Name();
461 std::string mediumName = volume->MediumName();
462 fWriter->WriteSolid(volumeName, solid, mediumName);
463
464 // store the name of logical volume in the set
465 fVolumeNames.insert(fVolumeNames.begin(), volumeName);
466
467 // process daughters
468 int nofDaughters = volume->NofDaughters();
469 if (nofDaughters > 0) {
470 for (int i = 0; i < nofDaughters; i++) {
471
472 if (fDebug > 1) {
473 std::cout << "processing " << i << "th daughter of " << volume->Name()
474 << std::endl;
475 }
476
477 VGM::IVolume* dVolume = volume->Daughter(i)->Volume();
478 std::string dVolumeName = dVolume->Name();
479
480 if (fVolumeNames.find(dVolumeName) == fVolumeNames.end()) {
481 // process dVolume only if it was not yet processed
482 ProcessSolids(dVolume);
483 }
484
485 // process solids if Parameterised placement
486 if (volume->Daughter(i)->Type() == VGM::kParameterised) {
487 std::vector<VGM::Transform> transforms;
488 std::vector<VGM::IVolume*> volumes;
489 volume->Daughter(i)->ParameterisedPlacementData(transforms, volumes);
490
491 for (size_t i=0; i<volumes.size(); ++i) {
492 std::string iVolumeName = volumes[i]->Name();
493 if (fVolumeNames.find(iVolumeName) == fVolumeNames.end()) {
494 ProcessSolids(volumes[i]);
495 }
496 }
497 }
498 }
499 }
500}
501
502//
503// protected methods
504//
505
506//_____________________________________________________________________________
508{
511
512 // Open section
513 fWriter->OpenPositions();
514
515 // Store first the center position
516 std::string name = fMaps.AddPosition(ClhepVGM::Identity());
517 fWriter->WritePosition(name, ClhepVGM::Identity());
518
519 // Process and write positions
520 ProcessPositions(volume);
521 ClearVolumeNames();
522
523 // Close section
524 fWriter->ClosePositions();
525 fWriter->WriteEmptyLine();
526}
527
528//_____________________________________________________________________________
530{
533
534 // Open section
535 fWriter->OpenRotations();
536
537 // Store first the identity matrix
538 std::string name = fMaps.AddRotation(ClhepVGM::Identity());
539 fWriter->WriteRotation(name, ClhepVGM::Identity());
540
541 // Process and write rotations
542 ProcessRotations(volume);
543 ClearVolumeNames();
544
545 // Write scale
546 fWriter->WriteEmptyLine();
547 std::string name0 = "scale_0";
548 fWriter->WriteScale(name0);
549
550 // Close section
551 fWriter->CloseRotations();
552 fWriter->WriteEmptyLine();
553}
554
555//_____________________________________________________________________________
557{
560
561 // Create section
562 fWriter->OpenMaterials();
563
564 // Fill maps of elements, materials and media
565 ProcessMaterials(volume);
566
567 // Write isotopes from the map
568 fMaps.WriteAllIsotopes(fWriter);
569
570 // Empty line
571 fWriter->WriteEmptyLine();
572
573 // Write elements from the map
574 fMaps.WriteAllElements(fWriter);
575
576 // Empty line
577 fWriter->WriteEmptyLine();
578
579 // Write materials from the map
580 fMaps.WriteAllMaterials(fWriter);
581
582 fWriter->WriteEmptyLine();
583 ClearVolumeNames();
584
585 // Close section
586 fWriter->CloseMaterials();
587 fWriter->WriteEmptyLine();
588}
589
590//_____________________________________________________________________________
592{
595
596 // Create section
597 fWriter->OpenMedia();
598
599 if (fFactory->MaterialFactory()->Media().size() > 0) {
600 // Fill maps of media
601 ProcessMedia(volume);
602
603 // Write elements from the map
604 fMaps.WriteAllMedia(fWriter);
605 }
606 else {
607 // Write media from materials if media are not defined
608 fMaps.WriteAllMediaFromMaterials(fWriter);
609 }
610
611 // Empty line
612 fWriter->WriteEmptyLine();
613 ClearVolumeNames();
614
615 // Close section
616 fWriter->CloseMedia();
617 fWriter->WriteEmptyLine();
618}
619
620//_____________________________________________________________________________
622{
625
626 fWriter->OpenSolids();
627 ProcessSolids(volume);
628 fWriter->CloseSolids();
629 fWriter->WriteEmptyLine();
630 ClearVolumeNames();
631}
632
633//_____________________________________________________________________________
635{
637
638 fVolumeNames.erase(fVolumeNames.begin(), fVolumeNames.end());
639}
640
641//
642// public methods
643//
644
645//_____________________________________________________________________________
647{
649
650 GenerateGeometry(fFactory->Top()->Volume());
651}
652
653//_____________________________________________________________________________
654void XmlVGM::VExporter::GenerateXMLGeometry(const std::string& volumeName)
655{
657
658 // Find volume
659 const VGM::VolumeStore& volumeStore = fFactory->Volumes();
660
661 for (unsigned int i = 0; i < volumeStore.size(); i++) {
662 VGM::IVolume* volume = volumeStore[i];
663 if (volume->Name() == volumeName) {
664
665 // Generate XML
666 GenerateGeometry(volume);
667
668 // Clear temprary maps
669 fMaps.ClearAllMaps();
670
671 return;
672 }
673 }
674
675 std::cerr << "++ Warning: ++ " << std::endl;
676 std::cerr << " XmlVGM::VExporter::GenerateXMLGeometry:" << std::endl;
677 std::cerr << " Logical volume " << volumeName << " does not exist."
678 << std::endl;
679}
680
681//_____________________________________________________________________________
683{
685
686 fWriter->SetNumWidth(width);
687}
688
689//_____________________________________________________________________________
691{
693
694 fWriter->SetNumPrecision(precision);
695 fMaps.SetNumPrecision(precision);
696}
The VGM interface to Boolean solids.
virtual ISolid * ConstituentSolidB() const =0
Return the second constituent solid.
virtual ISolid * ConstituentSolidA() const =0
Return the first constituent solid.
virtual Transform Displacement() const =0
Return the 3D displacement of the second constituent solid with respect to the first one.
The VGM interface to elements.
Definition IElement.h:34
virtual IIsotope * Isotope(int i) const =0
Return the i-th isotope constituing this element.
virtual int NofIsotopes() const =0
Return the number of isotopes constituing this element.
The VGM interface to geometry factory providing functions for geometry construction and conversions.
Definition IFactory.h:50
The VGM interface to materials.
Definition IMaterial.h:44
virtual IElement * Element(int iel) const =0
Return the i-th element constituing this material.
virtual int NofElements() const =0
Return the number of elements constituing this material.
The VGM interface to tracking medium.
Definition IMedium.h:31
The VGM interface to Boolean solids.
Definition IMultiUnion.h:31
virtual Transform Transformation(int index) const =0
Return the displacement of the ith constituent solid.
virtual int NofSolids() const =0
Return the number of constituent solids.
The VGM interface to positions of volumes.
Definition IPlacement.h:44
virtual PlacementType Type() const =0
Return the type of this placement.
virtual Transform Transformation() const =0
Return the 3D transformation (if simple placement)
virtual bool ParameterisedPlacementData(std::vector< VGM::Transform > &transforms, std::vector< VGM::IVolume * > &volumes) const =0
Fill the parameterised placement data if relevant and return true; return false if not parameterised ...
virtual IVolume * Volume() const =0
Return the associated volume.
The VGM interface to solids.
Definition ISolid.h:58
virtual SolidType Type() const =0
Return the type of this solid.
The VGM interface to extruded solids.
virtual int NofVertices(int ifacet) const =0
Return the number of vertices in the the ifacet-th facet.
virtual ThreeVector Vertex(int ifacet, int index) const =0
Return the index-th vertex in the ifacet-th facet.
virtual int NofFacets() const =0
Return the number of facets.
The VGM interface to volumes.
Definition IVolume.h:32
virtual ISolid * Solid() const =0
Return the associated solid.
virtual std::string MaterialName() const =0
Return the name of the associated material.
virtual std::string Name() const =0
Return the name of this volume.
virtual IPlacement * Daughter(int i) const =0
Return the i-th daughter.
virtual std::string MediumName() const =0
Return the name of the associated medium.
virtual int NofDaughters() const =0
Return the number of volume daughters.
The interface for the XML writer that writes VGM geometry objects to XML:
Definition IWriter.h:43
Class for generation of geometry data files in XML, the XML format is independent from the geometry o...
Definition VExporter.h:48
void GenerateXMLGeometry()
void GenerateMedia(VGM::IVolume *volume)
void GeneratePositions(VGM::IVolume *volume)
void SetNumPrecision(int precision)
void GenerateMaterials(VGM::IVolume *volume)
void SetNumWidth(int width)
VExporter & operator=(const VExporter &)
void GenerateRotations(VGM::IVolume *volume)
void GenerateSolids(VGM::IVolume *volume)
static const std::string fgkUndefinedFileName
Definition VExporter.h:99
virtual ~VExporter()
Definition VExporter.cxx:91
VGM::Transform Identity()
Definition transform.cxx:98
std::vector< double > Transform
Definition Transform.h:40
std::vector< IVolume * > VolumeStore
Definition IFactory.h:43
std::vector< double > ThreeVector
Definition ThreeVector.h:27
@ kParameterised
Definition IPlacement.h:35
@ kSimplePlacement
Definition IPlacement.h:33
@ kTessellated
Definition ISolid.h:43
@ kMultiUnion
Definition ISolid.h:50
@ kBoolean
Definition ISolid.h:48