/** * Based on a position+direction, view up and scale, * calculate an orientation matrix combining these. */ Transform3D CustomMetric::calculateOrientation(Vector3D pos, Vector3D dir, Vector3D vup, Vector3D scale) const { Transform3D R = this->calculateRotation(dir, vup); Transform3D center2DImage = this->calculateTransformTo2DImageCenter(); Transform3D S = createTransformScale(scale); Transform3D T = createTransformTranslate(pos); Transform3D M = T*R*S*center2DImage; return M; }
void EraserWidget::eraseVolume(TYPE* volumePointer) { ImagePtr image = mPatientModelService->getActiveImage(); vtkImageDataPtr img = image->getBaseVtkImageData(); Eigen::Array3i dim(img->GetDimensions()); Vector3D spacing(img->GetSpacing()); Transform3D rMd = mVisualizationService->getGroup(0)->getOptions().mPickerGlyph->get_rMd(); Vector3D c(mSphere->GetCenter()); c = rMd.coord(c); double r = mSphere->GetRadius(); mPreviousCenter = c; mPreviousRadius = r; DoubleBoundingBox3D bb_r(c[0]-r, c[0]+r, c[1]-r, c[1]+r, c[2]-r, c[2]+r); Transform3D dMr = image->get_rMd().inv(); Transform3D rawMd = createTransformScale(spacing).inv(); Transform3D rawMr = rawMd * dMr; Vector3D c_d = dMr.coord(c); double r_d = dMr.vector(r * Vector3D::UnitX()).length(); c = rawMr.coord(c); r = rawMr.vector(r * Vector3D::UnitX()).length(); DoubleBoundingBox3D bb0_raw = transform(rawMr, bb_r); IntBoundingBox3D bb1_raw(0, dim[0], 0, dim[1], 0, dim[2]); // std::cout << " sphere: " << bb0_raw << std::endl; // std::cout << " raw: " << bb1_raw << std::endl; for (int i=0; i<3; ++i) { bb1_raw[2*i] = std::max<double>(bb1_raw[2*i], bb0_raw[2*i]); bb1_raw[2*i+1] = std::min<double>(bb1_raw[2*i+1], bb0_raw[2*i+1]); } int replaceVal = mEraseValueAdapter->getValue(); for (int x = bb1_raw[0]; x < bb1_raw[1]; ++x) for (int y = bb1_raw[2]; y < bb1_raw[3]; ++y) for (int z = bb1_raw[4]; z < bb1_raw[5]; ++z) { int index = x + y * dim[0] + z * dim[0] * dim[1]; if ((Vector3D(x*spacing[0], y*spacing[1], z*spacing[2]) - c_d).length() < r_d) volumePointer[index] = replaceVal; } }
void GraphicalArrow3D::setValue(Vector3D base, Vector3D normal, double length) { // find an arbitrary vector k perpendicular to normal: Vector3D k = cross(Vector3D(1,0,0), normal); if (similar(k, Vector3D(0,0,0))) k = cross(Vector3D(0,1,0), normal); k = k.normalized(); Transform3D M = createTransformIJC(normal, k, base); // std::cout << "GraphicalArrow3D::setValue " << base << " - " << normal << std::endl; Transform3D S = createTransformScale(Vector3D(length,1,1)); M = M * S; // let arrow shape increase slowly with length: // source->SetTipLength(0.35/sqrt(length)); // source->SetTipRadius(0.1*sqrt(length)); // source->SetShaftRadius(0.03*sqrt(length)); source->SetTipLength(0.35); source->SetTipRadius(0.1*(length)); source->SetShaftRadius(0.03*(length)); actor->SetUserMatrix(M.getVtkMatrix()); }
void GraphicalAxes3D::rescale() { if (!mViewportListener->isListening()) return; double size = mViewportListener->getVpnZoom(); double axisSize = mSize/size; double scale = axisSize / m_vtkAxisLength; // NOTE: vtkAxesActor dislikes small values for SetTotalLength, thus we // keep that value constant at m_vtkAxisLength and instead scale the transform. Transform3D rMq = m_rMt * createTransformScale(Vector3D(scale,scale,scale)); mActor->SetUserMatrix(rMq.getVtkMatrix()); for (unsigned i=0; i<mCaption.size(); ++i) { Vector3D pos = rMq.coord(axisSize*mCaptionPos[i]); mCaption[i]->SetAttachmentPoint(pos.begin()); } }
/**Normalize volume defined by in to volume defined by out. * * This is intended for creating transforms from one viewport to another, i.e. * the two boxes should be aligned and differ only in translation + scaling. */ Transform3D createTransformNormalize(const DoubleBoundingBox3D& in, const DoubleBoundingBox3D& out) { // translate input bottomleft to origin, scale, translate back to output bottomleft. Transform3D T0 = createTransformTranslate(-in.bottomLeft()); Vector3D inrange = in.range(); Vector3D outrange = out.range(); Vector3D scale; // check for zero input dimensions for (unsigned i = 0; i < scale.size(); ++i) { if (fabs(inrange[i]) < 1.0E-5) scale[i] = 0; else scale[i] = outrange[i] / inrange[i]; } Transform3D S = createTransformScale(scale); Transform3D T1 = createTransformTranslate(out.bottomLeft()); Transform3D M = T1 * S * T0; return M; }