CustusX  22.04-rc3
An IGT application
cxRouteToTargetFilterService.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
13 
14 #include <ctkPluginContext.h>
15 #include <QDir>
16 
17 #include "cxAlgorithmHelpers.h"
19 
20 #include "cxUtilHelpers.h"
22 #include "cxStringProperty.h"
23 #include "cxDoubleProperty.h"
24 #include "cxBoolProperty.h"
25 #include "cxTypeConversions.h"
26 #include "cxImage.h"
27 
28 #include "cxRouteToTarget.h"
29 #include "cxPatientModelService.h"
30 #include "cxPointMetric.h"
31 #include "cxVisServices.h"
34 #include "cxViewService.h"
35 #include "cxLog.h"
36 
37 #include <vtkPolyData.h>
38 
39 
40 namespace cx
41 {
42 
43 RouteToTargetFilter::RouteToTargetFilter(VisServicesPtr services, bool createRouteInformationFile) :
44  FilterImpl(services),
45  mGenerateFileWithRouteInformation(createRouteInformationFile),
46  mSmoothing(true)
47 {
48 }
49 
51 {
52  return "Route to target";
53 }
54 
56 {
57  return "routetotarget_filter";
58 }
59 
61 {
62  return "<html>"
63  "<h3>Route to target.</h3>"
64  "<p>Calculates the route to a selected target in navigated bronchocopy. "
65  "The route starts at the top of trachea and ends at the most adjacent airway centerline"
66  "from the target.</p>"
67  "</html>";
68 }
69 
71 {
72  return "_rtt_cl";
73 }
74 
76 {
77  return "_ext";
78 }
79 
81 {
82  return "_vessel";
83 }
84 
86 {
87  return "_AirwaysModel";
88 }
89 
91 {
92  return "_AirwaysAndVessel_RTT";
93 }
94 
95 
97 {
98  mOptionsAdapters.push_back(this->getBloodVesselOption(mOptions));
99 }
100 
102 {
103  StringPropertySelectMeshPtr centerline;
104  centerline = StringPropertySelectMesh::New(mServices->patient());
105  centerline->setValueName("Airways centerline");
106  centerline->setHelp("Select airways centerline");
107  mInputTypes.push_back(centerline);
108 
110  targetPoint = StringPropertySelectPointMetric::New(mServices->patient());
111  targetPoint->setValueName("Target point");
112  targetPoint->setHelp("Select target point metric");
113  mInputTypes.push_back(targetPoint);
114 
115  StringPropertySelectMeshPtr bloodVesselCenterline;
116  bloodVesselCenterline = StringPropertySelectMesh::New(mServices->patient());
117  bloodVesselCenterline->setValueName("Blood vessel centerline");
118  bloodVesselCenterline->setHelp("Select blood vessel centerline");
119  mInputTypes.push_back(bloodVesselCenterline);
120 
121  SelectDataStringPropertyBasePtr bloodVesselSegmentationVolume;
122  bloodVesselSegmentationVolume = StringPropertySelectImage::New(mServices->patient());
123  bloodVesselSegmentationVolume->setValueName("Blood vessel segmentation volume");
124  bloodVesselSegmentationVolume->setHelp("Select blood vessel segmentation volume");
125  mInputTypes.push_back(bloodVesselSegmentationVolume);
126 
127 }
128 
129 
131 {
132  StringPropertySelectMeshPtr tempRTTMeshStringAdapter;
133  tempRTTMeshStringAdapter = StringPropertySelectMesh::New(mServices->patient());
134  tempRTTMeshStringAdapter->setValueName("Route to target (mesh)");
135  tempRTTMeshStringAdapter->setHelp("Generated route to target mesh (vtk-format).");
136  mOutputTypes.push_back(tempRTTMeshStringAdapter);
137 
138  StringPropertySelectMeshPtr tempRTTEXTMeshStringAdapter;
139  tempRTTEXTMeshStringAdapter = StringPropertySelectMesh::New(mServices->patient());
140  tempRTTEXTMeshStringAdapter->setValueName("Route to target extended (mesh)");
141  tempRTTEXTMeshStringAdapter->setHelp("Generated route to target extended mesh (vtk-format).");
142  mOutputTypes.push_back(tempRTTEXTMeshStringAdapter);
143 
144  StringPropertySelectMeshPtr tempRTTVesselMeshStringAdapter;
145  tempRTTVesselMeshStringAdapter = StringPropertySelectMesh::New(mServices->patient());
146  tempRTTVesselMeshStringAdapter->setValueName("Route to target along blood vessels (mesh)");
147  tempRTTVesselMeshStringAdapter->setHelp("Generated route to target along blood vessels mesh (vtk-format).");
148  mOutputTypes.push_back(tempRTTVesselMeshStringAdapter);
149 
150  StringPropertySelectMeshPtr tempRTTVesselAndAirwayRTTMeshStringAdapter;
151  tempRTTVesselAndAirwayRTTMeshStringAdapter = StringPropertySelectMesh::New(mServices->patient());
152  tempRTTVesselAndAirwayRTTMeshStringAdapter->setValueName("Connected route - airways and vessels (mesh)");
153  tempRTTVesselAndAirwayRTTMeshStringAdapter->setHelp("Connected route to target - airways and blood vessels mesh (vtk-format).");
154  mOutputTypes.push_back(tempRTTVesselAndAirwayRTTMeshStringAdapter);
155 
156  StringPropertySelectMeshPtr tempAirwaysModelMeshStringAdapter;
157  tempAirwaysModelMeshStringAdapter = StringPropertySelectMesh::New(mServices->patient());
158  tempAirwaysModelMeshStringAdapter->setValueName("Airways along blood vessels surface model (mesh)");
159  tempAirwaysModelMeshStringAdapter->setHelp("Generated airways surface model mesh (vtk-format).");
160  mOutputTypes.push_back(tempAirwaysModelMeshStringAdapter);
161 }
162 
163 
165 {
166  mRouteToTarget.reset(new RouteToTarget());
167 
168  MeshPtr mesh = boost::dynamic_pointer_cast<StringPropertySelectMesh>(mInputTypes[0])->getMesh();
169  if (!mesh)
170  return false;
171 
172  PointMetricPtr targetPoint = boost::dynamic_pointer_cast<StringPropertySelectPointMetric>(mInputTypes[1])->getPointMetric();
173  if (!targetPoint)
174  return false;
175 
176  mRouteToTarget->setSmoothing(mSmoothing);
177 
178  mRouteToTarget->processCenterline(mesh);
179 
180  //note: mOutput is in reference space
181  mOutput = mRouteToTarget->findRouteToTarget(targetPoint);
182 
183  if(mOutput->GetNumberOfPoints() < 1)
184  return false;
185 
186  mExtendedRoute = mRouteToTarget->findExtendedRoute(targetPoint);
187 
188  if (mGenerateFileWithRouteInformation)
189  mRouteToTarget->addRouteInformationToFile(mServices);
190 
191  if (getBloodVesselOption(mOptions)->getValue())
192  {
193  ImagePtr bloodVesselVolume = this->getCopiedInputImage(3);
194 
195  MeshPtr bloodVesselCenterline = boost::dynamic_pointer_cast<StringPropertySelectMesh>(mInputTypes[2])->getMesh();
196  if (bloodVesselCenterline)
197  {
198  if (bloodVesselVolume)
199  mRouteToTarget->setBloodVesselVolume(bloodVesselVolume);
200 
201  mBloodVesselRoute = mRouteToTarget->findRouteToTargetAlongBloodVesselCenterlines( bloodVesselCenterline, targetPoint);
202  mAirwaysFromBloodVessel = mRouteToTarget->generateAirwaysFromBloodVesselCenterlines();
203  }
204 
205  mAirwayAndBloodVesselRoute = mRouteToTarget->getConnectedAirwayAndBloodVesselRoute();
206  }
207  return true;
208 }
209 
211 {
212 
213  MeshPtr inputMesh = boost::dynamic_pointer_cast<StringPropertySelectMesh>(mInputTypes[0])->getMesh();
214  if (!inputMesh)
215  return false;
216 
217  PointMetricPtr targetPoint = boost::dynamic_pointer_cast<StringPropertySelectPointMetric>(mInputTypes[1])->getPointMetric();
218  if (!targetPoint)
219  return false;
220 
221  QString uidOutputCenterline = inputMesh->getName() + "_" + targetPoint->getName() + RouteToTargetFilter::getNameSuffix();
222  QString nameOutputCenterline = inputMesh->getName() + "_" + targetPoint->getName() + RouteToTargetFilter::getNameSuffix();
223 
224  MeshPtr outputCenterline = patientService()->createSpecificData<Mesh>(uidOutputCenterline, nameOutputCenterline);
225  outputCenterline->setVtkPolyData(mOutput);
226  outputCenterline->getProperties().mLineWidth->setValue(5); //Setting thicker line for RTT
227  patientService()->insertData(outputCenterline, true);
228 
229  QString uidCenterlineExt = outputCenterline->getUid() + RouteToTargetFilter::getNameSuffixExtension();
230  QString nameCenterlineExt = outputCenterline->getName() + RouteToTargetFilter::getNameSuffixExtension();
231  MeshPtr outputCenterlineExt = patientService()->createSpecificData<Mesh>(uidCenterlineExt, nameCenterlineExt);
232  outputCenterlineExt->setVtkPolyData(mExtendedRoute);
233  outputCenterlineExt->setColor(QColor(0, 0, 255, 255));
234  outputCenterlineExt->getProperties().mLineWidth->setValue(5); //Setting thicker line for RTT
235  patientService()->insertData(outputCenterlineExt, true);
236 
237  //note: mOutput and outputCenterline is in reference(r) space
238 
239 
240  //Meshes are expected to be in data(d) space
241  outputCenterline->get_rMd_History()->setParentSpace(inputMesh->getUid());
242  outputCenterlineExt->get_rMd_History()->setParentSpace(inputMesh->getUid());
243 
244  mServices->view()->autoShowData(outputCenterline);
245 
246  if(mOutputTypes.size() > 0)
247  mOutputTypes[0]->setValue(outputCenterline->getUid());
248  if(mOutputTypes.size() > 1)
249  mOutputTypes[1]->setValue(outputCenterlineExt->getUid());
250 
251  MeshPtr bloodVesselCenterlineMesh = boost::dynamic_pointer_cast<StringPropertySelectMesh>(mInputTypes[2])->getMesh();
252  if(mBloodVesselRoute && bloodVesselCenterlineMesh && getBloodVesselOption(mOptions)->getValue())
254 
255 // //Create Ceetron route-to-target file
256 // QString CeetronPath = mServices->patient()->getActivePatientFolder() + "/Images/MarianaRTT/";
257 // QDir CeetronDirectory(CeetronPath);
258 // if (!CeetronDirectory.exists()) // Creating MarianaRTT folder if it does not exist
259 // CeetronDirectory.mkpath(CeetronPath);
260 // QString filePathCeetron = CeetronPath + outputCenterline->getUid() + ".txt";
261 // mRouteToTarget->makeMarianaCenterlineFile(filePathCeetron);
262 
263  return true;
264 }
265 
267 {
268  MeshPtr inputMesh = boost::dynamic_pointer_cast<StringPropertySelectMesh>(mInputTypes[0])->getMesh();
269  PointMetricPtr targetPoint = boost::dynamic_pointer_cast<StringPropertySelectPointMetric>(mInputTypes[1])->getPointMetric();
270  QString uidOutputCenterline = inputMesh->getName() + "_" + targetPoint->getName() + RouteToTargetFilter::getNameSuffix();
271  QString nameOutputCenterline = inputMesh->getName() + "_" + targetPoint->getName() + RouteToTargetFilter::getNameSuffix();
272  MeshPtr outputCenterline = patientService()->createSpecificData<Mesh>(uidOutputCenterline, nameOutputCenterline);
273 
274  MeshPtr bloodVesselCenterlineMesh = boost::dynamic_pointer_cast<StringPropertySelectMesh>(mInputTypes[2])->getMesh();
275 
276  QString uidCenterlineBV = outputCenterline->getUid() + RouteToTargetFilter::getNameSuffixBloodVessel();
277  QString nameCenterlineBV = outputCenterline->getName() + RouteToTargetFilter::getNameSuffixBloodVessel();
278  MeshPtr outputCenterlineBV = patientService()->createSpecificData<Mesh>(uidCenterlineBV, nameCenterlineBV);
279  outputCenterlineBV->setVtkPolyData(mBloodVesselRoute);
280  outputCenterlineBV->setColor(QColor(0, 255, 0, 255));
281  patientService()->insertData(outputCenterlineBV);
282 
283  outputCenterlineBV->get_rMd_History()->setParentSpace(inputMesh->getUid());
284 
285  if(mOutputTypes.size() > 2)
286  mOutputTypes[2]->setValue(outputCenterlineBV->getUid());
287 
288  if(mAirwaysFromBloodVessel)
289  {
290  QString uidSurfaceModel = uidCenterlineBV + RouteToTargetFilter::getNameSuffixAirwayModel();
291  QString nameSurfaceModel = nameCenterlineBV + RouteToTargetFilter::getNameSuffixAirwayModel();
292 
293  MeshPtr outputMesh = patientService()->createSpecificData<Mesh>(uidSurfaceModel, nameSurfaceModel);
294  outputMesh->setVtkPolyData(mAirwaysFromBloodVessel);
295  outputMesh->setColor(QColor(192, 253, 246, 255));
296  patientService()->insertData(outputMesh);
297 
298  //Meshes are expected to be in data(d) space
299  outputMesh->get_rMd_History()->setParentSpace(inputMesh->getUid());
300 
301  if(mOutputTypes.size() > 4)
302  mOutputTypes[4]->setValue(outputMesh->getUid());
303 
304  }
305 
306  QString uidMergedCenterline = outputCenterline->getUid() + RouteToTargetFilter::getNameSuffixAirwayAndVesselRTT();
307  QString nameMergedCenterline = outputCenterline->getName() + RouteToTargetFilter::getNameSuffixAirwayAndVesselRTT();
308  MeshPtr outputMergedCenterline = patientService()->createSpecificData<Mesh>(uidMergedCenterline, nameMergedCenterline);
309  outputMergedCenterline->setVtkPolyData(mAirwayAndBloodVesselRoute);
310  outputMergedCenterline->setColor(QColor(0, 255, 0, 255));
311  outputMergedCenterline->getProperties().mLineWidth->setValue(5); //Setting thicker line for RTT
312  patientService()->insertData(outputMergedCenterline);
313 
314  outputMergedCenterline->get_rMd_History()->setParentSpace(inputMesh->getUid());
315 
316  if(mOutputTypes.size() >3)
317  mOutputTypes[3]->setValue(outputMergedCenterline->getUid());
318 
319  return true;
320 
321 }
322 
324 {
325  mSmoothing = smoothing; // default true
326 }
327 
328 std::vector< Eigen::Vector3d > RouteToTargetFilter::getRoutePositions()
329 {
330  return mRouteToTarget->getRoutePositions();
331 }
332 
334 {
335  return mRouteToTarget->getCameraRotation();
336 }
337 
338 BoolPropertyPtr RouteToTargetFilter::getBloodVesselOption(QDomElement root)
339 {
340  BoolPropertyPtr retval =
341  BoolProperty::initialize("Use blood vessels to find RTT beyond airways",
342  "",
343  "Selecting this option to use blood vessels to find RTT beyond airways",
344  false, root);
345  return retval;
346 
347 }
348 
349 
350 } // namespace cx
351 
static BoolPropertyPtr initialize(const QString &uid, QString name, QString help, bool value, QDomNode root=QDomNode())
std::vector< SelectDataStringPropertyBasePtr > mInputTypes
Definition: cxFilterImpl.h:73
A mesh data set.
Definition: cxMesh.h:45
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:40
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
void setSmoothing(bool smoothing=true)
std::vector< PropertyPtr > mOptionsAdapters
Definition: cxFilterImpl.h:75
VisServicesPtr mServices
Definition: cxFilterImpl.h:82
boost::shared_ptr< class SelectDataStringPropertyBase > SelectDataStringPropertyBasePtr
PatientModelServicePtr patientService()
void setVtkPolyData(const vtkPolyDataPtr &polyData)
Definition: cxMesh.cpp:92
ImagePtr getCopiedInputImage(int index=0)
QDomElement mOptions
Definition: cxFilterImpl.h:76
std::vector< SelectDataStringPropertyBasePtr > mOutputTypes
Definition: cxFilterImpl.h:74
static StringPropertySelectPointMetricPtr New(PatientModelServicePtr patientModelService)
std::vector< double > getCameraRotation()
static StringPropertySelectMeshPtr New(PatientModelServicePtr patientModelService)
boost::shared_ptr< class StringPropertySelectPointMetric > StringPropertySelectPointMetricPtr
static StringPropertySelectImagePtr New(PatientModelServicePtr patientModelService)
boost::shared_ptr< class BoolProperty > BoolPropertyPtr
boost::shared_ptr< class Mesh > MeshPtr
RouteToTargetFilter(VisServicesPtr services, bool createRouteInformationFile=false)
std::vector< Eigen::Vector3d > getRoutePositions()
boost::shared_ptr< class StringPropertySelectMesh > StringPropertySelectMeshPtr
Namespace for all CustusX production code.
boost::shared_ptr< class PointMetric > PointMetricPtr