00001
00002
00003 #include "Iguana/Inventor/interface/IgSoCircularHist.h"
00004 #include <Inventor/nodes/SoText2.h>
00005 #include <Inventor/nodes/SoFont.h>
00006 #include <Inventor/nodes/SoTranslation.h>
00007 #include <Inventor/nodes/SoRotation.h>
00008 #include <Inventor/nodes/SoSeparator.h>
00009 #include <Inventor/nodes/SoIndexedFaceSet.h>
00010 #include <Inventor/nodes/SoShapeHints.h>
00011 #include <Inventor/nodes/SoMaterial.h>
00012 #include <Inventor/nodes/SoMaterialBinding.h>
00013 #include <Inventor/nodes/SoIndexedLineSet.h>
00014 #include <Inventor/nodes/SoVertexProperty.h>
00015 #include <Inventor/nodes/SoCoordinate3.h>
00016 #include <Inventor/nodes/SoFaceSet.h>
00017 #include <vector>
00018
00019
00020
00021
00022
00023
00024
00025
00026 SO_KIT_SOURCE (IgSoCircularHist);
00027
00028
00029
00030
00031
00032
00033
00034 inline SbVec3f
00035 convertCoordinates (SbVec3f radialCoords)
00036 {
00037 SbVec3f cartesianCoords;
00038 cartesianCoords [0] = radialCoords [0] * cos (radialCoords [1]);
00039 cartesianCoords [1] = radialCoords [0] * sin (radialCoords [1]);
00040 cartesianCoords [2] = radialCoords [2];
00041 return cartesianCoords;
00042 }
00043
00044
00045
00046
00047 void
00048 IgSoCircularHist::initClass (void)
00049 { SO_KIT_INIT_CLASS (IgSoCircularHist, IgSoShapeKit, "IgSoShapeKit"); }
00050
00051 IgSoCircularHist::IgSoCircularHist (void)
00052 {
00053 SO_KIT_CONSTRUCTOR (IgSoCircularHist);
00054
00055 SO_KIT_ADD_FIELD (minRadius, (1.3));
00056 SO_KIT_ADD_FIELD (maxRadius, (1.5));
00057 SO_KIT_ADD_FIELD (numberOfBins, (180));
00058 SO_KIT_ADD_FIELD (energies, (0.0));
00059 SO_KIT_ADD_FIELD (logScale, (false));
00060 SO_KIT_ADD_FIELD (layer, (0.0));
00061 SO_KIT_ADD_FIELD (scaleFactor, (0.1));
00062 SO_KIT_ADD_FIELD (showAnnotations, (false));
00063 SO_KIT_ADD_CATALOG_ENTRY (shapeHints, SoShapeHints, FALSE, separator,\x0, TRUE);
00064 SO_KIT_ADD_CATALOG_ENTRY (faceSet, SoIndexedFaceSet, FALSE, separator,\x0, TRUE);
00065 SO_KIT_ADD_CATALOG_ENTRY (lines, SoIndexedLineSet, FALSE, separator,\x0, TRUE);
00066 SO_KIT_ADD_CATALOG_ENTRY (ruler, SoSeparator, FALSE, separator,\x0, TRUE);
00067
00068 SO_KIT_INIT_INSTANCE ();
00069 setUpConnections (true, true);
00070 }
00071
00072 void
00073 IgSoCircularHist::refresh (void)
00074 {
00075 if (energies.getNum () == 0)
00076 {
00077 setPart ("shapeHints", NULL);
00078 setPart ("faceSet", NULL);
00079 setPart ("lines", NULL);
00080 setPart ("ruler", NULL);
00081 return;
00082 }
00083
00084
00085 SoIndexedFaceSet* faceSet = new SoIndexedFaceSet;
00086 SoIndexedLineSet* lineSet = new SoIndexedLineSet;
00087 SoShapeHints* shapeHints = new SoShapeHints;
00088 SoVertexProperty* vtx = new SoVertexProperty;
00089
00090
00091 float rMin = minRadius.getValue ();
00092 float rMax = maxRadius.getValue ();
00093 int nbrOfBins = numberOfBins.getValue ();
00094 float zLayer = layer.getValue ();
00095 float factor = scaleFactor.getValue ();
00096 bool annotations = showAnnotations.getValue ();
00097 bool logarithmic = logScale.getValue ();
00098
00099
00100 shapeHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
00101 shapeHints->faceType = SoShapeHints::CONVEX;
00102
00103
00104 std::vector<float> energies2 (nbrOfBins);
00105
00106
00107 float maxEn = 0.0;
00108 int maxEnIndex = 0;
00109 for (int i = 0; i < nbrOfBins; i++)
00110 {
00111 if (energies [i] > maxEn)
00112 {
00113 maxEn = energies [i];
00114 maxEnIndex = i;
00115 }
00116 }
00117
00118
00119
00120 if (logarithmic)
00121 {
00122 for (int i = 0; i < nbrOfBins; i++)
00123 {
00124 energies2 [i] = factor * log (energies [i] + 1.0);
00125 }
00126 }
00127
00128
00129 std::vector<SbVec3f> vertexData (3 * nbrOfBins + 1);
00130
00131 vertexData [0] = convertCoordinates (SbVec3f (rMin, 0.0, zLayer));
00132 for (int i = 0; i < nbrOfBins ; i++)
00133 {
00134 float phi = 2.0 * M_PI / nbrOfBins * (i + 1);
00135
00136 if (! logarithmic)
00137 {
00138
00139 if (rMax == -1)
00140 {
00141 vertexData [i * 3 + 1] = convertCoordinates (SbVec3f (rMin, phi, zLayer));
00142 vertexData [i * 3 + 2] = convertCoordinates (SbVec3f (rMin + factor * energies [i], phi, zLayer));
00143 vertexData [i * 3 + 3] = convertCoordinates (SbVec3f (rMin + factor * energies [i], 2 * M_PI / nbrOfBins * i, zLayer));
00144 }
00145
00146 else
00147 {
00148 vertexData [i * 3 + 1] = convertCoordinates (SbVec3f (rMin, phi, zLayer));
00149 vertexData [i * 3 + 2] = convertCoordinates (SbVec3f (rMin + energies [i] / maxEn * (rMax - rMin), phi, zLayer));
00150 vertexData [i * 3 + 3] = convertCoordinates (SbVec3f (rMin + energies [i] / maxEn * (rMax - rMin), 2 * M_PI / nbrOfBins * i, zLayer));
00151 }
00152 }
00153
00154 else
00155 {
00156 if ((rMax >= rMin) || (rMax == -1))
00157 {
00158 vertexData [i * 3 + 1] = convertCoordinates (SbVec3f (rMin, phi, zLayer));
00159 vertexData [i * 3 + 2] = convertCoordinates (SbVec3f (rMin + energies2 [i], phi, zLayer));
00160 vertexData [i * 3 + 3] = convertCoordinates (SbVec3f (rMin + energies2 [i], 2 * M_PI / nbrOfBins * i, zLayer));
00161 }
00162 else
00163 {
00164 vertexData [i * 3 + 1] = convertCoordinates (SbVec3f (rMin, phi, zLayer));
00165 vertexData [i * 3 + 2] = convertCoordinates (SbVec3f (rMin - energies2 [i], phi, zLayer));
00166 vertexData [i * 3 + 3] = convertCoordinates (SbVec3f (rMin - energies2 [i], 2 * M_PI / nbrOfBins * i, zLayer));
00167 }
00168 }
00169 }
00170
00171
00172 std::vector<int> faceIndices (nbrOfBins * 5);
00173 faceIndices [0] = 0;
00174 faceIndices [1] = 1;
00175 faceIndices [2] = 2;
00176 faceIndices [3] = 3;
00177 faceIndices [4] = SO_END_FACE_INDEX;
00178
00179 for (int i = 1; i < nbrOfBins; i++)
00180 {
00181 faceIndices [i * 5] = (i - 1) * 3 + 1;
00182 faceIndices [i * 5 + 1] = (i - 1) * 3 + 4;
00183 faceIndices [i * 5 + 2] = (i - 1) * 3 + 5;
00184 faceIndices [i * 5 + 3] = (i - 1) * 3 + 6;
00185 faceIndices [i * 5 + 4] = SO_END_FACE_INDEX;
00186 }
00187
00188 vtx->vertex.setValues (0, nbrOfBins * 3 + 1 ,&vertexData [0]);
00189 vtx->materialBinding = SoMaterialBinding::PER_FACE_INDEXED;
00190
00191 faceSet->coordIndex.setValues (0, nbrOfBins * 5, &faceIndices [0]);
00192 faceSet->vertexProperty = vtx;
00193
00194
00195 std::vector<int> lineIndices (2 * nbrOfBins + 1);
00196
00197 for (int i = 0; i < nbrOfBins; i++)
00198 {
00199 lineIndices [2 * i] = 3 * i + 3;
00200 lineIndices [2 * i + 1] = 3 * i + 2;
00201 }
00202 lineIndices [2 * nbrOfBins] = 3;
00203
00204 SoVertexProperty* lineVtx = new SoVertexProperty;
00205 lineVtx->vertex.setValues (0, nbrOfBins * 3 + 1, &vertexData [0]);
00206
00207 lineSet->coordIndex.setValues (0, 2 * nbrOfBins + 1, &lineIndices [0]);
00208 lineSet->vertexProperty = lineVtx;
00209
00212 setPart ("shapeHints", shapeHints);
00213 setPart ("faceSet", faceSet);
00214 setPart ("lines", lineSet);
00215
00219
00220 if (annotations)
00221 {
00222 float offset;
00223 int nbrOfDivisions;
00224 float divisionLength;
00225 float rulerLength;
00226
00227
00228
00229 if (! logarithmic)
00230 {
00231
00232 rulerLength = (rMax == -1 ) ? factor * maxEn : rMax - rMin;
00233 }
00234
00235 else
00236 {
00237 rulerLength = ((rMax >= rMin) || (rMax == -1)) ? energies2 [maxEnIndex] : (-energies2 [maxEnIndex]);
00238 }
00239
00240
00241 if ((rulerLength > 0.1) || (rulerLength < -0.1))
00242 {
00243
00244 SoSeparator* ruler = new SoSeparator;
00245 SoMaterial* axisMaterial = new SoMaterial;
00246 SoRotation* zrot = new SoRotation;
00247
00248
00249
00250 axisMaterial->diffuseColor.setValue(0.0, 0.0, 0.0);
00251
00252
00253 offset = (rulerLength >= 0) ? (rulerLength * (1.0 - floor (0.1 * maxEn) / (maxEn * 0.1))) : (-rulerLength * (1.0 - floor (0.1 * maxEn) / (maxEn * 0.1)));
00254
00255 if (! logarithmic)
00256 {
00257 nbrOfDivisions = static_cast<int>(floor (maxEn * 0.1));
00258
00259 if (nbrOfDivisions == 0)
00260 {
00261 nbrOfDivisions = 1;
00262 divisionLength = rulerLength;
00263 }
00264 else
00265 {
00266 divisionLength = (rulerLength - offset) / nbrOfDivisions;
00267
00268 if (! (offset == 0) && ((offset - divisionLength) > 0.1 * rulerLength))
00269 {
00270 nbrOfDivisions += 1;
00271 }
00272 }
00273 }
00274
00275 else
00276 {
00277 nbrOfDivisions = 1;
00278 divisionLength = rulerLength;
00279 }
00280
00281 float w = 2 * M_PI / nbrOfBins;
00282 float rulerAngle = 2 * M_PI / nbrOfBins * (float (maxEnIndex) + 0.5) ;
00283 float zDist = 0.001;
00284
00285
00286 std::vector<SbVec3f> rulerVtx (7 + 4 * nbrOfDivisions);
00287
00288 rulerVtx [0] = convertCoordinates (SbVec3f (rMin, rulerAngle - w / 4.0, zLayer + zDist));
00289 rulerVtx [1] = convertCoordinates (SbVec3f (rMin + 9.0/10.0*rulerLength, rulerAngle - w / 8.0, zLayer + zDist));
00290 rulerVtx [2] = convertCoordinates (SbVec3f (rMin + 9.0/10.0*rulerLength, rulerAngle + w / 8.0, zLayer + zDist));
00291 rulerVtx [3] = convertCoordinates (SbVec3f (rMin, rulerAngle + w / 4.0, zLayer + zDist));
00292 rulerVtx [4] = convertCoordinates (SbVec3f (rMin + 9.0/10.0*rulerLength, rulerAngle - w / 4.0, zLayer + zDist));
00293 rulerVtx [5] = convertCoordinates (SbVec3f (rMin + rulerLength, rulerAngle, zLayer + zDist));
00294 rulerVtx [6] = convertCoordinates (SbVec3f (rMin + 9.0/10.0*rulerLength, rulerAngle + w / 4.0, zLayer + zDist));
00295
00296 for (int i = 1; i < nbrOfDivisions; i++)
00297 {
00298 rulerVtx [3+ i * 4] = convertCoordinates (SbVec3f (rMin + divisionLength * i - 0.01, rulerAngle - w / 3.0, zLayer + zDist));
00299 rulerVtx [3+ i * 4 + 1] = convertCoordinates (SbVec3f (rMin + divisionLength * i + 0.01, rulerAngle - w / 3.0, zLayer + zDist));
00300 rulerVtx [3+ i * 4 + 2] = convertCoordinates (SbVec3f (rMin + divisionLength * i + 0.01, rulerAngle + w / 3.0, zLayer + zDist));
00301 rulerVtx [3+ i * 4 + 3] = convertCoordinates (SbVec3f (rMin + divisionLength * i - 0.01, rulerAngle + w / 3.0, zLayer + zDist));
00302 }
00303
00304 SoCoordinate3* rulerCoords = new SoCoordinate3;
00305 rulerCoords->point.setValues (0, 7 + 4 * (nbrOfDivisions - 1), &rulerVtx [0]);
00306
00307 std::vector<int> numVtx (1 + nbrOfDivisions);
00308 numVtx [0] = 4;
00309 numVtx [1] = 3;
00310 for (int i = 0; i < (nbrOfDivisions - 1); i++)
00311 {
00312 numVtx [2 + i] = 4;
00313 }
00314
00315 SoFaceSet* rulerFaceSet = new SoFaceSet;
00316 rulerFaceSet->numVertices.setValues (0, 2 + nbrOfDivisions - 1 , &numVtx [0]);
00317
00318
00319
00320 char label [50];
00321 if (maxEn >= 100.0)
00322 {
00323 sprintf (label, "Emax = %.1f TeV", maxEn / 1000.0);
00324 }
00325 else
00326 {
00327 sprintf (label, "Emax = %.1f GeV", maxEn);
00328 }
00329
00330 SoFont* labelFont = new SoFont;
00331 labelFont->size.setValue (16.0);
00332 labelFont->name.setValue ("Times-Roman");
00333
00334 SoText2* labelText = new SoText2;
00335 labelText->string = label;
00336 labelText->justification = SoText2::CENTER;
00337
00338 SoTranslation* labelTrans = new SoTranslation;
00339
00340
00341
00342
00343 if ((rMax == -1) || (rMax >= rMin))
00344 {
00345 zrot->rotation.setValue (SbVec3f (0.0, 0.0, 1.0), - (M_PI / 2 - 2 * M_PI / nbrOfBins * (float (maxEnIndex) + 0.5)));
00346 labelTrans->translation.setValue (0.0, 1.1 * (rMin + rulerLength), zLayer + zDist);
00347 }
00348
00349 else
00350 {
00351 zrot->rotation.setValue (SbVec3f (0.0, 0.0, 1.0), - (M_PI / 2 - 2 * M_PI / nbrOfBins * (float (maxEnIndex) + 0.5)) + M_PI);
00352 labelTrans->translation.setValue (0.0, -0.9 * (rMin + rulerLength), zLayer + zDist);
00353 }
00354
00355
00356 ruler->addChild (axisMaterial);
00357 ruler->addChild (rulerCoords);
00358 ruler->addChild (rulerFaceSet);
00359 ruler->addChild (labelFont);
00360 ruler->addChild (zrot);
00361 ruler->addChild (labelTrans);
00362 ruler->addChild (labelText);
00363
00364 setPart ("ruler", ruler);
00365 }
00366 }
00367 }