Пример #1
0
/**Move the tool pos / axis pos to a new position given
 * by the input click position in vp space.
 */
void ViewWrapper2D::setAxisPos(Vector3D click_vp)
{
	ToolPtr tool = mServices->getToolManager()->getManualTool();

	Transform3D sMr = mSliceProxy->get_sMr();
	Transform3D rMpr = mServices->getPatientService()->get_rMpr();
	Transform3D prMt = tool->get_prMt();

	// find tool position in s
	Vector3D tool_t(0, 0, tool->getTooltipOffset());
	Vector3D tool_s = (sMr * rMpr * prMt).coord(tool_t);

	// find click position in s.
	Transform3D vpMs = mView->get_vpMs();
	Vector3D click_s = vpMs.inv().coord(click_vp);

	// compute the new tool position in slice space as a synthesis of the plane part of click and the z part of original.
	Vector3D cross_s(click_s[0], click_s[1], tool_s[2]);
	// compute the position change and transform to patient.
	Vector3D delta_s = cross_s - tool_s;
	Vector3D delta_pr = (rMpr.inv() * sMr.inv()).vector(delta_s);

	// MD is the actual tool movement in patient space, matrix form
	Transform3D MD = createTransformTranslate(delta_pr);
	// set new tool position to old modified by MD:
	tool->set_prMt(MD * prMt);
}
Пример #2
0
void ViewWrapper2D::samplePoint(Vector3D click_vp)
{
	if(!this->isAnyplane())
		return;

	Transform3D sMr = mSliceProxy->get_sMr();
	Transform3D vpMs = mView->get_vpMs();

	Vector3D p_s = vpMs.inv().coord(click_vp);
	Vector3D p_r = sMr.inv().coord(p_s);

	emit pointSampled(p_r);
}
Пример #3
0
/**Call when viewport size or zoom has changed.
 * Recompute camera zoom and  reps requiring vpMs.
 */
void ViewWrapper2D::viewportChanged()
{
	if (!mView->getRenderer()->IsActiveCameraCreated())
		return;

	mView->setZoomFactor(mZoom2D->getFactor());

	double viewHeight = mView->getViewport_s().range()[1];
	mView->getRenderer()->GetActiveCamera()->SetParallelScale(viewHeight / 2);

	// Heuristic guess for a good clip depth. The point is to show 3D data clipped in 2D
	// with a suitable thickness projected onto the plane.
	double clipDepth = 2.0; // i.e. all 3D props rendered outside this range is not shown.
	double length = clipDepth*10;
	clipDepth = viewHeight/120 + 1.5;
	mView->getRenderer()->GetActiveCamera()->SetPosition(0,0,length);
	mView->getRenderer()->GetActiveCamera()->SetClippingRange(length-clipDepth, length+0.1);

	mSliceProxy->setToolViewportHeight(viewHeight);
	double anyplaneViewOffset = settings()->value("Navigation/anyplaneViewOffset").toDouble();
	mSliceProxy->initializeFromPlane(mSliceProxy->getComputer().getPlaneType(), false, Vector3D(0, 0, 1), true, viewHeight, anyplaneViewOffset, true);

	DoubleBoundingBox3D BB_vp = getViewport();
	Transform3D vpMs = mView->get_vpMs();
	DoubleBoundingBox3D BB_s = transform(vpMs.inv(), BB_vp);
	PLANE_TYPE plane = mSliceProxy->getComputer().getPlaneType();

	mToolRep2D->setViewportData(vpMs, BB_vp);
	if (mSlicePlanes3DMarker)
	{
		mSlicePlanes3DMarker->getProxy()->setViewportData(plane, mSliceProxy, BB_s);
	}

	mViewFollower->setView(BB_s);
}
void LandmarkRegistrationWidget::cellChangedSlot(int row, int column)
{
	QTableWidgetItem* item = mLandmarkTableWidget->item(row, column);
	QString uid = item->data(Qt::UserRole).toString();

	if (column == 0)
	{
		QString name = item->text();
		mServices->patient()->setLandmarkName(uid, name);
	}
	if (column == 1)
	{
		Qt::CheckState state = item->checkState();
		mServices->patient()->setLandmarkActive(uid, state == Qt::Checked);
		this->performRegistration(); // automatic when changing active state (Mantis #0000674)s
	}
	if (column == 2)
	{
		QString val = item->text();
		// remove formatting stuff:
		val = val.replace('(', " ");
		val = val.replace(')', " ");
		val = val.replace(',', " ");

		Transform3D rMtarget = this->getTargetTransform();

		Vector3D p_r = Vector3D::fromString(val);
		Vector3D p_target = rMtarget.inv().coord(p_r);
		this->setTargetLandmark(uid, p_target);
	}
}
/**\brief Identical to doFastRegistration_Orientation(), except data does not move.
 *
 * When applying a new transform to the patient orientation, all data is moved
 * the the inverse of that value, thus giving a net zero change along the path
 * pr...d_i.
 *
 */
void RegistrationImplService::applyPatientOrientation(const Transform3D& tMtm, const Transform3D& prMt)
{
	Transform3D rMpr = mPatientModelService->get_rMpr();

	//create a marked(m) space tm, which is related to tool space (t) as follows:
	//the tool is defined in DICOM space such that
	//the tool points toward the patients feet and the spheres faces the same
	//direction as the nose
	Transform3D tMpr = prMt.inv();

	// this is the new patient registration:
	Transform3D tmMpr = tMtm * tMpr;
	// the change in pat reg becomes:
	Transform3D F = tmMpr * rMpr.inv();

	QString description("Patient Orientation");

	QDateTime oldTime = this->getLastRegistrationTime(); // time of previous reg
	this->applyPatientRegistration(tmMpr, description);

	// now apply the inverse of F to all data,
	// thus ensuring the total path from pr to d_i is unchanged:
	Transform3D delta_pre_rMd = F;


	// use the same registration time as generated in the applyPatientRegistration() above:
	RegistrationTransform regTrans(delta_pre_rMd, this->getLastRegistrationTime(), description);

	std::map<QString,DataPtr> data = mPatientModelService->getData();
	// update the transform on all target data:
	for (std::map<QString,DataPtr>::iterator iter = data.begin(); iter!=data.end(); ++iter)
	{
		DataPtr current = iter->second;
		RegistrationTransform newTransform = regTrans;
		newTransform.mValue = regTrans.mValue * current->get_rMd();
		current->get_rMd_History()->updateRegistration(oldTime, newTransform);

		report("Updated registration of data " + current->getName());
		std::cout << "rMd_new\n" << newTransform.mValue << std::endl;
	}

	this->setLastRegistrationTime(regTrans.mTimestamp);

	reportSuccess("Patient Orientation has been performed");
}
Пример #6
0
/**Move the tool pos / axis pos to a new position given
 * by delta movement in vp space.
 */
void ViewWrapper2D::shiftAxisPos(Vector3D delta_vp)
{
	delta_vp = -delta_vp;
	ToolPtr tool = mServices->getToolManager()->getManualTool();

	Transform3D sMr = mSliceProxy->get_sMr();
	Transform3D rMpr = mServices->getPatientService()->get_rMpr();
	Transform3D prMt = tool->get_prMt();
	Transform3D vpMs = mView->get_vpMs();
	Vector3D delta_s = vpMs.inv().vector(delta_vp);

	Vector3D delta_pr = (rMpr.inv() * sMr.inv()).vector(delta_s);

	// MD is the actual tool movement in patient space, matrix form
	Transform3D MD = createTransformTranslate(delta_pr);
	// set new tool position to old modified by MD:
	tool->set_prMt(MD * prMt);
}
Пример #7
0
Vector3D ViewFollower::findCenter_r_fromShift_s(Vector3D shift_s)
{
	Transform3D sMr = mSliceProxy->get_sMr();
	Vector3D c_s = sMr.coord(mDataManager->getCenter());

	Vector3D newcenter_s = c_s + shift_s;

	Vector3D newcenter_r = sMr.inv().coord(newcenter_s);
	return newcenter_r;
}
Пример #8
0
/**called when transform is changed
 * reset it in the prop.*/
void GeometricRep2D::transformChangedSlot()
{
	if (!mSlicer || !mMesh)
		return;

	Transform3D rMs = mSlicer->get_sMr().inv();
	Transform3D dMr = mMesh->get_rMd().inv();
	Transform3D dMs = dMr * rMs;

	mActor->SetUserMatrix(dMs.inv().getVtkMatrix());
}
Пример #9
0
void ViewWrapper2D::setSlicePlanesProxy(SlicePlanesProxyPtr proxy)
{
	mSlicePlanes3DMarker = SlicePlanes3DMarkerIn2DRep::New("uid");
	PLANE_TYPE plane = mSliceProxy->getComputer().getPlaneType();
	mSlicePlanes3DMarker->setProxy(plane, proxy);

	DoubleBoundingBox3D BB_vp = getViewport();
	Transform3D vpMs = mView->get_vpMs();
	mSlicePlanes3DMarker->getProxy()->setViewportData(plane, mSliceProxy, transform(vpMs.inv(), BB_vp));

	mView->addRep(mSlicePlanes3DMarker);
}
/**Perform a fast orientation by setting the patient registration equal to the current active
 * tool position.
 * Input is an additional transform tMtm that modifies the tool position. Use this to
 * define DICOM-ish spaces relative to the tool.
 *
 */
void RegistrationImplService::doFastRegistration_Orientation(const Transform3D& tMtm, const Transform3D& prMt)
{
	//create a marked(m) space tm, which is related to tool space (t) as follows:
	//the tool is defined in DICOM space such that
	//the tool points toward the patients feet and the spheres faces the same
	//direction as the nose
		Transform3D tMpr = prMt.inv();

	Transform3D tmMpr = tMtm * tMpr;

	this->applyPatientRegistration(tmMpr, "Fast Orientation");

	// also apply the fast translation registration if any (this frees us form doing stuff in a well-defined order.)
	this->doFastRegistration_Translation();
}
void LandmarkRegistrationWidget::setManualToolPosition(Vector3D p_r)
{
	Transform3D rMpr = mServices->patient()->get_rMpr();
	Vector3D p_pr = rMpr.inv().coord(p_r);

	// set the picked point as offset tip
	ToolPtr tool = mServices->tracking()->getManualTool();
	Vector3D offset = tool->get_prMt().vector(Vector3D(0, 0, tool->getTooltipOffset()));
	p_pr -= offset;
	p_r = rMpr.coord(p_pr);

	// TODO set center here will not do: must handle
	mServices->patient()->setCenter(p_r);
	Vector3D p0_pr = tool->get_prMt().coord(Vector3D(0, 0, 0));
	tool->set_prMt(createTransformTranslate(p_pr - p0_pr) * tool->get_prMt());
}
Transform3D ManualImage2ImageRegistrationWidget::getMatrixFromBackend()
{
    if (!this->isValid())               // Check if fixed and moving data are defined
		return Transform3D::Identity();

	Transform3D rMm = mServices->registration()->getMovingData()->get_rMd();
	Transform3D rMf = mServices->registration()->getFixedData()->get_rMd();
	Transform3D fMm = rMf.inv() * rMm;

    RegistrationHistoryPtr history = mServices->registration()->getMovingData()->get_rMd_History();
    Transform3D init_rMd;
    if(!history->getData().empty())     // Is vector with RegistrationTransforms empty ?
        init_rMd = history->getData().front().mValue;
    else
        init_rMd = Transform3D::Identity();

    Transform3D current_rMd = history->getCurrentRegistration().mValue;
    fMm = current_rMd * init_rMd.inv();

    return fMm;
}
Пример #13
0
void ElastixManager::executionFinishedSlot()
{
	if (mDisableRendering->getValue())
		mServices->view()->enableRender(true);

	bool ok = false;
	Transform3D mMf = mExecuter->getAffineResult_mMf(&ok);

	if (!ok)
		return;

//	std::cout << "ElastixManager::executionFinishedSlot(), Linear Result mMf: \n" << mMf << std::endl;

	QStringList parameterFiles = mParameters->getActiveParameterFiles();
	QString desc = QString("Image2Image [exe=%1]").arg(QFileInfo(mParameters->getActiveExecutable()->getValue()).fileName());
	for (unsigned i=0; i<parameterFiles.size(); ++i)
		desc += QString("[par=%1]").arg(QFileInfo(parameterFiles[i]).fileName());

	// Start with fMr * D * rMm = fMm'
	// where the lhs is the existing data and the delta that is input to regmanager,
	// and the rhs is the (inverse of the) output from ElastiX.
	// This gives
	// D = rMf * fMm' * mMr
	// as the input to regmanager applyImage2ImageRegistration()

	Transform3D delta_pre_rMd =
		mServices->registration()->getFixedData()->get_rMd()
		* mMf.inv()
		* mServices->registration()->getMovingData()->get_rMd().inv();

//	std::cout << "ElastixManager::executionFinishedSlot(), delta_pre_rMd: \n" << delta_pre_rMd << std::endl;
//	std::cout << "ElastixManager::executionFinishedSlot(), expected new rMdm: \n" << mServices->registration()->getFixedData()->get_rMd() * mMf.inv() << std::endl;

//	mServices->registration()->applyImage2ImageRegistration(mMf.inv(), desc);
	mServices->registration()->applyImage2ImageRegistration(delta_pre_rMd, desc);

	// add nonlinear data AFTER registering - we dont want these data to be double-registered!
	this->addNonlinearData();
}
Пример #14
0
/** return the bow widget current size in data space
 */
DoubleBoundingBox3D InteractiveCropper::getBoxWidgetSize()
{
	if (!mImage || !mBoxWidget)
	{
		return DoubleBoundingBox3D::zero();
	}

	double bb_hard[6] =
	{ -0.5, 0.5, -0.5, 0.5, -0.5, 0.5 };
	DoubleBoundingBox3D bb_unit(bb_hard);

	vtkTransformPtr transform = vtkTransformPtr::New();
	mBoxWidget->GetTransform(transform);
	Transform3D M(transform->GetMatrix());

	Transform3D rMd = mImage->get_rMd();
	M = rMd.inv() * M;

	DoubleBoundingBox3D bb_new_r = cx::transform(M, bb_unit);

	return bb_new_r;
}
void ManualImage2ImageRegistrationWidget::setMatrixFromWidget(Transform3D M)
{
    if (!this->isValid())               // Check if fixed and moving data are defined
		return;

	Transform3D rMm = mServices->registration()->getMovingData()->get_rMd();

    RegistrationHistoryPtr history = mServices->registration()->getMovingData()->get_rMd_History();

    Transform3D init_rMd;

    if(!history->getData().empty())     // Is vector with RegistrationTransforms empty ?
        init_rMd = history->getData().front().mValue;
    else
        init_rMd = Transform3D::Identity();

    Transform3D new_rMd = M * init_rMd;
    Transform3D delta = new_rMd * rMm.inv();

    mServices->registration()->addImage2ImageRegistration(delta, "Manual Image");
    this->updateAverageAccuracyLabel();

}