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
00171 static SbBool orientView( MedicalHelper::Axis axis, SoCamera* camera,
00172 const SoVolumeData* volume = NULL, float slack = 1.01 );
00173
00197 static SbBool dicomAdjustVolume( SoVolumeData* volume, SbBool useImagePosition = TRUE );
00198
00219 static SbBool dicomAdjustVolume( SoVolumeData* volume, SoMatrixTransform* imgToPatient );
00220
00227 static SbBool dicomAdjustDataRange( SoDataRange* rangeNode, const SoVolumeData* volume );
00228
00245 static SbBool dicomCheckMonochrome1( SoTransferFunction* cmapNode, const SoVolumeData* volume,
00246 SbBool forceReverse = FALSE );
00247
00259 static SbBool dicomGetImagePosition( const SoVolumeData* volume, SbVec3f& imagePos );
00260
00273 static SbBool dicomGetWindowCenterWidth( const SoVolumeData* volume, SbVec2f& winCW );
00274
00278 static SbVec2f dicomGetWindowCenterWidth( const SoDataRange* dataRange );
00279
00284 static SbBool dicomSetWindowCenterWidth( SoDataRange* dataRange, const SbVec2f& winCW );
00285
00310 static int dicomFindFilesbySeries( const SbString& firstFile, std::vector<SbString>& files );
00311
00317 static int dicomFindFilesbySeries( const SbString& firstFile, SbStringList& files );
00318
00345 static void dollyZoom( float value, SoCamera* camera );
00346
00353 static SbBool setFilenameList( SoVRDicomFileReader& reader, const std::vector<SbString>& list );
00354
00359 SbVec3f getVoxelSize( const SoVolumeData* volume ) const;
00360
00365 SbVec3f getPhysicalSize( const SoVolumeData* volume ) const;
00366
00376 SbVec3f getDicomOrigin( const SoVolumeData* volume ) const;
00377
00400 static SoMemoryDataAdapter* getImageDataAdapter( const SoVolumeData* volume );
00401
00416 static SoVolumeData* getVolumeData( const SoImageDataAdapter* adapter );
00417
00426 static SoSeparator* buildSliceOrientationMarkers( const SoOrthoSlice* orthoSlice );
00427
00438 static SoSeparator* buildSliceScaleBars( const SoCamera* camera );
00439
00449 static SoSeparator* buildSliceAnnotation( const SoCamera* camera,
00450 const SoOrthoSlice* sliceNode,
00451 const SbString* dicomFilename );
00452
00456 static const SbVec2s& exampleWindowSize();
00457
00464 static SoNode* exampleLogoNode();
00465
00471 static SoNode* exampleDicomAnnotation( const SbString& filename );
00472
00473
00475 template <typename NodeType>
00476 static NodeType*
00477 find(SoNode* root, const SbString& nodeName = SbString(), const bool okIfNotFound = false)
00478 {
00479 if (root == NULL)
00480 return NULL;
00481
00482 SoSearchAction* spa = NULL;
00483 if (!nodeName.isEmpty())
00484 {
00485 spa = new SoSearchPathAction;
00486 ((SoSearchPathAction*)spa)->setSearchString(nodeName.getString());
00487 }
00488 else
00489 {
00490 spa = new SoSearchAction;
00491 }
00492 spa->setSearchingAll(TRUE);
00493 spa->setType(NodeType::getClassTypeId());
00494
00495
00496
00497
00498 root->ref();
00499 spa->apply(root);
00500
00501 if (spa->getPath() == NULL)
00502 {
00503 delete spa;
00504 if (!okIfNotFound)
00505 std::cerr << "Cannot find \"" << nodeName << "\" of type \"" << NodeType::getClassTypeId().getName() << "\" in scene graph." << std::endl;
00506 return NULL;
00507 }
00508
00509 NodeType* node = dynamic_cast<NodeType*>(spa->getPath()->getTail());
00510 if (node == NULL)
00511 {
00512 delete spa;
00513 if (!okIfNotFound)
00514 std::cerr << "Cannot find \"" << nodeName << "\" of type \"" << NodeType::getClassTypeId().getName() << "\" in scene graph." << std::endl;
00515 return NULL;
00516 }
00517
00518 delete spa;
00519 root->unrefNoDelete();
00520 return node;
00521 }
00522
00523
00525 template <typename NodeType>
00526 static std::vector<NodeType*>findNodes(SoNode* scene)
00527 {
00528 SoSearchAction* sa = new SoSearchAction;
00529 sa->setType(NodeType::getClassTypeId());
00530 sa->setInterest(SoSearchAction::ALL);
00531
00532 scene->ref();
00533 sa->apply(scene);
00534 scene->unrefNoDelete();
00535
00536 std::vector<NodeType*> ret;
00537
00538 const SoPathList& path = sa->getPaths();
00539 if (path.getLength() == 0)
00540 {
00541 std::cerr << NodeType::getClassTypeId().getName().getString() << " not found" << std::endl;
00542 return ret;
00543 }
00544
00545 for (int i = 0; i < path.getLength(); i++)
00546 ret.push_back(dynamic_cast<NodeType*>(path[i]->getTail()));
00547
00548 delete sa;
00549
00550 return ret;
00551 }
00552
00553
00555 template <typename NodeType>
00556 static NodeType*
00557 find(SoTopLevelDialog* root, const SbString& auditorId = SbString(), bool exitIfNotFound = true)
00558 {
00559 if (root == NULL)
00560 return NULL;
00561
00562 NodeType* node = dynamic_cast<NodeType*>(root->searchForAuditorId(auditorId));
00563 if (node == NULL)
00564 {
00565 std::cerr << "Cannot find " << auditorId << " of type " << NodeType::getClassTypeId().getName() << " in interface." << std::endl;
00566 if (exitIfNotFound)
00567 exit(1);
00568 }
00569
00570 return node;
00571 }
00572
00573
00577 static SbBox3f getBoundingBox(SoNode* node);
00578
00579
00582 static SoSeparator* createCube(const SbBox3f& bbox);
00583
00584
00587 static SoSeparator* createBoundingBox(const SbBox3f& bbox, SbColor* color = NULL);
00588
00589
00592 static SoSeparator* readFile(const char *filename);
00593
00594
00596 static Widget buildInterface(Widget window, const char* filename, const char* viewerName, SoTopLevelDialog** topLevelDialog);
00597 };
00598
00599 #endif