CMS 3D CMS Logo

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