Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:55:06

0001 #include "DetectorDescription/Parser/src/DDLBooleanSolid.h"
0002 #include "DetectorDescription/Core/interface/DDTranslation.h"
0003 #include "DetectorDescription/Core/interface/DDName.h"
0004 #include "DetectorDescription/Core/interface/DDSolid.h"
0005 #include "DetectorDescription/Core/interface/DDTransform.h"
0006 #include "DetectorDescription/Core/interface/ClhepEvaluator.h"
0007 #include "DetectorDescription/Parser/interface/DDLElementRegistry.h"
0008 #include "DetectorDescription/Parser/src/DDLSolid.h"
0009 #include "DetectorDescription/Parser/src/DDXMLElement.h"
0010 #include "FWCore/Utilities/interface/Exception.h"
0011 
0012 class DDCompactView;
0013 
0014 DDLBooleanSolid::DDLBooleanSolid(DDLElementRegistry* myreg) : DDLSolid(myreg) {}
0015 
0016 // Clear out rSolids.
0017 void DDLBooleanSolid::preProcessElement(const std::string& name, const std::string& nmspace, DDCompactView& cpv) {
0018   myRegistry_->getElement("rSolid")->clear();
0019 }
0020 
0021 // To process a BooleanSolid we should have in the meantime
0022 // hit two rSolid calls and possibly one rRotation and one Translation.
0023 // So, retrieve them and make the call to DDCore.
0024 void DDLBooleanSolid::processElement(const std::string& name, const std::string& nmspace, DDCompactView& cpv) {
0025   // new DDLBoolean will handle:
0026   // <UnionSolid name="bs" firstSolid="blah" secondSolid="argh"> <Translation...> <rRotation .../> </UnionSolid
0027   // AND <UnionSolid> <rSolid...> <rSolid...> <Translation...> <rRotation...> </UnionSolid>
0028 
0029   auto myrSolid = myRegistry_->getElement("rSolid");            // get rSolid children
0030   auto myTranslation = myRegistry_->getElement("Translation");  // get Translation child
0031   auto myrRotation = myRegistry_->getElement("rRotation");      // get rRotation child
0032 
0033   ClhepEvaluator& ev = myRegistry_->evaluator();
0034   DDXMLAttribute atts = getAttributeSet();
0035 
0036   DDName ddn1, ddn2;
0037   double x = 0.0, y = 0.0, z = 0.0;
0038   DDRotation ddrot;
0039 
0040   // Basically check if there are rSolids or Translation or rRotation then we have
0041   // should NOT have any of the attributes shown above.
0042   if (myrSolid->size() == 0) {
0043     // do the solids using the attributes only.
0044     if (atts.find("firstSolid") != atts.end() && atts.find("secondSolid") != atts.end()) {
0045       ddn1 = getDDName(nmspace, "firstSolid");
0046       ddn2 = getDDName(nmspace, "secondSolid");
0047     } else {
0048       std::string s("DDLBooleanSolid did not find any solids with which to form a boolean solid.");
0049       s += dumpBooleanSolid(name, nmspace);
0050       throwError(s);
0051     }
0052   } else if (myrSolid->size() == 2) {
0053     ddn1 = myrSolid->getDDName(nmspace, "name", 0);
0054     ddn2 = myrSolid->getDDName(nmspace, "name", 1);
0055   } else {
0056     std::string s("DDLBooleanSolid did not find any solids with which to form a boolean solid.");
0057     s += dumpBooleanSolid(name, nmspace);
0058     throwError(s);
0059   }
0060 
0061   if (myTranslation->size() > 0) {
0062     atts.clear();
0063     atts = myTranslation->getAttributeSet();
0064     x = ev.eval(nmspace, atts.find("x")->second);
0065     y = ev.eval(nmspace, atts.find("y")->second);
0066     z = ev.eval(nmspace, atts.find("z")->second);
0067   }
0068 
0069   if (myrRotation->size() > 0) {
0070     ddrot = DDRotation(myrRotation->getDDName(nmspace));
0071   }
0072 
0073   DDSolid theSolid;
0074 
0075   if (name == "UnionSolid") {
0076     theSolid =
0077         DDSolidFactory::unionSolid(getDDName(nmspace), DDSolid(ddn1), DDSolid(ddn2), DDTranslation(x, y, z), ddrot);
0078   } else if (name == "SubtractionSolid") {
0079     theSolid =
0080         DDSolidFactory::subtraction(getDDName(nmspace), DDSolid(ddn1), DDSolid(ddn2), DDTranslation(x, y, z), ddrot);
0081   } else if (name == "IntersectionSolid") {
0082     theSolid =
0083         DDSolidFactory::intersection(getDDName(nmspace), DDSolid(ddn1), DDSolid(ddn2), DDTranslation(x, y, z), ddrot);
0084   } else {
0085     throw cms::Exception("DDException")
0086         << "DDLBooleanSolid was asked to do something other than Union-, Subtraction- or IntersectionSolid?";
0087   }
0088 
0089   DDLSolid::setReference(nmspace, cpv);
0090 
0091   // clear all "children" and attributes
0092   myTranslation->clear();
0093   myrRotation->clear();
0094   myrSolid->clear();
0095   clear();
0096 }
0097 
0098 // This only happens on error, so I don't care how "slow" it is :-)
0099 std::string DDLBooleanSolid::dumpBooleanSolid(const std::string& name, const std::string& nmspace) {
0100   std::string s;
0101   DDXMLAttribute atts = getAttributeSet();
0102 
0103   s = std::string("\n<") + name + " name=\"" + atts.find("name")->second + "\"";
0104 
0105   if (atts.find("firstSolid") != atts.end())
0106     s += " firstSolid=\"" + atts.find("firstSolid")->second + "\"";
0107   if (atts.find("secondSolid") != atts.end())
0108     s += " secondSolid=\"" + atts.find("secondSolid")->second + "\"";
0109   s += ">\n";
0110 
0111   auto myrSolid = myRegistry_->getElement("rSolid");            // get rSolid children
0112   auto myTranslation = myRegistry_->getElement("Translation");  // get Translation child
0113   auto myrRotation = myRegistry_->getElement("rRotation");      // get rRotation child
0114   if (myrSolid->size() > 0) {
0115     for (size_t i = 0; i < myrSolid->size(); ++i) {
0116       atts = myrSolid->getAttributeSet(i);
0117       s += "<rSolid name=\"" + atts.find("name")->second + "\"/>\n";
0118     }
0119   }
0120 
0121   atts = myTranslation->getAttributeSet();
0122   s += "<Translation";
0123   if (atts.find("x") != atts.end())
0124     s += " x=\"" + atts.find("x")->second + "\"";
0125   if (atts.find("y") != atts.end())
0126     s += " y=\"" + atts.find("y")->second + "\"";
0127   if (atts.find("z") != atts.end())
0128     s += " z=\"" + atts.find("z")->second + "\"";
0129   s += "/>\n";
0130 
0131   atts = myrRotation->getAttributeSet();
0132   if (atts.find("name") != atts.end()) {
0133     s += "<rRotation name=\"" + atts.find("name")->second + "\"/>\n";
0134   }
0135   s += "</" + name + ">\n\n";
0136   return s;
0137 }