00001
00002
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016 #ifndef _INVENTOR_MEDICAL_HELPER_H_
00017 #define _INVENTOR_MEDICAL_HELPER_H_
00018
00019 #include <Medical/InventorMedical.h>
00020 #include <Inventor/nodes/SoNode.h>
00021 #include <DialogViz/dialog/SoTopLevelDialog.h>
00022 #include <Inventor/actions/SoSearchPathAction.h>
00023
00024 #include <Inventor/STL/vector>
00025
00026 class SoCamera;
00027 class SoDataRange;
00028 class SoImageBackground;
00029 class SoImageDataAdapter;
00030 class SoMemoryDataAdapter;
00031 class SoOrthoSlice;
00032 class SoTransferFunction;
00033 class SoVolumeData;
00034 class SoVRDicomFileReader;
00035
00135 class INVENTORMEDICAL_API MedicalHelper {
00136 public:
00137
00140 enum Axis {
00142 AXIAL = 2,
00144 TRANSVERSE = 2,
00146 CORONAL = 1,
00148 SAGITTAL = 0
00149 };
00150
00193 static SbBool orientView( MedicalHelper::Axis axis, SoCamera* camera,
00194 const SoVolumeData* volume = NULL, float slack = 1.01 );
00195
00219 static SbBool dicomAdjustVolume( SoVolumeData* volume, SbBool useImagePosition = TRUE );
00220
00241 static SbBool dicomAdjustVolume( SoVolumeData* volume, SoMatrixTransform* imgToPatient );
00242
00249 static SbBool dicomAdjustDataRange( SoDataRange* rangeNode, const SoVolumeData* volume );
00250
00267 static SbBool dicomCheckMonochrome1( SoTransferFunction* cmapNode, const SoVolumeData* volume,
00268 SbBool forceReverse = FALSE );
00269
00281 static SbBool dicomGetImagePosition( const SoVolumeData* volume, SbVec3f& imagePos );
00282
00295 static SbBool dicomGetWindowCenterWidth( const SoVolumeData* volume, SbVec2f& winCW );
00296
00300 static SbVec2f dicomGetWindowCenterWidth( const SoDataRange* dataRange );
00301
00306 static SbBool dicomSetWindowCenterWidth( SoDataRange* dataRange, const SbVec2f& winCW );
00307
00332 static int dicomFindFilesbySeries( const SbString& firstFile, std::vector<SbString>& files );
00333
00339 static int dicomFindFilesbySeries( const SbString& firstFile, SbStringList& files );
00340
00367 static void dollyZoom( float value, SoCamera* camera );
00368
00375 static SbBool setFilenameList( SoVRDicomFileReader& reader, const std::vector<SbString>& list );
00376
00381 SbVec3f getVoxelSize( const SoVolumeData* volume ) const;
00382
00387 SbVec3f getPhysicalSize( const SoVolumeData* volume ) const;
00388
00398 SbVec3f getDicomOrigin( const SoVolumeData* volume ) const;
00399
00423 static SoMemoryDataAdapter* getImageDataAdapter( const SoVolumeData* volume );
00424
00439 static SoVolumeData* getVolumeData( const SoImageDataAdapter* adapter );
00440
00449 static SoSeparator* buildSliceOrientationMarkers( const SoOrthoSlice* orthoSlice );
00450
00461 static SoSeparator* buildSliceScaleBars( const SoCamera* camera );
00462
00472 static SoSeparator* buildSliceAnnotation( const SoCamera* camera,
00473 const SoOrthoSlice* sliceNode,
00474 const SbString* dicomFilename );
00475
00479 static const SbVec2s& exampleWindowSize();
00480
00487 static SoNode* exampleLogoNode();
00488
00494 static SoNode* exampleDicomAnnotation( const SbString& filename );
00495
00496
00498 template <typename NodeType>
00499 static NodeType*
00500 find(SoNode* root, const SbString& nodeName = SbString(), const bool okIfNotFound = false)
00501 {
00502 if (root == NULL)
00503 return NULL;
00504
00505 SoSearchAction* spa = NULL;
00506 if (!nodeName.isEmpty())
00507 {
00508 spa = new SoSearchPathAction;
00509 ((SoSearchPathAction*)spa)->setSearchString(nodeName.getString());
00510 }
00511 else
00512 {
00513 spa = new SoSearchAction;
00514 }
00515 spa->setSearchingAll(TRUE);
00516 spa->setType(NodeType::getClassTypeId());
00517
00518
00519
00520
00521 root->ref();
00522 spa->apply(root);
00523
00524 if (spa->getPath() == NULL)
00525 {
00526 delete spa;
00527 if (!okIfNotFound)
00528 std::cerr << "Cannot find \"" << nodeName << "\" of type \"" << NodeType::getClassTypeId().getName() << "\" in scene graph." << std::endl;
00529 return NULL;
00530 }
00531
00532 NodeType* node = dynamic_cast<NodeType*>(spa->getPath()->getTail());
00533 if (node == NULL)
00534 {
00535 delete spa;
00536 if (!okIfNotFound)
00537 std::cerr << "Cannot find \"" << nodeName << "\" of type \"" << NodeType::getClassTypeId().getName() << "\" in scene graph." << std::endl;
00538 return NULL;
00539 }
00540
00541 delete spa;
00542 root->unrefNoDelete();
00543 return node;
00544 }
00545
00546
00548 template <typename NodeType>
00549 static std::vector<NodeType*>findNodes(SoNode* scene)
00550 {
00551 SoSearchAction* sa = new SoSearchAction;
00552 sa->setType(NodeType::getClassTypeId());
00553 sa->setInterest(SoSearchAction::ALL);
00554
00555 scene->ref();
00556 sa->apply(scene);
00557 scene->unrefNoDelete();
00558
00559 std::vector<NodeType*> ret;
00560
00561 const SoPathList& path = sa->getPaths();
00562 if (path.getLength() == 0)
00563 {
00564 std::cerr << NodeType::getClassTypeId().getName().getString() << " not found" << std::endl;
00565 return ret;
00566 }
00567
00568 for (int i = 0; i < path.getLength(); i++)
00569 ret.push_back(dynamic_cast<NodeType*>(path[i]->getTail()));
00570
00571 delete sa;
00572
00573 return ret;
00574 }
00575
00576
00578 template <typename NodeType>
00579 static NodeType*
00580 find(SoTopLevelDialog* root, const SbString& auditorId = SbString(), bool exitIfNotFound = true)
00581 {
00582 if (root == NULL)
00583 return NULL;
00584
00585 NodeType* node = dynamic_cast<NodeType*>(root->searchForAuditorId(auditorId));
00586 if (node == NULL)
00587 {
00588 std::cerr << "Cannot find " << auditorId << " of type " << NodeType::getClassTypeId().getName() << " in interface." << std::endl;
00589 if (exitIfNotFound)
00590 exit(1);
00591 }
00592
00593 return node;
00594 }
00595
00596
00600 static SbBox3f getBoundingBox(SoNode* node);
00601
00602
00605 static SoSeparator* createCube(const SbBox3f& bbox);
00606
00607
00610 static SoSeparator* createBoundingBox(const SbBox3f& bbox, SbColor* color = NULL);
00611
00612
00615 static SoSeparator* readFile(const char *filename);
00616
00617
00619 static Widget buildInterface(Widget window, const char* filename, const char* viewerName, SoTopLevelDialog** topLevelDialog);
00620 };
00621
00622 #endif