4 #include <vtkPolyData.h> 7 #include <vtkCellArray.h> 8 #include "vtkCardinalSpline.h" 12 #include <QTextStream> 40 int N = centerline_r->GetNumberOfPoints();
41 Eigen::MatrixXd CLpoints(3,N);
42 for(vtkIdType i = 0; i < N; i++)
45 centerline_r->GetPoint(i,p);
46 Eigen::Vector3d position;
47 position(0) = p[0]; position(1) = p[1]; position(2) = p[2];
48 CLpoints.block(0 , i , 3 , 1) = position;
56 mBranchListPtr->deleteAllBranches();
60 mBranchListPtr->findBranchesInCenterline(CLpoints_r);
62 mBranchListPtr->calculateOrientations();
63 mBranchListPtr->smoothOrientations();
66 std::cout <<
"Number of branches in CT centerline: " << mBranchListPtr->getBranches().size() << std::endl;
72 double minDistance = 100000;
73 int minDistancePositionIndex;
75 std::vector<BranchPtr> branches = mBranchListPtr->getBranches();
76 for (
int i = 0; i < branches.size(); i++)
78 Eigen::MatrixXd positions = branches[i]->getPositions();
79 for (
int j = 0; j < positions.cols(); j++)
81 double D =
findDistance(positions.col(j), targetCoordinate_r);
85 minDistanceBranch = branches[i];
86 minDistancePositionIndex = j;
91 mProjectedBranchPtr = minDistanceBranch;
92 mProjectedIndex = minDistancePositionIndex;
98 mRoutePositions.clear();
111 if (!searchBranchPtr)
114 std::vector< Eigen::Vector3d > positions = smoothBranch(searchBranchPtr, startIndex, searchBranchPtr->getPositions().col(startIndex));
117 for (
int i = 0; i<=startIndex && i<positions.size(); i++)
118 mRoutePositions.push_back(positions[i]);
120 BranchPtr parentBranchPtr = searchBranchPtr->getParentBranch();
122 searchBranchUp(parentBranchPtr, parentBranchPtr->getPositions().cols()-1);
128 mTargetPosition = targetCoordinate_r;
139 mTargetPosition = targetCoordinate_r;
140 double extentionPointIncrement = 0.25;
141 mExtendedRoutePositions.clear();
142 mExtendedRoutePositions = mRoutePositions;
143 if(mRoutePositions.size() > 0)
145 double extentionDistance =
findDistance(mRoutePositions.front(),targetCoordinate_r);
146 Eigen::Vector3d extentionVectorNormalized = ( targetCoordinate_r - mRoutePositions.front() ) / extentionDistance;
147 int numberOfextentionPoints = int(extentionDistance / extentionPointIncrement);
148 Eigen::Vector3d extentionPointIncrementVector = extentionVectorNormalized * extentionDistance / numberOfextentionPoints;
150 for (
int i = 1; i<= numberOfextentionPoints; i++)
152 mExtendedRoutePositions.insert(mExtendedRoutePositions.begin(), mRoutePositions.front() + extentionPointIncrementVector*i);
165 int numberOfPositions = positions.size();
166 for (
int j = numberOfPositions - 1; j >= 0; j--)
168 points->InsertNextPoint(positions[j](0),positions[j](1),positions[j](2));
170 for (
int j = 0; j < numberOfPositions-1; j++)
172 vtkIdType connection[2] = {j, j+1};
173 lines->InsertNextCell(2, connection);
175 retval->SetPoints(points);
176 retval->SetLines(lines);
187 Eigen::MatrixXd branchPositions = branchPtr->getPositions();
188 std::vector< Eigen::Vector3d > positions;
190 for (
int i = startIndex; i >=0; i--)
191 positions.push_back(branchPositions.col(i));
206 std::vector< Eigen::Vector3d > RouteToTarget::smoothBranch(
BranchPtr branchPtr,
int startIndex, Eigen::MatrixXd startPosition)
212 double branchRadius = branchPtr->findBranchRadius();
217 Eigen::MatrixXd positions = branchPtr->getPositions();
218 splineX->AddPoint(0,startPosition(0));
219 splineY->AddPoint(0,startPosition(1));
220 splineZ->AddPoint(0,startPosition(2));
226 if(!branchPtr->getParentBranch())
228 splineX->AddPoint(startIndex,positions(0,0));
229 splineY->AddPoint(startIndex,positions(1,0));
230 splineZ->AddPoint(startIndex,positions(2,0));
234 Eigen::MatrixXd parentPositions = branchPtr->getParentBranch()->getPositions();
235 splineX->AddPoint(startIndex,parentPositions(0,parentPositions.cols()-1));
236 splineY->AddPoint(startIndex,parentPositions(1,parentPositions.cols()-1));
237 splineZ->AddPoint(startIndex,parentPositions(2,parentPositions.cols()-1));
243 double maxAcceptedDistanceToOriginalPosition = std::max(branchRadius - 1, 1.0);
244 double maxDistanceToOriginalPosition = maxAcceptedDistanceToOriginalPosition + 1;
245 int maxDistanceIndex = -1;
246 std::vector< Eigen::Vector3d > smoothingResult;
249 while (maxDistanceToOriginalPosition >= maxAcceptedDistanceToOriginalPosition && splineX->GetNumberOfPoints() < startIndex)
251 if(maxDistanceIndex > 0)
254 splineX->AddPoint(maxDistanceIndex,positions(0,startIndex - maxDistanceIndex));
255 splineY->AddPoint(maxDistanceIndex,positions(1,startIndex - maxDistanceIndex));
256 splineZ->AddPoint(maxDistanceIndex,positions(2,startIndex - maxDistanceIndex));
260 maxDistanceToOriginalPosition = 0.0;
261 smoothingResult.clear();
262 for(
int j=0; j<=startIndex; j++)
264 double splineParameter = j;
265 Eigen::Vector3d tempPoint;
266 tempPoint(0) = splineX->Evaluate(splineParameter);
267 tempPoint(1) = splineY->Evaluate(splineParameter);
268 tempPoint(2) = splineZ->Evaluate(splineParameter);
269 smoothingResult.push_back(tempPoint);
274 if (distance > maxDistanceToOriginalPosition)
276 maxDistanceToOriginalPosition = distance;
277 maxDistanceIndex = j;
282 return smoothingResult;
287 QString RTTpath = services->patient()->getActivePatientFolder() +
"/RouteToTargetInformation/";
288 QDir RTTDirectory(RTTpath);
289 if (!RTTDirectory.exists())
290 RTTDirectory.mkpath(RTTpath);
293 QString filePath = RTTpath + QDateTime::currentDateTime().toString(format) +
"_RouteToTargetInformation.txt";
295 QFile outfile(filePath);
296 if (outfile.open(QIODevice::ReadWrite))
298 QTextStream stream(&outfile);
300 stream <<
"#Target position:" << endl;
301 stream << mTargetPosition(0) <<
" " << mTargetPosition(1) <<
" " << mTargetPosition(2) <<
" " << endl;
302 if (mProjectedBranchPtr)
304 stream <<
"#Route to target generations:" << endl;
305 stream << mProjectedBranchPtr->findGenerationNumber() << endl;
308 stream <<
"#Trachea length (mm):" << endl;
309 BranchPtr trachea = mBranchListPtr->getBranches()[0];
310 int numberOfPositionsInTrachea = trachea->getPositions().cols();
311 double tracheaLength =
calculateRouteLength(smoothBranch(trachea, numberOfPositionsInTrachea-1, trachea->getPositions().col(numberOfPositionsInTrachea-1)));
312 stream << tracheaLength << endl;
314 stream <<
"#Route to target length - from Carina (mm):" << endl;
316 stream <<
"#Extended route to target length - from Carina (mm):" << endl;
323 double routeLenght = 0;
324 for (
int i=0; i<route.size()-1; i++)
326 double d0 = route[i+1](0) - route[i](0);
327 double d1 = route[i+1](1) - route[i](1);
328 double d2 = route[i+1](2) - route[i](2);
330 routeLenght += sqrt( d0*d0 +d1*d1 + d2*d2 );
339 for (
int i=1; i<line.cols(); i++)
348 double d0 = p1(0) - p2(0);
349 double d1 = p1(1) - p2(1);
350 double d2 = p1(2) - p2(2);
352 double D = sqrt( d0*d0 + d1*d1 + d2*d2 );
vtkPolyDataPtr findExtendedRoute(Vector3D targetCoordinate_r)
double findDistanceToLine(Eigen::MatrixXd point, Eigen::MatrixXd line)
boost::shared_ptr< class VisServices > VisServicesPtr
vtkSmartPointer< class vtkCellArray > vtkCellArrayPtr
vtkSmartPointer< vtkPoints > vtkPointsPtr
vtkPolyDataPtr addVTKPoints(std::vector< Eigen::Vector3d > positions)
std::vector< Eigen::Vector3d > getBranchPositions(BranchPtr branchPtr, int startIndex)
QString timestampSecondsFormat()
boost::shared_ptr< class Branch > BranchPtr
double findDistance(Eigen::MatrixXd p1, Eigen::MatrixXd p2)
vtkSmartPointer< class vtkCardinalSpline > vtkCardinalSplinePtr
void findClosestPointInBranches(Vector3D targetCoordinate_r)
void searchBranchUp(BranchPtr searchBranchPtr, int startIndex)
void processCenterline(vtkPolyDataPtr centerline_r)
void addRouteInformationToFile(VisServicesPtr services)
vtkSmartPointer< class vtkCardinalSpline > vtkCardinalSplinePtr
double calculateRouteLength(std::vector< Eigen::Vector3d > route)
vtkSmartPointer< vtkPolyData > vtkPolyDataPtr
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
vtkPolyDataPtr findRouteToTarget(Vector3D targetCoordinate_r)
void findRoutePositions()
Eigen::MatrixXd getCenterlinePositions(vtkPolyDataPtr centerline_r)
Namespace for all CustusX production code.