CMS 3D CMS Logo

IgSoRectColHist.cc

Go to the documentation of this file.
00001 #include "Iguana/Inventor/interface/IgSoRectColHist.h"
00002 #include <Inventor/nodes/SoIndexedFaceSet.h>
00003 #include <Inventor/nodes/SoShapeHints.h>
00004 #include <Inventor/nodes/SoMaterial.h>
00005 #include <Inventor/nodes/SoIndexedLineSet.h>
00006 #include <Inventor/nodes/SoVertexProperty.h>
00007 // #include <Inventor/nodes/SoAnnotation.h>
00008 #include <Inventor/SbLinear.h>
00009 
00010 #include <math.h>
00011 #include <iostream>
00012 
00013 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00014 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00015 const unsigned IgSoRectColHist::IN = 0;
00016 const unsigned IgSoRectColHist::OUT = 1;
00017 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00018 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00019 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00020 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00021 
00022 SO_KIT_SOURCE (IgSoRectColHist);
00023 
00024 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00025 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00026 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00027 
00028 void
00029 IgSoRectColHist::initClass (void)
00030 { SO_KIT_INIT_CLASS (IgSoRectColHist, IgSoShapeKit, "IgSoShapeKit"); }
00031 
00032 //default constructor
00033 IgSoRectColHist::IgSoRectColHist ()
00034         : m_barrelDeltaEta (0.f),
00035           m_barrelMaxEta (0.f),
00036           m_endcapDeltaTheta (0.f),
00037           m_endcapMaxTheta (0.f),
00038           m_deltasSet (false)
00039 {
00040         SO_KIT_CONSTRUCTOR (IgSoRectColHist);
00041         
00042         // parameters of the constructor
00043         SO_KIT_ADD_FIELD (radiusZ,    (10.f));
00044         SO_KIT_ADD_FIELD (radiusR,    (5.f));
00045         SO_KIT_ADD_FIELD (offsetR,    (0.f));
00046         SO_KIT_ADD_FIELD (offsetZ,    (0.f));
00047         SO_KIT_ADD_FIELD (numR,       (10));
00048         SO_KIT_ADD_FIELD (numZ,       (10));
00049         SO_KIT_ADD_FIELD (energies,   (0.f));
00050         SO_KIT_ADD_FIELD (layer,      (0.f));
00051         SO_KIT_ADD_FIELD (center,     (SbVec3f (layer.getValue (), 0.f, 0.f)));
00052         SO_KIT_ADD_FIELD (faceColors, (SbColor (0.f, 0.f, 0.f)));
00053         SO_KIT_ADD_FIELD (lineColor,  (SbColor (0.f, 0.f, 0.f)));
00054         SO_KIT_ADD_FIELD (barrelMaxEta, (0.f));
00055         SO_KIT_ADD_FIELD (beamPipeTheta, (0.f));
00056         SO_KIT_ADD_FIELD (endcapMaxTheta, (0.f));
00057         
00058         SO_KIT_ADD_FIELD (logScale,    (FALSE));
00059         SO_KIT_ADD_FIELD (scaleFactor, (1.f));
00060         SO_KIT_ADD_FIELD (maxDist,     (0.f));
00061 
00062 //     SO_KIT_ADD_FIELD (showAnnotations,       (FALSE));
00063         
00064         SO_KIT_ADD_CATALOG_ENTRY (shapeHints, SoShapeHints, FALSE, separator,\x0, TRUE);
00065         SO_KIT_ADD_CATALOG_ENTRY (faceSet, SoIndexedFaceSet, FALSE, separator,\x0, TRUE);
00066 //      SO_KIT_ADD_CATALOG_ENTRY (inPosFaceSet, SoIndexedFaceSet, FALSE, separator,\x0, TRUE);
00067 //      SO_KIT_ADD_CATALOG_ENTRY (outPosFaceSet, SoIndexedFaceSet, FALSE, separator,\x0, TRUE);
00068 //      SO_KIT_ADD_CATALOG_ENTRY (inNegFaceSet, SoIndexedFaceSet, FALSE, separator,\x0, TRUE);
00069 //      SO_KIT_ADD_CATALOG_ENTRY (outNegFaceSet, SoIndexedFaceSet, FALSE, separator,\x0, TRUE);
00070         SO_KIT_ADD_CATALOG_ENTRY (lineSet, SoIndexedLineSet, FALSE, separator,\x0, TRUE);
00071 
00072     //LABELS
00073 //     SO_KIT_ADD_CATALOG_ENTRY (soAnnotation, SoAnnotation, FALSE, separator,\x0,TRUE);
00074         
00075         SO_KIT_INIT_INSTANCE ();
00076         setUpConnections (true, true);
00077 
00078         faceColors.set1Value (0, SbVec3f (1.f, 0.f, 0.f));
00079         faceColors.set1Value (1, SbVec3f (0.f, 1.f, 0.f));
00080         faceColors.set1Value (2, SbVec3f (0.f, 0.f, 1.f));
00081         faceColors.set1Value (3, SbVec3f (1.f, 1.f, 0.f));
00082 }
00083 
00084 std::vector<int>
00085 IgSoRectColHist::assignIndices (std::vector<std::vector<float> >& localEnergies, std::vector<int>& colorIndices) 
00086 {
00087         // we push the indices for each face which has to be drawn into the vector
00088         // and determine the color for each face. We also distinguish between EM
00089         // and hadronic energy
00090         std::vector<int> faceIndices;
00091         unsigned count = 0;
00092         for (unsigned i = 0; i < localEnergies[IN].size (); i++)
00093         {
00094                 if (localEnergies[IN][i] != 0.f)
00095                 {
00096                         faceIndices.push_back (count);
00097                         faceIndices.push_back (count + 1);
00098                         faceIndices.push_back (count + 2);
00099                         faceIndices.push_back (count + 3);
00100                         faceIndices.push_back (count);
00101                         faceIndices.push_back (SO_END_FACE_INDEX);
00102                         count += 4;
00103                         colorIndices.push_back ((localEnergies[IN][i] > 0.f) ? (0) : (1));
00104                 }
00105                 if (localEnergies[OUT][i] != 0.f)
00106                 {
00107                         faceIndices.push_back (count);
00108                         faceIndices.push_back (count + 1);
00109                         faceIndices.push_back (count + 2);
00110                         faceIndices.push_back (count + 3);
00111                         faceIndices.push_back (count);
00112                         faceIndices.push_back (SO_END_FACE_INDEX);
00113                         count += 4;
00114                         colorIndices.push_back ( (localEnergies[OUT][i] >= 0.f) ? (2) : (3));
00115                 }
00116         }
00117         return faceIndices;
00118 }
00119 
00120 IgSoRectColHist::n_placement 
00121 IgSoRectColHist::findBinPlacement (const unsigned binIndex) 
00122 {
00123         // This method tells you on which side the given bin(number) is located.
00124         // NOTE: This doesn't work with an odd number of bins, but since, as far
00125         // as I know, the detector is symmetrical, there cannot be an odd number
00126         // of bins. CCW. starting in the middle of the right endcap
00127         unsigned _numZ = numZ.getValue ();
00128         unsigned _numR = numR.getValue ();
00129         
00130         if (binIndex  < _numR/2) return RIGHT;
00131         else if (binIndex < _numR/2 + _numZ) return TOP;
00132         else if (binIndex < 3*_numR/2 + _numZ ) return LEFT;
00133         else if (binIndex < 3*_numR/2 + 2*_numZ ) return BOTTOM;
00134         else return RIGHT;
00135 }
00136 
00137 SbVec3f
00138 IgSoRectColHist::projectPoint (const float energy, const SbVec3f& point, const SbVec3f& center)
00139 {
00140         // This method returns a point which is projected the given amount of
00141         // energy in the direction of 'point-center' from 'point' onwards.
00142         // NOTE: the provided energy equals the length of the rectangle's edge(s) 
00143         // which point away from the central rectangle. The disadvantage of this 
00144         // method is that towers with equal energy dont look equally high. Another
00145         // way to implement the representation of the energy could be to make the 
00146         // energy equal to the height of the rectangle, but then the towers will
00147         // appear bigger since they have a larger area.
00148         
00149         const float y = point[1] - center[1];
00150         const float z = point[2] - center[2];
00151         const float radius = calcLocalRadius (point, center);
00152         const float angle  = atan2 (y, z); // returns a value in [-pi;pi]
00153         
00154         return convertCoordinates (radius + energy, convertAngle (angle), center);
00155 }
00156 
00157 // returns x (= layer), y and z coordinates given polar coordinates
00158 // angle supposed to be in rad
00159 SbVec3f
00160 IgSoRectColHist::convertCoordinates (const float radius, const float phi, const SbVec3f& center)
00161 {
00162         SbVec3f cartesianCoords;
00163         cartesianCoords[0] =  layer.getValue ();
00164         cartesianCoords[1] =  radius * sin (phi) + center[2];;
00165         cartesianCoords[2] =  radius * cos (phi) + center[1];
00166         return cartesianCoords;
00167 }
00168 
00169 int
00170 IgSoRectColHist::findMaxEnergyBin (std::vector<std::vector<float> >& energies)
00171 {
00172         // look for the bin with maximum summed energy and set the max energy
00173         m_maxEnergy         = 0.0f;
00174         int maxEnergyBin    = -1;
00175         float totalE        = 0.0f;
00176         const float numBins = energies[IN].size ();
00177         
00178         for (unsigned i = 0; i < numBins; i++)
00179         {
00180                 totalE =  energies[IN][i] + energies[OUT][i];
00181                 if (totalE > m_maxEnergy)
00182                 {
00183                         m_maxEnergy = totalE;
00184                         maxEnergyBin = i;
00185                 }
00186         }
00187         return maxEnergyBin;
00188 }
00189 
00190 void
00191 IgSoRectColHist::calcLogEnergies (std::vector<std::vector<float> >& logEnergies)
00192 {
00193         for (unsigned i = 0; i < logEnergies[IN].size (); i++)
00194         {
00195                 logEnergies[IN][i]  = log ((logEnergies[IN][i]  <= 0.0f) ? (1.0f) : (logEnergies[IN][i]));
00196                 logEnergies[OUT][i] = log ((logEnergies[OUT][i] <= 0.0f) ? (1.0f) : (logEnergies[OUT][i]));
00197         }
00198 }
00199 
00200 void
00201 IgSoRectColHist::scaleEnergies (std::vector<std::vector<float> >& energies)
00202 {
00203         const float _maxDist = maxDist.getValue ();
00204         float localScaleFactor = 1.0f;
00205         
00206         // maxDist scaling
00207         if (_maxDist > 0.f)
00208         {
00209                 if (m_maxEnergy != 0.f)
00210                 {
00211                         localScaleFactor = _maxDist / m_maxEnergy;
00212                 }
00213                 else
00214                 {
00215                         std::cerr << "Maximum energy equals zero, no maxDist scaling is done!" << std::endl;
00216                 }
00217         }
00218         
00219         const float _scaleFactor = scaleFactor.getValue ();
00220         // multiply the energies by a given factor
00221         if (_scaleFactor != 1.0f)
00222         {
00223                 localScaleFactor = localScaleFactor * _scaleFactor;
00224         }
00225 
00226         for (unsigned i = 0; i < energies[0].size (); i++)
00227         {
00228                 energies[IN][i]  = localScaleFactor * energies[IN][i];
00229                 energies[OUT][i] = localScaleFactor * energies[OUT][i];
00230         }
00231 }
00232 
00233 void
00234 IgSoRectColHist::setLogEnergies (std::vector<std::vector<float> >& energies)
00235 {
00236         int maxEnergyBin = -1;
00237         maxEnergyBin = findMaxEnergyBin (energies);
00238         
00239         // if we are using logscale, change to the log values
00240         if (logScale.getValue () && maxEnergyBin != -1)
00241         {
00242                 // calculate max energies and determine new maxenergy
00243                 calcLogEnergies (energies);
00244                 m_maxEnergy = energies[IN][maxEnergyBin] + energies[OUT][maxEnergyBin];
00245         }
00246 }
00247 
00248 float
00249 IgSoRectColHist::calcLocalRadius (const SbVec3f& point, const SbVec3f& center) const
00250 {
00251         // calculate the radius within the local system
00252         const float y = point[1] - center[1];
00253         const float z = point[2] - center[2];
00254         return sqrt (y * y + z * z);
00255 }
00256 
00257 SbVec3f
00258 IgSoRectColHist::calcAnglePoint (float angle, float y, float z)
00259 {
00260         // this method returns a three dimensional point which lies in the
00261         // intersection of a fixed line and a moving line (and in the x layer).
00262         // The fixed line is defined by the floats y and z, one of them must be
00263         // zero which then will be calculated, the other float defines the distance
00264         // of the line to the corresponding coordinate axis, i.e. it is parallel to
00265         // it. The "moving" line is defined by the angle and the center of the
00266         // coordinate system and it is moving with respect to the previous
00267         // calculation
00268         const float _layer = layer.getValue ();
00269         SbLine fixedLine;
00270         SbVec3f point1 (_layer, y, z);
00271         
00272         if (y == 0.f)
00273         {
00274                 fixedLine.setValue (point1, SbVec3f (_layer, z, z));
00275         }
00276         else if (z == 0.f)
00277         {
00278                 fixedLine.setValue (point1, SbVec3f (_layer, y, y));
00279         }
00280         else
00281         {
00282                 return SbVec3f (_layer, y, z);
00283         }
00284         
00285         SbVec3f test = convertCoordinates (1.f, angleToLeftHanded (angle), SbVec3f (_layer, 0.f, 0.f));
00286         SbLine movingLine (test, SbVec3f (_layer, 0.f, 0.f));
00287 
00288         SbVec3f result;
00289         SbVec3f result2;
00290         // since they are in the same layer, they must intersect
00291         movingLine.getClosestPoints (fixedLine, result, result2);
00292         return result;
00293 }
00294 
00295 float
00296 IgSoRectColHist::angleToLeftHanded (float rightHandedAngle)
00297 {
00298         return (2.f * M_PI - rightHandedAngle);
00299 }
00300 
00301 void
00302 IgSoRectColHist::determineAngularDelta (void)
00303 {
00304         // assumption: barrel's deltaEta is const, endcap's deltatheta is (more or
00305         // less) const
00306         float _radiusZ = radiusZ.getValue ();
00307         float _radiusR = radiusR.getValue ();
00308         unsigned _numZ = numZ.getValue ();
00309         unsigned _numR = numR.getValue ();
00310         _radiusZ = (_radiusZ <= 0.f) ? (1.f) : (_radiusZ);
00311         _radiusR = (_radiusR <= 0.f) ? (1.f) : (_radiusR);
00312         _numZ = (_numZ == 0) ? (1) : (_numZ);
00313         _numR = (_numR == 0) ? (1) : (_numR);
00314         
00315         // calculate the barrel's delta eta, if no maxEta is given, assume that
00316         // it's the corner of the detector
00317         m_barrelMaxEta = barrelMaxEta.getValue ();
00318         if (m_barrelMaxEta <= 0.f)
00319         {
00320                 if (m_endcapMaxTheta <= 0.f)
00321                 {
00322                         m_barrelMaxEta = thetaToEta (M_PI/2.f - atan (_radiusZ/_radiusR));
00323                 }
00324                 else
00325                 {
00326                         m_barrelMaxEta = thetaToEta (m_endcapMaxTheta);
00327                 }
00328         }
00329         m_barrelDeltaEta = m_barrelMaxEta / (_numZ / 2);
00330         
00331         // theta is used for the endcaps, if the maximum is defined, use it,
00332         // otherwise determine it from maxeta or the corner
00333         m_endcapMaxTheta = endcapMaxTheta.getValue ();
00334         if (m_endcapMaxTheta <= 0.f)
00335         {
00336                 if (m_barrelMaxEta > 0.f)
00337                 {
00338                         m_endcapMaxTheta = etaToTheta (m_barrelMaxEta);
00339                 }
00340                 else
00341                 {
00342                         m_endcapMaxTheta = atan (_radiusR / _radiusZ);
00343                 }
00344         }
00345         m_endcapDeltaTheta = (m_endcapMaxTheta - beamPipeTheta.getValue ()) / (_numR / 2);
00346         m_deltasSet = true;
00347 }
00348 
00349 float
00350 IgSoRectColHist::etaToTheta (float eta)
00351 {
00352         return (2.f * atan (exp (- eta)));
00353 }
00354 
00355 float
00356 IgSoRectColHist::thetaToEta (float theta)
00357 {
00358         return (-log (tan (theta/2.f)));
00359 }
00360 
00361 float
00362 IgSoRectColHist::getBinAngle (unsigned _binNum, bool isLeftPoint)
00363 {
00364         // returns the mathematical angle of the left resp. right lower corner of the bin with the bin number '_binNum'.
00365         float result = 0.f;
00366         // determine the delta eta and delta theta first
00367         if (!m_deltasSet) determineAngularDelta ();
00368         
00369         unsigned _numZ = numZ.getValue ();
00370         unsigned _numR = numR.getValue ();
00371         _numZ = (_numZ == 0) ? (1) : (_numZ);
00372         _numR = (_numR == 0) ? (1) : (_numR);
00373         const unsigned binNum = (isLeftPoint) ? (_binNum + 1) : (_binNum);
00374 
00375         // bin nbr zero starts in the right endcap's center. NOTE that the angle
00376         // depends on the beam pipe opening (in theta), on the endcaps' maximum
00377         // theta and on the barrel's maximum eta. There are 8 different sectors,
00378         // starting at the mathematical angel zero up to 2Pi. Sectors change at the
00379         // detector's corners. Corners on the other hand, might differ depending on
00380         // the sector if maxtheta and maxeta aren't equal.
00381         if (_binNum < _numR/2)
00382         {
00383                 result = binNum * m_endcapDeltaTheta + beamPipeTheta.getValue ();
00384         }
00385         else if (_binNum < (_numZ/2 + _numR/2))
00386         {
00387                 const float tempEta = m_barrelMaxEta - (binNum - _numR/2) * m_barrelDeltaEta;
00388                 result = ((tempEta < 0.f) ? (M_PI - etaToTheta (fabs (tempEta))) : (etaToTheta (tempEta)));
00389         }
00390         else if (_binNum < (_numZ + _numR/2))
00391         {
00392                 const float tempEta = (binNum - (_numZ/2 + _numR/2)) * m_barrelDeltaEta;
00393                 result = M_PI - etaToTheta (tempEta);
00394         }
00395         else if (_binNum < (_numZ + _numR))
00396         {
00397                 result = (binNum - (_numZ + _numR/2)) * m_endcapDeltaTheta + M_PI - m_endcapMaxTheta;
00398         }
00399         else if (_binNum < (_numZ + 3*_numR/2))
00400         {
00401                 result = (binNum - (_numR + _numZ)) * m_endcapDeltaTheta + beamPipeTheta.getValue () + M_PI;
00402         }
00403         else if (_binNum < (3*(_numZ+_numR)/2))
00404         {
00405                 const float tempEta = m_barrelMaxEta - (binNum - (_numZ + 3*_numR/2)) * m_barrelDeltaEta;
00406                 result =  ((tempEta < 0.f) ? (M_PI - etaToTheta (fabs (tempEta))) : (etaToTheta (tempEta))) + M_PI;
00407         }
00408         else if (_binNum < (2*_numZ + 3*_numR/2))
00409         {
00410                 const float tempEta = (binNum - (3*(_numZ+_numR)/2)) * m_barrelDeltaEta;
00411                 result = 2.f * M_PI - etaToTheta (tempEta);
00412         }
00413         else
00414         {
00415                 result = (binNum - (3*_numR/2 + 2*_numZ)) * m_endcapDeltaTheta + 2.f * M_PI - m_endcapMaxTheta;
00416         }
00417         return result;
00418 }
00419 
00420 float
00421 IgSoRectColHist::convertAngle (float angle)
00422 {
00423         // this method takes a value within [-pi;pi] and returns a value [0;2*pi].
00424         // values from 0 to pi are the same. Returns a "mathematical" angle
00425         // starting on the positive x-axis.
00426         float result;
00427         if (angle > (2.f * M_PI))
00428         {
00429                 result = fmod (angle, 2 * M_PI);
00430         }
00431         else if (angle < 0.f)
00432         {
00433                 result = (angle + 2 * M_PI);
00434         }
00435         else
00436         {
00437                 result = angle;
00438         }
00439         return result;
00440 }
00441 
00442 void
00443 IgSoRectColHist::calcBinCorner (unsigned i, SbVec3f& left, SbVec3f& right)
00444 {
00445         // this method calculates the lower left and right corner of a bin i
00446         float yCoord, zCoord;
00447         float _radiusR = radiusR.getValue ();
00448         float _radiusZ = radiusZ.getValue ();
00449 
00450         switch (findBinPlacement (i)) 
00451         {
00452                 case TOP:
00453                         zCoord = 0.f;
00454                         yCoord = -_radiusR;
00455                 break;
00456 
00457                 case RIGHT:
00458                         zCoord = _radiusZ;
00459                         yCoord = 0.f;
00460                 break;
00461                 
00462                 case BOTTOM:
00463                         zCoord = 0.f;
00464                         yCoord = _radiusR;
00465                 break;
00466 
00467                 default: //LEFT 
00468                         zCoord = -_radiusZ;
00469                         yCoord = 0.f;
00470                 break;
00471         }
00472         left  = calcAnglePoint (getBinAngle (i, true), yCoord, zCoord);
00473         right = calcAnglePoint (getBinAngle (i, false), yCoord, zCoord);
00474 }
00475 
00476 void
00477 IgSoRectColHist::addOffset (SbVec3f& point, unsigned binNum)
00478 {
00479         if (offsetZ.getValue () == 0.f && offsetR.getValue () == 0.f) return;
00480         
00481         SbVec3f offset (layer.getValue (), 0.f, 0.f);
00482         switch (findBinPlacement (binNum)) 
00483         {
00484                 case TOP:
00485                         offset[1] = - offsetR.getValue ();
00486                 break;
00487 
00488                 case RIGHT:
00489                         offset[2] = offsetZ.getValue ();
00490                 break;
00491                 
00492                 case BOTTOM:
00493                         offset[1] = offsetR.getValue ();
00494                 break;
00495 
00496                 default: //LEFT 
00497                         offset[2] = - offsetZ.getValue ();
00498                 break;
00499         }
00500         point = point + offset;
00501 }
00502 
00503 void
00504 IgSoRectColHist::refresh (void)
00505 {
00506         const unsigned numOfBins = energies.getNum () / 2;
00507         const unsigned _numR = numR.getValue ();
00508         const unsigned _numZ = numZ.getValue ();
00509         
00510         if (2*(_numR + _numZ) == numOfBins && (_numR * _numZ > 0))
00511         {
00512                 SbVec3f inner[4]; // points of the inner towers
00513                 SbVec3f outer[4]; // points of the outer towers
00514                 
00515                 // local copy of the energies, note that the energy vector is split
00516                 // into 2 vectors for convenience
00517                 std::vector<std::vector<float> > localEnergies (2, std::vector<float> (numOfBins, 0.f));
00518                 for (unsigned i = 0; i < numOfBins; i++) 
00519                 {
00520                         localEnergies[IN][i] = energies[i];
00521                         localEnergies[OUT][i] = energies[numOfBins + i];
00522         }
00523                 
00524                 setLogEnergies (localEnergies);
00525                 scaleEnergies (localEnergies);
00526                 
00527                 // the lower corners of a to "i" corresponding bin, note that "left"
00528                 // and "right" are relative
00529                 SbVec3f leftPoint;
00530                 SbVec3f rightPoint;
00531                 
00532                 // calculate the radius of each point from the "center"
00533                 SbVec3f zero (layer.getValue (), 0.f, 0.f);
00534                 float leftRadius  = 0.f;
00535                 float rightRadius = 0.f;
00536                 SbVec3f _center    = center.getValue ();
00537                 SbColor _lineColor = lineColor.getValue ();
00538                 std::vector<SbVec3f> vertexData;
00539                 
00540                 // draw the towers
00541                 for (unsigned i = 0; i < numOfBins; i++)
00542                 {
00543                         // don't display the bin if the energies are zero
00544                         if (localEnergies[0][i] == 0.0f && localEnergies[1][i] == 0.0f) continue;
00545 
00546                         calcBinCorner (i, leftPoint, rightPoint);
00547                         
00548                         leftRadius = calcLocalRadius (leftPoint, zero);
00549                         rightRadius = calcLocalRadius (rightPoint, zero);
00550                         
00551                         // the tower's base line must be perpendicular to the normal which
00552                         // comes from the central point, but which side we have to shift
00553                         // for that, is decided below
00554                         if (leftRadius < rightRadius)
00555                         {
00556                                 inner[3] = rightPoint + _center;
00557                                 inner[0] = projectPoint (rightRadius - leftRadius, leftPoint, zero) + _center;
00558                         }
00559                         else
00560                         {
00561                                 inner[0] = leftPoint + _center;
00562                                 inner[3] = projectPoint (leftRadius - rightRadius, rightPoint, zero) + _center;
00563                         }
00564 
00565                         // inner tower's outer points
00566                         inner[1] = projectPoint (localEnergies[0][i], inner[0], _center);
00567                         inner[2] = projectPoint (localEnergies[0][i], inner[3], _center);                       
00568                         // outer tower's inner points
00569                         outer[0] = inner[1];
00570                         outer[3] = inner[2];
00571                         // outer tower's outer points
00572                         outer[1] = projectPoint (localEnergies[1][i], outer[0], _center);
00573                         outer[2] = projectPoint (localEnergies[1][i], outer[3], _center);
00574                         
00575                         // add offsets for each point
00576                         for (unsigned j = 0; j < 4; j++)
00577                         {
00578                                 addOffset (inner[j], i);
00579                                 addOffset (outer[j], i);
00580                         }
00581                         
00582                         // push the vertex information
00583                         for (unsigned j = 0; j < 4; j++)
00584                         {
00585                                 // only display the bin if its energy is not zero
00586                                 if (localEnergies[0][i] != 0.f)
00587                                 {
00588                                         vertexData.push_back (inner[j]);
00589                                 }
00590                         }
00591                         
00592                         for (unsigned j = 0; j < 4; j++)
00593                         {
00594                                 if (localEnergies[1][i] != 0.f)
00595                                 {
00596                                         vertexData.push_back (outer[j]);
00597                                 }
00598                         }
00599                 }
00600                 
00601                 // declare shapehints
00602                 SoShapeHints* shapeHints = new SoShapeHints;
00603                 shapeHints->faceType = SoShapeHints::CONVEX;
00604                 shapeHints->vertexOrdering = SoShapeHints::CLOCKWISE;
00605 
00606                 SoIndexedFaceSet* faceSet = new SoIndexedFaceSet;
00607                 SoIndexedLineSet* lineSet = new SoIndexedLineSet;
00608                 
00609                 // set the properties for the faceset and lineset: vertices and colors
00610                 SoVertexProperty* vtx = new SoVertexProperty;
00611                 vtx->materialBinding = SoMaterialBinding::PER_FACE_INDEXED;
00612                 
00613                 // setting face colors (only diffuse color)
00614                 vtx->orderedRGBA.set1Value (0, faceColors[0].getPackedValue ());
00615                 vtx->orderedRGBA.set1Value (1, faceColors[1].getPackedValue ());
00616                 vtx->orderedRGBA.set1Value (2, faceColors[2].getPackedValue ());
00617                 vtx->orderedRGBA.set1Value (3, faceColors[3].getPackedValue ());
00618                 vtx->orderedRGBA.set1Value (4, _lineColor.getPackedValue ()); // line color
00619                 
00620                 // set the vertices for the towers
00621                 vtx->vertex.setValues (0, vertexData.size (), &vertexData[0]);
00622                 
00623                 std::vector<int> colorIndices;
00624                 std::vector<int> faceIndices = assignIndices (localEnergies, colorIndices);
00625                 
00626                 // assign the face and color indices for the faces and lines
00627                 faceSet->coordIndex.setValues (0, faceIndices.size (), &faceIndices[0]);
00628                 faceSet->materialIndex.setValues (0, colorIndices.size (), &colorIndices[0]);
00629                 lineSet->coordIndex.setValues (0, faceIndices.size (), &faceIndices[0]);
00630                 
00631                 // custom single color for the lines surrounding the faces
00632                 if (!(_lineColor[0] == 0.f && _lineColor[1] == 0.f && _lineColor[2] == 0.f))
00633                 {
00634                         for (unsigned i = 0; i < colorIndices.size (); i++)
00635                         {
00636                                 colorIndices[i] = 4;
00637                         }
00638                 }
00639                 lineSet->materialIndex.setValues (0, colorIndices.size (), &colorIndices[0]);
00640                 
00641                 faceSet->vertexProperty = vtx;
00642                 lineSet->vertexProperty = vtx;
00643                 
00644                 setPart ("shapeHints", shapeHints);
00645                 setPart ("faceSet",    faceSet);
00646                 setPart ("lineSet",    lineSet);
00647         }
00648 }
00649 

Generated on Tue Jun 9 17:38:47 2009 for CMSSW by  doxygen 1.5.4