00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifdef USE_LCDD
00012
00013 #ifndef BDSGeometryLCDD_h
00014 #define BDSGeometryLCDD_h 1
00015
00016 #include "globals.hh"
00017 #include "BDSMaterials.hh"
00018 #include "G4UniformMagField.hh"
00019 #include "G4LogicalVolume.hh"
00020 #include "G4VSolid.hh"
00021 #include "G4Cons.hh"
00022 #include "G4Tubs.hh"
00023 #include "G4Polycone.hh"
00024 #include "G4Polyhedra.hh"
00025 #include "G4SubtractionSolid.hh"
00026 #include "G4Box.hh"
00027 #include "G4Trd.hh"
00028 #include "G4UserLimits.hh"
00029 #include "G4VisAttributes.hh"
00030 #include "G4VPhysicalVolume.hh"
00031 #include "G4PVPlacement.hh"
00032 #include "G4MagIntegratorStepper.hh"
00033 #include "G4Mag_UsualEqRhs.hh"
00034 #include "G4FieldManager.hh"
00035 #include "BDSSamplerSD.hh"
00036 #include <fstream>
00037 #include <vector>
00038 #include <map>
00039 #include "BDSMagField.hh"
00040 #include "G4TessellatedSolid.hh"
00041 #include "G4TriangularFacet.hh"
00042 #include "G4QuadrangularFacet.hh"
00043
00044
00045 #include <libxml/xmlmemory.h>
00046 #include <libxml/parser.h>
00047 #include <libxml/xpath.h>
00048
00049 struct POS_REF{
00050 G4String name;
00051 G4ThreeVector value;
00052 };
00053
00054 struct ROT_REF{
00055 G4String name;
00056 G4ThreeVector value;
00057 };
00058
00059 struct CONST_REF{
00060 G4String name;
00061 G4double value;
00062 };
00063
00064 struct VIS_REF{
00065 G4String name;
00066 G4VisAttributes* value;
00067 };
00068
00069 class BDSGeometryLCDD
00070 {
00071 public:
00072 BDSGeometryLCDD(G4String LCDDfile);
00073 ~BDSGeometryLCDD();
00074
00075 inline G4String GetFieldVolName(){return itsFieldVolName;}
00076
00077 void parseDoc();
00078 void parseLCDD(xmlNodePtr cur);
00079 void parseHEADER(xmlNodePtr cur);
00080 void parseDISPLAY(xmlNodePtr cur);
00081 void parseVIS(xmlNodePtr cur);
00082 void parseDEFINE(xmlNodePtr cur);
00083 void parseMATERIALS(xmlNodePtr cur);
00084 void parseSOLID(xmlNodePtr cur);
00085 void parseSTRUCTURE(xmlNodePtr cur);
00086 void parseVOLUME(xmlNodePtr cur);
00087 void parsePHYSVOL(xmlNodePtr cur, G4String volume_name);
00088 void parseFIELDS(xmlNodePtr cur);
00089
00090 BDSMagField* GetField();
00091 G4UniformMagField* GetUniformField();
00092 G4bool GetFieldIsUniform();
00093
00094 G4RotationMatrix* RotateComponent(G4ThreeVector rotvalues);
00095
00096 void Construct(G4LogicalVolume *marker);
00097 std::vector<G4LogicalVolume*> SensitiveComponents;
00098
00099 std::vector<G4LogicalVolume*> VOL_LIST;
00100 G4String parseStrChar(xmlChar* value);
00101 G4double parseDblChar(xmlChar* value);
00102 G4bool parseBoolChar(xmlChar* value);
00103
00104 G4bool stripwhitespace(G4String& str);
00105
00106
00107 G4bool EvaluateExpression(const char*, G4double& result);
00108 G4bool EvaluateTerm(const char* term, G4int termLength, G4double& result);
00109 G4bool VerifyExpression(const char*);
00110 G4bool VerifyNumber(const char*);
00111 G4bool StrToFloat(const char* str, G4int start, G4int end, G4double& f);
00112
00113 private:
00115 BDSGeometryLCDD& operator=(const BDSGeometryLCDD&);
00116 BDSGeometryLCDD(BDSGeometryLCDD&);
00117 #ifndef NOUSERLIMITS
00118 G4UserLimits* itsUserLimits;
00119 #endif
00120 G4bool itsFieldIsUniform;
00121 G4String itsFieldVolName;
00122
00123 G4VisAttributes* GetVisByName(G4String name);
00124 G4VSolid* GetSolidByName(G4String name);
00125 G4LogicalVolume* GetLogVolByName(G4String name);
00126 G4ThreeVector GetPosition(G4String name);
00127 G4ThreeVector GetPosition(xmlNodePtr cur, G4double lunit=0.0);
00128 G4RotationMatrix* GetRotation(G4String name);
00129 G4RotationMatrix* GetRotation(xmlNodePtr cur, G4double aunit=0.0);
00130
00131
00132 G4String itsWorldRef;
00133
00134
00135
00136 void BuildBox(xmlNodePtr cur);
00137 void BuildTrd(xmlNodePtr cur);
00138 void BuildTube(xmlNodePtr cur);
00139 void BuildPolycone(xmlNodePtr cur);
00140 void BuildPolyhedra(xmlNodePtr cur);
00141 void BuildSubtraction(xmlNodePtr cur);
00142 void BuildTessellated(xmlNodePtr cur);
00143
00144 G4String itsLCDDfile;
00145 G4LogicalVolume* itsMarkerVol;
00146 std::vector <struct CONST_REF> CONST_LIST;
00147 std::vector <struct POS_REF> POS_LIST;
00148 std::vector <struct ROT_REF> ROT_LIST;
00149 std::vector <struct VIS_REF> VIS_LIST;
00150 std::vector <G4VSolid*> SOLID_LIST;
00151 std::vector <G4LogicalVolume*> LOGVOL_LIST;
00152
00153 G4double visRed, visGreen, visBlue;
00154
00155
00156 BDSMagField* itsMagField;
00157 G4UniformMagField* itsUniformMagField;
00158
00159 protected:
00160 };
00161
00162 inline G4ThreeVector BDSGeometryLCDD::GetPosition(xmlNodePtr cur, G4double lunit)
00163 {
00164 G4String name, type;
00165 G4double unit;
00166 G4ThreeVector pos;
00167
00168 name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00169 unit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"unit"));
00170 type = parseStrChar(xmlGetProp(cur,(const xmlChar*)"type"));
00171 pos = G4ThreeVector(parseDblChar(xmlGetProp(cur,(const xmlChar*)"x")),
00172 parseDblChar(xmlGetProp(cur,(const xmlChar*)"y")),
00173 parseDblChar(xmlGetProp(cur,(const xmlChar*)"z")));
00174 if(unit!=0.0 && lunit==0) pos*=unit;
00175 else if(lunit!=0.0) pos*=lunit;
00176 POS_REF apos;
00177 apos.name = name;
00178 apos.value = pos;
00179 POS_LIST.push_back(apos);
00180 #ifdef BDSDEBUG
00181 G4cout << "pos: " <<name << " " << pos << G4endl;
00182 #endif
00183 return pos;
00184 }
00185 inline G4ThreeVector BDSGeometryLCDD::GetPosition(G4String name)
00186 {
00187 G4int ID = -1;
00188 G4int i;
00189 for(i=0; i<(G4int)POS_LIST.size();i++)
00190 {
00191 if(POS_LIST[i].name==name)
00192 {
00193 ID=i;
00194 break;
00195 }
00196 }
00197 if(ID==-1)
00198 {
00199 G4cout << "Couldn't find position: " << name<<G4endl;
00200 G4Exception("Quitting in BDSGeometryLCDD", "-1", FatalException, "");
00201 }
00202 #ifdef BDSDEBUG
00203 G4cout << "pos: " <<name << " " << POS_LIST[ID].value << G4endl;
00204 #endif
00205 return POS_LIST[ID].value;
00206 }
00207 inline G4RotationMatrix* BDSGeometryLCDD::GetRotation(xmlNodePtr cur, G4double aunit)
00208 {
00209 G4String name, type;
00210 G4double unit;
00211 G4ThreeVector rotvect;
00212
00213 name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00214 unit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"unit"));
00215 type = parseStrChar(xmlGetProp(cur,(const xmlChar*)"type"));
00216 rotvect = G4ThreeVector(parseDblChar(xmlGetProp(cur,(const xmlChar*)"x")),
00217 parseDblChar(xmlGetProp(cur,(const xmlChar*)"y")),
00218 parseDblChar(xmlGetProp(cur,(const xmlChar*)"z")));
00219 if(unit!=0.0 && aunit==0) rotvect*=unit;
00220 else if(aunit!=0.0) rotvect*=aunit;
00221 ROT_REF arot;
00222 arot.name = name;
00223 arot.value = rotvect;
00224 ROT_LIST.push_back(arot);
00225 #ifdef BDSDEBUG
00226 G4cout << "rot: " << name << " "<<rotvect << G4endl;
00227 #endif
00228 return RotateComponent(rotvect);
00229 }
00230 inline G4RotationMatrix* BDSGeometryLCDD::GetRotation(G4String name)
00231 {
00232 G4int ID = -1;
00233 G4int i;
00234 for(i=0; i<(G4int)ROT_LIST.size();i++)
00235 {
00236 if(ROT_LIST[i].name==name)
00237 {
00238 ID=i;
00239 break;
00240 }
00241 }
00242 if(ID==-1)
00243 {
00244 G4cout << "Couldn't find rotation: " << name<<G4endl;
00245 G4Exception("Quitting in BDSGeometryLCDD", "-1", FatalException, "");
00246 }
00247 #ifdef BDSDEBUG
00248 G4cout << "rot: " << name << " "<<ROT_LIST[ID].value << G4endl;
00249 #endif
00250 return RotateComponent(ROT_LIST[ID].value);
00251 }
00252 inline G4VisAttributes* BDSGeometryLCDD::GetVisByName(G4String name)
00253 {
00254 G4int ID = -1;
00255 G4int i;
00256 for(i=0; i<(G4int)VIS_LIST.size(); i++)
00257 {
00258 if(VIS_LIST[i].name==name)
00259 {
00260 ID=i;
00261 break;
00262 }
00263 }
00264 if(ID==-1)
00265 {
00266 G4cout << "Couldn't find visref: " << name<<G4endl;
00267 G4cout << "Using default Vis settings" << G4endl;
00268 return new G4VisAttributes(G4Colour(1.0,1.0,1.0));
00269 }
00270
00271 return VIS_LIST[ID].value;
00272 }
00273 inline G4VSolid* BDSGeometryLCDD::GetSolidByName(G4String name)
00274 {
00275 G4int ID = -1;
00276 G4int i;
00277 for(i=0; i<(G4int)SOLID_LIST.size(); i++)
00278 {
00279 if(SOLID_LIST[i]->GetName()==name)
00280 {
00281 ID=i;
00282 break;
00283 }
00284 }
00285 if(ID==-1)
00286 {
00287 G4cout << "Couldn't find solid: " << name<<G4endl;
00288 G4Exception("Quitting in BDSGeometryLCDD", "-1", FatalException, "");
00289 }
00290 return SOLID_LIST[ID];
00291 }
00292
00293 inline G4LogicalVolume* BDSGeometryLCDD::GetLogVolByName(G4String name)
00294 {
00295 G4int ID = -1;
00296 G4int i;
00297 for(i=0; i<(G4int)LOGVOL_LIST.size(); i++)
00298 {
00299 if(LOGVOL_LIST[i]->GetName()==name)
00300 {
00301 ID=i;
00302 break;
00303 }
00304 }
00305 if(ID==-1)
00306 {
00307 G4cout << "Couldn't find logical volume: " << name<<G4endl;
00308 G4Exception("Quitting in BDSGeometryLCDD", "-1", FatalException, "");
00309 }
00310 return LOGVOL_LIST[ID];
00311 }
00312
00313 inline G4String BDSGeometryLCDD::parseStrChar(xmlChar* value)
00314 {
00315 if(value==NULL) return "";
00316 G4String val = G4String((char*)value);
00317 #ifdef BDSDEBUG
00318 G4cout << "BDSGeometryLCDD:parseStrChar> value = " << value << G4endl;
00319 G4cout << "strVAL: "<< val << G4endl;
00320 #endif
00321 return val;
00322 }
00323
00324 inline G4bool BDSGeometryLCDD::parseBoolChar(xmlChar* value)
00325 {
00326 if(value==NULL) return false;
00327 #ifdef BDSDEBUG
00328 G4cout << "BDSGeometryLCDD:parseBoolChar> value = " << value << G4endl;
00329 #endif
00330 G4String val = G4String((char*)value);
00331
00332 if(val=="true") return true;
00333 if(val=="false") return false;
00334
00335 return false;
00336 }
00337
00338 inline G4double BDSGeometryLCDD::parseDblChar(xmlChar* value)
00339 {
00340 if(value==NULL) return 0.0;
00341 G4String val = G4String((char*)value);
00342 stripwhitespace(val);
00343 #ifdef BDSDEBUG
00344 G4cout << "BDSGeometryLCDD:parseDblChar> value = " << value << G4endl;
00345 G4cout << "dblVAL: "<< val << G4endl;
00346 #endif
00347
00348 for(unsigned int i=0; i<CONST_LIST.size(); i++)
00349 {
00350 if(val.contains(CONST_LIST[i].name))
00351 {
00352
00353
00354 G4int endpos = val.index(CONST_LIST[i].name)+(CONST_LIST[i].name).length();
00355 G4int startpos = val.index(CONST_LIST[i].name);
00356 G4bool replaceStr = false;
00357 if(val==CONST_LIST[i].name) replaceStr = true;
00358
00359
00360 else if((val.data()[endpos] == '+' ||
00361 val.data()[endpos] == '-' ||
00362 val.data()[endpos] == '*' ||
00363 val.data()[endpos] == '/' ||
00364 endpos>=(int)val.length()) &&
00365 (val.data()[startpos-1] == '+' ||
00366 val.data()[startpos-1] == '-' ||
00367 val.data()[startpos-1] == '*' ||
00368 val.data()[startpos-1] == '/' ||
00369 startpos-1<=0))
00370 replaceStr = true;
00371
00372
00373
00374 if(replaceStr)
00375 {
00376 char constval[40];
00377 sprintf(constval,"%f",CONST_LIST[i].value);
00378 val.replace(val.index((CONST_LIST[i].name)), (CONST_LIST[i].name).length(), constval);
00379 #ifdef BDSDEBUG
00380 G4cout << "BDSGeometryLCDD::ParseDbl Replacing " << CONST_LIST[i].name << " with " << constval << G4endl;
00381 #endif
00382 i=0;
00383 }
00384 }
00385 }
00386 G4double dbl_val = 0.0;
00387
00388 if(VerifyExpression(val)) EvaluateExpression(val.data(),dbl_val);
00389 else
00390 {
00391 #ifdef BDSDEBUG
00392 G4cout << "BDSGeometryLCDD::ParseDbl Unable to evaluate expression: " << value << G4endl;
00393 #endif
00394 G4Exception("Check spellings and that constants are declared properly", "-1", FatalException, "");
00395 }
00396
00397
00398 #ifdef BDSDEBUG
00399 G4cout << "BDSGeometryLCDD::ParseDbl returning value: " << dbl_val << G4endl;
00400 #endif
00401 return dbl_val;
00402 }
00403
00404 inline G4bool BDSGeometryLCDD::EvaluateExpression(const char* expr, G4double& result)
00405 {
00406
00407 G4int length = strlen(expr);
00408 G4int end = length-1;
00409 double term;
00410 result = 0.0;
00411 G4int i;
00412 for(i = length-1; i>=0; i--)
00413 {
00414 if(expr[i]=='+')
00415 {
00416 if(!EvaluateTerm(expr + i + 1, end-i, term))
00417 return false;
00418 result += term;
00419 end = i-1;
00420 }
00421 else if (expr[i] == '-')
00422 {
00423 if(!EvaluateTerm(expr + i + 1, end-i, term))
00424 return false;
00425 result -= term;
00426 end = i-1;
00427 }
00428 }
00429
00430 if (expr[0] !='+' && expr[0]!='-')
00431 {
00432 if(!EvaluateTerm(expr, end+1, term))
00433 return false;
00434 result += term;
00435 end = i-1;
00436 }
00437
00438 return true;
00439
00440 }
00441
00442 inline G4bool BDSGeometryLCDD::EvaluateTerm(const char* term, G4int termLength, G4double& result)
00443 {
00444 G4int end = termLength-1;
00445 result = 1.0;
00446 G4double number;
00447 G4int i;
00448 for (i = end ; i>=0; i--)
00449 {
00450 if(term[i] == '*')
00451 {
00452 if(!StrToFloat(term+i+1, 0, end-i, number))
00453 return false;
00454 result *= number;
00455 end = i-1;
00456 }
00457 else if(term[i] == '/')
00458 {
00459 if(!StrToFloat(term+i+1, 0, end-i, number))
00460 return false;
00461 result /= number;
00462 end = i-1;
00463 }
00464 }
00465 if (term[0] != '*' && term[0] != '/')
00466 {
00467 if(!StrToFloat(term, 0, end+1, number))
00468 return false;
00469 result *= number;
00470 }
00471 return true;
00472 }
00473
00474 inline G4bool BDSGeometryLCDD::VerifyExpression(const char* expr)
00475 {
00476 G4int length = strlen(expr);
00477 if(length==0) return false;
00478 G4int i;
00479 for (i=0; i<length; i++)
00480 {
00481 if(expr[i] >='0' && expr[i] <= '9')
00482 continue;
00483 else
00484 if (expr[i] == '+' || expr[i] =='-' || expr[i] =='*' ||
00485 expr[i] == '/' || expr[i] =='.' || expr[i] =='e' ||
00486 expr[i] == 'E' || expr[i] =='^')
00487 continue;
00488 else return false;
00489 }
00490 return true;
00491 }
00492
00493 inline G4bool BDSGeometryLCDD::VerifyNumber(const char* expr)
00494 {
00495 G4int length = strlen(expr);
00496 if(length==0) return false;
00497 G4int i;
00498 for (i=0; i<length; i++)
00499 {
00500 if(expr[i] >='0' && expr[i] <= '9')
00501 continue;
00502 else
00503 if (expr[i] =='.') continue;
00504 else return false;
00505 }
00506 return true;
00507 }
00508
00509 inline G4bool BDSGeometryLCDD::StrToFloat(const char* str, G4int start, G4int end, G4double& f)
00510 {
00511 if(!str) return false;
00512
00513 G4double factor=0.1;
00514 G4int i,j;
00515 for(i=start; i<end; i++)
00516 {
00517
00518 if(str[i]=='.' && (str[i+1]=='e' || str[i]=='E' || str[i] =='^'))
00519 {
00520 for(j= i+2; j< end; j++)
00521 if(str[j] <'0' || str[j] >'9') return false;
00522 break;
00523 }
00524 else if(str[i]=='.')
00525 {
00526 for(j= i+1; j< end; j++)
00527 if(str[j] <'0' || str[j] >'9') return false;
00528 break;
00529 }
00530 else if(str[i] =='^')
00531 {
00532 for(j= i+1; j< end; j++)
00533 {
00534 if(str[j] == '.') continue;
00535 if(str[j] <'0' || str[j] >'9') return false;
00536 }
00537 break;
00538 }
00539 else if(str[i]=='e' || str[i]=='E')
00540 {
00541 for(j= i+1; j< end; j++)
00542 if(str[j] <'0' || str[j] >'9') return false;
00543 break;
00544 }
00545 else if(str[i] <'0' || str[i]>'9') return false;
00546 factor *=10;
00547 }
00548
00549 f=0.0;
00550 for(i=start; i<end; i++)
00551 {
00552 if(str[i]=='.') continue;
00553
00554 else if(str[i]=='e' || str[i]=='E')
00555 {
00556 G4double f1 = 0.0;
00557 G4double f2 = 0.0;
00558 StrToFloat(str,0,i,f1);
00559 StrToFloat(str,i+1,end,f2);
00560 f = f1*pow(10,f2);
00561 }
00562 else if(str[i]=='^')
00563 {
00564 G4double f1 = 0.0;
00565 G4double f2 = 0.0;
00566 StrToFloat(str,0,i,f1);
00567 StrToFloat(str,i+1,end,f2);
00568 f = pow(f1,f2);
00569 }
00570
00571 else
00572 {
00573 f+= (G4double)(str[i] - '0')*factor;
00574 factor *= 0.1;
00575 }
00576 }
00577 return true;
00578
00579 }
00580
00581 inline G4bool BDSGeometryLCDD::stripwhitespace(G4String& str)
00582 {
00583
00584 if(str.length()==0) return false;
00585
00586 G4String newstr;
00587
00588 str_size i;
00589 for(i=0;i<str.length();i++)
00590 {
00591 if(str[i] != ' ')
00592 newstr+=str[i];
00593 }
00594
00595 str = newstr;
00596 return true;
00597 }
00598
00599 inline void BDSGeometryLCDD::BuildBox(xmlNodePtr cur)
00600 {
00601 G4String name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00602 G4double x = parseDblChar(xmlGetProp(cur,(const xmlChar*)"x"));
00603 G4double y = parseDblChar(xmlGetProp(cur,(const xmlChar*)"y"));
00604 G4double z = parseDblChar(xmlGetProp(cur,(const xmlChar*)"z"));
00605
00606 G4double lunit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"lunit"));
00607 G4double aunit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"aunit"));
00608
00609 if(aunit!=0) {}
00610 if(lunit!=0)
00611 {
00612 x*=lunit;
00613 y*=lunit;
00614 z*=lunit;
00615 }
00616
00617 SOLID_LIST.push_back(new G4Box(name,
00618 x/2.0,
00619 y/2.0,
00620 z/2.0)
00621 );
00622 }
00623
00624 inline void BDSGeometryLCDD::BuildTrd(xmlNodePtr cur)
00625 {
00626 G4String name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00627 G4double x1 = parseDblChar(xmlGetProp(cur,(const xmlChar*)"x1"));
00628 G4double y1 = parseDblChar(xmlGetProp(cur,(const xmlChar*)"y1"));
00629 G4double x2 = parseDblChar(xmlGetProp(cur,(const xmlChar*)"x2"));
00630 G4double y2 = parseDblChar(xmlGetProp(cur,(const xmlChar*)"y2"));
00631 G4double z = parseDblChar(xmlGetProp(cur,(const xmlChar*)"z"));
00632
00633 G4double lunit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"lunit"));
00634 G4double aunit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"launit"));
00635
00636 if(aunit!=0) {}
00637 if(lunit!=0)
00638 {
00639 x1*=lunit;
00640 x2*=lunit;
00641 y1*=lunit;
00642 y2*=lunit;
00643 z*=lunit;
00644 }
00645
00646 SOLID_LIST.push_back(new G4Trd(name,
00647 x1/2.0,
00648 x2/2.0,
00649 y1/2.0,
00650 y2/2.0,
00651 z/2.0)
00652 );
00653 }
00654
00655 inline void BDSGeometryLCDD::BuildTube(xmlNodePtr cur)
00656 {
00657 G4String name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00658 G4double rmin = parseDblChar(xmlGetProp(cur,(const xmlChar*)"rmin"));
00659 G4double rmax = parseDblChar(xmlGetProp(cur,(const xmlChar*)"rmax"));
00660 G4double length = parseDblChar(xmlGetProp(cur,(const xmlChar*)"z"));
00661 G4double dphi = parseDblChar(xmlGetProp(cur,(const xmlChar*)"deltaphi"));
00662
00663 G4double lunit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"lunit"));
00664 G4double aunit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"launit"));
00665
00666 if(aunit!=0) dphi*=aunit;
00667 if(lunit!=0)
00668 {
00669 rmin*=lunit;
00670 rmax*=lunit;
00671 length*=lunit;
00672 }
00673
00674 SOLID_LIST.push_back(new G4Tubs(name,
00675 rmin,
00676 rmax,
00677 length/2.0,
00678 0.0,
00679 dphi)
00680 );
00681 }
00682 inline void BDSGeometryLCDD::BuildPolycone(xmlNodePtr cur)
00683 {
00684 xmlNodePtr tempcur = cur->xmlChildrenNode;
00685
00686 G4int numZPlanes = 0;
00687 while(tempcur!=NULL)
00688 {
00689 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"zplane")))
00690 numZPlanes++;
00691 tempcur = tempcur->next;
00692 }
00693
00694 G4double* zPlanes = NULL;
00695 G4double* rInner = NULL;
00696 G4double* rOuter = NULL;
00697 zPlanes = new G4double[numZPlanes];
00698 rInner = new G4double[numZPlanes];
00699 rOuter = new G4double[numZPlanes];
00700
00701 tempcur = cur->xmlChildrenNode;
00702 G4int i=0;
00703 while(tempcur!=NULL)
00704 {
00705 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"zplane")))
00706 {
00707 zPlanes[i] = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"z"));
00708 rInner[i] = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"rmin"));
00709 rOuter[i] = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"rmax"));
00710 i++;
00711 }
00712 tempcur = tempcur->next;
00713 }
00714
00715 SOLID_LIST.push_back(new G4Polycone((parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"))),
00716 parseDblChar(xmlGetProp(cur,(const xmlChar*)"startphi")),
00717 parseDblChar(xmlGetProp(cur,(const xmlChar*)"deltaphi")),
00718 numZPlanes,
00719 zPlanes,
00720 rInner,
00721 rOuter)
00722 );
00723
00724 delete [] rInner;
00725 rInner = NULL;
00726 delete [] rOuter;
00727 rOuter = NULL;
00728 delete [] zPlanes;
00729 zPlanes = NULL;
00730 }
00731
00732 inline void BDSGeometryLCDD::BuildPolyhedra(xmlNodePtr cur)
00733 {
00734 xmlNodePtr tempcur = cur->xmlChildrenNode;
00735
00736 G4int numZPlanes = 0;
00737 while(tempcur!=NULL)
00738 {
00739 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"zplane")))
00740 numZPlanes++;
00741 tempcur = tempcur->next;
00742 }
00743
00744 G4double* zPlanes = NULL;
00745 G4double* rInner = NULL;
00746 G4double* rOuter = NULL;
00747 zPlanes = new G4double[numZPlanes];
00748 rInner = new G4double[numZPlanes];
00749 rOuter = new G4double[numZPlanes];
00750
00751 tempcur = cur->xmlChildrenNode;
00752 G4int i=0;
00753 while(tempcur!=NULL)
00754 {
00755 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"zplane")))
00756 {
00757 zPlanes[i] = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"z"));
00758 rInner[i] = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"rmin"));
00759 rOuter[i] = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"rmax"));
00760 i++;
00761 }
00762 tempcur = tempcur->next;
00763 }
00764
00765 SOLID_LIST.push_back(new G4Polyhedra((parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"))),
00766 parseDblChar(xmlGetProp(cur,(const xmlChar*)"startphi")),
00767 parseDblChar(xmlGetProp(cur,(const xmlChar*)"deltaphi")),
00768 (G4int)parseDblChar(xmlGetProp(cur,(const xmlChar*)"numsides")),
00769 numZPlanes,
00770 zPlanes,
00771 rInner,
00772 rOuter)
00773 );
00774
00775 delete [] rInner;
00776 rInner = NULL;
00777 delete [] rOuter;
00778 rOuter = NULL;
00779 delete [] zPlanes;
00780 zPlanes = NULL;
00781 }
00782
00783
00784
00785
00786 inline void BDSGeometryLCDD::BuildSubtraction(xmlNodePtr cur)
00787 {
00788
00789 G4String name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00790 G4double lunit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"lunit"));
00791 G4double aunit = parseDblChar(xmlGetProp(cur,(const xmlChar*)"launit"));
00792 G4String firstname, secondname;
00793
00794 G4ThreeVector PlacementPoint = G4ThreeVector(0.,0.,0.);
00795
00796 G4RotationMatrix* componentRotation = NULL;
00797
00798 G4ThreeVector FirstPlacementPoint = G4ThreeVector(0.,0.,0.);
00799
00800 xmlNodePtr tempcur = cur->xmlChildrenNode;
00801
00802 while(tempcur!=NULL)
00803 {
00804 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"first")))
00805 firstname = parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref"));
00806
00807 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"second")))
00808 secondname = parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref"));
00809
00810 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"position")))
00811 PlacementPoint = GetPosition(tempcur,lunit);
00812
00813 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"positionref")))
00814 PlacementPoint = GetPosition(parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref")));
00815
00816 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"rotation")))
00817 componentRotation = GetRotation(tempcur,aunit);
00818
00819 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"rotationref")))
00820 componentRotation = GetRotation(parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref")));
00821
00822 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"firstposition")))
00823 G4cout << "BDSGeometryLCDD::BuildSubtraction: " << name<< " firstposition not supported" << G4endl;
00824
00825 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"firstpositionref")))
00826 G4cout << "BDSGeometryLCDD::BuildSubtraction: " << name<< " firstpositionref not supported" << G4endl;
00827
00828 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"firstrotation")))
00829 G4cout << "BDSGeometryLCDD::BuildSubtraction: " << name<< " firstrotation not supported" << G4endl;
00830
00831 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"firstrotationref")))
00832 G4cout << "BDSGeometryLCDD::BuildSubtraction: " << name<< " firstrotationref not supported" << G4endl;
00833
00834 tempcur = tempcur->next;
00835 }
00836
00837
00838 if(componentRotation==0 && PlacementPoint.x()==0 && PlacementPoint.y()==0 && PlacementPoint.z()==0)
00839 {
00840 SOLID_LIST.push_back(new G4SubtractionSolid(name,
00841 GetSolidByName(firstname),
00842 GetSolidByName(secondname))
00843 );
00844 }
00845 else
00846 {
00847
00848 G4Transform3D transform(*componentRotation,PlacementPoint);
00849 SOLID_LIST.push_back(new G4SubtractionSolid(name,
00850 GetSolidByName(firstname),
00851 GetSolidByName(secondname),
00852 transform)
00853 );
00854
00855 }
00856
00857 }
00858
00859 inline void BDSGeometryLCDD::BuildTessellated(xmlNodePtr cur){
00860 G4TessellatedSolid* tessellatedSolid = new G4TessellatedSolid(parseStrChar(xmlGetProp(cur,(const xmlChar*)"name")));
00861
00862 xmlNodePtr tempcur = cur->xmlChildrenNode;
00863
00864 G4int numTriFacets = 0;
00865 G4int numQuadFacets = 0;
00866 G4String sType;
00867 G4FacetVertexType iType=ABSOLUTE;
00868 G4ThreeVector vertex[4];
00869
00870 while(tempcur!=NULL) {
00871
00872 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"triangular")) || (!xmlStrcmp(tempcur->name, (const xmlChar *)"quadrangular"))){
00873 sType = parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"type"));
00874 if(!sType.compare("ABSOLUTE")){
00875 iType=ABSOLUTE;
00876 } else if (!sType.compare("RELATIVE")){
00877 iType=RELATIVE;
00878 } else {
00879 G4cerr << "BDSGeometryLCDD::BuildTessellateSolid -> error, unknown type " << sType << ". Valid options are ABSOLUTE or RELATIVE." << G4endl;
00880 }
00881 vertex[0]=GetPosition(parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"vertex1")));
00882 vertex[1]=GetPosition(parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"vertex2")));
00883 vertex[2]=GetPosition(parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"vertex3")));
00884
00885 if(!xmlStrcmp(tempcur->name, (const xmlChar *)"triangular")){
00886 #ifdef BDSDEBUG
00887 G4cout << "BDSGeometryLCDD adding triangular facet, vertices: "<< G4endl;
00888 G4cout << "vertex1: " << vertex[0].x() << " " << vertex[0].y() << " " << vertex[0].z() << G4endl;
00889 G4cout << "vertex2: " << vertex[1].x() << " " << vertex[1].y() << " " << vertex[1].z() << G4endl;
00890 G4cout << "vertex3: " << vertex[2].x() << " " << vertex[2].y() << " " << vertex[2].z() << G4endl;
00891 #endif
00892
00893 tessellatedSolid->AddFacet((G4VFacet*)(new G4TriangularFacet(vertex[0], vertex[1], vertex[2], iType)));
00894 numTriFacets++;
00895 } else {
00896 vertex[3]=GetPosition(parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"vertex4")));
00897 #ifdef BDSDEBUG
00898 G4cout << "BDSGeometryLCDD adding quadrangular facet, vertices: "<< G4endl;
00899 G4cout << "vertex1: " << vertex[0].x() << " " << vertex[0].y() << " " << vertex[0].z() << G4endl;
00900 G4cout << "vertex2: " << vertex[1].x() << " " << vertex[1].y() << " " << vertex[1].z() << G4endl;
00901 G4cout << "vertex3: " << vertex[2].x() << " " << vertex[2].y() << " " << vertex[2].z() << G4endl;
00902 G4cout << "vertex4: " << vertex[3].x() << " " << vertex[3].y() << " " << vertex[3].z() << G4endl;
00903 #endif
00904 tessellatedSolid->AddFacet((G4VFacet*)(new G4QuadrangularFacet(vertex[0], vertex[1], vertex[2], vertex[3], iType)));
00905 numQuadFacets++;
00906 }
00907 }
00908 tempcur = tempcur->next;
00909 }
00910 G4cout << "BDSGeometryLCDD closing the solid... "<< G4endl;
00911 tessellatedSolid->SetSolidClosed(true);
00912
00913 SOLID_LIST.push_back(tessellatedSolid);
00914 }
00915
00916 #endif
00917
00918 #endif //from use_xml