CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/DetectorDescription/Parser/src/DDLBooleanSolid.cc

Go to the documentation of this file.
00001 /***************************************************************************
00002                           DDLBooleanSolid.cc  -  description
00003                              -------------------
00004     begin                : Wed Dec 12, 2001
00005     email                : case@ucdhep.ucdavis.edu
00006  ***************************************************************************/
00007 
00008 /***************************************************************************
00009  *                                                                         *
00010  *           DDDParser sub-component of DDD                                *
00011  *                                                                         *
00012  ***************************************************************************/
00013 
00014 #include "DetectorDescription/Parser/src/DDLBooleanSolid.h"
00015 #include "DetectorDescription/Parser/src/DDXMLElement.h"
00016 
00017 #include "DetectorDescription/Core/interface/DDSolid.h"
00018 #include "DetectorDescription/Core/interface/DDName.h"
00019 #include "DetectorDescription/Base/interface/DDdebug.h"
00020 #include "DetectorDescription/Base/interface/DDException.h"
00021 
00022 #include "DetectorDescription/ExprAlgo/interface/ExprEvalSingleton.h"
00023 
00024 DDLBooleanSolid::DDLBooleanSolid( DDLElementRegistry* myreg )
00025   : DDLSolid( myreg )
00026 {}
00027 
00028 DDLBooleanSolid::~DDLBooleanSolid( void )
00029 {}
00030 
00031 // Clear out rSolids.
00032 void
00033 DDLBooleanSolid::preProcessElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
00034 {
00035   myRegistry_->getElement( "rSolid" )->clear();
00036 }
00037 
00038 // To process a BooleanSolid we should have in the meantime
00039 // hit two rSolid calls and possibly one rRotation and one Translation.
00040 // So, retrieve them and make the call to DDCore.
00041 void
00042 DDLBooleanSolid::processElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
00043 {
00044   DCOUT_V( 'P', "DDLBooleanSolid::processElement started" );
00045 
00046   // new DDLBoolean will handle:
00047   // <UnionSolid name="bs" firstSolid="blah" secondSolid="argh"> <Translation...> <rRotation .../> </UnionSolid
00048   // AND <UnionSolid> <rSolid...> <rSolid...> <Translation...> <rRotation...> </UnionSolid>
00049 
00050   DDXMLElement* myrSolid = myRegistry_->getElement( "rSolid" ); // get rSolid children
00051   DDXMLElement* myTranslation = myRegistry_->getElement( "Translation" ); // get Translation child
00052   DDXMLElement* myrRotation  = myRegistry_->getElement( "rRotation" ); // get rRotation child
00053 
00054   ExprEvalInterface & ev = ExprEvalSingleton::instance();
00055   DDXMLAttribute atts = getAttributeSet();
00056 
00057   DDName ddn1, ddn2;
00058   double x=0.0, y=0.0, z=0.0;
00059   DDRotation ddrot;
00060 
00061   // Basically check if there are rSolids or Translation or rRotation then we have
00062   // should NOT have any of the attributes shown above.
00063   if( myrSolid->size() == 0 ) 
00064   {
00065     // do the solids using the attributes only.
00066     if ( atts.find("firstSolid") != atts.end() && atts.find("secondSolid") != atts.end() ) {
00067       ddn1 = getDDName(nmspace, "firstSolid");
00068       ddn2 = getDDName(nmspace, "secondSolid");
00069     } else {
00070       std::string s ("DDLBooleanSolid did not find any solids with which to form a boolean solid.");
00071       s += dumpBooleanSolid(name, nmspace);
00072       throwError( s );
00073     }
00074   }
00075   else if (myrSolid->size() == 2)
00076   {
00077     ddn1 = myrSolid->getDDName(nmspace, "name", 0);
00078     ddn2 = myrSolid->getDDName(nmspace, "name", 1);
00079   } else {
00080     std::string s("DDLBooleanSolid did not find any solids with which to form a boolean solid.");
00081     s += dumpBooleanSolid(name, nmspace);
00082     throwError( s );
00083   }
00084 
00085   if (myTranslation->size() > 0)
00086   {
00087     atts.clear();
00088     atts = myTranslation->getAttributeSet();
00089     x = ev.eval(nmspace, atts.find("x")->second);
00090     y = ev.eval(nmspace, atts.find("y")->second);
00091     z = ev.eval(nmspace, atts.find("z")->second);
00092   }
00093 
00094   if (myrRotation->size() > 0) 
00095   {
00096     ddrot = DDRotation( myrRotation->getDDName (nmspace) );
00097   }
00098 
00099   DDSolid theSolid;
00100 
00101   if (name == "UnionSolid") {
00102     theSolid = DDSolidFactory::unionSolid (getDDName(nmspace)
00103                                            , DDSolid(ddn1)
00104                                            , DDSolid(ddn2)
00105                                            , DDTranslation(x, y, z)
00106                                            , ddrot
00107       );               
00108   }
00109   else if (name == "SubtractionSolid") {
00110     theSolid = DDSolidFactory::subtraction (getDDName(nmspace)
00111                                             , DDSolid(ddn1)
00112                                             , DDSolid(ddn2)
00113                                             , DDTranslation(x, y, z)
00114                                             , ddrot
00115       );               
00116   }
00117   else if (name == "IntersectionSolid") {
00118     theSolid = DDSolidFactory::intersection (getDDName(nmspace)
00119                                              , DDSolid(ddn1)
00120                                              , DDSolid(ddn2)
00121                                              , DDTranslation(x, y, z)
00122                                              , ddrot
00123       );               
00124   }
00125   else {
00126     throw DDException("DDLBooleanSolid was asked to do something other than Union-, Subtraction- or IntersectionSolid?");
00127   }
00128   
00129   DDLSolid::setReference(nmspace, cpv);
00130 
00131   DCOUT_V('p', theSolid);
00132 
00133   // clear all "children" and attributes
00134   myTranslation->clear();
00135   myrRotation->clear();
00136   myrSolid->clear();
00137   clear();
00138   DCOUT_V('P', "DDLBooleanSolid::processElement completed");
00139 
00140 }
00141 
00142 // This only happens on error, so I don't care how "slow" it is :-)
00143 std::string
00144 DDLBooleanSolid::dumpBooleanSolid( const std::string& name, const std::string& nmspace )
00145 {
00146   std::string s;
00147   DDXMLAttribute atts = getAttributeSet();
00148 
00149   s = std::string ("\n<") + name + " name=\"" + atts.find("name")->second + "\"";
00150 
00151   if (atts.find("firstSolid") != atts.end()) s+= " firstSolid=\"" + atts.find("firstSolid")->second + "\"";
00152   if (atts.find("secondSolid") != atts.end()) s+= " secondSolid=\"" + atts.find("secondSolid")->second + "\"";
00153   s +=  ">\n";
00154 
00155   DDXMLElement* myrSolid = myRegistry_->getElement("rSolid"); // get rSolid children
00156   DDXMLElement* myTranslation = myRegistry_->getElement("Translation"); // get Translation child
00157   DDXMLElement* myrRotation  = myRegistry_->getElement("rRotation"); // get rRotation child
00158   if (myrSolid->size() > 0)
00159   {
00160     for (size_t i = 0; i < myrSolid->size(); ++i)
00161     {
00162       atts = myrSolid->getAttributeSet(i);
00163       s+="<rSolid name=\"" + atts.find("name")->second + "\"/>\n";
00164     }
00165   }
00166 
00167   atts = myTranslation->getAttributeSet();
00168   s+= "<Translation";
00169   if (atts.find("x") != atts.end()) 
00170     s+=" x=\"" + atts.find("x")->second + "\"";
00171   if (atts.find("y") != atts.end()) 
00172     s+= " y=\"" + atts.find("y")->second + "\"";
00173   if (atts.find("z") != atts.end()) 
00174     s+= " z=\"" + atts.find("z")->second + "\"";
00175   s+="/>\n";
00176 
00177   atts = myrRotation->getAttributeSet();
00178   if (atts.find("name") != atts.end())
00179   {
00180     s+= "<rRotation name=\"" + atts.find("name")->second + "\"/>\n";
00181   }
00182   s+= "</" + name + ">\n\n";
00183   return s;
00184 }