void Viewer::SetImageLocation(std::string path) { auto fixedPath = boost::filesystem::path(path); if (IO::DoPathExist(path)) { fixedPath += boost::filesystem::path::preferred_separator; } else if (IO::DoFileExist(fixedPath.string()) == false) { return; } m_folderMonitor.Close(); if (m_folder.Path(IO::GetPath(fixedPath.string())) == false) { return; } m_folderMonitor.Start(m_folder.Path()); Img::FillCacher(m_cacher, m_folder); size_t imageIndex = 0; if (m_cacher.FindImage(path, &imageIndex)) { ActiveImage(m_cacher.GotoImage(imageIndex)); } else { ActiveImage(m_cacher.FirstImage()); } }
void Viewer::RemoveImage(RemoveOp op) { auto image(m_viewPort.Image()); if (image == nullptr) { return; } if (op == RemoveOnly) { ActiveImage(m_cacher.RemoveCurrentImage()); return; } auto old_name(m_cacher.CurrentImageFilename()); auto reader = m_cacher.CurrentImageFileReader(); if (reader == nullptr) { return; } auto f = dynamic_cast<IO::StreamFile*>(reader->GetStream()); if (f->Delete((op == RemoveRecycle), this)) { ActiveImage(m_cacher.RemoveCurrentImage()); } UpdateImageInformation(); }
void Viewer::OnFolderEvent(wxCommandEvent& evt) { std::unique_lock<std::mutex> l(m_mutexNotification); if (m_folderNotifications.empty()) { DO_THROW(Err::CriticalError, "Notification queue is empty."); } IO::FileEvent notification = m_folderNotifications.front(); m_folderNotifications.pop_front(); l.unlock(); auto full_path = notification.Path + notification.Entry.Name; switch (notification.Type) { case IO::MonitoredFolderDeleted: ActiveImage(Img::Image::Ptr()); m_cacher.Clear(); m_folderMonitor.Close(); break; case IO::FileRenamed: m_cacher.RenamedImage(notification.Path + notification.Entry.PreviousName, notification.Path + notification.Entry.Name); break; case IO::FileAdded: ActiveImage(m_cacher.AddImageLast(full_path)); break; case IO::FileRemoved: ActiveImage(m_cacher.RemoveImageFilename(full_path)); break; } UpdateImageInformation(); }
void Viewer::ImageRandom() { size_t imageCount = m_cacher.ImageCount(); if (imageCount <= 1) return; std::uniform_int_distribution<size_t> posDist(0, imageCount - 2); size_t pos = posDist(m_random); if (pos >= m_cacher.CurrentImageIndex()) pos++; ActiveImage(m_cacher.GotoImage(pos)); }
//Move the active image slice by the specified amount void WITVolumeViz::MoveActiveImage(int amount) { if(!_vol) return; uint dim[4]; _vol->getDimension(dim[0], dim[1], dim[2], dim[3]); DTIVoxel lPos = DTIVoxel(3); WorldToLocal(_vol->getTransformMatrix(), _vPos, dim, lPos); DTISceneActorID i = ActiveImage(); if(i >=0 && i < 3) { lPos[i] += amount; // see if the new position exceeds the dimensions // since both are unsigned, a value of -1 will be mapped to 0xfffffff which is greater than dim[i] if(lPos[i] >= dim[i]) lPos[i] = (amount > 0) ? dim[i]-1 : 0; Vector3d vPos; LocalToWorld(_vol->getTransformMatrix(), lPos, vPos.v); SetPosition(vPos); } }
void Viewer::Sort(Img::Cacher::SortMethod m) { ActiveImage(m_cacher.Sort(m)); UpdateImageInformation(); }
void Viewer::ToEnd() { ActiveImage(m_cacher.LastImage()); }
void Viewer::ImageNext(unsigned toStep) { while (toStep-- > 0) m_cacher.NextImage(); ActiveImage(m_cacher.CurrentImage()); }
void Viewer::ImagePrev(unsigned toStep) { while (toStep-- > 0) m_cacher.PreviousImage(); ActiveImage(m_cacher.CurrentImage()); }
void Viewer::ToStart() { ActiveImage(m_cacher.FirstImage()); }
void WITVolumeViz::ActiveImageExtents(double transPts[4][3], double transNormal[4]) { // get the active image extents double pts[4][3]; int displayExtent[6]; double planeNormal[4]= {0,0,0,0}; uint dim[4]; // get the image dimensions _vol->getDimension (dim[0], dim[1], dim[2], dim[3]); DTIVoxel lPos = DTIVoxel(3); // map position from ACPC to 3d world space WorldToLocal(_vol->getTransformMatrix(), _vPos, dim, lPos); memset(pts, 0, sizeof(double)*4*3); int i = ActiveImage(); GetDisplayExtent ((DTISceneActorID)i,displayExtent); for (int j = 0; j < 4; j++) pts[j][i] = lPos[i]; planeNormal[i] = 1; // get the 4 corners depending on which image plane is selected switch (ActiveImage()) { case DTI_ACTOR_SAGITTAL_TOMO: pts[1][1] = displayExtent[3]; pts[2][1] = displayExtent[3]; pts[2][2] = displayExtent[5]; pts[3][2] = displayExtent[5]; break; case DTI_ACTOR_CORONAL_TOMO: pts[1][0] = displayExtent[1]; pts[2][0] = displayExtent[1]; pts[2][2] = displayExtent[5]; pts[3][2] = displayExtent[5]; break; case DTI_ACTOR_AXIAL_TOMO: pts[1][0] = displayExtent[1]; pts[2][0] = displayExtent[1]; pts[2][1] = displayExtent[3]; pts[3][1] = displayExtent[3]; break; default: break; }; vtkMatrix4x4 *mx = GetUserMatrix(); // map the points from 3d world space to ACPC space for (int i = 0; i < 4; i++) { double fooIn[4] = {pts[i][0], pts[i][1], pts[i][2], 1}; double fooOut[4]; mx->MultiplyPoint (fooIn, fooOut); transPts[i][0] = fooOut[0]; transPts[i][1] = fooOut[1]; transPts[i][2] = fooOut[2]; } // inverse of transpose: vtkMatrix4x4 *invertedMx = vtkMatrix4x4::New(); vtkMatrix4x4 *transposedMx = vtkMatrix4x4::New(); mx->Invert (mx, invertedMx); mx->Transpose (invertedMx, transposedMx); mx->MultiplyPoint (planeNormal, transNormal); transposedMx->Delete(); invertedMx->Delete(); }