ATLAS Offline Software
Loading...
Searching...
No Matches
HitsSoNodeManager.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "VP1Base/VP1Msg.h"
7
8#include <Inventor/C/errors/debugerror.h>
9#include <Inventor/nodes/SoVertexProperty.h>
10#include <Inventor/nodes/SoLineSet.h>
11#include <Inventor/nodes/SoPointSet.h>
12#include <Inventor/nodes/SoSeparator.h>
13#include <Inventor/nodes/SoCylinder.h>
14#include <Inventor/nodes/SoRotationXYZ.h>
15#include <Inventor/nodes/SoTranslation.h>
16#include <Inventor/nodes/SoInfo.h>
17#include <Inventor/nodes/SoTransform.h>
18
20
21#include <map>
22#include <iostream>
23
24#include "CxxUtils/fpcompare.h"
25
26//____________________________________________________________________
28public:
31 const double driftdischeight;
32 std::map<double,SoNode*,CxxUtils::fpcompare_fn::less> cachedshapes_drifttubes;
33 std::map<double,SoNode*,CxxUtils::fpcompare_fn::less> cachedshapes_driftdiscs;
34 std::map<double,SoNode*,CxxUtils::fpcompare_fn::less> cachedshapes_projdrifttubes;
35 std::map<double,SoNode*,CxxUtils::fpcompare_fn::less> cachedshapes_strips;
37 std::map<double,SoNode*,CxxUtils::fpcompare_fn::less> cachedshapes_cross;
38 SoTransform * cached_unittransform;
39
40 //Util, for cleaning up:
41 template <class T>
42 static void unrefValues(T&t) {
43 typename T::iterator it(t.begin()), itE(t.end());
44 for (;it!=itE;++it)
45 it->second->unref();
46 }
47
48 void sanitiseParameterValue( double& x ) {
49 //Flips sign of parameter if negative, and makes sure it is not of
50 //negligible size.
51 if ( x != x ) {
52 theclass->message("sanitiseParameterValue WARNING - received nan paramter. Putting to 1.0e-5.");
53 x = 1.0e-5;
54 return;
55 }
56 if ( x <= 1.0e-5 ) {
57 if ( x < 0.0 ) {
58 if (VP1Msg::verbose())
59 theclass->messageVerbose("sanitiseParameterValue WARNING - received negative parameter. Flipping sign.");
60 x = - x;
61 }
62 if ( x < 1.0e-5 )
63 x = 1.0e-5;
64 }
65 }
67 //Flips sign of parameter if negative, and makes sure it, if
68 //non-zero, that it is not of negligible size.
69 if ( x != x ) {
70 theclass->message("sanitiseParameterValue WARNING - received nan paramter. Putting to 1.0e-5.");
71 x = 1.0e-5;
72 return;
73 }
74 if ( x <= 1.0e-5 ) {
75 if ( x < 0.0 ) {
76 if (VP1Msg::verbose())
77 theclass->messageVerbose("sanitiseParameterValue WARNING - received negative parameter. Flipping sign.");
78 x = - x;
79 }
80 if ( x < 1.0e-5 && x != 0.0 )
81 x = 1.0e-5;
82 }
83 }
84
85 void summarise(unsigned n,const QString& shapename) const;
86
87};
88
89
90//____________________________________________________________________
92 : VP1HelperClassBase(sys,"HitsSoNodeManager"), m_d(new Imp)
93{
94 m_d->theclass = this;
95 m_d->cachedshape_point = 0;
96 m_d->cached_unittransform = 0;
97}
98
99
100//____________________________________________________________________
101void HitsSoNodeManager::Imp::summarise(unsigned n,const QString& shapename) const
102{
103 if (n>100)
104 theclass->messageDebug(" WARNING: Created more than 100 ("+QString::number(n)+") different "+shapename+" shapes.");
105 else if (VP1Msg::verbose())
106 theclass->messageVerbose("Created "+QString::number(n)+" different "+shapename+" shapes.");
107}
108
109
110//____________________________________________________________________
112{
113 messageVerbose("destructor begin");
114
115 //Make sure we know if we didn't have efficient shared instancing:
116 m_d->summarise(m_d->cachedshapes_drifttubes.size(),"drift tube");
117 m_d->summarise(m_d->cachedshapes_driftdiscs.size(),"drift disc");
118 m_d->summarise(m_d->cachedshapes_projdrifttubes.size(),"projected drift tube");
119 m_d->summarise(m_d->cachedshapes_strips.size(),"strip");
120 m_d->summarise(m_d->cachedshapes_cross.size(),"cross");
121
122 //unref kept nodes:
123 Imp::unrefValues(m_d->cachedshapes_drifttubes);
124 Imp::unrefValues(m_d->cachedshapes_driftdiscs);
125 Imp::unrefValues(m_d->cachedshapes_projdrifttubes);
126 Imp::unrefValues(m_d->cachedshapes_strips);
127 Imp::unrefValues(m_d->cachedshapes_cross);
128 if (m_d->cachedshape_point)
129 m_d->cachedshape_point->unref();
130 if (m_d->cached_unittransform)
131 m_d->cached_unittransform->unref();
132
133 delete m_d;
134 messageVerbose("destructor end");
135}
136
137//____________________________________________________________________
138SoNode* HitsSoNodeManager::getShapeNode_DriftTube( double halfLength, double radius )
139{
140 m_d->sanitiseParameterValue(halfLength);
141 m_d->sanitiseParameterValueAllowZero(radius);
142 //Fixme: discretize by radius!!
143
144 double id(halfLength-999999999.9*radius);
145 std::map<double,SoNode*>::const_iterator it = m_d->cachedshapes_drifttubes.find(id);
146 if (it!=m_d->cachedshapes_drifttubes.end())
147 return it->second;
148
149 if (radius>0) {
150 SoSeparator*sep = new SoSeparator;
151 SoRotationXYZ * rot = new SoRotationXYZ;
152 rot->axis.setValue(SoRotationXYZ::X);
153 rot->angle.setValue(M_PI*0.5f);
154 sep->addChild(rot);
155 SoCylinder * cyl = new SoCylinder;
156 cyl->radius.setValue(radius);
157 cyl->height.setValue(2.0f*halfLength);
158 sep->addChild(cyl);
159 m_d->cachedshapes_drifttubes[id] = sep;
160 sep->ref();
161 return sep;
162 } else {
163 SoVertexProperty * scatVtxProperty = new SoVertexProperty();
164 scatVtxProperty->vertex.set1Value(0, 0.0f,0.0f,-halfLength);
165 scatVtxProperty->vertex.set1Value(1, 0.0f,0.0f, halfLength);
166 SoLineSet * line = new SoLineSet();
167 line->numVertices = 2;
168 line->vertexProperty = scatVtxProperty;
169 m_d->cachedshapes_drifttubes[id] = line;
170 line->ref();
171 return line;
172 }
173
174}
175
176//____________________________________________________________________
178{
179 m_d->sanitiseParameterValueAllowZero(radius);
180 if (radius==0.0)
181 return getShapeNode_Point();
182
183 std::map<double,SoNode*>::const_iterator it = m_d->cachedshapes_driftdiscs.find(radius);
184 if (it!=m_d->cachedshapes_driftdiscs.end())
185 return it->second;
186
187 SoSeparator*sep = new SoSeparator;//fixme: check if sogroup improves performance.
188 SoRotationXYZ * rot = new SoRotationXYZ;
189 rot->axis.setValue(SoRotationXYZ::X);
190 rot->angle.setValue(M_PI*0.5f);
191 sep->addChild(rot);
192 SoCylinder * cyl = new SoCylinder;
193 cyl->radius.setValue(radius);
194 cyl->height.setValue(m_d->driftdischeight);
195 sep->addChild(cyl);
196
197 m_d->cachedshapes_driftdiscs[radius] = sep;
198 sep->ref();
199 return sep;
200}
201
202//____________________________________________________________________
203SoNode* HitsSoNodeManager::getShapeNode_ProjectedDriftTube( double halfLength, double radius,
204 bool inner, bool outer )
205{
206 m_d->sanitiseParameterValue(halfLength);
207 m_d->sanitiseParameterValueAllowZero(radius);
208 //Fixme: discretize by radius!!
209
210 double id(halfLength-9999.9*radius-(inner?0.0:-9999799.99)-(outer?0.0:-9999997979.99));//something unique
211 std::map<double,SoNode*>::const_iterator it = m_d->cachedshapes_projdrifttubes.find(id);
212 if (it!=m_d->cachedshapes_projdrifttubes.end())
213 return it->second;
214
215 if (!inner&&!outer) {
216 //Should probably never be called. But whatever:
217 SoInfo * info = new SoInfo;//something harmless and lightweight.
218 info->ref();
219 m_d->cachedshapes_projdrifttubes[id] = info;
220 return info;
221 }
222
223 //Fix for inner projections to put the hits from short barrel straws onto same z as the long barrel straws:
224 double halfLengthInner = halfLength<160.0 ? 2*349.3150-halfLength : halfLength;
225 m_d->sanitiseParameterValue(halfLengthInner);
226
227 if (radius>0) {
228 SoSeparator*sep = new SoSeparator;//fixme: check if sogroup improves performance.
229 SoRotationXYZ * rot = new SoRotationXYZ;
230 rot->axis.setValue(SoRotationXYZ::X);
231 rot->angle.setValue(M_PI*0.5f);
232 sep->addChild(rot);
233 SoCylinder * cyl = new SoCylinder;
234 cyl->radius.setValue(radius);
235 cyl->height.setValue(m_d->driftdischeight);
236 if (inner) {
237 SoTranslation * trans = new SoTranslation;
238 trans->translation.setValue(0.0f,halfLengthInner,0.0f);
239 sep->addChild(trans);
240 sep->addChild(cyl);
241 }
242 if (outer) {
243 SoTranslation * trans = new SoTranslation;
244 trans->translation.setValue(0.0f,(inner?-halfLength-halfLengthInner:-halfLength),0.0f);
245 sep->addChild(trans);
246 sep->addChild(cyl);
247 }
248 m_d->cachedshapes_projdrifttubes[id] = sep;
249 sep->ref();
250 return sep;
251 } else {
252 SoPointSet * scatPointSet = new SoPointSet;
253 SoVertexProperty * scatVtxProperty = new SoVertexProperty;
254 int i(0);
255 if (inner)
256 scatVtxProperty->vertex.set1Value(i++,0.0f,0.0f,halfLengthInner);
257 if (outer)
258 scatVtxProperty->vertex.set1Value(i++,0.0f,0.0f,-halfLength);
259 scatPointSet->numPoints=i;
260 scatPointSet->vertexProperty.setValue(scatVtxProperty);
261 m_d->cachedshapes_projdrifttubes[id] = scatPointSet;
262 scatPointSet->ref();
263 return scatPointSet;
264 }
265}
266
267
268//____________________________________________________________________
270{
271 //std::cout << "HitsSoNodeManager::getShapeNode_Strip()" << std::endl;
272
273 m_d->sanitiseParameterValueAllowZero(length);
274 m_d->sanitiseParameterValueAllowZero(width);
275 m_d->sanitiseParameterValueAllowZero(depth);
276
277 double id(length-width*9999.99-depth*999999799.0);//something unique
278 std::map<double,SoNode*>::const_iterator it = m_d->cachedshapes_strips.find(id);
279 if (it!=m_d->cachedshapes_strips.end())
280 return it->second;
281
282 if (width==0.0&&depth==0) {
283 if (length==0.0) {
284 std::cout << "lengthStrip==0.0, returning a point..." << std::endl;
285 return getShapeNode_Point();
286 }
287 //Return a line:
288 SoVertexProperty * scatVtxProperty = new SoVertexProperty();
289 scatVtxProperty->vertex.set1Value(0, 0.0f,-length*0.5f,0.0f);
290 scatVtxProperty->vertex.set1Value(1, 0.0f, length*0.5f,0.0f);
291 SoLineSet * line = new SoLineSet();
292 line->numVertices = 2;
293 line->vertexProperty = scatVtxProperty;
294 m_d->cachedshapes_strips[id] = line;
295 line->ref();
296 return line;
297 } else {
298 //Return a box.
300 SoGenericBox* cube = new SoGenericBox;
301 m_d->sanitiseParameterValue(length);
302 m_d->sanitiseParameterValue(width);
303 m_d->sanitiseParameterValue(depth);
304 cube->setParametersForBox(0.5*width,0.5*length,0.5*depth);
305 m_d->cachedshapes_strips[id] = cube;
306 cube->drawEdgeLines = true;
307 cube->ref();
308 return cube;
309 }
314}
315
316//____________________________________________________________________
317SoNode* HitsSoNodeManager::getShapeNode_Wire( double length, double minWidth, double maxWidth, double depth )
318{
319
320 //std::cout << "HitsSoNodeManager::getShapeNode_Wire()" << std::endl;
321
322 m_d->sanitiseParameterValueAllowZero(length);
323 m_d->sanitiseParameterValueAllowZero(minWidth);
324 m_d->sanitiseParameterValueAllowZero(maxWidth);
325 m_d->sanitiseParameterValueAllowZero(depth);
326
327 //double id(length-minWidth*9999.99-depth*999999799.0);//something unique
328 //std::map<double,SoNode*>::const_iterator it = m_d->cachedshapes_strips.find(id);
329 //if (it!=m_d->cachedshapes_strips.end())
330 // return it->second;
331
332 if (maxWidth==0.0&&depth==0) {
333 if (length==0.0) {
334 std::cout << "lengthWire==0.0, returning a point..." << std::endl;
335 return getShapeNode_Point();
336 }
337 //Return a line:
338 SoVertexProperty * scatVtxProperty = new SoVertexProperty();
339 scatVtxProperty->vertex.set1Value(0, 0.0f,-length*0.5f,0.0f);
340 scatVtxProperty->vertex.set1Value(1, 0.0f, length*0.5f,0.0f);
341 SoLineSet * line = new SoLineSet();
342 line->numVertices = 2;
343 line->vertexProperty = scatVtxProperty;
344 //m_d->cachedshapes_strips[id] = line;
345 line->ref();
346 return line;
347 } else {
348 //Return a box.
350 SoGenericBox* trd = new SoGenericBox;
351 m_d->sanitiseParameterValue(length);
352 m_d->sanitiseParameterValue(minWidth);
353 m_d->sanitiseParameterValue(maxWidth);
354 m_d->sanitiseParameterValue(depth);
355 trd->setParametersForTrd(0.5*minWidth,0.5*maxWidth,0.5*length,0.5*length,0.5*depth);
356 //m_d->cachedshapes_strips[id] = trd;
357 trd->drawEdgeLines = true;
358 trd->ref();
359 return trd;
360 }
361}
362//____________________________________________________________________
363SoNode* HitsSoNodeManager::getShapeNode_Pad( double length, double minWidth, double maxWidth, double depth )
364{
365
366 //std::cout << "HitsSoNodeManager::getShapeNode_Pad()" << std::endl;
367
368 m_d->sanitiseParameterValueAllowZero(length);
369 m_d->sanitiseParameterValueAllowZero(minWidth);
370 m_d->sanitiseParameterValueAllowZero(maxWidth);
371 m_d->sanitiseParameterValueAllowZero(depth);
372
373 //double id(length-minWidth*9999.99-depth*999999799.0);//something unique
374 //std::map<double,SoNode*>::const_iterator it = m_d->cachedshapes_strips.find(id);
375 //if (it!=m_d->cachedshapes_strips.end())
376 // return it->second;
377
378 if (maxWidth==0.0 && depth==0) {
379 if (length==0.0) {
380 std::cout << "maxWidth==0.0 && depth==0 && lengthPad==0.0, returning a point..." << std::endl;
381 return getShapeNode_Point();
382 }
383 //Return a line:
384 //std::cout << "maxWidth==0.0 && depth==0, returning a line..." << std::endl;
385 SoVertexProperty * scatVtxProperty = new SoVertexProperty();
386 scatVtxProperty->vertex.set1Value(0, 0.0f,-length*0.5f,0.0f);
387 scatVtxProperty->vertex.set1Value(1, 0.0f, length*0.5f,0.0f);
388 SoLineSet * line = new SoLineSet();
389 line->numVertices = 2;
390 line->vertexProperty = scatVtxProperty;
391 //m_d->cachedshapes_strips[id] = line;
392 line->ref();
393 return line;
394 } else {
395 //std::cout << "returning a box..." << std::endl;
396 //Return a box.
398 SoGenericBox* trd = new SoGenericBox;
399 m_d->sanitiseParameterValue(length);
400 m_d->sanitiseParameterValue(minWidth);
401 m_d->sanitiseParameterValue(maxWidth);
402 m_d->sanitiseParameterValue(depth);
403 trd->setParametersForTrd(0.5*minWidth,0.5*maxWidth,0.5*length,0.5*length,0.5*depth);
404 //m_d->cachedshapes_strips[id] = trd;
405 trd->drawEdgeLines = true;
406 trd->ref();
407 return trd;
408 }
409}
410
411//____________________________________________________________________
413{
414 if (!m_d->cachedshape_point) {
415 SoPointSet * scatPointSet = new SoPointSet;
416 SoVertexProperty * scatVtxProperty = new SoVertexProperty;
417 scatVtxProperty->vertex.set1Value(0,0.0f,0.0f,0.0f);
418 scatPointSet->numPoints=1;
419 scatPointSet->vertexProperty.setValue(scatVtxProperty);
420 m_d->cachedshape_point = scatPointSet;
421 m_d->cachedshape_point->ref();
422 }
423 return m_d->cachedshape_point;
424}
425
426//____________________________________________________________________
428{
429 std::map<double,SoNode*>::const_iterator it = m_d->cachedshapes_cross.find(extent);
430 if (it!=m_d->cachedshapes_cross.end())
431 return it->second;
432
433 SoVertexProperty * vertices = new SoVertexProperty;
434 int iver(0);
435 vertices->vertex.set1Value(iver++,-extent,0.0,0.0);
436 vertices->vertex.set1Value(iver++,+extent,0.0,0.0);
437 vertices->vertex.set1Value(iver++,0.0,-extent,0.0);
438 vertices->vertex.set1Value(iver++,0.0,+extent,0.0);
439 vertices->vertex.set1Value(iver++,0.0,0.0,-extent);
440 vertices->vertex.set1Value(iver++,0.0,0.0,+extent);
441
442 SoLineSet * cross = new SoLineSet;
443 cross->vertexProperty = vertices;
444 int numlines(0);
445 cross->numVertices.set1Value(numlines++,2);
446 cross->numVertices.set1Value(numlines++,2);
447 cross->numVertices.set1Value(numlines++,2);
448
449 m_d->cachedshapes_cross[extent] = cross;
450 m_d->cachedshapes_cross[extent]->ref();
451
452 return m_d->cachedshapes_cross[extent];
453}
454
455//____________________________________________________________________
457{
458 if (!m_d->cached_unittransform) {
459 m_d->cached_unittransform = new SoTransform;
460 m_d->cached_unittransform->ref();
461 }
462 return m_d->cached_unittransform;
463}
#define M_PI
double length(const pvec &v)
const double width
#define x
void summarise(unsigned n, const QString &shapename) const
std::map< double, SoNode *, CxxUtils::fpcompare_fn::less > cachedshapes_projdrifttubes
std::map< double, SoNode *, CxxUtils::fpcompare_fn::less > cachedshapes_drifttubes
std::map< double, SoNode *, CxxUtils::fpcompare_fn::less > cachedshapes_cross
static void unrefValues(T &t)
void sanitiseParameterValueAllowZero(double &x)
void sanitiseParameterValue(double &x)
HitsSoNodeManager * theclass
std::map< double, SoNode *, CxxUtils::fpcompare_fn::less > cachedshapes_driftdiscs
std::map< double, SoNode *, CxxUtils::fpcompare_fn::less > cachedshapes_strips
HitsSoNodeManager(IVP1System *sys=0)
SoNode * getShapeNode_Wire(double length, double minWidth=0, double maxWidth=0, double depth=0)
SoNode * getShapeNode_DriftDisc(double radius)
SoNode * getShapeNode_Cross(double extent)
SoNode * getShapeNode_Strip(double length, double width=0, double depth=0)
SoTransform * getUnitTransform()
SoNode * getShapeNode_Pad(double length, double minWidth=0, double maxWidth=0, double depth=0)
SoNode * getShapeNode_ProjectedDriftTube(double halfLength, double radius, bool inner, bool outer)
SoNode * getShapeNode_DriftTube(double halfLength, double radius)
void setParametersForBox(float dx, float dy, float dz, float xcenter=0.0, float ycenter=0.0, float zcenter=0.0)
void setParametersForTrd(float dx1, float dx2, float dy1, float dy2, float dz)
static void initClass()
SoSFBool drawEdgeLines
VP1HelperClassBase(IVP1System *sys=0, QString helpername="")
void messageVerbose(const QString &) const
static bool verbose()
Definition VP1Msg.h:31
std::string depth
tag string for intendation
Definition fastadd.cxx:46
Workaround x86 precision issues for FP inequality comparisons.