24#include "G4ExtrudedSolid.hh"
25#include "G4ReflectedSolid.hh"
26#include "G4UnionSolid.hh"
34 std::vector<VGM::TwoVector> polygon,
35 std::vector<std::vector<double> > zsections)
37 VGM::IExtrudedSolid(),
41 fZSections(zsections),
49 if (zsections.size() < 2) {
50 std::cerr <<
"+++ Error +++" << std::endl;
51 std::cerr <<
" Number of z-sections = " << zsections.size()
52 <<
" has to be >= 2" << std::endl;
57 std::vector<G4TwoVector> g4Polygon;
58 for (G4int i = 0; i < G4int(polygon.size()); ++i) {
67 std::set<unsigned int> toBreak;
68 for (
unsigned int i = 1; i < zsections.size(); ++i)
69 if (fabs(zsections[i][0] - zsections[i - 1][0]) < 1e-09)
70 toBreak.insert(i - 1);
71 toBreak.insert(zsections.size() - 1);
75 std::vector<G4ExtrudedSolid::ZSection> g4Zsections;
76 for (
unsigned int iz = 0; iz < zsections.size(); ++iz) {
78 g4Zsections.push_back(
84 if (toBreak.find(iz) != toBreak.end()) {
89 G4ExtrudedSolid* xtru =
90 new G4ExtrudedSolid(fName, g4Polygon, g4Zsections);
91 fConstituents.push_back(xtru);
98 G4VSolid* xtruA = *fConstituents.begin();
100 std::vector<G4ExtrudedSolid*>::const_iterator it;
101 for (it = fConstituents.begin() + 1; it != fConstituents.end(); ++it) {
102 G4ExtrudedSolid* xtruB = *it;
104 new G4UnionSolid(fName, xtruA, xtruB, 0, G4ThreeVector());
107 fExtrudedSolid = xtruA;
116 G4ExtrudedSolid* xtru, G4ReflectedSolid* reflXtru)
118 VGM::IExtrudedSolid(),
120 fName(xtru->GetName()),
121 fExtrudedSolid(xtru),
128 if (reflXtru) sign = -1;
131 for (G4int iz = 0; iz < xtru->GetNofZSections(); ++iz) {
132 ZSectionType zsection(4);
136 zsection[3] = xtru->GetZSection(iz).fScale;
138 fZSections.push_back(zsection);
140 fZSections.insert(fZSections.begin(), zsection);
144 fConstituents.push_back(xtru);
155 VGM::IExtrudedSolid(),
168 VGM::IExtrudedSolid(rhs),
190 G4cout << "Geant4GM::ExtrudedSolid::CreateFinalSolid" << G4endl;
192 G4VSolid* xtruA = *fConstituents.begin();
193 G4double hzTotal = (*fConstituents.begin())->GetZHalfLength();
195 // compose boolean solid if more then 1 constituent
196 std::vector<G4ExtrudedSolid*>::const_iterator it;
197 for ( it = fConstituents.begin()+1; it != fConstituents.end(); ++it ) {
198 G4ExtrudedSolid* xtruB = *it;
199 G4double dz = hzTotal + xtruB->GetZHalfLength();
201 = new G4UnionSolid(fName, xtruA, xtruB, 0, G4ThreeVector(0., 0., dz));
203 hzTotal += xtruB->GetZHalfLength();
206 fExtrudedSolid = xtruA;
207 fZDisplacement = fZDisplacement - hzTotal; // CHECK !!!
209 G4cout << *fExtrudedSolid << G4endl;
211 // Reset VGM polygon data
212 dynamic_cast<Geant4GM::Polygon*>(fPolygon)
213 ->SetExtrudedSolid(*fConstituents.begin());
215 Geant4GM::SolidMap::Instance()->AddSolid(this, fExtrudedSolid);
218//_____________________________________________________________________________
219void Geant4GM::ExtrudedSolid::AddZPlane(double zpos,
220 VGM::TwoVector offset, double scale)
223 if ( fZSections.size() > 0) {
226 std::vector<G4TwoVector> polygon;
227 if ( fConstituents.size() == 0 ) {
228 // Fill it from VGM object if not yet defined
229 for ( G4int i=0; i<fPolygon->NofVertices(); i++ ) {
232 fPolygon->Vertex(i).first / ClhepVGM::Units::Length(),
233 fPolygon->Vertex(i).second / ClhepVGM::Units::Length()));
237 // Get polygon from existing ExtrudedSolid solid
238 polygon = (*fConstituents.begin())->GetPolygon();
241 ZPlaneType zplane = fZSections[fZSections.size()-1];
242 G4double hz = (zpos -zplane[0])/2.0 / ClhepVGM::Units::Length();
244 G4TwoVector off1 = G4TwoVector(
245 zplane[1]/ ClhepVGM::Units::Length(),
246 zplane[2]/ ClhepVGM::Units::Length());
247 G4double scale1 = zplane[3];
248 G4TwoVector off2 = G4TwoVector(
249 offset.first / ClhepVGM::Units::Length(),
250 offset.second/ ClhepVGM::Units::Length());
251 G4double scale2 = scale;
253 // Create xtru for 2 planes and save it in the map
254 G4ExtrudedSolid* xtru
255 = new G4ExtrudedSolid(fName, polygon, hz, off1, scale1, off2, scale2);
256 fConstituents.push_back(xtru);
260 // Keep starting position of the solid
261 // fZDisplacement = zpos;
264 // Keep data of this z plane
265 ZPlaneType zplane(4);
267 zplane[1] = offset.first;
268 zplane[2] = offset.second;
270 fZSections.push_back(zplane);
273 // If the last z plane create the final solid
274 if ( G4int(fZSections.size()) == fNofZSections ) CreateFinalSolid();
281 return fExtrudedSolid->GetName();
287 return fConstituents[0]->GetNofVertices();
293 if (index < 0 || index > NofVertices()) {
294 std::cerr <<
"+++ Error +++" << std::endl;
295 std::cerr <<
" Wrong vertex index: " << index << std::endl;
310 if (iz < 0 || iz > NofZSections()) {
311 std::cerr <<
"+++ Error +++" << std::endl;
312 std::cerr <<
" Wrong index: " << iz << std::endl;
316 ZSectionType zplane = fZSections[iz];
323 if (iz < 0 || iz > NofZSections()) {
324 std::cerr <<
"+++ Error +++" << std::endl;
325 std::cerr <<
" Wrong index: " << iz << std::endl;
329 ZSectionType zplane = fZSections[iz];
337 if (iz < 0 || iz > NofZSections()) {
338 std::cerr <<
"+++ Error +++" << std::endl;
339 std::cerr <<
" Wrong index: " << iz << std::endl;
343 ZSectionType zplane = fZSections[iz];
static double Length()
Return CLHEP default length unit in VGM units.
VGM implementation for Geant4 xtru solid.
virtual std::string Name() const
Return the name of this solid.
virtual double ZPosition(int iz) const
Return the z position of the iz-th plane in mm.
virtual VGM::TwoVector Offset(int iz) const
Return the polygon offset in iz-th side.
virtual int NofZSections() const
Return the number of planes perpendicular to the z axis.
VGM::TwoVector Vertex(int index) const
Return the index-th vertex of outline polygon.
int NofVertices() const
Return the number of vertices of outline polygon.
virtual double Scale(int iz) const
Return the polygon scale in iz-th side.
static SolidMap * Instance()
void AddSolid(VGM::ISolid *, G4VSolid *)
std::pair< double, double > TwoVector