Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4OpenInventorSceneHandler.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id$
28//
29//
30// Jeff Kallenbach 01 Aug 1996
31// OpenInventor stored scene - creates OpenInventor display lists.
32#ifdef G4VIS_BUILD_OI_DRIVER
33
34// this :
36
37#include <Inventor/SoPath.h>
38#include <Inventor/SoNodeKitPath.h>
39#include <Inventor/nodes/SoCoordinate3.h>
40#include <Inventor/nodes/SoCoordinate4.h>
41#include <Inventor/nodes/SoSeparator.h>
42#include <Inventor/nodes/SoDrawStyle.h>
43#include <Inventor/nodes/SoLightModel.h>
44#include <Inventor/nodes/SoMaterial.h>
45#include <Inventor/nodes/SoLineSet.h>
46#include <Inventor/nodes/SoCube.h>
47#include <Inventor/nodes/SoFont.h>
48#include <Inventor/nodes/SoText2.h>
49#include <Inventor/nodes/SoFaceSet.h>
50#include <Inventor/nodes/SoNormal.h>
51#include <Inventor/nodes/SoNormalBinding.h>
52#include <Inventor/nodes/SoComplexity.h>
53#include <Inventor/nodes/SoNurbsSurface.h>
54#include <Inventor/nodes/SoTranslation.h>
55#include <Inventor/nodes/SoTransform.h>
56#include <Inventor/nodes/SoResetTransform.h>
57#include <Inventor/nodes/SoMatrixTransform.h>
58
59#define USE_SOPOLYHEDRON
60
61#ifndef USE_SOPOLYHEDRON
62#include "HEPVis/nodes/SoBox.h"
63#include "HEPVis/nodes/SoTubs.h"
64#include "HEPVis/nodes/SoCons.h"
65#include "HEPVis/nodes/SoTrd.h"
66#include "HEPVis/nodes/SoTrap.h"
67#endif
69typedef HEPVis_SoMarkerSet SoMarkerSet;
72
73#include "SoG4Polyhedron.h"
74#include "SoG4LineSet.h"
75#include "SoG4MarkerSet.h"
76
77#include "G4Scene.hh"
78#include "G4NURBS.hh"
79#include "G4OpenInventor.hh"
81#include "G4ThreeVector.hh"
82#include "G4Point3D.hh"
83#include "G4Normal3D.hh"
84#include "G4Transform3D.hh"
85#include "G4Polyline.hh"
86#include "G4Text.hh"
87#include "G4Circle.hh"
88#include "G4Square.hh"
89#include "G4Polymarker.hh"
90#include "G4Polyhedron.hh"
91#include "G4Box.hh"
92#include "G4Tubs.hh"
93#include "G4Cons.hh"
94#include "G4Trap.hh"
95#include "G4Trd.hh"
97#include "G4VPhysicalVolume.hh"
98#include "G4LogicalVolume.hh"
99#include "G4Material.hh"
100#include "G4VisAttributes.hh"
101
102G4int G4OpenInventorSceneHandler::fSceneIdCount = 0;
103
104G4OpenInventorSceneHandler::G4OpenInventorSceneHandler (G4OpenInventor& system,
105 const G4String& name)
106:G4VSceneHandler (system, fSceneIdCount++, name)
107,fRoot(0)
108,fDetectorRoot(0)
109,fTransientRoot(0)
110,fCurrentSeparator(0)
111,fModelingSolid(false)
112,fReducedWireFrame(true)
113,fStyleCache(0)
114,fPreviewAndFull(true)
115{
116 fStyleCache = new SoStyleCache;
117 fStyleCache->ref();
118
119 fRoot = new SoSeparator;
120 fRoot->ref();
121 fRoot->setName("Root");
122
123 fDetectorRoot = new SoSeparator;
124 fDetectorRoot->setName("StaticRoot");
125 fRoot->addChild(fDetectorRoot);
126
127 fTransientRoot = new SoSeparator;
128 fTransientRoot->setName("TransientRoot");
129 fRoot->addChild(fTransientRoot);
130
131 fCurrentSeparator = fTransientRoot;
132}
133
134G4OpenInventorSceneHandler::~G4OpenInventorSceneHandler ()
135{
136 fRoot->unref();
137 fStyleCache->unref();
138}
139
140void G4OpenInventorSceneHandler::ClearStore ()
141{
142 fDetectorRoot->removeAllChildren();
143 fSeparatorMap.clear();
144
145 fTransientRoot->removeAllChildren();
146}
147
148void G4OpenInventorSceneHandler::ClearTransientStore ()
149{
150 fTransientRoot->removeAllChildren();
151}
152
153//
154// Generates prerequisites for solids
155//
156void G4OpenInventorSceneHandler::PreAddSolid
157(const G4Transform3D& objectTransformation,
158 const G4VisAttributes& visAttribs)
159{
160 G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs);
161 // Stores arguments away for future use, e.g., AddPrimitives.
162
163 GeneratePrerequisites();
164}
165
166//
167// Generates prerequisites for primitives
168//
169void G4OpenInventorSceneHandler::BeginPrimitives
170(const G4Transform3D& objectTransformation) {
171
172 G4VSceneHandler::BeginPrimitives (objectTransformation);
173
174 // If thread of control has already passed through PreAddSolid,
175 // avoid opening a graphical data base component again.
176 if (!fProcessingSolid) {
177 GeneratePrerequisites();
178 }
179}
180
181//
182// Method for handling G4Polyline objects (from tracking).
183//
184void G4OpenInventorSceneHandler::AddPrimitive (const G4Polyline& line)
185{
186 if (fProcessing2D) {
187 static G4bool warned = false;
188 if (!warned) {
189 warned = true;
191 ("G4OpenInventorSceneHandler::AddPrimitive (const G4Polyline&)",
192 "OpenInventor-0001", JustWarning,
193 "2D polylines not implemented. Ignored.");
194 }
195 return;
196 }
197
198 // Get vis attributes - pick up defaults if none.
199 const G4VisAttributes* pVA =
200 fpViewer -> GetApplicableVisAttributes (line.GetVisAttributes ());
201
202 AddProperties(pVA); // Colour, etc.
203 AddTransform(); // Transformation
204
205 G4int nPoints = line.size();
206 SbVec3f* pCoords = new SbVec3f[nPoints];
207
208 for (G4int iPoint = 0; iPoint < nPoints ; iPoint++) {
209 pCoords[iPoint].setValue((float)line[iPoint].x(),
210 (float)line[iPoint].y(),
211 (float)line[iPoint].z());
212 }
213
214 //
215 // Point Set
216 //
217 SoCoordinate3 *polyCoords = new SoCoordinate3;
218 polyCoords->point.setValues(0,nPoints,pCoords);
219 fCurrentSeparator->addChild(polyCoords);
220
221 //
222 // Wireframe
223 //
224 SoDrawStyle* drawStyle = fStyleCache->getLineStyle();
225 fCurrentSeparator->addChild(drawStyle);
226
227 SoG4LineSet *pLine = new SoG4LineSet;
228
229 // Loads G4Atts for picking...
230 if (fpViewer->GetViewParameters().IsPicking()) LoadAtts(line, pLine);
231
232#ifdef INVENTOR2_0
233 pLine->numVertices.setValues(0,1,(const long *)&nPoints);
234#else
235 pLine->numVertices.setValues(0,1,&nPoints);
236#endif
237
238 fCurrentSeparator->addChild(pLine);
239
240 delete [] pCoords;
241}
242
243void G4OpenInventorSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
244{
245 if (fProcessing2D) {
246 static G4bool warned = false;
247 if (!warned) {
248 warned = true;
250 ("G4OpenInventorSceneHandler::AddPrimitive (const G4Polymarker&)",
251 "OpenInventor-0002", JustWarning,
252 "2D polymarkers not implemented. Ignored.");
253 }
254 return;
255 }
256
257 // Get vis attributes - pick up defaults if none.
258 const G4VisAttributes* pVA =
259 fpViewer -> GetApplicableVisAttributes (polymarker.GetVisAttributes ());
260
261 AddProperties(pVA); // Colour, etc.
262 AddTransform(); // Transformation
263
264 G4int pointn = polymarker.size();
265 if(pointn<=0) return;
266
267 SbVec3f* points = new SbVec3f[pointn];
268 for (G4int iPoint = 0; iPoint < pointn ; iPoint++) {
269 points[iPoint].setValue((float)polymarker[iPoint].x(),
270 (float)polymarker[iPoint].y(),
271 (float)polymarker[iPoint].z());
272 }
273
274 SoCoordinate3* coordinate3 = new SoCoordinate3;
275 coordinate3->point.setValues(0,pointn,points);
276 fCurrentSeparator->addChild(coordinate3);
277
278 MarkerSizeType sizeType;
279 G4double screenSize = GetMarkerSize (polymarker, sizeType);
280 switch (sizeType) {
281 default:
282 case screen:
283 // Draw in screen coordinates. OK.
284 break;
285 case world:
286 // Draw in world coordinates. Not implemented. Use screenSize = 10.
287 screenSize = 10.;
288 break;
289 }
290
291 SoG4MarkerSet* markerSet = new SoG4MarkerSet;
292 markerSet->numPoints = pointn;
293
294 // Loads G4Atts for picking...
295 if (fpViewer->GetViewParameters().IsPicking())
296 LoadAtts(polymarker, markerSet);
297
298 G4VMarker::FillStyle style = polymarker.GetFillStyle();
299 switch (polymarker.GetMarkerType()) {
300 default:
301 // Are available 5_5, 7_7 and 9_9
303 if (screenSize <= 5.) {
304 markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_5_5;
305 } else if (screenSize <= 7.) {
306 markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_7_7;
307 } else {
308 markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_9_9;
309 }
310 break;
312 if (screenSize <= 5.) {
313 if (style == G4VMarker::filled) {
314 markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_5_5;
315 } else {
316 markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_5_5;
317 }
318 } else if (screenSize <= 7.) {
319 if (style == G4VMarker::filled) {
320 markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_7_7;
321 } else {
322 markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_7_7;
323 }
324 } else {
325 if (style == G4VMarker::filled) {
326 markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_9_9;
327 } else {
328 markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_9_9;
329 }
330 }
331 break;
333 if (screenSize <= 5.) {
334 if (style == G4VMarker::filled) {
335 markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_5_5;
336 } else {
337 markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_5_5;
338 }
339 } else if (screenSize <= 7.) {
340 if (style == G4VMarker::filled) {
341 markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_7_7;
342 } else {
343 markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_7_7;
344 }
345 } else {
346 if (style == G4VMarker::filled) {
347 markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_9_9;
348 } else {
349 markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_9_9;
350 }
351 }
352 }
353 fCurrentSeparator->addChild(markerSet);
354
355 delete [] points;
356}
357
358// Method for handling G4Text objects
359//
360void G4OpenInventorSceneHandler::AddPrimitive (const G4Text& text)
361{
362 if (fProcessing2D) {
363 static G4bool warned = false;
364 if (!warned) {
365 warned = true;
367 ("G4OpenInventorSceneHandler::AddPrimitive (const G4Text&)",
368 "OpenInventor-0003", JustWarning,
369 "2D text not implemented. Ignored.");
370 }
371 return;
372 }
373
374 AddProperties(text.GetVisAttributes()); // Colour, etc.
375 AddTransform(text.GetPosition()); // Transformation
376
377 //
378 // Color. Note: text colour is worked out differently. This
379 // over-rides the colour added in AddProperties...
380 //
381 const G4Colour& c = GetTextColour (text);
382 SoMaterial* material =
383 fStyleCache->getMaterial((float)c.GetRed(),
384 (float)c.GetGreen(),
385 (float)c.GetBlue(),
386 (float)(1-c.GetAlpha()));
387 fCurrentSeparator->addChild(material);
388
389 MarkerSizeType sizeType;
390 G4double size = GetMarkerSize (text, sizeType);
391 switch (sizeType) {
392 default:
393 case screen:
394 // Draw in screen coordinates. OK.
395 break;
396 case world:
397 // Draw in world coordinates. Not implemented. Use size = 20.
398 size = 20.;
399 break;
400 }
401
402 //
403 // Font
404 //
405 SoFont *g4Font = new SoFont();
406 g4Font->size = size;
407 fCurrentSeparator->addChild(g4Font);
408
409 //
410 // Text
411 //
412 SoText2 *g4String = new SoText2();
413 g4String->string.setValue(text.GetText());
414 g4String->spacing = 2.0;
415 switch (text.GetLayout()) {
416 default:
417 case G4Text::left:
418 g4String->justification = SoText2::LEFT; break;
419 case G4Text::centre:
420 g4String->justification = SoText2::CENTER; break;
421 case G4Text::right:
422 g4String->justification = SoText2::RIGHT; break;
423 }
424 fCurrentSeparator->addChild(g4String);
425}
426
427//
428// Method for handling G4Circle objects
429//
430void G4OpenInventorSceneHandler::AddPrimitive (const G4Circle& circle) {
431 AddCircleSquare(G4OICircle, circle);
432}
433
434//
435// Method for handling G4Square objects - defaults to wireframe
436//
437void G4OpenInventorSceneHandler::AddPrimitive (const G4Square& square) {
438 AddCircleSquare(G4OISquare, square);
439}
440
441void G4OpenInventorSceneHandler::AddCircleSquare
442(G4OIMarker markerType, const G4VMarker& marker)
443{
444 if (fProcessing2D) {
445 static G4bool warned = false;
446 if (!warned) {
447 warned = true;
449 ("G4OpenInventorSceneHandler::AddCircleSquare",
450 "OpenInventor-0004", JustWarning,
451 "2D circles and squares not implemented. Ignored.");
452 }
453 return;
454 }
455
456 // Get vis attributes - pick up defaults if none.
457 const G4VisAttributes* pVA =
458 fpViewer -> GetApplicableVisAttributes (marker.GetVisAttributes ());
459
460 AddProperties(pVA); // Colour, etc.
461 AddTransform(); // Transformation
462
463 MarkerSizeType sizeType;
464 G4double screenSize = GetMarkerSize (marker, sizeType);
465 switch (sizeType) {
466 default:
467 case screen:
468 // Draw in screen coordinates. OK.
469 break;
470 case world:
471 // Draw in world coordinates. Not implemented. Use size = 10.
472 screenSize = 10.;
473 break;
474 }
475
476 G4Point3D centre = marker.GetPosition();
477
478 // Borrowed from AddPrimitive(G4Polymarker) - inefficient? JA
479 SbVec3f* points = new SbVec3f[1];
480 points[0].setValue((float)centre.x(),
481 (float)centre.y(),
482 (float)centre.z());
483 SoCoordinate3* coordinate3 = new SoCoordinate3;
484 coordinate3->point.setValues(0,1,points);
485 fCurrentSeparator->addChild(coordinate3);
486
487 SoG4MarkerSet* markerSet = new SoG4MarkerSet;
488 markerSet->numPoints = 1;
489
490 // Loads G4Atts for picking...
491 if (fpViewer->GetViewParameters().IsPicking()) LoadAtts(marker, markerSet);
492
493 G4VMarker::FillStyle style = marker.GetFillStyle();
494 switch (markerType) {
495 case G4OICircle:
496 if (screenSize <= 5.) {
497 if (style == G4VMarker::filled) {
498 markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_5_5;
499 } else {
500 markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_5_5;
501 }
502 } else if (screenSize <= 7.) {
503 if (style == G4VMarker::filled) {
504 markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_7_7;
505 } else {
506 markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_7_7;
507 }
508 } else {
509 if (style == G4VMarker::filled) {
510 markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_9_9;
511 } else {
512 markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_9_9;
513 }
514 }
515 break;
516 case G4OISquare:
517 if (screenSize <= 5.) {
518 if (style == G4VMarker::filled) {
519 markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_5_5;
520 } else {
521 markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_5_5;
522 }
523 } else if (screenSize <= 7.) {
524 if (style == G4VMarker::filled) {
525 markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_7_7;
526 } else {
527 markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_7_7;
528 }
529 } else {
530 if (style == G4VMarker::filled) {
531 markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_9_9;
532 } else {
533 markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_9_9;
534 }
535 }
536 break;
537 }
538 fCurrentSeparator->addChild(markerSet);
539
540 delete [] points;
541}
542
543//
544// Method for handling G4Polyhedron objects for drawing solids.
545//
546void G4OpenInventorSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron)
547{
548 if (polyhedron.GetNoFacets() == 0) return;
549
550 if (fProcessing2D) {
551 static G4bool warned = false;
552 if (!warned) {
553 warned = true;
555 ("G4OpenInventorSceneHandler::AddPrimitive (const G4Polyhedron&)",
556 "OpenInventor-0005", JustWarning,
557 "2D polyhedra not implemented. Ignored.");
558 }
559 return;
560 }
561
562 // Get vis attributes - pick up defaults if none.
563 const G4VisAttributes* pVA =
564 fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
565
566 AddProperties(pVA); // Colour, etc.
567 AddTransform(); // Transformation
568
569 SoG4Polyhedron* soPolyhedron = new SoG4Polyhedron(polyhedron);
570
571 // Loads G4Atts for picking...
572 if (fpViewer->GetViewParameters().IsPicking())
573 LoadAtts(polyhedron, soPolyhedron);
574
575 SbString name = "Non-geometry";
576 G4PhysicalVolumeModel* pPVModel =
577 dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
578 if (pPVModel) {
579 name = pPVModel->GetCurrentLV()->GetName().c_str();
580 }
581 SbName sbName(name);
582 soPolyhedron->setName(sbName);
583 soPolyhedron->solid.setValue(fModelingSolid);
584 soPolyhedron->reducedWireFrame.setValue(fReducedWireFrame?TRUE:FALSE);
585 fCurrentSeparator->addChild(soPolyhedron);
586}
587
588//
589// Method for handling G4NURBS objects for drawing solids.
590// Knots and Ctrl Pnts MUST be arrays of GLfloats.
591//
592void G4OpenInventorSceneHandler::AddPrimitive (const G4NURBS& nurb) {
593
594 if (fProcessing2D) {
595 static G4bool warned = false;
596 if (!warned) {
597 warned = true;
599 ("G4OpenInventorSceneHandler::AddPrimitive (const G4NURBS&)",
600 "OpenInventor-0006", JustWarning,
601 "2D NURBS not implemented. Ignored.");
602 }
603 return;
604 }
605
606 // Get vis attributes - pick up defaults if none.
607 const G4VisAttributes* pVA =
608 fpViewer -> GetApplicableVisAttributes (nurb.GetVisAttributes ());
609
610 AddProperties(pVA); // Colour, etc.
611 AddTransform(); // Transformation
612
613 G4float *u_knot_array, *u_knot_array_ptr;
614 u_knot_array = u_knot_array_ptr = new G4float [nurb.GetnbrKnots(G4NURBS::U)];
615 G4NURBS::KnotsIterator u_iterator (nurb, G4NURBS::U);
616 while (u_iterator.pick (u_knot_array_ptr++)){}
617
618 G4float *v_knot_array, *v_knot_array_ptr;
619 v_knot_array = v_knot_array_ptr = new G4float [nurb.GetnbrKnots(G4NURBS::V)];
620 G4NURBS::KnotsIterator v_iterator (nurb, G4NURBS::V);
621 while (v_iterator.pick (v_knot_array_ptr++)){}
622
623 G4float *ctrl_pnt_array, *ctrl_pnt_array_ptr;
624 ctrl_pnt_array = ctrl_pnt_array_ptr =
625 new G4float [nurb.GettotalnbrCtrlPts () * G4NURBS::NofC*sizeof(G4float)];
626 G4NURBS::CtrlPtsCoordsIterator c_p_iterator (nurb);
627 while (c_p_iterator.pick (ctrl_pnt_array_ptr++)){}
628
629 SoSeparator *surfSep = new SoSeparator();
630
631 //
632 // Set up NURBS
633 //
634 SoComplexity *complexity = new SoComplexity;
635 SoCoordinate4 *ctlPts = new SoCoordinate4;
636 SoNurbsSurface *oi_nurb = new SoNurbsSurface;
637
638 complexity->value = (float)0.6;
639 G4int nPoints = nurb.GettotalnbrCtrlPts ();
640 SbVec4f* points = new SbVec4f[nPoints];
641 for (G4int iPoint = 0; iPoint < nPoints ; iPoint++) {
642 points[iPoint].setValue(
643 ctrl_pnt_array[iPoint*4 + 0],
644 ctrl_pnt_array[iPoint*4 + 1],
645 ctrl_pnt_array[iPoint*4 + 2],
646 ctrl_pnt_array[iPoint*4 + 3]);
647 }
648 ctlPts->point.setValues (0,nPoints,points);
649 oi_nurb->numUControlPoints = nurb.GetnbrCtrlPts(G4NURBS::U);
650 oi_nurb->numVControlPoints = nurb.GetnbrCtrlPts(G4NURBS::V);
651 oi_nurb->uKnotVector.setValues(0,nurb.GetnbrKnots(G4NURBS::U),u_knot_array);
652 oi_nurb->vKnotVector.setValues(0,nurb.GetnbrKnots(G4NURBS::V),v_knot_array);
653
654 surfSep->addChild(complexity);
655 surfSep->addChild(ctlPts);
656 surfSep->addChild(oi_nurb);
657
658 fCurrentSeparator->addChild(surfSep);
659
660 //
661 // Clean-up
662 //
663 delete [] u_knot_array;
664 delete [] v_knot_array;
665 delete [] ctrl_pnt_array;
666 delete [] points;
667}
668
669void G4OpenInventorSceneHandler::GeneratePrerequisites()
670{
671 // Utility for PreAddSolid and BeginPrimitives.
672
673 // This routines prepares for adding items to the scene database. We
674 // are expecting two kinds of solids: leaf parts and non-leaf parts.
675 // For non-leaf parts, we create a detector tree kit. This has two
676 // separators. The solid itself goes in the preview separator, the
677 // full separator is forseen for daughters. This separator is not
678 // only created--it is also put in a dictionary for future use by
679 // the leaf part.
680
681 // For leaf parts, we first locate the mother volume and find its
682 // separator through the dictionary.
683
684 // The private member fCurrentSeparator is set to the proper
685 // location on in the scene database so that when the solid is
686 // actually added (in addthis), it is put in the right place.
687
688 G4PhysicalVolumeModel* pPVModel =
689 dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
690
691 if (pPVModel) {
692
693 // This call comes from a G4PhysicalVolumeModel. drawnPVPath is
694 // the path of the current drawn (non-culled) volume in terms of
695 // drawn (non-culled) ancesters. Each node is identified by a
696 // PVNodeID object, which is a physical volume and copy number. It
697 // is a vector of PVNodeIDs corresponding to the geometry hierarchy
698 // actually selected, i.e., not culled.
700 typedef std::vector<PVNodeID> PVPath;
701 const PVPath& drawnPVPath = pPVModel->GetDrawnPVPath();
702 //G4int currentDepth = pPVModel->GetCurrentDepth();
703 G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
704 G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
705 //G4Material* pCurrentMaterial = pPVModel->GetCurrentMaterial();
706 // Note: pCurrentMaterial may be zero (parallel world).
707
708 // The simplest algorithm, used by the Open Inventor Driver
709 // developers, is to rely on the fact the G4PhysicalVolumeModel
710 // traverses the geometry hierarchy in an orderly manner. The last
711 // mother, if any, will be the node to which the volume should be
712 // added. So it is enough to keep a map of scene graph nodes keyed
713 // on the volume path ID. Actually, it is enough to use the logical
714 // volume as the key. (An alternative would be to keep the PVNodeID
715 // in the tree and match the PVPath from the root down.)
716
717 // Find mother. ri points to mother, if any...
718 PVPath::const_reverse_iterator ri;
719 G4LogicalVolume* MotherVolume = 0;
720 ri = ++drawnPVPath.rbegin();
721 if (ri != drawnPVPath.rend()) {
722 // This volume has a mother.
723 MotherVolume = ri->GetPhysicalVolume()->GetLogicalVolume();
724 }
725
726 if (pCurrentLV->GetNoDaughters()!=0 ||
727 pCurrentPV->IsReplicated()) { //????Don't understand this???? JA
728 // This block of code is executed for non-leaf parts:
729
730 // Make the detector tree kit:
731 SoDetectorTreeKit* detectorTreeKit = new SoDetectorTreeKit();
732
733 SoSeparator* previewSeparator =
734 (SoSeparator*) detectorTreeKit->getPart("previewSeparator",TRUE);
735 previewSeparator->renderCaching = SoSeparator::OFF;
736
737 SoSeparator* fullSeparator =
738 (SoSeparator*) detectorTreeKit->getPart("fullSeparator", TRUE);
739 fullSeparator->renderCaching = SoSeparator::OFF;
740
741 if(fPreviewAndFull) detectorTreeKit->setPreviewAndFull();
742 else detectorTreeKit->setPreview(TRUE);
743
744 // Colour, etc., for SoDetectorTreeKit. Treated differently to
745 // othere SoNodes(?). Use fpVisAttribs stored away in
746 // PreAddSolid...
747 const G4VisAttributes* pApplicableVisAttribs =
748 fpViewer->GetApplicableVisAttributes (fpVisAttribs);
749
750 // First find the color attributes...
751 const G4Colour& g4Col = pApplicableVisAttribs->GetColour ();
752 const double red = g4Col.GetRed ();
753 const double green = g4Col.GetGreen ();
754 const double blue = g4Col.GetBlue ();
755 double transparency = 1 - g4Col.GetAlpha();
756
757 // Drawing style...
758 G4ViewParameters::DrawingStyle drawing_style =
759 GetDrawingStyle(pApplicableVisAttribs);
760 switch (drawing_style) {
762 fModelingSolid = false;
763 break;
767 fModelingSolid = true;
768 break;
769 }
770
771 SoMaterial* material =
772 fStyleCache->getMaterial((float)red,
773 (float)green,
774 (float)blue,
775 (float)transparency);
776 detectorTreeKit->setPart("appearance.material",material);
777
778 SoLightModel* lightModel =
779 fModelingSolid ? fStyleCache->getLightModelPhong() :
780 fStyleCache->getLightModelBaseColor();
781 detectorTreeKit->setPart("appearance.lightModel",lightModel);
782
783 // Add the full separator to the dictionary; it is indexed by the
784 // address of the logical volume!
785 fSeparatorMap[pCurrentLV] = fullSeparator;
786
787 // Find out where to add this volume.
788 // If no mother can be found, it goes under root.
789 if (MotherVolume) {
790 if (fSeparatorMap.find(MotherVolume) != fSeparatorMap.end()) {
791 //printf("debug : PreAddSolid : mother %s found in map\n",
792 // MotherVolume->GetName().c_str());
793 fSeparatorMap[MotherVolume]->addChild(detectorTreeKit);
794 } else {
795 // Mother not previously encountered. Shouldn't happen, since
796 // G4PhysicalVolumeModel sends volumes as it encounters them,
797 // i.e., mothers before daughters, in its descent of the
798 // geometry tree. Error!
799 G4cout <<
800 "ERROR: G4OpenInventorSceneHandler::GeneratePrerequisites: Mother "
801 << ri->GetPhysicalVolume()->GetName()
802 << ':' << ri->GetCopyNo()
803 << " not previously encountered."
804 "\nShouldn't happen! Please report to visualization coordinator."
805 << G4endl;
806 // Continue anyway. Add to root of scene graph tree...
807 //printf("debug : PreAddSolid : mother %s not found in map !!!\n",
808 // MotherVolume->GetName().c_str());
809 fDetectorRoot->addChild(detectorTreeKit);
810 }
811 } else {
812 //printf("debug : PreAddSolid : has no mother\n");
813 fDetectorRoot->addChild(detectorTreeKit);
814 }
815
816 fCurrentSeparator = previewSeparator;
817
818 } else {
819 // This block of code is executed for leaf parts.
820
821 if (MotherVolume) {
822 if (fSeparatorMap.find(MotherVolume) != fSeparatorMap.end()) {
823 fCurrentSeparator = fSeparatorMap[MotherVolume];
824 } else {
825 // Mother not previously encountered. Shouldn't happen, since
826 // G4PhysicalVolumeModel sends volumes as it encounters them,
827 // i.e., mothers before daughters, in its descent of the
828 // geometry tree. Error!
829 G4cout << "ERROR: G4OpenInventorSceneHandler::PreAddSolid: Mother "
830 << ri->GetPhysicalVolume()->GetName()
831 << ':' << ri->GetCopyNo()
832 << " not previously encountered."
833 "\nShouldn't happen! Please report to visualization coordinator."
834 << G4endl;
835 // Continue anyway. Add to root of scene graph tree...
836 fCurrentSeparator = fDetectorRoot;
837 }
838 } else {
839 fCurrentSeparator = fDetectorRoot;
840 }
841 }
842
843 } else {
844 // Not from G4PhysicalVolumeModel, so add to root as leaf part...
845
846 if (fReadyForTransients) {
847 fCurrentSeparator = fTransientRoot;
848 } else {
849 fCurrentSeparator = fDetectorRoot;
850 }
851 }
852}
853
854void G4OpenInventorSceneHandler::AddProperties(const G4VisAttributes* visAtts)
855{
856 // Use the applicable vis attributes...
857 const G4VisAttributes* pApplicableVisAttribs =
858 fpViewer->GetApplicableVisAttributes (visAtts);
859
860 // First find the color attributes...
861 const G4Colour& g4Col = pApplicableVisAttribs->GetColour ();
862 const double red = g4Col.GetRed ();
863 const double green = g4Col.GetGreen ();
864 const double blue = g4Col.GetBlue ();
865 double transparency = 1 - g4Col.GetAlpha();
866
867 // Drawing style...
868 G4ViewParameters::DrawingStyle drawing_style =
869 GetDrawingStyle(pApplicableVisAttribs);
870 switch (drawing_style) {
872 fModelingSolid = false;
873 break;
877 fModelingSolid = true;
878 break;
879 }
880
881 // Edge visibility...
882 G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pApplicableVisAttribs);
883 fReducedWireFrame = !isAuxEdgeVisible;
884
885 SoMaterial* material =
886 fStyleCache->getMaterial((float)red,
887 (float)green,
888 (float)blue,
889 (float)transparency);
890 fCurrentSeparator->addChild(material);
891
892 SoLightModel* lightModel =
893 fModelingSolid ? fStyleCache->getLightModelPhong() :
894 fStyleCache->getLightModelBaseColor();
895 fCurrentSeparator->addChild(lightModel);
896}
897
898void G4OpenInventorSceneHandler::AddTransform(const G4Point3D& translation)
899{
900 // AddTransform takes fObjectTransformation and "adds" a translation.
901 // Set up the geometrical transformation for the coming
902 fCurrentSeparator->addChild(fStyleCache->getResetTransform());
903
904 SoMatrixTransform* matrixTransform = new SoMatrixTransform;
905 G4OpenInventorTransform3D oiTran
906 (fObjectTransformation * G4Translate3D(translation));
907 SbMatrix* sbMatrix = oiTran.GetSbMatrix();
908
909 const G4Vector3D scale = fpViewer->GetViewParameters().GetScaleFactor();
910 SbMatrix sbScale;
911 sbScale.setScale
912 (SbVec3f((float)scale.x(),(float)scale.y(),(float)scale.z()));
913 sbMatrix->multRight(sbScale);
914
915 matrixTransform->matrix.setValue(*sbMatrix);
916 delete sbMatrix;
917 fCurrentSeparator->addChild(matrixTransform);
918}
919#endif
@ JustWarning
HepGeom::Translate3D G4Translate3D
double G4double
Definition: G4Types.hh:64
float G4float
Definition: G4Types.hh:65
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define SoDetectorTreeKit
#define SoStyleCache
Definition: SoStyleCache.h:41
G4double GetBlue() const
Definition: G4Colour.hh:140
G4double GetAlpha() const
Definition: G4Colour.hh:141
G4double GetRed() const
Definition: G4Colour.hh:138
G4double GetGreen() const
Definition: G4Colour.hh:139
G4int GetNoDaughters() const
G4String GetName() const
G4int GetnbrKnots(t_direction in_dir) const
Definition: G4NURBS.hh:459
@ NofC
Definition: G4NURBS.hh:106
G4int GettotalnbrCtrlPts() const
Definition: G4NURBS.hh:437
G4int GetnbrCtrlPts(t_direction in_dir) const
Definition: G4NURBS.hh:463
const std::vector< G4PhysicalVolumeNodeID > & GetDrawnPVPath() const
G4VPhysicalVolume * GetCurrentPV() const
G4LogicalVolume * GetCurrentLV() const
MarkerType GetMarkerType() const
Definition: G4Text.hh:73
Layout GetLayout() const
G4String GetText() const
@ centre
Definition: G4Text.hh:77
@ right
Definition: G4Text.hh:77
@ left
Definition: G4Text.hh:77
FillStyle GetFillStyle() const
G4Point3D GetPosition() const
virtual G4bool IsReplicated() const =0
virtual void PreAddSolid(const G4Transform3D &objectTransformation, const G4VisAttributes &)
virtual void BeginPrimitives(const G4Transform3D &objectTransformation)
const G4Colour & GetColour() const
const G4VisAttributes * GetVisAttributes() const
G4int GetNoFacets() const
void setPreviewAndFull()
virtual void setPreview(SbBool Flag)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
#define TRUE
Definition: globals.hh:55
#define FALSE
Definition: globals.hh:52
G4PhysicalVolumeModel::G4PhysicalVolumeNodeID PVNodeID
std::vector< PVNodeID > PVPath