00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef G4VIS_BUILD_OI_DRIVER
00029
00030
00031 #include "G4OpenInventorViewer.hh"
00032
00033 #include <Inventor/nodes/SoSelection.h>
00034 #include <Inventor/nodes/SoShape.h>
00035 #include <Inventor/nodes/SoOrthographicCamera.h>
00036 #include <Inventor/nodes/SoPerspectiveCamera.h>
00037 #include <Inventor/actions/SoCallbackAction.h>
00038 #include <Inventor/actions/SoWriteAction.h>
00039 #include <Inventor/sensors/SoNodeSensor.h>
00040
00041 #include "HEPVis/nodes/SoImageWriter.h"
00042 #include "HEPVis/actions/SoGL2PSAction.h"
00043 #include "HEPVis/actions/SoCounterAction.h"
00044 #include "HEPVis/actions/SoAlternateRepAction.h"
00045
00046 #include "G4OpenInventor.hh"
00047 #include "G4OpenInventorSceneHandler.hh"
00048 #include "G4VInteractorManager.hh"
00049 #include "G4Scene.hh"
00050 #include "Geant4_SoPolyhedron.h"
00051 #include "G4AttValue.hh"
00052 #include "G4AttDef.hh"
00053 #include "G4AttCheck.hh"
00054 #include "G4AttHolder.hh"
00055
00056 G4OpenInventorViewer::G4OpenInventorViewer(
00057 G4OpenInventorSceneHandler& sceneHandler
00058 ,const G4String& name)
00059 :G4VViewer(sceneHandler, sceneHandler.IncrementViewCount(), name)
00060 ,fG4OpenInventorSceneHandler(sceneHandler)
00061 ,fInteractorManager(0)
00062 ,fSoSelection(0)
00063 ,fSoImageWriter(0)
00064 ,fGL2PSAction(0)
00065 ,fGroupCameraSensor(0)
00066 ,fCameraSensor(0)
00067 {
00068 fNeedKernelVisit = true;
00069
00070 fVP.SetAutoRefresh(true);
00071 fDefaultVP.SetAutoRefresh(true);
00072 fVP.SetPicking(true);
00073 fDefaultVP.SetPicking(true);
00074
00075
00076
00077
00078
00079
00080 fInteractorManager =
00081 ((G4OpenInventor*)fG4OpenInventorSceneHandler.GetGraphicsSystem())->
00082 GetInteractorManager();
00083
00084
00085 fSoSelection = new SoSelection;
00086 fSoSelection->ref();
00087 fSoSelection->addSelectionCallback(SelectionCB,this);
00088
00089 fSoSelection->policy = SoSelection::SINGLE;
00090
00091 SoGroup* group = new SoGroup;
00092 fSoSelection->addChild(group);
00093
00094
00095
00096
00097
00098
00099
00100 SoOrthographicCamera* camera = new SoOrthographicCamera;
00101 camera->viewportMapping.setValue(SoCamera::ADJUST_CAMERA);
00102
00103 camera->position.setValue(0,0,10);
00104 camera->orientation.setValue(SbRotation(SbVec3f(0,1,0),0));
00105 camera->height.setValue(10);
00106 camera->nearDistance.setValue(1);
00107 camera->farDistance.setValue(100);
00108 camera->focalDistance.setValue(10);
00109 group->addChild(camera);
00110
00111 {SoInput soInput;
00112 if(soInput.openFile("g4view.iv",TRUE)) {
00113 SoSeparator* separator = SoDB::readAll(&soInput);
00114 if(separator) fSoSelection->addChild(separator);
00115 }}
00116
00117 fSoSelection->addChild(fG4OpenInventorSceneHandler.fRoot);
00118
00119
00120 fSoImageWriter = new SoImageWriter();
00121 fSoImageWriter->fileName.setValue("g4out.ps");
00122 fSoSelection->addChild(fSoImageWriter);
00123
00124
00125
00126 fGroupCameraSensor = new SoNodeSensor(GroupCameraSensorCB,this);
00127 fGroupCameraSensor->setPriority(0);
00128 fGroupCameraSensor->attach(group);
00129
00130 fCameraSensor = new SoNodeSensor(CameraSensorCB,this);
00131 fCameraSensor->setPriority(0);
00132 }
00133
00134 G4OpenInventorViewer::~G4OpenInventorViewer () {
00135 fCameraSensor->detach();
00136 delete fCameraSensor;
00137 fGroupCameraSensor->detach();
00138 delete fGroupCameraSensor;
00139 fSoSelection->unref();
00140 }
00141
00142 void G4OpenInventorViewer::KernelVisitDecision () {
00143
00144
00145
00146
00147 if (
00148
00149
00150
00151
00152 CompareForKernelVisit(fLastVP)) {
00153 NeedKernelVisit ();
00154 }
00155 fLastVP = fVP;
00156 }
00157
00158 G4bool G4OpenInventorViewer::CompareForKernelVisit(G4ViewParameters& vp) {
00159
00160 if (
00161 (vp.GetDrawingStyle () != fVP.GetDrawingStyle ()) ||
00162 (vp.IsAuxEdgeVisible () != fVP.IsAuxEdgeVisible ()) ||
00163 (vp.GetRepStyle () != fVP.GetRepStyle ()) ||
00164 (vp.IsCulling () != fVP.IsCulling ()) ||
00165 (vp.IsCullingInvisible () != fVP.IsCullingInvisible ()) ||
00166 (vp.IsDensityCulling () != fVP.IsDensityCulling ()) ||
00167 (vp.IsCullingCovered () != fVP.IsCullingCovered ()) ||
00168 (vp.IsSection () != fVP.IsSection ()) ||
00169 (vp.IsCutaway () != fVP.IsCutaway ()) ||
00170
00171
00172
00173
00174
00175 (vp.IsExplode () != fVP.IsExplode ()) ||
00176 (vp.GetNoOfSides () != fVP.GetNoOfSides ()) ||
00177 (vp.IsMarkerNotHidden () != fVP.IsMarkerNotHidden ()) ||
00178 (vp.GetDefaultVisAttributes()->GetColour() !=
00179 fVP.GetDefaultVisAttributes()->GetColour()) ||
00180 (vp.GetDefaultTextVisAttributes()->GetColour() !=
00181 fVP.GetDefaultTextVisAttributes()->GetColour()) ||
00182 (vp.GetBackgroundColour ()!= fVP.GetBackgroundColour ())||
00183 (vp.IsPicking () != fVP.IsPicking ()) ||
00184
00185
00186
00187 (vp.GetScaleFactor () != fVP.GetScaleFactor ()) ||
00188 (vp.GetVisAttributesModifiers().size() !=
00189 fVP.GetVisAttributesModifiers().size())
00190 )
00191 return true;
00192
00193 if (vp.IsDensityCulling () &&
00194 (vp.GetVisibleDensity () != fVP.GetVisibleDensity ()))
00195 return true;
00196
00197 if (vp.IsSection () &&
00198 (vp.GetSectionPlane () != fVP.GetSectionPlane ()))
00199 return true;
00200
00201 if (vp.IsCutaway ()) {
00202 if (vp.GetCutawayPlanes ().size () !=
00203 fVP.GetCutawayPlanes ().size ()) return true;
00204 for (size_t i = 0; i < vp.GetCutawayPlanes().size(); ++i)
00205 if (vp.GetCutawayPlanes()[i] != fVP.GetCutawayPlanes()[i])
00206 return true;
00207 }
00208
00209 if (vp.IsExplode () &&
00210 (vp.GetExplodeFactor () != fVP.GetExplodeFactor ()))
00211 return true;
00212
00213 return false;
00214 }
00215
00216 void G4OpenInventorViewer::ClearView () {
00217 }
00218
00219 void G4OpenInventorViewer::SetView () {
00220
00221
00222 const G4Point3D target
00223 = fSceneHandler.GetScene()->GetStandardTargetPoint()
00224 + fVP.GetCurrentTargetPoint ();
00225 G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
00226 if(radius<=0.) radius = 1.;
00227 const G4double cameraDistance = fVP.GetCameraDistance (radius);
00228 const G4Vector3D& direction = fVP.GetViewpointDirection().unit();
00229 const G4Point3D cameraPosition = target + cameraDistance * direction;
00230
00231
00232 const G4Normal3D& up = fVP.GetUpVector ();
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 SoCamera* camera = GetCamera();
00248 if(!camera) return;
00249
00250
00251 camera->position.setValue((float)cameraPosition.x(),
00252 (float)cameraPosition.y(),
00253 (float)cameraPosition.z());
00254
00255 SbVec3f sbTarget((float)target.x(),
00256 (float)target.y(),
00257 (float)target.z());
00258 SbVec3f sbUp((float)up.x(),
00259 (float)up.y(),
00260 (float)up.z());
00261 sbUp.normalize();
00262
00263
00264 pointAt(camera,sbTarget,sbUp);
00265
00266
00267
00268
00269
00270
00271 if(camera->isOfType(SoOrthographicCamera::getClassTypeId())) {
00272 if (fVP.GetFieldHalfAngle() == 0.) {
00273
00274
00275 } else {
00276
00277
00278
00279
00280 }
00281 } else if(camera->isOfType(SoPerspectiveCamera::getClassTypeId())) {
00282 if (fVP.GetFieldHalfAngle() == 0.) {
00283
00284
00285 } else {
00286
00287
00288 }
00289 }
00290 }
00291
00292
00293 void
00294 G4OpenInventorViewer::pointAt(SoCamera* camera,const SbVec3f & targetpoint, const SbVec3f & upvector)
00295 {
00296 SbVec3f dir = targetpoint - camera->position.getValue();
00297 if (dir.normalize() == 0.0f) return;
00298 lookAt(camera,dir, upvector);
00299 }
00300
00301
00302
00303
00304 void
00305 G4OpenInventorViewer::lookAt(SoCamera* camera,const SbVec3f & dir, const SbVec3f & up)
00306 {
00307 SbVec3f z = -dir;
00308 SbVec3f y = up;
00309 SbVec3f x = y.cross(z);
00310
00311
00312 y = z.cross(x);
00313
00314
00315 y.normalize();
00316 x.normalize();
00317
00318
00319 SbMatrix rot = SbMatrix::identity();
00320 rot[0][0] = x[0];
00321 rot[0][1] = x[1];
00322 rot[0][2] = x[2];
00323
00324 rot[1][0] = y[0];
00325 rot[1][1] = y[1];
00326 rot[1][2] = y[2];
00327
00328 rot[2][0] = z[0];
00329 rot[2][1] = z[1];
00330 rot[2][2] = z[2];
00331
00332 camera->orientation.setValue(SbRotation(rot));
00333 }
00334
00335 void
00336 G4OpenInventorViewer::lookedAt(SoCamera* camera,SbVec3f & dir, SbVec3f & up)
00337 {
00338 SbRotation rot = camera->orientation.getValue();
00339 SbMatrix mrot; rot.getValue(mrot);
00340
00341 SbVec3f x, y, z;
00342
00343
00344 x[0] = mrot[0][0];
00345 x[1] = mrot[0][1];
00346 x[2] = mrot[0][2];
00347
00348 y[0] = mrot[1][0];
00349 y[1] = mrot[1][1];
00350 y[2] = mrot[1][2];
00351
00352 z[0] = mrot[2][0];
00353 z[1] = mrot[2][1];
00354 z[2] = mrot[2][2];
00355
00356 dir = -z;
00357 dir.normalize();
00358 up = SbVec3f(0.f,1.f,0.f);
00359 if (std::abs(up.dot(z)) > 1.e-6) {
00360 up = y;
00361 up.normalize();
00362 }
00363 }
00364
00365 void G4OpenInventorViewer::DrawView () {
00366
00367 if (!fNeedKernelVisit) KernelVisitDecision();
00368 ProcessView();
00369 FinishView();
00370 }
00371
00372 void G4OpenInventorViewer::ShowView () {
00373 fInteractorManager -> SecondaryLoop ();
00374 }
00375
00376 void G4OpenInventorViewer::GroupCameraSensorCB(void* aThis,SoSensor* aSensor){
00377 G4OpenInventorViewer* This = (G4OpenInventorViewer*)aThis;
00378
00379 SoNode* node = ((SoNodeSensor*)aSensor)->getTriggerNode();
00380
00381
00382
00383 if(node->isOfType(SoCamera::getClassTypeId())) {
00384
00385
00386 SoCamera* camera = (SoCamera*)node;
00387 This->fCameraSensor->detach();
00388 This->fCameraSensor->attach(camera);
00389 }
00390
00391 }
00392
00393 void G4OpenInventorViewer::CameraSensorCB(void* aThis,SoSensor* aSensor) {
00394 G4OpenInventorViewer* This = (G4OpenInventorViewer*)aThis;
00395
00396
00397
00398 SoNode* node = ((SoNodeSensor*)aSensor)->getTriggerNode();
00399
00400 if(node->isOfType(SoCamera::getClassTypeId())) {
00401 SoCamera* camera = (SoCamera*)node;
00402
00403 SbVec3f direction, up;
00404 lookedAt(camera,direction, up);
00405 This->fVP.SetViewpointDirection
00406 (G4Vector3D(-direction[0],-direction[1],-direction[2]));
00407 This->fVP.SetUpVector(G4Vector3D(up[0],up[1],up[2]));
00408
00409 SbVec3f pos = camera->position.getValue();
00410 SbVec3f target = pos + direction * camera->focalDistance.getValue();
00411
00412 This->fVP.SetCurrentTargetPoint(G4Point3D(target[0],target[1],target[2]));
00413 }
00414 }
00415
00416 void G4OpenInventorViewer::SelectionCB(
00417 void* aThis
00418 ,SoPath* aPath
00419 )
00420 {
00421 G4OpenInventorViewer* This = (G4OpenInventorViewer*)aThis;
00422 SoNode* node = ((SoFullPath*)aPath)->getTail();
00423 G4AttHolder* attHolder = dynamic_cast<G4AttHolder*>(node);
00424 if(attHolder && attHolder->GetAttDefs().size()) {
00425 for (size_t i = 0; i < attHolder->GetAttDefs().size(); ++i) {
00426 G4cout << G4AttCheck(attHolder->GetAttValues()[i],
00427 attHolder->GetAttDefs()[i]);
00428 }
00429 } else {
00430 G4String name((char*)node->getName().getString());
00431 G4String cls((char*)node->getTypeId().getName().getString());
00432 G4cout << "SoNode : " << node
00433 << " SoType : " << cls
00434 << " name : " << name
00435 << G4endl;
00436 G4cout << "No attributes attached." << G4endl;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446 This->fSoSelection->deselectAll();
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 void G4OpenInventorViewer::DrawDetector() {
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471 DrawView();
00472 }
00473
00477
00478 void G4OpenInventorViewer::Escape(){
00479 G4cout << "Escape..." <<G4endl;
00480 fInteractorManager->RequireExitSecondaryLoop (OIV_EXIT_CODE);
00481 }
00482
00483 void G4OpenInventorViewer::WritePostScript(const G4String& aFile) {
00484 if(!fGL2PSAction) return;
00485 fGL2PSAction->setFileName(aFile.c_str());
00486 G4cout << "Produce " << aFile << "..." << G4endl;
00487 if (fGL2PSAction->enableFileWriting()) {
00488 ViewerRender();
00489 fGL2PSAction->disableFileWriting();
00490 }
00491 }
00492
00493 void G4OpenInventorViewer::WritePixmapPostScript(const G4String& aFile) {
00494 fSoImageWriter->fileName.setValue(aFile.c_str());
00495
00496 fSoImageWriter->enable();
00497 ViewerRender();
00498 fSoImageWriter->disable();
00499 if(fSoImageWriter->getStatus()) {
00500 G4cout << G4String(fSoImageWriter->fileName.getValue().getString())
00501 << " produced."
00502 << G4endl;
00503 } else {
00504 G4cout << G4String(fSoImageWriter->fileName.getValue().getString())
00505 << " not produced."
00506 << G4endl;
00507 }
00508 }
00509
00510 void G4OpenInventorViewer::WriteInventor(const G4String& aFile) {
00511 G4cout << "Produce " << aFile << "..." << G4endl;
00512
00513 SbBool genAlternateRep = TRUE;
00514
00515 SbBool binary = TRUE;
00516 SoAlternateRepAction alternateRepAction;
00517 if(genAlternateRep==TRUE) {
00518 alternateRepAction.setGenerate(TRUE);
00519 alternateRepAction.apply(fSoSelection);
00520 }
00521
00522 SoWriteAction writeAction;
00523 writeAction.getOutput()->openFile(aFile.c_str());
00524 writeAction.getOutput()->setBinary(binary);
00525 writeAction.apply(fSoSelection);
00526 writeAction.getOutput()->closeFile();
00527
00528 if(genAlternateRep==TRUE) {
00529 alternateRepAction.setGenerate(FALSE);
00530 alternateRepAction.apply(fSoSelection);
00531 }
00532
00533
00534
00535 }
00536
00537 struct Counter {
00538 int fTriangles;
00539 int fLineSegments;
00540 int fPoints;
00541 };
00542
00543 static void CountTrianglesCB(
00544 void* userData
00545 ,SoCallbackAction*
00546 ,const SoPrimitiveVertex*
00547 ,const SoPrimitiveVertex*,
00548 const SoPrimitiveVertex*)
00549 {
00550 Counter* counter = (Counter*)userData;
00551 counter->fTriangles++;
00552 }
00553
00554 static void CountLineSegmentsCB(
00555 void* userData
00556 ,SoCallbackAction*
00557 ,const SoPrimitiveVertex*
00558 ,const SoPrimitiveVertex*)
00559 {
00560 Counter* counter = (Counter*)userData;
00561 counter->fLineSegments++;
00562 }
00563
00564 static void CountPointsCB(
00565 void* userData
00566 ,SoCallbackAction*
00567 ,const SoPrimitiveVertex*)
00568 {
00569 Counter* counter = (Counter*)userData;
00570 counter->fPoints++;
00571 }
00572
00573 void G4OpenInventorViewer::SceneGraphStatistics() {
00574 Counter counter;
00575 counter.fTriangles = 0;
00576 counter.fLineSegments = 0;
00577 counter.fPoints = 0;
00578
00579 SoCallbackAction callbackAction;
00580 callbackAction.addTriangleCallback
00581 (SoShape::getClassTypeId(),CountTrianglesCB,(void*)&counter);
00582 callbackAction.addLineSegmentCallback
00583 (SoShape::getClassTypeId(),CountLineSegmentsCB,(void*)&counter);
00584 callbackAction.addPointCallback
00585 (SoShape::getClassTypeId(),CountPointsCB,(void*)&counter);
00586 callbackAction.apply(fSoSelection);
00587
00588 SoCounterAction counterAction;
00589 counterAction.apply(fSoSelection);
00590 int nodes = counterAction.getCount();
00591
00592 counterAction.setLookFor(SoCounterAction::TYPE);
00593 counterAction.setType(SoShape::getClassTypeId());
00594 counterAction.apply(fSoSelection);
00595 int shapes = counterAction.getCount();
00596
00597 G4cout << "Number of triangles : " << counter.fTriangles << G4endl;
00598 G4cout << "Number of line segments : " << counter.fLineSegments << G4endl;
00599 G4cout << "Number of points : " << counter.fPoints << G4endl;
00600 G4cout << "Number of nodes : " << nodes << G4endl;
00601 G4cout << "Number of shapes : " << shapes << G4endl;
00602 }
00603
00604 void G4OpenInventorViewer::EraseDetector() {
00605 fG4OpenInventorSceneHandler.fDetectorRoot->removeAllChildren();
00606 }
00607 void G4OpenInventorViewer::EraseEvent() {
00608 fG4OpenInventorSceneHandler.fTransientRoot->removeAllChildren();
00609 }
00610
00611 void G4OpenInventorViewer::SetPreviewAndFull() {
00612 fG4OpenInventorSceneHandler.fPreviewAndFull = true;
00613
00614 NeedKernelVisit();
00615 DrawDetector();
00616 }
00617
00618 void G4OpenInventorViewer::SetPreview() {
00619 fG4OpenInventorSceneHandler.fPreviewAndFull = false;
00620
00621 NeedKernelVisit();
00622 DrawDetector();
00623 }
00624
00625
00626
00627
00628
00629 void G4OpenInventorViewer::SetSolid() {
00630 G4ViewParameters vp = GetViewParameters();
00631 G4ViewParameters::DrawingStyle existingStyle = vp.GetDrawingStyle();
00632
00633 switch (existingStyle) {
00634 case G4ViewParameters::wireframe:
00635 vp.SetDrawingStyle(G4ViewParameters::hsr);
00636 break;
00637 case G4ViewParameters::hlr:
00638 vp.SetDrawingStyle(G4ViewParameters::hlhsr);
00639 break;
00640 case G4ViewParameters::hsr:
00641 break;
00642 case G4ViewParameters::hlhsr:
00643 break;
00644 }
00645 SetViewParameters(vp);
00646 DrawDetector();
00647 }
00648 void G4OpenInventorViewer::SetWireFrame() {
00649 G4ViewParameters vp = GetViewParameters();
00650 G4ViewParameters::DrawingStyle existingStyle = vp.GetDrawingStyle();
00651 switch (existingStyle) {
00652 case G4ViewParameters::wireframe:
00653 break;
00654 case G4ViewParameters::hlr:
00655 break;
00656 case G4ViewParameters::hsr:
00657 vp.SetDrawingStyle(G4ViewParameters::wireframe);
00658 break;
00659 case G4ViewParameters::hlhsr:
00660 vp.SetDrawingStyle(G4ViewParameters::hlr);
00661 break;
00662 }
00663 SetViewParameters(vp);
00664 DrawDetector();
00665 }
00666
00667
00668 void G4OpenInventorViewer::SetReducedWireFrame(bool aValue) {
00669 G4ViewParameters vp = GetViewParameters();
00670
00671
00672 vp.SetAuxEdgeVisible(!aValue);
00673
00674
00675 G4ViewParameters::DrawingStyle existingStyle = vp.GetDrawingStyle();
00676 switch (existingStyle) {
00677 case G4ViewParameters::wireframe:
00678 break;
00679 case G4ViewParameters::hlr:
00680 break;
00681 case G4ViewParameters::hsr:
00682 vp.SetDrawingStyle(G4ViewParameters::wireframe);
00683 break;
00684 case G4ViewParameters::hlhsr:
00685 vp.SetDrawingStyle(G4ViewParameters::hlr);
00686 break;
00687 }
00688 SetViewParameters(vp);
00689 NeedKernelVisit();
00690 DrawDetector();
00691 }
00692
00693 void G4OpenInventorViewer::UpdateScene() {
00694
00695
00696
00697
00698
00699
00700
00701
00702 NeedKernelVisit();
00703 DrawView();
00704 }
00705 G4String G4OpenInventorViewer::Help(const G4String& aTopic) {
00706 if(aTopic=="controls") {
00707 return G4String("\
00708 Controls on an Inventor examiner viewer are :\n\
00709 - in picking mode (cursor is the upper left arrow)\n\
00710 Ctrl + pick a volume : see daughters.\n\
00711 Shift + pick a volume : see mother.\n\
00712 - in viewing mode (cursor is the hand)\n\
00713 Left-button + pointer move : rotate.\n\
00714 Ctrl+Left-button + pointer move : pan.\n\
00715 Ctrl+Shift+Left-button + pointer move : scale.\n\
00716 Middle-button + pointer move : pan.\n\
00717 Right-button : popup menu.\n");
00718 } else {
00719 return "";
00720 }
00721 }
00722
00723 #endif