G4OpenInventorSceneHandler.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // Jeff Kallenbach 01 Aug 1996
00031 // OpenInventor stored scene - creates OpenInventor display lists.
00032 #ifdef G4VIS_BUILD_OI_DRIVER
00033 
00034 // this :
00035 #include "G4OpenInventorSceneHandler.hh"
00036 
00037 #include <Inventor/SoPath.h>
00038 #include <Inventor/SoNodeKitPath.h>
00039 #include <Inventor/nodes/SoCoordinate3.h>
00040 #include <Inventor/nodes/SoCoordinate4.h>
00041 #include <Inventor/nodes/SoSeparator.h>
00042 #include <Inventor/nodes/SoDrawStyle.h>
00043 #include <Inventor/nodes/SoLightModel.h>
00044 #include <Inventor/nodes/SoMaterial.h>
00045 #include <Inventor/nodes/SoLineSet.h>
00046 #include <Inventor/nodes/SoCube.h>
00047 #include <Inventor/nodes/SoFont.h>
00048 #include <Inventor/nodes/SoText2.h>
00049 #include <Inventor/nodes/SoFaceSet.h>
00050 #include <Inventor/nodes/SoNormal.h>
00051 #include <Inventor/nodes/SoNormalBinding.h>
00052 #include <Inventor/nodes/SoComplexity.h>
00053 #include <Inventor/nodes/SoNurbsSurface.h>
00054 #include <Inventor/nodes/SoTranslation.h>
00055 #include <Inventor/nodes/SoTransform.h>
00056 #include <Inventor/nodes/SoResetTransform.h>
00057 #include <Inventor/nodes/SoMatrixTransform.h>
00058 
00059 #define USE_SOPOLYHEDRON
00060 
00061 #ifndef USE_SOPOLYHEDRON
00062 #include "HEPVis/nodes/SoBox.h"
00063 #include "HEPVis/nodes/SoTubs.h"
00064 #include "HEPVis/nodes/SoCons.h"
00065 #include "HEPVis/nodes/SoTrd.h"
00066 #include "HEPVis/nodes/SoTrap.h"
00067 #endif
00068 #include "HEPVis/nodes/SoMarkerSet.h"
00069 typedef HEPVis_SoMarkerSet SoMarkerSet;
00070 #include "HEPVis/nodekits/SoDetectorTreeKit.h"
00071 #include "HEPVis/misc/SoStyleCache.h"
00072 
00073 #include "SoG4Polyhedron.h"
00074 #include "SoG4LineSet.h"
00075 #include "SoG4MarkerSet.h"
00076 
00077 #include "G4Scene.hh"
00078 #include "G4NURBS.hh"
00079 #include "G4OpenInventor.hh"
00080 #include "G4OpenInventorTransform3D.hh"
00081 #include "G4ThreeVector.hh"
00082 #include "G4Point3D.hh"
00083 #include "G4Normal3D.hh"
00084 #include "G4Transform3D.hh"
00085 #include "G4Polyline.hh"
00086 #include "G4Text.hh"
00087 #include "G4Circle.hh"
00088 #include "G4Square.hh"
00089 #include "G4Polymarker.hh"
00090 #include "G4Polyhedron.hh"
00091 #include "G4Box.hh"
00092 #include "G4Tubs.hh"
00093 #include "G4Cons.hh"
00094 #include "G4Trap.hh"
00095 #include "G4Trd.hh"
00096 #include "G4ModelingParameters.hh"
00097 #include "G4VPhysicalVolume.hh"
00098 #include "G4LogicalVolume.hh"
00099 #include "G4Material.hh"
00100 #include "G4VisAttributes.hh"
00101 
00102 G4int G4OpenInventorSceneHandler::fSceneIdCount = 0;
00103 
00104 G4OpenInventorSceneHandler::G4OpenInventorSceneHandler (G4OpenInventor& system,
00105                                           const G4String& name)
00106 :G4VSceneHandler (system, fSceneIdCount++, name)
00107 ,fRoot(0)
00108 ,fDetectorRoot(0)
00109 ,fTransientRoot(0)
00110 ,fCurrentSeparator(0)
00111 ,fModelingSolid(false)
00112 ,fReducedWireFrame(true)
00113 ,fStyleCache(0)
00114 ,fPreviewAndFull(true)
00115 {
00116   fStyleCache = new SoStyleCache;
00117   fStyleCache->ref();
00118 
00119   fRoot = new SoSeparator;
00120   fRoot->ref();
00121   fRoot->setName("Root");
00122   
00123   fDetectorRoot = new SoSeparator;
00124   fDetectorRoot->setName("StaticRoot");
00125   fRoot->addChild(fDetectorRoot);
00126   
00127   fTransientRoot = new SoSeparator;
00128   fTransientRoot->setName("TransientRoot");
00129   fRoot->addChild(fTransientRoot);
00130   
00131   fCurrentSeparator = fTransientRoot;
00132 }
00133 
00134 G4OpenInventorSceneHandler::~G4OpenInventorSceneHandler ()
00135 {
00136   fRoot->unref();
00137   fStyleCache->unref();
00138 }
00139 
00140 void G4OpenInventorSceneHandler::ClearStore ()
00141 {
00142   fDetectorRoot->removeAllChildren();
00143   fSeparatorMap.clear();
00144 
00145   fTransientRoot->removeAllChildren();
00146 }
00147 
00148 void G4OpenInventorSceneHandler::ClearTransientStore ()
00149 {
00150   fTransientRoot->removeAllChildren();
00151 }
00152 
00153 //
00154 // Generates prerequisites for solids
00155 //  
00156 void G4OpenInventorSceneHandler::PreAddSolid
00157 (const G4Transform3D& objectTransformation,
00158  const G4VisAttributes& visAttribs)
00159 {
00160   G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs);
00161   // Stores arguments away for future use, e.g., AddPrimitives.
00162 
00163   GeneratePrerequisites();
00164 }
00165 
00166 //
00167 // Generates prerequisites for primitives
00168 //  
00169 void G4OpenInventorSceneHandler::BeginPrimitives
00170 (const G4Transform3D& objectTransformation) {
00171 
00172   G4VSceneHandler::BeginPrimitives (objectTransformation);
00173 
00174   // If thread of control has already passed through PreAddSolid,
00175   // avoid opening a graphical data base component again.
00176   if (!fProcessingSolid) {
00177     GeneratePrerequisites();
00178   }
00179 }
00180 
00181 //
00182 // Method for handling G4Polyline objects (from tracking).
00183 //
00184 void G4OpenInventorSceneHandler::AddPrimitive (const G4Polyline& line)
00185 {
00186   if (fProcessing2D) {
00187     static G4bool warned = false;
00188     if (!warned) {
00189       warned = true;
00190       G4Exception
00191         ("G4OpenInventorSceneHandler::AddPrimitive (const G4Polyline&)",
00192          "OpenInventor-0001", JustWarning,
00193          "2D polylines not implemented.  Ignored.");
00194     }
00195     return;
00196   }
00197 
00198   // Get vis attributes - pick up defaults if none.
00199   const G4VisAttributes* pVA =
00200   fpViewer -> GetApplicableVisAttributes (line.GetVisAttributes ());
00201   
00202   AddProperties(pVA);  // Colour, etc.
00203   AddTransform();      // Transformation
00204 
00205   G4int nPoints = line.size();
00206   SbVec3f* pCoords = new SbVec3f[nPoints];
00207 
00208   for (G4int iPoint = 0; iPoint < nPoints ; iPoint++) {
00209     pCoords[iPoint].setValue((float)line[iPoint].x(),
00210                              (float)line[iPoint].y(),
00211                              (float)line[iPoint].z());
00212   }
00213 
00214   //
00215   // Point Set
00216   // 
00217   SoCoordinate3 *polyCoords = new SoCoordinate3;
00218   polyCoords->point.setValues(0,nPoints,pCoords);
00219   fCurrentSeparator->addChild(polyCoords);
00220   
00221   //
00222   // Wireframe
00223   // 
00224   SoDrawStyle* drawStyle = fStyleCache->getLineStyle();
00225   fCurrentSeparator->addChild(drawStyle);
00226 
00227   SoG4LineSet *pLine = new SoG4LineSet;
00228 
00229   // Loads G4Atts for picking...
00230   if (fpViewer->GetViewParameters().IsPicking()) LoadAtts(line, pLine);
00231 
00232 #ifdef INVENTOR2_0
00233   pLine->numVertices.setValues(0,1,(const long *)&nPoints);
00234 #else 
00235   pLine->numVertices.setValues(0,1,&nPoints);
00236 #endif
00237 
00238   fCurrentSeparator->addChild(pLine);
00239 
00240   delete [] pCoords;
00241 }
00242 
00243 void G4OpenInventorSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
00244 {
00245   if (fProcessing2D) {
00246     static G4bool warned = false;
00247     if (!warned) {
00248       warned = true;
00249       G4Exception
00250         ("G4OpenInventorSceneHandler::AddPrimitive (const G4Polymarker&)",
00251          "OpenInventor-0002", JustWarning,
00252          "2D polymarkers not implemented.  Ignored.");
00253     }
00254     return;
00255   }
00256 
00257   // Get vis attributes - pick up defaults if none.
00258   const G4VisAttributes* pVA =
00259   fpViewer -> GetApplicableVisAttributes (polymarker.GetVisAttributes ());
00260 
00261   AddProperties(pVA);  // Colour, etc.
00262   AddTransform();      // Transformation
00263 
00264   G4int pointn = polymarker.size();
00265   if(pointn<=0) return;
00266 
00267   SbVec3f* points = new SbVec3f[pointn];
00268   for (G4int iPoint = 0; iPoint < pointn ; iPoint++) {
00269     points[iPoint].setValue((float)polymarker[iPoint].x(),
00270                             (float)polymarker[iPoint].y(),
00271                             (float)polymarker[iPoint].z());
00272   }
00273 
00274   SoCoordinate3* coordinate3 = new SoCoordinate3;
00275   coordinate3->point.setValues(0,pointn,points);
00276   fCurrentSeparator->addChild(coordinate3);
00277 
00278   MarkerSizeType sizeType;
00279   G4double screenSize = GetMarkerSize (polymarker, sizeType);
00280   switch (sizeType) {
00281   default:
00282   case screen:
00283     // Draw in screen coordinates.  OK.
00284     break;
00285   case world:
00286     // Draw in world coordinates.   Not implemented.  Use screenSize = 10.
00287     screenSize = 10.;
00288     break;
00289   }
00290   
00291   SoG4MarkerSet* markerSet = new SoG4MarkerSet;
00292   markerSet->numPoints = pointn;
00293 
00294   // Loads G4Atts for picking...
00295   if (fpViewer->GetViewParameters().IsPicking())
00296     LoadAtts(polymarker, markerSet);
00297 
00298   G4VMarker::FillStyle style = polymarker.GetFillStyle();
00299   switch (polymarker.GetMarkerType()) {
00300   default:
00301     // Are available 5_5, 7_7 and 9_9
00302   case G4Polymarker::dots:
00303     if (screenSize <= 5.) {
00304       markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_5_5;
00305     } else if (screenSize <= 7.) {
00306       markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_7_7;
00307     } else {
00308       markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_9_9;
00309     }
00310     break;
00311   case G4Polymarker::circles:
00312     if (screenSize <= 5.) {
00313       if (style == G4VMarker::filled) {
00314         markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_5_5;
00315       } else {
00316         markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_5_5;
00317       }
00318     } else if (screenSize <= 7.) {
00319       if (style == G4VMarker::filled) {
00320         markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_7_7;
00321       } else {
00322         markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_7_7;
00323       }
00324     } else {
00325       if (style == G4VMarker::filled) {
00326         markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_9_9;
00327       } else {
00328         markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_9_9;
00329       }
00330     }
00331     break;
00332   case G4Polymarker::squares:
00333     if (screenSize <= 5.) {
00334       if (style == G4VMarker::filled) {
00335         markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_5_5;
00336       } else {
00337         markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_5_5;
00338       }
00339     } else if (screenSize <= 7.) {
00340       if (style == G4VMarker::filled) {
00341         markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_7_7;
00342       } else {
00343         markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_7_7;
00344       }
00345     } else {
00346       if (style == G4VMarker::filled) {
00347         markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_9_9;
00348       } else {
00349         markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_9_9;
00350       }
00351     }
00352   }
00353   fCurrentSeparator->addChild(markerSet);
00354 
00355   delete [] points;
00356 }
00357 
00358 // Method for handling G4Text objects
00359 //
00360 void G4OpenInventorSceneHandler::AddPrimitive (const G4Text& text)
00361 {
00362   if (fProcessing2D) {
00363     static G4bool warned = false;
00364     if (!warned) {
00365       warned = true;
00366       G4Exception
00367         ("G4OpenInventorSceneHandler::AddPrimitive (const G4Text&)",
00368          "OpenInventor-0003", JustWarning,
00369          "2D text not implemented.  Ignored.");
00370     }
00371     return;
00372   }
00373 
00374   AddProperties(text.GetVisAttributes());  // Colour, etc.
00375   AddTransform(text.GetPosition());        // Transformation
00376 
00377   //
00378   // Color.  Note: text colour is worked out differently.  This
00379   // over-rides the colour added in AddProperties...
00380   //
00381   const G4Colour& c = GetTextColour (text);
00382   SoMaterial* material = 
00383     fStyleCache->getMaterial((float)c.GetRed(),
00384                              (float)c.GetGreen(),
00385                              (float)c.GetBlue(),
00386                              (float)(1-c.GetAlpha()));
00387   fCurrentSeparator->addChild(material);
00388 
00389   MarkerSizeType sizeType;
00390   G4double size = GetMarkerSize (text, sizeType);
00391   switch (sizeType) {
00392   default:
00393   case screen:
00394     // Draw in screen coordinates.  OK.
00395     break;
00396   case world:
00397     // Draw in world coordinates.   Not implemented.  Use size = 20.
00398     size = 20.;
00399     break;
00400   }
00401 
00402   //
00403   // Font
00404   // 
00405   SoFont *g4Font = new SoFont();
00406   g4Font->size = size;
00407   fCurrentSeparator->addChild(g4Font);
00408 
00409   //
00410   // Text
00411   // 
00412   SoText2 *g4String = new SoText2();
00413   g4String->string.setValue(text.GetText());
00414   g4String->spacing = 2.0;
00415   switch (text.GetLayout()) {
00416   default:
00417   case G4Text::left:
00418     g4String->justification = SoText2::LEFT; break;
00419   case G4Text::centre:
00420     g4String->justification = SoText2::CENTER; break;
00421   case G4Text::right:
00422     g4String->justification = SoText2::RIGHT; break;
00423   }
00424   fCurrentSeparator->addChild(g4String);
00425 }
00426 
00427 //
00428 // Method for handling G4Circle objects
00429 //
00430 void G4OpenInventorSceneHandler::AddPrimitive (const G4Circle& circle) {
00431   AddCircleSquare(G4OICircle, circle);
00432 }
00433 
00434 //
00435 // Method for handling G4Square objects - defaults to wireframe
00436 //
00437 void G4OpenInventorSceneHandler::AddPrimitive (const G4Square& square) {
00438   AddCircleSquare(G4OISquare, square);
00439 }
00440 
00441 void G4OpenInventorSceneHandler::AddCircleSquare
00442 (G4OIMarker markerType, const G4VMarker& marker)
00443 {
00444   if (fProcessing2D) {
00445     static G4bool warned = false;
00446     if (!warned) {
00447       warned = true;
00448       G4Exception
00449         ("G4OpenInventorSceneHandler::AddCircleSquare",
00450          "OpenInventor-0004", JustWarning,
00451          "2D circles and squares not implemented.  Ignored.");
00452     }
00453     return;
00454   }
00455 
00456   // Get vis attributes - pick up defaults if none.
00457   const G4VisAttributes* pVA =
00458   fpViewer -> GetApplicableVisAttributes (marker.GetVisAttributes ());
00459 
00460   AddProperties(pVA);  // Colour, etc.
00461   AddTransform();      // Transformation
00462 
00463   MarkerSizeType sizeType;
00464   G4double screenSize = GetMarkerSize (marker, sizeType);
00465   switch (sizeType) {
00466   default:
00467   case screen:
00468     // Draw in screen coordinates.  OK.
00469     break;
00470   case world:
00471     // Draw in world coordinates.   Not implemented.  Use size = 10.
00472     screenSize = 10.;
00473     break;
00474   }
00475 
00476   G4Point3D centre = marker.GetPosition();
00477 
00478   // Borrowed from AddPrimitive(G4Polymarker) - inefficient? JA
00479   SbVec3f* points = new SbVec3f[1];
00480   points[0].setValue((float)centre.x(),
00481                      (float)centre.y(),
00482                      (float)centre.z());
00483   SoCoordinate3* coordinate3 = new SoCoordinate3;
00484   coordinate3->point.setValues(0,1,points);
00485   fCurrentSeparator->addChild(coordinate3);
00486 
00487   SoG4MarkerSet* markerSet = new SoG4MarkerSet;
00488   markerSet->numPoints = 1;
00489 
00490   // Loads G4Atts for picking...
00491   if (fpViewer->GetViewParameters().IsPicking()) LoadAtts(marker, markerSet);
00492 
00493   G4VMarker::FillStyle style = marker.GetFillStyle();
00494   switch (markerType) {
00495   case G4OICircle:
00496     if (screenSize <= 5.) {
00497       if (style == G4VMarker::filled) {
00498         markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_5_5;
00499       } else {
00500         markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_5_5;
00501       }
00502     } else if (screenSize <= 7.) {
00503       if (style == G4VMarker::filled) {
00504         markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_7_7;
00505       } else {
00506         markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_7_7;
00507       }
00508     } else {
00509       if (style == G4VMarker::filled) {
00510         markerSet->markerIndex = SoMarkerSet::CIRCLE_FILLED_9_9;
00511       } else {
00512         markerSet->markerIndex = SoMarkerSet::CIRCLE_LINE_9_9;
00513       }
00514     }
00515     break;
00516   case G4OISquare:
00517     if (screenSize <= 5.) {
00518       if (style == G4VMarker::filled) {
00519         markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_5_5;
00520       } else {
00521         markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_5_5;
00522       }
00523     } else if (screenSize <= 7.) {
00524       if (style == G4VMarker::filled) {
00525         markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_7_7;
00526       } else {
00527         markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_7_7;
00528       }
00529     } else {
00530       if (style == G4VMarker::filled) {
00531         markerSet->markerIndex = SoMarkerSet::SQUARE_FILLED_9_9;
00532       } else {
00533         markerSet->markerIndex = SoMarkerSet::SQUARE_LINE_9_9;
00534       }
00535     }
00536   break;
00537   }
00538   fCurrentSeparator->addChild(markerSet);
00539 
00540   delete [] points;
00541 }
00542 
00543 //
00544 // Method for handling G4Polyhedron objects for drawing solids.
00545 //
00546 void G4OpenInventorSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron)
00547 {
00548   if (polyhedron.GetNoFacets() == 0) return;
00549 
00550   if (fProcessing2D) {
00551     static G4bool warned = false;
00552     if (!warned) {
00553       warned = true;
00554       G4Exception
00555         ("G4OpenInventorSceneHandler::AddPrimitive (const G4Polyhedron&)",
00556          "OpenInventor-0005", JustWarning,
00557          "2D polyhedra not implemented.  Ignored.");
00558     }
00559     return;
00560   }
00561 
00562   // Get vis attributes - pick up defaults if none.
00563   const G4VisAttributes* pVA =
00564   fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
00565 
00566   AddProperties(pVA);  // Colour, etc.
00567   AddTransform();      // Transformation
00568 
00569   SoG4Polyhedron* soPolyhedron = new SoG4Polyhedron(polyhedron);
00570 
00571   // Loads G4Atts for picking...
00572   if (fpViewer->GetViewParameters().IsPicking())
00573     LoadAtts(polyhedron, soPolyhedron);
00574 
00575   SbString name = "Non-geometry";
00576   G4PhysicalVolumeModel* pPVModel =
00577     dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
00578   if (pPVModel) {
00579     name = pPVModel->GetCurrentLV()->GetName().c_str();
00580   }
00581   SbName sbName(name);
00582   soPolyhedron->setName(sbName);
00583   soPolyhedron->solid.setValue(fModelingSolid);
00584   soPolyhedron->reducedWireFrame.setValue(fReducedWireFrame?TRUE:FALSE);
00585   fCurrentSeparator->addChild(soPolyhedron);  
00586 }
00587 
00588 //
00589 // Method for handling G4NURBS objects for drawing solids.
00590 // Knots and Ctrl Pnts MUST be arrays of GLfloats.
00591 //
00592 void G4OpenInventorSceneHandler::AddPrimitive (const G4NURBS& nurb) {
00593 
00594   if (fProcessing2D) {
00595     static G4bool warned = false;
00596     if (!warned) {
00597       warned = true;
00598       G4Exception
00599         ("G4OpenInventorSceneHandler::AddPrimitive (const G4NURBS&)",
00600          "OpenInventor-0006", JustWarning,
00601          "2D NURBS not implemented.  Ignored.");
00602     }
00603     return;
00604   }
00605 
00606   // Get vis attributes - pick up defaults if none.
00607   const G4VisAttributes* pVA =
00608   fpViewer -> GetApplicableVisAttributes (nurb.GetVisAttributes ());
00609 
00610   AddProperties(pVA);  // Colour, etc.
00611   AddTransform();      // Transformation
00612 
00613   G4float *u_knot_array, *u_knot_array_ptr;
00614   u_knot_array = u_knot_array_ptr = new G4float [nurb.GetnbrKnots(G4NURBS::U)];
00615   G4NURBS::KnotsIterator u_iterator (nurb, G4NURBS::U);
00616   while (u_iterator.pick (u_knot_array_ptr++)){}
00617 
00618   G4float *v_knot_array, *v_knot_array_ptr;
00619   v_knot_array = v_knot_array_ptr = new G4float [nurb.GetnbrKnots(G4NURBS::V)];
00620   G4NURBS::KnotsIterator v_iterator (nurb, G4NURBS::V);
00621   while (v_iterator.pick (v_knot_array_ptr++)){}
00622 
00623   G4float *ctrl_pnt_array, *ctrl_pnt_array_ptr;
00624   ctrl_pnt_array = ctrl_pnt_array_ptr =
00625     new G4float [nurb.GettotalnbrCtrlPts () * G4NURBS::NofC*sizeof(G4float)];
00626   G4NURBS::CtrlPtsCoordsIterator c_p_iterator (nurb);
00627   while (c_p_iterator.pick (ctrl_pnt_array_ptr++)){}
00628   
00629   SoSeparator *surfSep = new SoSeparator();
00630 
00631   //
00632   // Set up NURBS
00633   //
00634   SoComplexity *complexity = new SoComplexity;
00635   SoCoordinate4 *ctlPts = new SoCoordinate4;
00636   SoNurbsSurface *oi_nurb = new SoNurbsSurface;
00637   
00638   complexity->value = (float)0.6;
00639   G4int    nPoints = nurb.GettotalnbrCtrlPts ();
00640   SbVec4f* points  = new SbVec4f[nPoints];
00641   for (G4int iPoint = 0; iPoint < nPoints ; iPoint++) {
00642     points[iPoint].setValue(
00643                             ctrl_pnt_array[iPoint*4 + 0],
00644                             ctrl_pnt_array[iPoint*4 + 1],
00645                             ctrl_pnt_array[iPoint*4 + 2],
00646                             ctrl_pnt_array[iPoint*4 + 3]);
00647   }
00648   ctlPts->point.setValues (0,nPoints,points);
00649   oi_nurb->numUControlPoints = nurb.GetnbrCtrlPts(G4NURBS::U);
00650   oi_nurb->numVControlPoints = nurb.GetnbrCtrlPts(G4NURBS::V);
00651   oi_nurb->uKnotVector.setValues(0,nurb.GetnbrKnots(G4NURBS::U),u_knot_array);
00652   oi_nurb->vKnotVector.setValues(0,nurb.GetnbrKnots(G4NURBS::V),v_knot_array);
00653 
00654   surfSep->addChild(complexity);
00655   surfSep->addChild(ctlPts);
00656   surfSep->addChild(oi_nurb);
00657   
00658   fCurrentSeparator->addChild(surfSep);
00659 
00660   //
00661   // Clean-up
00662   //
00663   delete [] u_knot_array;
00664   delete [] v_knot_array;
00665   delete [] ctrl_pnt_array;
00666   delete [] points;
00667 }
00668 
00669 void G4OpenInventorSceneHandler::GeneratePrerequisites()
00670 {
00671   // Utility for PreAddSolid and BeginPrimitives.
00672 
00673   // This routines prepares for adding items to the scene database.  We
00674   // are expecting two kinds of solids: leaf parts and non-leaf parts.
00675   // For non-leaf parts, we create a detector tree kit.  This has two
00676   // separators.  The solid itself goes in the preview separator, the
00677   // full separator is forseen for daughters.  This separator is not
00678   // only created--it is also put in a dictionary for future use by
00679   // the leaf part.
00680 
00681   // For leaf parts, we first locate the mother volume and find its
00682   // separator through the dictionary.
00683 
00684   // The private member fCurrentSeparator is set to the proper
00685   // location on in the scene database so that when the solid is
00686   // actually added (in addthis), it is put in the right place.
00687 
00688   G4PhysicalVolumeModel* pPVModel =
00689     dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
00690   
00691   if (pPVModel) {
00692 
00693     // This call comes from a G4PhysicalVolumeModel.  drawnPVPath is
00694     // the path of the current drawn (non-culled) volume in terms of
00695     // drawn (non-culled) ancesters.  Each node is identified by a
00696     // PVNodeID object, which is a physical volume and copy number.  It
00697     // is a vector of PVNodeIDs corresponding to the geometry hierarchy
00698     // actually selected, i.e., not culled.
00699     typedef G4PhysicalVolumeModel::G4PhysicalVolumeNodeID PVNodeID;
00700     typedef std::vector<PVNodeID> PVPath;
00701     const PVPath& drawnPVPath = pPVModel->GetDrawnPVPath();
00702     //G4int currentDepth = pPVModel->GetCurrentDepth();
00703     G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
00704     G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
00705     //G4Material* pCurrentMaterial = pPVModel->GetCurrentMaterial();
00706     // Note: pCurrentMaterial may be zero (parallel world).
00707 
00708     // The simplest algorithm, used by the Open Inventor Driver
00709     // developers, is to rely on the fact the G4PhysicalVolumeModel
00710     // traverses the geometry hierarchy in an orderly manner.  The last
00711     // mother, if any, will be the node to which the volume should be
00712     // added.  So it is enough to keep a map of scene graph nodes keyed
00713     // on the volume path ID.  Actually, it is enough to use the logical
00714     // volume as the key.  (An alternative would be to keep the PVNodeID
00715     // in the tree and match the PVPath from the root down.)
00716 
00717     // Find mother.  ri points to mother, if any...
00718     PVPath::const_reverse_iterator ri;
00719     G4LogicalVolume* MotherVolume = 0;
00720     ri = ++drawnPVPath.rbegin();
00721     if (ri != drawnPVPath.rend()) {
00722       // This volume has a mother.
00723       MotherVolume = ri->GetPhysicalVolume()->GetLogicalVolume();
00724     }
00725 
00726     if (pCurrentLV->GetNoDaughters()!=0 ||
00727         pCurrentPV->IsReplicated()) {  //????Don't understand this???? JA
00728       // This block of code is executed for non-leaf parts:
00729 
00730       // Make the detector tree kit:
00731       SoDetectorTreeKit* detectorTreeKit = new SoDetectorTreeKit();  
00732 
00733       SoSeparator* previewSeparator   =  
00734         (SoSeparator*) detectorTreeKit->getPart("previewSeparator",TRUE);
00735       previewSeparator->renderCaching = SoSeparator::OFF;
00736 
00737       SoSeparator* fullSeparator =  
00738         (SoSeparator*) detectorTreeKit->getPart("fullSeparator",   TRUE);
00739       fullSeparator->renderCaching = SoSeparator::OFF;
00740 
00741       if(fPreviewAndFull) detectorTreeKit->setPreviewAndFull();
00742       else detectorTreeKit->setPreview(TRUE);
00743 
00744       // Colour, etc., for SoDetectorTreeKit.  Treated differently to
00745       // othere SoNodes(?).  Use fpVisAttribs stored away in
00746       // PreAddSolid...
00747       const G4VisAttributes* pApplicableVisAttribs =
00748         fpViewer->GetApplicableVisAttributes (fpVisAttribs);
00749 
00750       // First find the color attributes...
00751       const G4Colour& g4Col =  pApplicableVisAttribs->GetColour ();
00752       const double red = g4Col.GetRed ();
00753       const double green = g4Col.GetGreen ();
00754       const double blue = g4Col.GetBlue ();
00755       double transparency = 1 - g4Col.GetAlpha();
00756 
00757       // Drawing style...
00758       G4ViewParameters::DrawingStyle drawing_style =
00759         GetDrawingStyle(pApplicableVisAttribs);
00760       switch (drawing_style) {
00761       case (G4ViewParameters::wireframe):    
00762         fModelingSolid = false;
00763         break;
00764       case (G4ViewParameters::hlr):
00765       case (G4ViewParameters::hsr):
00766       case (G4ViewParameters::hlhsr):
00767         fModelingSolid = true;
00768         break;
00769       }
00770 
00771       SoMaterial* material = 
00772         fStyleCache->getMaterial((float)red,
00773                                  (float)green,
00774                                  (float)blue,
00775                                  (float)transparency);
00776       detectorTreeKit->setPart("appearance.material",material);
00777 
00778       SoLightModel* lightModel = 
00779         fModelingSolid ? fStyleCache->getLightModelPhong() : 
00780         fStyleCache->getLightModelBaseColor();
00781       detectorTreeKit->setPart("appearance.lightModel",lightModel);
00782 
00783       // Add the full separator to the dictionary; it is indexed by the 
00784       // address of the logical volume!
00785       fSeparatorMap[pCurrentLV] = fullSeparator;
00786 
00787       // Find out where to add this volume.
00788       // If no mother can be found, it goes under root.
00789       if (MotherVolume) {
00790         if (fSeparatorMap.find(MotherVolume) != fSeparatorMap.end()) {
00791           //printf("debug : PreAddSolid : mother %s found in map\n",
00792           //     MotherVolume->GetName().c_str());
00793           fSeparatorMap[MotherVolume]->addChild(detectorTreeKit);
00794         } else {
00795           // Mother not previously encountered.  Shouldn't happen, since
00796           // G4PhysicalVolumeModel sends volumes as it encounters them,
00797           // i.e., mothers before daughters, in its descent of the
00798           // geometry tree.  Error!
00799           G4cout <<
00800             "ERROR: G4OpenInventorSceneHandler::GeneratePrerequisites: Mother "
00801                  << ri->GetPhysicalVolume()->GetName()
00802                  << ':' << ri->GetCopyNo()
00803                  << " not previously encountered."
00804             "\nShouldn't happen!  Please report to visualization coordinator."
00805                  << G4endl;
00806           // Continue anyway.  Add to root of scene graph tree...
00807           //printf("debug : PreAddSolid : mother %s not found in map !!!\n",
00808           //     MotherVolume->GetName().c_str());
00809           fDetectorRoot->addChild(detectorTreeKit);
00810         }
00811       } else {
00812         //printf("debug : PreAddSolid : has no mother\n");
00813         fDetectorRoot->addChild(detectorTreeKit);
00814       }
00815 
00816       fCurrentSeparator = previewSeparator;
00817 
00818     } else {
00819       // This block of code is executed for leaf parts.
00820 
00821       if (MotherVolume) {
00822         if (fSeparatorMap.find(MotherVolume) != fSeparatorMap.end()) {
00823           fCurrentSeparator = fSeparatorMap[MotherVolume];
00824         } else {
00825           // Mother not previously encountered.  Shouldn't happen, since
00826           // G4PhysicalVolumeModel sends volumes as it encounters them,
00827           // i.e., mothers before daughters, in its descent of the
00828           // geometry tree.  Error!
00829           G4cout << "ERROR: G4OpenInventorSceneHandler::PreAddSolid: Mother "
00830                  << ri->GetPhysicalVolume()->GetName()
00831                  << ':' << ri->GetCopyNo()
00832                  << " not previously encountered."
00833             "\nShouldn't happen!  Please report to visualization coordinator."
00834                  << G4endl;
00835           // Continue anyway.  Add to root of scene graph tree...
00836           fCurrentSeparator = fDetectorRoot;
00837         }
00838       } else {
00839         fCurrentSeparator = fDetectorRoot;
00840       }
00841     }
00842 
00843   } else {
00844     // Not from G4PhysicalVolumeModel, so add to root as leaf part...
00845 
00846     if (fReadyForTransients) {
00847       fCurrentSeparator = fTransientRoot;
00848     } else {
00849       fCurrentSeparator = fDetectorRoot;
00850     }
00851   }
00852 }
00853 
00854 void G4OpenInventorSceneHandler::AddProperties(const G4VisAttributes* visAtts)
00855 {
00856   // Use the applicable vis attributes...
00857   const G4VisAttributes* pApplicableVisAttribs =
00858     fpViewer->GetApplicableVisAttributes (visAtts);
00859 
00860   // First find the color attributes...
00861   const G4Colour& g4Col =  pApplicableVisAttribs->GetColour ();
00862   const double red = g4Col.GetRed ();
00863   const double green = g4Col.GetGreen ();
00864   const double blue = g4Col.GetBlue ();
00865   double transparency = 1 - g4Col.GetAlpha();
00866 
00867   // Drawing style...
00868   G4ViewParameters::DrawingStyle drawing_style =
00869     GetDrawingStyle(pApplicableVisAttribs);
00870   switch (drawing_style) {
00871   case (G4ViewParameters::wireframe):    
00872     fModelingSolid = false;
00873     break;
00874   case (G4ViewParameters::hlr):
00875   case (G4ViewParameters::hsr):
00876   case (G4ViewParameters::hlhsr):
00877     fModelingSolid = true;
00878     break;
00879   }
00880 
00881   // Edge visibility...
00882   G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pApplicableVisAttribs);
00883   fReducedWireFrame = !isAuxEdgeVisible;
00884 
00885   SoMaterial* material = 
00886     fStyleCache->getMaterial((float)red,
00887                              (float)green,
00888                              (float)blue,
00889                              (float)transparency);
00890   fCurrentSeparator->addChild(material);
00891 
00892   SoLightModel* lightModel = 
00893     fModelingSolid ? fStyleCache->getLightModelPhong() : 
00894     fStyleCache->getLightModelBaseColor();
00895   fCurrentSeparator->addChild(lightModel);
00896 }
00897 
00898 void G4OpenInventorSceneHandler::AddTransform(const G4Point3D& translation)
00899 {
00900   // AddTransform takes fObjectTransformation and "adds" a translation.
00901   // Set up the geometrical transformation for the coming
00902   fCurrentSeparator->addChild(fStyleCache->getResetTransform());
00903 
00904   SoMatrixTransform* matrixTransform = new SoMatrixTransform;
00905   G4OpenInventorTransform3D oiTran
00906   (fObjectTransformation * G4Translate3D(translation));
00907   SbMatrix* sbMatrix = oiTran.GetSbMatrix();
00908 
00909   const G4Vector3D scale = fpViewer->GetViewParameters().GetScaleFactor();
00910   SbMatrix sbScale;
00911   sbScale.setScale
00912     (SbVec3f((float)scale.x(),(float)scale.y(),(float)scale.z()));
00913   sbMatrix->multRight(sbScale);
00914 
00915   matrixTransform->matrix.setValue(*sbMatrix);
00916   delete sbMatrix;
00917   fCurrentSeparator->addChild(matrixTransform);
00918 }
00919 #endif

Generated on Mon May 27 17:49:12 2013 for Geant4 by  doxygen 1.4.7