POINT CBezier::getNextPos() { POINT rlt = hor(num_point-1, point, step_now); step_now += step; if(step_now > 1.0) step_now = 0.0; return rlt; }
int main() { int ct=1; while (1) { scanf("%d%d%d", &s, &t, &n); if (s == 0 && t == 0 && n == 0) break; printf("Case %d:\n", ct++); w = n*(t+s) + t; for (int i = 0; i < n; i++) { for (int j = 0; j < t; j++) hor(); for (int j = 0; j < s; j++) gr(); } for (int j = 0; j < t; j++) hor(); printf("\n"); } return 0; }
void pose(int a){ int i; for(i=0;i<4;i++){ if(a&(1<<i)) frec[i]=vrt(frec[i]); else frec[i]=hor(frec[i]); } }
void Canvas::overdraw_rectangle(wxRect rect, wxDC *dc) { wxRect edges[4]; wxSize hor(rect.GetWidth(), 1), ver(1, rect.GetHeight()); edges[0] = wxRect( rect.GetTopLeft(), hor ); edges[1] = wxRect( rect.GetTopLeft(), ver ); edges[2] = wxRect( rect.GetTopRight(), ver ); edges[3] = wxRect( rect.GetBottomLeft(), hor ); for (int i = 0; i < 4; i++) { dc->DrawBitmap( zoomed_bitmap_for_canvas_region( edges[i] ), edges[i].GetTopLeft() ); } }
void SheetView::drawBoxAround(int x,int y,int w,int h){ move(y-1,x-1); addch('+'); string hor(w,'-'); addstr(hor.data()); addch('+'); for(int i=y;i<y+h;i++){ mvaddch(i,x-1,'|'); mvaddch(i,x+w,'|'); } mvaddch(y+h,x-1,'+'); addstr(hor.data()); addch('+'); }
//------------------------------------------------------------------------------- void MaterialViewer::tick(const Ogre::FrameEvent &evt) { OIS::MouseState ms = Util::getMouseState(); if (ms.buttonDown(OIS::MB_Right)) { Ogre::Degree hor(ms.X.rel * GlbVar.settings.controls.turningSensitivity * -0.4); Ogre::Degree ver(ms.Y.rel * GlbVar.settings.controls.turningSensitivity * 0.4); mCameraYawNode->yaw(hor); mCameraPitchNode->pitch(ver); } else if (ms.buttonDown(OIS::MB_Middle)) { mCameraDist += ms.Y.rel * GlbVar.settings.controls.turningSensitivity * 0.02; mCameraDist = Util::clamp<Ogre::Real>(mCameraDist, 0.5, 10); } GlbVar.camNode->setPosition(mCameraPitchNode->_getDerivedOrientation() * Ogre::Vector3(0,0,-mCameraDist)); GlbVar.camNode->lookAt(Ogre::Vector3::ZERO, Ogre::Node::TS_WORLD); if (Util::isKeyDown(OIS::KC_ESCAPE)) Util::gotoWorld(0); }
void TitleScene::processMenu() { if(doExit) return; if(!menu.isSelected()) return; if(menu.isAccepted()) { menustates[_currentMenu].first = menu.currentItemI(); menustates[_currentMenu].second = menu.offset(); QString value = menu.currentItem().value; switch(_currentMenu) { case menu_main: if(value=="game1p") { numOfPlayers=1; menuChain.push(_currentMenu); setMenu(menu_playepisode); } else if(value=="game2p") { numOfPlayers=2; menuChain.push(_currentMenu); setMenu(menu_playepisode); } else if(value=="gamebt") { menuChain.push(_currentMenu); setMenu(menu_playlevel); } else if(value=="Options") { menuChain.push(_currentMenu); setMenu(menu_options); } else if(value=="Exit") { ret = ANSWER_EXIT; fader.setNull(); doExit=true; } else { PGE_MsgBox msgBox(this, QString("Sorry, is not implemented yet..."), PGE_MsgBox::msg_warn); fader.setRatio(0.5); PGE_Window::setCursorVisibly(true); msgBox.exec(); PGE_Window::setCursorVisibly(false); fader.setNull(); menu.resetState(); } break; case menu_playepisode: { if(value=="noworlds") { //do nothing! menu.resetState(); } else { result_episode.worldfile = value; result_episode.character = 0; result_episode.savefile = "save1.savx"; if(numOfPlayers>1) ret = ANSWER_PLAYEPISODE_2P; else ret = ANSWER_PLAYEPISODE; fader.setFade(10, 1.0f, 0.06f); doExit=true; menu.resetState(); } } break; case menu_playlevel: if(value=="nolevel") { //do nothing! menu.resetState(); } else { result_level.levelfile = value; ret = ANSWER_PLAYLEVEL; fader.setFade(10, 1.0f, 0.06f); doExit=true; menu.resetState(); } break; case menu_options: if(value=="tests") { menuChain.push(_currentMenu); setMenu(menu_tests); } else if(value=="testboxes") { menuChain.push(_currentMenu); setMenu(menu_testboxes); } else if(value=="controls") { menuChain.push(_currentMenu); setMenu(menu_controls); } else if(value=="videosetup") { menuChain.push(_currentMenu); setMenu(menu_videosettings); } else { PGE_MsgBox msgBox(this, QString("Dummy"), PGE_MsgBox::msg_warn); msgBox.exec(); menu.resetState(); } break; case menu_controls: if(value=="control_plr1") { menuChain.push(_currentMenu); setMenu(menu_controls_plr1); } else if(value=="control_plr2") { menuChain.push(_currentMenu); setMenu(menu_controls_plr2); } break; case menu_controls_plr1: break; case menu_controls_plr2: break; case menu_tests: if(value=="credits") { ret = ANSWER_CREDITS; doExit=true; } else if(value=="loading") { ret = ANSWER_LOADING; doExit=true; } else if(value=="gameover") { ret = ANSWER_GAMEOVER; doExit=true; } break; case menu_testboxes: if(value=="messagebox") { PGE_MsgBox msg(this, "This is a small message box without texture\nЭто маленкая коробочка-сообщение без текстуры", PGE_BoxBase::msg_info_light); msg.exec(); PGE_MsgBox msg2(this, "This is a small message box with texture\nЭто маленкая коробочка-сообщение с текстурой", PGE_BoxBase::msg_info, PGE_Point(-1,-1), ConfigManager::setup_message_box.box_padding, ConfigManager::setup_message_box.sprite); msg2.exec(); menu.resetState(); } else if(value=="menubox") { PGE_MenuBox menubox(this, "Select something", PGE_MenuBox::msg_info, PGE_Point(-1,-1), ConfigManager::setup_menu_box.box_padding, ConfigManager::setup_message_box.sprite); QStringList items; items<<"Menuitem 1"; items<<"Menuitem 2"; items<<"Menuitem 3"; items<<"Menuitem 4"; items<<"Menuitem 5"; items<<"Menuitem 6"; items<<"Menuitem 7"; items<<"Menuitem 8"; items<<"Menuitem 9"; items<<"Menuitem 10"; items<<"Menuitem 11"; menubox.addMenuItems(items); menubox.setRejectSnd(obj_sound_role::MenuPause); menubox.setMaxMenuItems(5); menubox.exec(); if(menubox.answer()>=0) { PGE_MsgBox msg(this, "Your answer is:\n"+items[menubox.answer()], PGE_BoxBase::msg_info_light, PGE_Point(-1,-1), ConfigManager::setup_message_box.box_padding, ConfigManager::setup_message_box.sprite); msg.exec(); } menu.resetState(); } else if(value=="inputbox") { PGE_TextInputBox text(this, "Type a text", PGE_BoxBase::msg_info_light); text.exec(); PGE_MsgBox msg(this, "Typed a text:\n"+text.inputText(), PGE_BoxBase::msg_info_light); msg.exec(); menu.resetState(); } else if (value=="questionbox") { PGE_QuestionBox hor(this, "AHHHH?", PGE_MenuBox::msg_info, PGE_Point(-1,-1), ConfigManager::setup_menu_box.box_padding, ConfigManager::setup_message_box.sprite); QStringList items; items<<"One"; items<<"Two"; items<<"Three"; items<<"Four"; items<<"Five"; items<<"Six"; items<<"Seven"; hor.addMenuItems(items); hor.setRejectSnd(obj_sound_role::BlockSmashed); hor.exec(); if(hor.answer()>=0) { PGE_MsgBox msg(this, "Answer on so dumb question is:\n"+items[hor.answer()], PGE_BoxBase::msg_info_light, PGE_Point(-1,-1), ConfigManager::setup_message_box.box_padding, ConfigManager::setup_message_box.sprite); msg.exec(); } menu.resetState(); } break; case menu_dummy_and_big: menu.resetState(); break; default: break; } } else { switch(_currentMenu) { case menu_main: menu.reset(); menu.setCurrentItem(4); break; case menu_options: AppSettings.apply(); AppSettings.save(); PGE_Audio::playSoundByRole(obj_sound_role::Bonus1up); default: if(menu.isKeyGrabbing()) menu.reset(); else if(menuChain.size()>0) { menu.reset(); setMenu((CurrentMenu)menuChain.pop()); } break; } } }
VolumeCollection* AnalyzeVolumeReader::readAnalyze(const std::string &fileName) throw (tgt::FileException, std::bad_alloc) { LWARNING("Loading analyze file " << fileName); LWARNING("Related img file: " << getRelatedImgFileName(fileName)); std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary); if(!file) { throw tgt::FileNotFoundException("Failed to open file: ", fileName); } file.seekg(0, std::ios::end); std::streamoff fileSize = file.tellg(); file.seekg(0, std::ios::beg); if(fileSize != 348) LWARNING("Filesize != 348"); header_key header; if (!file.read((char*)&header, sizeof(header))) { throw tgt::CorruptedFileException("Failed to read header!", fileName); } image_dimension dimension; if (!file.read((char*)&dimension, sizeof(dimension))) { throw tgt::CorruptedFileException("Failed to read dimensions!", fileName); } data_history history; if (!file.read((char*)&history, sizeof(history))) { throw tgt::CorruptedFileException("Failed to read history!", fileName); } bool bigEndian = false; //check if swap is necessary: if((dimension.dim[0] < 0) || (dimension.dim[0] > 15)) { bigEndian = true; header.swapEndianess(); dimension.swapEndianess(); history.swapEndianess(); } RawVolumeReader::ReadHints h; h.dimensions_.x = dimension.dim[1]; h.dimensions_.y = dimension.dim[2]; h.dimensions_.z = dimension.dim[3]; LINFO("Resolution: " << h.dimensions_); if (hor(lessThanEqual(h.dimensions_, ivec3(0)))) { LERROR("Invalid resolution or resolution not specified: " << h.dimensions_); throw tgt::CorruptedFileException("error while reading data", fileName); } h.spacing_.x = dimension.pixdim[1]; h.spacing_.y = dimension.pixdim[2]; h.spacing_.z = dimension.pixdim[3]; LINFO("Spacing: " << h.spacing_); LINFO("Datatype: " << dimension.datatype); switch(dimension.datatype) { case DT_UNSIGNED_CHAR: h.format_ = "UCHAR"; h.objectModel_ = "I"; break; case DT_SIGNED_SHORT: h.format_ = "SHORT"; h.objectModel_ = "I"; break; case DT_SIGNED_INT: h.format_ = "INT"; h.objectModel_ = "I"; break; case DT_FLOAT: h.format_ = "FLOAT"; h.objectModel_ = "I"; break; case DT_DOUBLE: h.format_ = "DOUBLE"; h.objectModel_ = "I"; break; case DT_RGB: h.format_ = "UCHAR"; h.objectModel_ = "RGB"; break; case DT_ALL: case DT_COMPLEX: case 0: //DT_NONE/DT_UNKNOWN case DT_BINARY: default: throw tgt::UnsupportedFormatException("Unsupported datatype!"); } h.bigEndianByteOrder_ = bigEndian; std::string objectType; std::string gridType; RawVolumeReader rawReader(getProgressBar()); rawReader.setReadHints(h); VolumeCollection* volumeCollection = rawReader.read(getRelatedImgFileName(fileName)); if (!volumeCollection->empty()) { static_cast<VolumeHandle*>(volumeCollection->first())->setOrigin(VolumeOrigin(fileName)); oldVolumePosition(static_cast<VolumeHandle*>(volumeCollection->first())); } return volumeCollection; }
VolumeCollection* AnalyzeVolumeReader::readNifti(const std::string &fileName, bool standalone) throw (tgt::FileException, std::bad_alloc) { LINFO("Loading nifti file " << fileName); std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary); if(!file) { throw tgt::FileNotFoundException("Failed to open file: ", fileName); } //file.seekg(0, std::ios::end); //int fileSize = file.tellg(); //file.seekg(0, std::ios::beg); nifti_1_header header; if (!file.read((char*)&header, sizeof(header))) { throw tgt::CorruptedFileException("Failed to read header!", fileName); } file.close(); bool bigEndian = false; //check if swap is necessary: if((header.dim[0] < 0) || (header.dim[0] > 15)) { bigEndian = true; header.swapEndianess(); } if(header.sizeof_hdr != 348) { throw tgt::CorruptedFileException("Invalid header.sizeof_hdr", fileName); } if(!( (header.magic[0] == 'n') && (header.magic[2] == '1') && (header.magic[3] == 0) )) throw tgt::CorruptedFileException("Not a Nifti header!", fileName); if(header.magic[1] == '+') { if(!standalone) LWARNING("Tried to read standalone Nifti as hdr+img!"); standalone = true; } else if(header.magic[1] == 'i') { if(!standalone) LWARNING("Tried to hdr+img Nifti as standalone!"); standalone = false; } else throw tgt::CorruptedFileException("Not a Nifti header!", fileName); RawVolumeReader::ReadHints h; h.dimensions_.x = header.dim[1]; h.dimensions_.y = header.dim[2]; h.dimensions_.z = header.dim[3]; LINFO("Resolution: " << h.dimensions_); if (hor(lessThanEqual(h.dimensions_, ivec3(0)))) { LERROR("Invalid resolution or resolution not specified: " << h.dimensions_); throw tgt::CorruptedFileException("error while reading data", fileName); } h.spacing_.x = header.pixdim[1]; h.spacing_.y = header.pixdim[2]; h.spacing_.z = header.pixdim[3]; LINFO("Spacing: " << h.spacing_); LINFO("Datatype: " << header.datatype); //TODO: support more datatypes if(header.datatype > 128) { header.datatype -= 128; h.objectModel_ = "RGB"; } else h.objectModel_ = "I"; switch(header.datatype) { case DT_UNSIGNED_CHAR: h.format_ = "UCHAR"; h.objectModel_ = "I"; break; case DT_SIGNED_SHORT: h.format_ = "SHORT"; h.objectModel_ = "I"; break; case DT_SIGNED_INT: h.format_ = "INT"; h.objectModel_ = "I"; break; case DT_FLOAT: h.format_ = "FLOAT"; h.objectModel_ = "I"; break; case DT_DOUBLE: h.format_ = "DOUBLE"; h.objectModel_ = "I"; break; case DT_RGB: h.format_ = "UCHAR"; h.objectModel_ = "RGB"; break; case DT_RGBA32: /* 4 byte RGBA (32 bits/voxel) */ h.format_ = "UCHAR"; h.objectModel_ = "RGBA"; break; case DT_INT8: /* signed char (8 bits) */ h.format_ = "CHAR"; h.objectModel_ = "I"; break; case DT_UINT16: /* unsigned short (16 bits) */ h.format_ = "USHORT"; h.objectModel_ = "I"; break; case DT_UINT32: /* unsigned int (32 bits) */ h.format_ = "UINT"; h.objectModel_ = "I"; break; case DT_INT64: /* long long (64 bits) */ case DT_UINT64: /* unsigned long long (64 bits) */ case DT_FLOAT128: /* long double (128 bits) */ case DT_COMPLEX128: /* double pair (128 bits) */ case DT_COMPLEX256: /* long double pair (256 bits) */ case DT_ALL: case DT_COMPLEX: case 0: //DT_NONE/DT_UNKNOWN case DT_BINARY: default: throw tgt::UnsupportedFormatException("Unsupported datatype!"); } if (header.intent_code == IC_INTENT_SYMMATRIX) { h.objectModel_ = "TENSOR_FUSION_LOW"; } h.bigEndianByteOrder_ = bigEndian; //std::string objectType; //std::string gridType; //} else if (type == "ObjectType:") { //args >> objectType; //LDEBUG(type << " " << objectType); //} else if (type == "GridType:") { //args >> gridType; //LDEBUG(type << " " << gridType); //} else if (type == "BitsStored:") { //args >> h.bitsStored_; //LDEBUG(type << " " << h.bitsStored_); //} else if (type == "Unit:") { //args >> h.unit_; //LDEBUG(type << " " << h.unit_); if (standalone) h.headerskip_ = static_cast<uint16_t>(header.vox_offset); RawVolumeReader rawReader(getProgressBar()); rawReader.setReadHints(h); VolumeCollection* volumeCollection = 0; if(standalone) volumeCollection = rawReader.read(fileName); else volumeCollection = rawReader.read(getRelatedImgFileName(fileName)); if (!volumeCollection->empty()) { static_cast<VolumeHandle*>(volumeCollection->first())->setOrigin(VolumeOrigin(fileName)); oldVolumePosition(static_cast<VolumeHandle*>(volumeCollection->first())); } return volumeCollection; }
VolumeList* AmiraMeshReader::readMetaFile(const std::string &fileName, size_t firstSlice, size_t lastSlice, int timeframe) throw (tgt::FileException, std::bad_alloc) { bool error = false; const char* FileName = fileName.c_str(); FILE* fp = fopen(FileName, "rb"); if (!fp) { LERROR("Could not find :" << FileName); error = true; goto K; } char buffer[2048]; fread(buffer, sizeof(char), 2047, fp); buffer[2047] = '\0'; //The following string routines prefer null-terminated strings if (!strstr(buffer, "# AmiraMesh BINARY-LITTLE-ENDIAN 2.1") && !strstr(buffer, "# AmiraMesh 3D BINARY 2.0")) { LERROR("Not a proper AmiraMesh file."); fclose(fp); error = true; goto K; } //Find the Lattice definition, i.e., the dimensions of the uniform grid int xDim(0), yDim(0), zDim(0); sscanf(FindAndJump(buffer, "define Lattice"), "%d %d %d", &xDim, &yDim, &zDim); LDEBUG("Grid Dimensions: " << xDim << " " << yDim << " " << zDim); //Find the BoundingBox float xmin(1.0f), ymin(1.0f), zmin(1.0f); float xmax(-1.0f), ymax(-1.0f), zmax(-1.0f); sscanf(FindAndJump(buffer, "BoundingBox"), "%g %g %g %g %g %g", &xmin, &xmax, &ymin, &ymax, &zmin, &zmax); LDEBUG("BoundingBox in x-Direction: [" << xmin << " " << xmax << "]"); LDEBUG("BoundingBox in x-Direction: [" << ymin << " " << ymax << "]"); LDEBUG("BoundingBox in x-Direction: [" << zmin << " " << zmax << "]"); //Is it a uniform grid? We need this only for the sanity check below. const bool bIsUniform = (strstr(buffer, "CoordType \"uniform\"") != NULL); LDEBUG("GridType: " << bIsUniform ? "uniform" : "UNKNOWN"); //Type of the field: scalar, vector int NumComponents(0); if (strstr(buffer, "Lattice { float Data }")) { //Scalar field NumComponents = 1; } else { //A field with more than one component, i.e., a vector field sscanf(FindAndJump(buffer, "Lattice { float["), "%d", &NumComponents); } LDEBUG("Number of Components: " << NumComponents); //Sanity check if (xDim <= 0 || yDim <= 0 || zDim <= 0 || xmin > xmax || ymin > ymax || zmin > zmax || !bIsUniform || NumComponents <= 0) { printf("Something went wrong\n"); fclose(fp); error = true; goto K; } K : RawVolumeReader::ReadHints h; std::string objectFilename = fileName; h.headerskip_ = strstr(buffer, "# Data section follows") - buffer; //Set the file pointer to the beginning of "# Data section follows" fseek(fp, h.headerskip_, SEEK_SET); //Consume this line, which is "# Data section follows" char buf1[2048]; fgets(buf1, 2047, fp); int l1 = strlen(buf1); //Consume the next line, which is "@1" char buf2[2048]; fgets(buf2, 2047, fp); int l2 = strlen(buf2); vec3 sliceThickness = vec3(1.f, 1.f, 1.f); int numFrames = NumComponents; h.dimensions_.x = xDim; h.dimensions_.y = yDim; h.dimensions_.z = zDim; h.format_ = "FLOAT"; h.objectModel_ = "I"; h.bigEndianByteOrder_ = false; h.headerskip_ += (l1 + l2); LDEBUG("Header size : " << h.headerskip_); if (hor(lessThanEqual(h.dimensions_, ivec3(0)))) { LERROR("Invalid resolution or resolution not specified: " << h.dimensions_); error = true; } h.spacing_ = sliceThickness; h.timeStep_ = 0; if (!error) { RawVolumeReader rawReader(getProgressBar()); // do we have a relative path? if ((objectFilename.substr(0, 1) != "/") && (objectFilename.substr(0, 1) != "\\") && (objectFilename.substr(1, 2) != ":/") && (objectFilename.substr(1, 2) != ":\\")) { size_t p = fileName.find_last_of("\\/"); // construct path relative to dat file objectFilename = fileName.substr(0, p + 1) + objectFilename; } int start = 0; int end = numFrames; if (timeframe != -1) { if (timeframe >= numFrames) throw tgt::FileException("Specified time frame not in volume", fileName); start = timeframe; end = timeframe+1; } VolumeList* toReturn = new VolumeList(); for (int frame = start; frame < end; ++frame) { h.timeframe_ = frame; rawReader.setReadHints(h); VolumeList* volumeList = rawReader.readSlices(objectFilename, firstSlice, lastSlice); if (!volumeList->empty()) { VolumeURL origin(fileName); origin.addSearchParameter("timeframe", itos(frame)); Volume* vh = static_cast<Volume*>(volumeList->first()); vh->setOrigin(origin); vh->setTimestep(static_cast<float>(frame)); oldVolumePosition(vh); if(!h.hash_.empty()) vh->setHash(h.hash_); toReturn->add(volumeList->first()); } delete volumeList; } return toReturn; } else { throw tgt::CorruptedFileException("error while reading data", fileName); } }
VolumeCollection* AnalyzeVolumeReader::readAnalyze(const std::string &fileName, int volId) throw (tgt::FileException, std::bad_alloc) { LINFO("Loading analyze file " << fileName); LINFO("Related img file: " << getRelatedImgFileName(fileName)); std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary); if(!file) { throw tgt::FileNotFoundException("Failed to open file: ", fileName); } file.seekg(0, std::ios::end); std::streamoff fileSize = file.tellg(); file.seekg(0, std::ios::beg); if(fileSize != 348) LWARNING("Filesize != 348"); header_key header; if (!file.read((char*)&header, sizeof(header))) { throw tgt::CorruptedFileException("Failed to read header!", fileName); } image_dimension dimension; if (!file.read((char*)&dimension, sizeof(dimension))) { throw tgt::CorruptedFileException("Failed to read dimensions!", fileName); } data_history history; if (!file.read((char*)&history, sizeof(history))) { throw tgt::CorruptedFileException("Failed to read history!", fileName); } bool bigEndian = false; //check if swap is necessary: if((dimension.dim[0] < 0) || (dimension.dim[0] > 15)) { bigEndian = true; header.swapEndianess(); dimension.swapEndianess(); history.swapEndianess(); } ivec3 dimensions; dimensions.x = dimension.dim[1]; dimensions.y = dimension.dim[2]; dimensions.z = dimension.dim[3]; LINFO("Resolution: " << dimensions); int numVolumes = dimension.dim[4]; LINFO("Number of volumes: " << numVolumes); if (hor(lessThanEqual(dimensions, ivec3(0)))) { LERROR("Invalid resolution or resolution not specified: " << dimensions); throw tgt::CorruptedFileException("error while reading data", fileName); } vec3 spacing; spacing.x = dimension.pixdim[1]; spacing.y = dimension.pixdim[2]; spacing.z = dimension.pixdim[3]; LINFO("Spacing: " << spacing); LINFO("Datatype: " << dimension.datatype); std::string voreenVoxelType; switch(dimension.datatype) { case DT_UNSIGNED_CHAR: voreenVoxelType = "uint8"; break; case DT_SIGNED_SHORT: voreenVoxelType = "int16"; break; case DT_SIGNED_INT: voreenVoxelType = "int32"; break; case DT_FLOAT: voreenVoxelType = "float"; break; case DT_DOUBLE: voreenVoxelType = "double"; break; case DT_RGB: voreenVoxelType = "Vector3(uint8)"; break; case DT_ALL: case DT_COMPLEX: case 0: //DT_NONE/DT_UNKNOWN case DT_BINARY: default: throw tgt::UnsupportedFormatException("Unsupported datatype!"); } std::string objectType; std::string gridType; int start = 0; int stop = numVolumes; if(volId != -1) { //we want to load a single volume: start = volId; stop = start + 1; } // Nifti transformations give us the center of the first voxel, we translate to correct: mat4 pToW = mat4::createTranslation(-spacing * 0.5f); VolumeCollection* vc = new VolumeCollection(); size_t volSize = hmul(tgt::svec3(dimensions)) * (dimension.bitpix / 8); for(int i=start; i<stop; i++) { VolumeRepresentation* volume = new VolumeDisk(getRelatedImgFileName(fileName), voreenVoxelType, dimensions, i * volSize, bigEndian); Volume* vh = new Volume(volume, spacing, vec3(0.0f)); vh->setOrigin(VolumeURL(fileName)); vh->setPhysicalToWorldMatrix(pToW); VolumeURL origin(fileName); origin.addSearchParameter("volumeId", itos(i)); vh->setOrigin(origin); vc->add(vh); } return vc; }
VolumeCollection* AnalyzeVolumeReader::readNifti(const std::string &fileName, bool standalone, int volId) throw (tgt::FileException, std::bad_alloc) { LINFO("Loading nifti file " << fileName); std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary); if(!file) { throw tgt::FileNotFoundException("Failed to open file: ", fileName); } nifti_1_header header; if (!file.read((char*)&header, sizeof(header))) { throw tgt::CorruptedFileException("Failed to read header!", fileName); } file.close(); bool bigEndian = false; //check if swap is necessary: if((header.dim[0] < 0) || (header.dim[0] > 15)) { bigEndian = true; header.swapEndianess(); } if(header.sizeof_hdr != 348) { throw tgt::CorruptedFileException("Invalid header.sizeof_hdr", fileName); } if(!( (header.magic[0] == 'n') && (header.magic[2] == '1') && (header.magic[3] == 0) )) throw tgt::CorruptedFileException("Not a Nifti header!", fileName); if(header.magic[1] == '+') { if(!standalone) LWARNING("Tried to read standalone Nifti as hdr+img!"); standalone = true; } else if(header.magic[1] == 'i') { if(!standalone) LWARNING("Tried to read hdr+img Nifti as standalone!"); standalone = false; } else throw tgt::CorruptedFileException("Not a Nifti header!", fileName); ivec3 dimensions; dimensions.x = header.dim[1]; dimensions.y = header.dim[2]; dimensions.z = header.dim[3]; LINFO("Resolution: " << dimensions); int numVolumes = header.dim[4]; LINFO("Number of volumes: " << numVolumes); if (hor(lessThanEqual(dimensions, ivec3(0)))) { LERROR("Invalid resolution or resolution not specified: " << dimensions); throw tgt::CorruptedFileException("error while reading data", fileName); } vec3 spacing; spacing.x = header.pixdim[1]; spacing.y = header.pixdim[2]; spacing.z = header.pixdim[3]; LINFO("Spacing: " << spacing); int timeunit = XYZT_TO_TIME(header.xyzt_units); int spaceunit = XYZT_TO_SPACE(header.xyzt_units); LINFO("timeunit: " << timeunit << " spaceunit: " << spaceunit); float dt = header.pixdim[4]; float toffset = header.toffset; switch(timeunit) { case NIFTI_UNITS_SEC: dt *= 1000.0f; toffset *= 1000.0f; break; case NIFTI_UNITS_MSEC: //nothing to do break; case NIFTI_UNITS_USEC: dt /= 1000.0f; toffset /= 1000.0f; break; } switch(spaceunit) { case NIFTI_UNITS_MM: //nothing to do break; case NIFTI_UNITS_METER: spacing *= 1000.0f; LWARNING("Units: meter"); break; case NIFTI_UNITS_MICRON: spacing /= 1000.0f; LWARNING("Units: micron"); break; case NIFTI_UNITS_UNKNOWN: default: LWARNING("Unknown space unit!"); break; } LINFO("Datatype: " << header.datatype); std::string voreenVoxelType = ""; RealWorldMapping denormalize; bool applyRWM = header.scl_slope != 0.0f; switch(header.intent_code) { case IC_INTENT_SYMMATRIX: /* parameter at each voxel is symmetrical matrix */ //TODO: should be relatively easy (=> tensors) case IC_INTENT_DISPVECT: /* parameter at each voxel is displacement vector */ case IC_INTENT_VECTOR: /* parameter at each voxel is vector */ //TODO: should be relatively easy case IC_INTENT_GENMATRIX: /* parameter at each voxel is matrix */ //TODO: should be relatively easy case IC_INTENT_POINTSET: /* value at each voxel is spatial coordinate (vertices/nodes of surface mesh) */ case IC_INTENT_TRIANGLE: /* value at each voxel is spatial coordinate (vertices/nodes of surface mesh) */ case IC_INTENT_QUATERNION: throw tgt::UnsupportedFormatException("Unsupported intent code!"); break; case IC_INTENT_ESTIMATE: /* parameter for estimate in intent_name */ case IC_INTENT_LABEL: /* parameter at each voxel is index to label defined in aux_file */ case IC_INTENT_NEURONAME: /* parameter at each voxel is index to label in NeuroNames label set */ case IC_INTENT_DIMLESS: /* dimensionless value */ case IC_INTENT_NONE: break; default: LWARNING("Unhandled intent code"); break; } //if (header.intent_code == IC_INTENT_SYMMATRIX) { //h.objectModel_ = "TENSOR_FUSION_LOW"; //} if(voreenVoxelType == "") { switch(header.datatype) { case DT_UNSIGNED_CHAR: voreenVoxelType = "uint8"; denormalize = RealWorldMapping::createDenormalizingMapping<uint8_t>(); break; case DT_SIGNED_SHORT: voreenVoxelType = "int16"; denormalize = RealWorldMapping::createDenormalizingMapping<int16_t>(); break; case DT_SIGNED_INT: voreenVoxelType = "int32"; denormalize = RealWorldMapping::createDenormalizingMapping<int32_t>(); break; case DT_FLOAT: voreenVoxelType = "float"; break; case DT_DOUBLE: voreenVoxelType = "double"; break; case DT_RGB: voreenVoxelType = "Vector3(uint8)"; applyRWM = false; break; case DT_RGBA32: /* 4 byte RGBA (32 bits/voxel) */ voreenVoxelType = "Vector4(uint8)"; applyRWM = false; break; case DT_INT8: /* signed char (8 bits) */ voreenVoxelType = "int8"; break; case DT_UINT16: /* unsigned short (16 bits) */ voreenVoxelType = "uint16"; denormalize = RealWorldMapping::createDenormalizingMapping<uint16_t>(); break; case DT_UINT32: /* unsigned int (32 bits) */ voreenVoxelType = "uint32"; denormalize = RealWorldMapping::createDenormalizingMapping<uint32_t>(); break; case DT_INT64: /* long long (64 bits) */ case DT_UINT64: /* unsigned long long (64 bits) */ case DT_FLOAT128: /* long double (128 bits) */ case DT_COMPLEX128: /* double pair (128 bits) */ case DT_COMPLEX256: /* long double pair (256 bits) */ case DT_ALL: case DT_COMPLEX: case 0: //DT_NONE/DT_UNKNOWN case DT_BINARY: default: throw tgt::UnsupportedFormatException("Unsupported datatype!"); } } RealWorldMapping rwm(header.scl_slope, header.scl_inter, ""); int headerskip = static_cast<uint16_t>(header.vox_offset); std::string rawFilename = fileName; if(!standalone) rawFilename = getRelatedImgFileName(fileName); mat4 pToW = mat4::identity; //Calculate transformation: if(header.sform_code > 0) { mat4 vToW(header.srow_x[0], header.srow_x[1], header.srow_x[2], header.srow_x[3], header.srow_y[0], header.srow_y[1], header.srow_y[2], header.srow_y[3], header.srow_z[0], header.srow_z[1], header.srow_z[2], header.srow_z[3], 0.0f, 0.0f, 0.0f, 1.0f); mat4 wToV = mat4::identity; if(!vToW.invert(wToV)) { LERROR("Failed to invert voxel to world matrix!"); } mat4 vToP = mat4::createScale(spacing); //no offset pToW = vToP * wToV; } else if(header.qform_code > 0) { float b = header.quatern_b; float c = header.quatern_c; float d = header.quatern_d; float a = static_cast<float>(sqrt(1.0-(b*b+c*c+d*d))); mat4 rot2(a*a+b*b-c*c-d*d, 2*b*c-2*a*d, 2*b*d+2*a*c, 0.0f, 2*b*c+2*a*d, a*a+c*c-b*b-d*d, 2*c*d-2*a*b, 0.0f, 2*b*d-2*a*c, 2*c*d+2*a*b, a*a+d*d-c*c-b*b, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); float qfac = header.pixdim[0]; if(fabs(qfac) < 0.1f) qfac = 1.0f; mat4 sc = mat4::createScale(vec3(1.0f, 1.0f, qfac)); mat4 os = mat4::createTranslation(vec3(header.qoffset_x, header.qoffset_y, header.qoffset_z)); pToW = os * rot2 * sc; } // Nifti transformations give us the center of the first voxel, we translate to correct: pToW = pToW * mat4::createTranslation(-spacing * 0.5f); VolumeCollection* vc = new VolumeCollection(); size_t volSize = hmul(tgt::svec3(dimensions)) * (header.bitpix / 8); int start = 0; int stop = numVolumes; if(volId != -1) { //we want to load a single volume: start = volId; stop = start + 1; } for(int i=start; i<stop; i++) { VolumeRepresentation* volume = new VolumeDisk(rawFilename, voreenVoxelType, dimensions, headerskip + (i * volSize), bigEndian); Volume* vh = new Volume(volume, spacing, vec3(0.0f)); VolumeURL origin(fileName); origin.addSearchParameter("volumeId", itos(i)); vh->setOrigin(origin); vh->setPhysicalToWorldMatrix(pToW); vh->setMetaDataValue<StringMetaData>("Description", std::string(header.descrip)); //vh->addMetaData("ActualFrameDuration", new IntMetaData(ih_.frame_duration)); //vh->addMetaData("FrameTime", new IntMetaData(ih_.frame_start_time)); vh->setMetaDataValue<IntMetaData>("FrameTime", static_cast<int>(toffset + (i * dt))); if(applyRWM) vh->setRealWorldMapping(RealWorldMapping::combine(denormalize, rwm)); vc->add(vh); } return vc; }