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 <Inventor/actions/SoSearchPathAction.h>
00022
00023
00024
00025
00026
00027
00028 #if defined(__DIALOGVIZLIB)
00029 #include <DialogViz/dialog/SoTopLevelDialog.h>
00030 #include <DialogViz/dialog/SoDialogCustom.h>
00031 #endif
00032
00033 #include <Inventor/Axis.h>
00034
00035 #include <Inventor/STL/vector>
00036
00037 class SoCamera;
00038 class SoDataRange;
00039 class SoImageBackground;
00040 class SoImageDataAdapter;
00041 class SoMemoryDataAdapter;
00042 class SoOrthoSlice;
00043 class SoTransferFunction;
00044 class SoVolumeData;
00045 class SoVRDicomFileReader;
00046 class SoMatrixTransform;
00047
00146 class INVENTORMEDICAL_API MedicalHelper {
00147 public:
00148
00151 enum Axis {
00153 AXIAL = 2,
00155 TRANSVERSE = 2,
00157 CORONAL = 1,
00159 SAGITTAL = 0
00160 };
00161
00204 static SbBool orientView( MedicalHelper::Axis axis, SoCamera* camera,
00205 const SoVolumeData* volume = NULL, float slack = 1.01 );
00206
00230 static SbBool dicomAdjustVolume( SoVolumeData* volume, SbBool useImagePosition = TRUE );
00231
00252 static SbBool dicomAdjustVolume( SoVolumeData* volume, SoMatrixTransform* imgToPatient );
00253
00260 static SbBool dicomAdjustDataRange( SoDataRange* rangeNode, const SoVolumeData* volume );
00261
00278 static SbBool dicomCheckMonochrome1( SoTransferFunction* cmapNode, const SoVolumeData* volume,
00279 SbBool forceReverse = FALSE );
00280
00292 static SbBool dicomGetImagePosition( const SoVolumeData* volume, SbVec3f& imagePos );
00293
00306 static SbBool dicomGetWindowCenterWidth( const SoVolumeData* volume, SbVec2f& winCW );
00307
00311 static SbVec2f dicomGetWindowCenterWidth( const SoDataRange* dataRange );
00312
00317 static SbBool dicomSetWindowCenterWidth( SoDataRange* dataRange, const SbVec2f& winCW );
00318
00343 static int dicomFindFilesbySeries( const SbString& firstFile, std::vector<SbString>& files );
00344
00350 static int dicomFindFilesbySeries( const SbString& firstFile, SbStringList& files );
00351
00378 static void dollyZoom( float value, SoCamera* camera );
00379
00386 static SbBool setFilenameList( SoVRDicomFileReader& reader, const std::vector<SbString>& list );
00387
00392 SbVec3f getVoxelSize( const SoVolumeData* volume ) const;
00393
00398 SbVec3f getPhysicalSize( const SoVolumeData* volume ) const;
00399
00409 SbVec3f getDicomOrigin( const SoVolumeData* volume ) const;
00410
00434 static SoMemoryDataAdapter* getImageDataAdapter( const SoVolumeData* volume );
00435
00450 static SoVolumeData* getVolumeData( const SoImageDataAdapter* adapter );
00451
00460 static SoSeparator* buildSliceOrientationMarkers( const SoOrthoSlice* orthoSlice );
00461
00472 static SoSeparator* buildSliceScaleBars( const SoCamera* camera );
00473
00483 static SoSeparator* buildSliceAnnotation( const SoCamera* camera,
00484 const SoOrthoSlice* sliceNode,
00485 const SbString* dicomFilename );
00486
00490 static const SbVec2s& exampleWindowSize();
00491
00498 static SoNode* exampleLogoNode();
00499
00505 static SoNode* exampleDicomAnnotation( const SbString& filename );
00506
00559 static Axis MedicalAxisFromViewAxis(openinventor::inventor::Axis::Type viewAxis, const SoVolumeData* volData);
00560
00572 static Axis MedicalAxisFromViewAxis(openinventor::inventor::Axis::Type viewAxis, const SbMatrix& orientationMatrix);
00573
00583 static openinventor::inventor::Axis::Type ViewAxisFromMedicalAxis(Axis medicalAxis, const SoVolumeData* volData);
00584
00596 static openinventor::inventor::Axis::Type ViewAxisFromMedicalAxis(Axis medicalAxis, const SbMatrix& orientationMatrix);
00597
00598
00600 template <typename NodeType>
00601 static NodeType*
00602 find(SoNode* root, const SbString& nodeName = SbString(), const bool okIfNotFound = false)
00603 {
00604 if (root == NULL)
00605 return NULL;
00606
00607 SoSearchAction* spa = NULL;
00608 if (!nodeName.isEmpty())
00609 {
00610 spa = new SoSearchPathAction;
00611 ((SoSearchPathAction*)spa)->setSearchString(nodeName.getString());
00612 }
00613 else
00614 {
00615 spa = new SoSearchAction;
00616 }
00617 spa->setSearchingAll(TRUE);
00618 spa->setType(NodeType::getClassTypeId());
00619
00620
00621
00622
00623 root->ref();
00624 spa->apply(root);
00625
00626 if (spa->getPath() == NULL)
00627 {
00628 delete spa;
00629 if (!okIfNotFound)
00630 std::cerr << "Cannot find \"" << nodeName << "\" of type \"" << NodeType::getClassTypeId().getName() << "\" in scene graph." << std::endl;
00631 return NULL;
00632 }
00633
00634 NodeType* node = dynamic_cast<NodeType*>(spa->getPath()->getTail());
00635 if (node == NULL)
00636 {
00637 delete spa;
00638 if (!okIfNotFound)
00639 std::cerr << "Cannot find \"" << nodeName << "\" of type \"" << NodeType::getClassTypeId().getName() << "\" in scene graph." << std::endl;
00640 return NULL;
00641 }
00642
00643 delete spa;
00644 root->unrefNoDelete();
00645 return node;
00646 }
00647
00648
00650 template <typename NodeType>
00651 static std::vector<NodeType*>findNodes(SoNode* scene)
00652 {
00653 SoSearchAction* sa = new SoSearchAction;
00654 sa->setType(NodeType::getClassTypeId());
00655 sa->setInterest(SoSearchAction::ALL);
00656
00657 scene->ref();
00658 sa->apply(scene);
00659 scene->unrefNoDelete();
00660
00661 std::vector<NodeType*> ret;
00662
00663 const SoPathList& path = sa->getPaths();
00664 if (path.getLength() == 0)
00665 {
00666 std::cerr << NodeType::getClassTypeId().getName().getString() << " not found" << std::endl;
00667 return ret;
00668 }
00669
00670 for (int i = 0; i < path.getLength(); i++)
00671 ret.push_back(dynamic_cast<NodeType*>(path[i]->getTail()));
00672
00673 delete sa;
00674
00675 return ret;
00676 }
00677
00678 #if defined(__DIALOGVIZLIB)
00679
00685 template <typename NodeType>
00686 static NodeType*
00687 find(SoTopLevelDialog* root, const SbString& auditorId = SbString(), bool exitIfNotFound = true)
00688 {
00689 if (root == NULL)
00690 return NULL;
00691
00692 NodeType* node = dynamic_cast<NodeType*>(root->searchForAuditorId(auditorId));
00693 if (node == NULL)
00694 {
00695 std::cerr << "Cannot find " << auditorId << " of type " << NodeType::getClassTypeId().getName() << " in interface." << std::endl;
00696 if (exitIfNotFound)
00697 exit(1);
00698 }
00699
00700 return node;
00701 }
00702 #endif
00703
00704
00708 static SbBox3f getBoundingBox(SoNode* node);
00709
00710
00713 static SoSeparator* createCube(const SbBox3f& bbox);
00714
00715
00718 static SoSeparator* createBoundingBox(const SbBox3f& bbox, SbColor* color = NULL);
00719
00720
00723 static SoSeparator* readFile(const char *filename);
00724
00725 #if defined(__DIALOGVIZLIB)
00726
00732 template<typename WidgetType>
00733 static WidgetType
00734 buildInterface(WidgetType window, const char* filename, const char* viewerName, SoTopLevelDialog** topLevelDialog)
00735 {
00736 SoInput myInput;
00737 if (!myInput.openFile(filename))
00738 return NULL;
00739
00740 SoGroup *myGroup = SoDB::readAll(&myInput);
00741 myInput.closeFile();
00742 if (!myGroup)
00743 return NULL;
00744
00745 *topLevelDialog = (SoTopLevelDialog *)myGroup->getChild(0);
00746
00747 SoDialogCustom *customNode = (SoDialogCustom *)(*topLevelDialog)->searchForAuditorId(SbString(viewerName));
00748
00749 (*topLevelDialog)->buildDialog(window, customNode != NULL);
00750 (*topLevelDialog)->show();
00751
00752 return customNode ? customNode->getWidget() : window;
00753 }
00754 #endif
00755 };
00756
00757 #endif
00758