36 #define _BACKWARD_BACKWARD_WARNING_H 1 //Cut out the vtk deprecated warning for now (gcc4.3) 37 #include <vtkPolygon.h> 39 #include "Exception.hpp" 41 #include "VesselNode.hpp" 42 #include "VesselSegment.hpp" 43 #include "UblasCustomFunctions.hpp" 44 #include "UblasIncludes.hpp" 45 #include "DimensionalChastePoint.hpp" 47 #include "BaseUnits.hpp" 49 #include "VesselSurfaceGenerator.hpp" 51 template<
unsigned DIM>
53 mpVesselNetwork(pVesselNetwork),
54 mpSurface(vtkSmartPointer<vtkPolyData>::New()),
55 mReferenceLength(
BaseUnits::Instance()->GetReferenceLengthScale())
59 template<
unsigned DIM>
64 template<
unsigned DIM>
67 std::vector<DimensionalChastePoint<DIM> > hole_locations;
68 std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments =
mpVesselNetwork->GetVesselSegments();
69 for (
unsigned idx = 0; idx < segments.size(); idx++)
71 hole_locations.push_back(segments[idx]->GetMidPoint());
73 return hole_locations;
76 template<
unsigned DIM>
81 EXCEPTION(
"The surface generator currently only works in 3D");
84 c_vector<double, DIM> z_axis = unit_vector<double>(DIM,2);
85 c_vector<double, DIM> y_axis = unit_vector<double>(DIM,1);
88 std::vector<std::vector<boost::shared_ptr<Polygon<DIM> > > > segment_polygons;
89 std::vector<boost::shared_ptr<VesselSegment<DIM> > > segments =
mpVesselNetwork->GetVesselSegments();
91 for (
unsigned idx = 0; idx < segments.size(); idx++)
93 boost::shared_ptr<VesselNode<DIM> > p_start_node = segments[idx]->GetNode(0);
94 boost::shared_ptr<VesselNode<DIM> > p_end_node = segments[idx]->GetNode(1);
95 c_vector<double, DIM> segment_tangent = segments[idx]->GetUnitTangent();
101 double angle = std::acos(inner_prod(z_axis, segment_tangent));
102 if (std::abs(inner_prod(z_axis, segment_tangent)) < 1.0 - 1.e-6)
104 c_vector<double, DIM> axis = VectorProduct(z_axis, segment_tangent);
110 std::vector<vtkSmartPointer<vtkPlane> > start_planes;
111 std::vector<vtkSmartPointer<vtkPlane> > end_planes;
112 c_vector<double, DIM> average_start_normal;
113 c_vector<double, DIM> average_end_normal;
115 if (p_start_node->GetNumberOfSegments() == 1)
117 c_vector<double, DIM> node_location = p_start_node->rGetLocation().GetLocation(
mReferenceLength);
118 vtkSmartPointer<vtkPlane> p_plane = vtkSmartPointer<vtkPlane>::New();
121 p_plane->SetOrigin(node_location[0], node_location[1], node_location[2]);
122 p_plane->SetNormal(segment_tangent[0], segment_tangent[1], segment_tangent[2]);
126 p_plane->SetOrigin(node_location[0], node_location[1], 0.0);
127 p_plane->SetNormal(segment_tangent[0], segment_tangent[1], 0.0);
129 start_planes.push_back(p_plane);
133 std::vector<boost::shared_ptr<VesselSegment<DIM> > > node_segments = p_start_node->GetSegments();
134 for (
unsigned jdx = 0; jdx < node_segments.size(); jdx++)
136 if (node_segments[jdx] != segments[idx])
138 c_vector<double, DIM> other_segment_tangent = node_segments[jdx]->GetUnitTangent();
139 if (node_segments[jdx]->GetNode(0) == p_start_node)
141 other_segment_tangent = -other_segment_tangent;
144 average_start_normal += VectorProduct(segment_tangent, other_segment_tangent);
145 c_vector<double, DIM> node_location = p_start_node->rGetLocation().GetLocation(
mReferenceLength);
146 vtkSmartPointer<vtkPlane> p_plane = vtkSmartPointer<vtkPlane>::New();
149 p_plane->SetOrigin(node_location[0], node_location[1], 0.0);
153 p_plane->SetOrigin(node_location[0], node_location[1], node_location[2]);
156 c_vector<double, DIM> bisection_vector = segment_tangent + other_segment_tangent;
157 bisection_vector /= norm_2(bisection_vector);
160 p_plane->SetNormal(bisection_vector[0], bisection_vector[1], 0.0);
164 p_plane->SetNormal(bisection_vector[0], bisection_vector[1], bisection_vector[2]);
166 start_planes.push_back(p_plane);
171 if (p_end_node->GetNumberOfSegments() == 1)
173 c_vector<double, DIM> node_location = p_end_node->rGetLocation().GetLocation(
mReferenceLength);
174 vtkSmartPointer<vtkPlane> p_plane = vtkSmartPointer<vtkPlane>::New();
175 p_plane->SetOrigin(node_location[0], node_location[1], node_location[2]);
176 p_plane->SetNormal(segment_tangent[0], segment_tangent[1], segment_tangent[2]);
177 end_planes.push_back(p_plane);
181 std::vector<boost::shared_ptr<VesselSegment<DIM> > > node_segments = p_end_node->GetSegments();
182 for (
unsigned jdx = 0; jdx < node_segments.size(); jdx++)
184 if (node_segments[jdx] != segments[idx])
186 c_vector<double, DIM> other_segment_tangent = node_segments[jdx]->GetUnitTangent();
187 if (node_segments[jdx]->GetNode(1) == p_end_node)
189 other_segment_tangent = -other_segment_tangent;
191 average_end_normal += VectorProduct(segment_tangent, other_segment_tangent);
193 c_vector<double, DIM> node_location = p_end_node->rGetLocation().GetLocation(
mReferenceLength);
194 vtkSmartPointer<vtkPlane> p_plane = vtkSmartPointer<vtkPlane>::New();
197 p_plane->SetOrigin(node_location[0], node_location[1], 0.0);
201 p_plane->SetOrigin(node_location[0], node_location[1], node_location[2]);
204 c_vector<double, DIM> bisection_vector = segment_tangent + other_segment_tangent;
205 bisection_vector /= norm_2(bisection_vector);
208 p_plane->SetNormal(bisection_vector[0], bisection_vector[1], 0.0);
212 p_plane->SetNormal(bisection_vector[0], bisection_vector[1], bisection_vector[2]);
214 end_planes.push_back(p_plane);
223 std::vector<c_vector<double, DIM> > projected_start_points = start_points;
224 std::vector<c_vector<double, DIM> > projected_end_points = end_points;
226 for (
unsigned jdx = 0; jdx < start_planes.size(); jdx++)
234 std::vector<c_vector<double, DIM> > candidate_points = start_points;
236 for (
unsigned mdx = 0; mdx < projected_start_points.size(); mdx++)
238 if (norm_2(candidate_points[mdx] - start_points[mdx])
239 < norm_2(projected_start_points[mdx] - start_points[mdx]))
241 projected_start_points[mdx] = candidate_points[mdx];
247 for (
unsigned jdx = 0; jdx < end_planes.size(); jdx++)
255 std::vector<c_vector<double, DIM> > candidate_points = end_points;
257 for (
unsigned mdx = 0; mdx < projected_end_points.size(); mdx++)
259 if (norm_2(candidate_points[mdx] - end_points[mdx])
260 < norm_2(projected_end_points[mdx] - end_points[mdx]))
262 projected_end_points[mdx] = candidate_points[mdx];
269 std::vector<boost::shared_ptr<DimensionalChastePoint<DIM> > > start_vertices;
270 std::vector<boost::shared_ptr<DimensionalChastePoint<DIM> > > end_vertices;
272 for (
unsigned jdx = 0; jdx < projected_start_points.size(); jdx++)
276 for (
unsigned jdx = 0; jdx < projected_end_points.size(); jdx++)
282 std::vector<boost::shared_ptr<Polygon<DIM> > > polygons;
283 for (
unsigned jdx = 0; jdx < start_vertices.size(); jdx++)
286 if (jdx != start_vertices.size() - 1)
295 p_polygon->AddVertex(start_vertices[index2]);
296 p_polygon->AddVertex(end_vertices[index2]);
297 p_polygon->AddVertex(end_vertices[jdx]);
298 polygons.push_back(p_polygon);
301 if (segments[idx]->GetNode(0)->GetNumberOfSegments() == 1)
306 if (segments[idx]->GetNode(1)->GetNumberOfSegments() == 1)
310 segment_polygons.push_back(polygons);
312 return segment_polygons;
315 template<
unsigned DIM>
318 std::vector<std::vector<boost::shared_ptr<Polygon<DIM> > > > segment_polygons =
GetSurface();
319 std::vector<boost::shared_ptr<Polygon<DIM> > > polygons;
320 for (
unsigned idx = 0; idx < segment_polygons.size(); idx++)
322 for (
unsigned jdx = 0; jdx < segment_polygons[idx].size(); jdx++)
324 polygons.push_back(segment_polygons[idx][jdx]);
330 template<
unsigned DIM>
333 std::vector<std::vector<boost::shared_ptr<Polygon<DIM> > > > segment_polygons =
GetSurface();
337 for (
unsigned idx = 0; idx < segment_polygons.size(); idx++)
339 for (
unsigned jdx = 0; jdx < segment_polygons[idx].size(); jdx++)
341 part.
AddPolygon(segment_polygons[idx][jdx]->GetVertices(),
true);
349 template<
unsigned DIM>
353 double increment = 2.0 * M_PI / double(numberOfSegments);
355 std::vector<c_vector<double, DIM> > points;
357 for (
unsigned idx = 0; idx < numberOfSegments; idx++)
359 c_vector<double, DIM> point;
360 point[0] = radius * std::cos(angle);
361 point[1] = radius * std::sin(angle);
363 points.push_back(point);
369 template<
unsigned DIM>
371 c_vector<double, DIM> directionVector,
double length,
372 vtkSmartPointer<vtkPlane> plane)
374 for (
unsigned idx = 0; idx < rPoints.size(); idx++)
376 c_vector<double, DIM> point_on_line = rPoints[idx] + length * directionVector;
377 c_vector<double, DIM> projected_point;
378 double parametric_distance;
379 plane->IntersectWithLine(&rPoints[idx][0], &point_on_line[0], parametric_distance, &projected_point[0]);
380 rPoints[idx] = projected_point;
384 template<
unsigned DIM>
388 double sin_a = std::sin(angle);
389 double cos_a = std::cos(angle);
390 c_vector<double, DIM> unit_axis = axis / norm_2(axis);
392 for (
unsigned idx = 0; idx < rPoints.size(); idx++)
394 double dot_product = inner_prod(rPoints[idx], unit_axis);
395 c_vector<double, DIM> new_point;
396 new_point[0] = (unit_axis[0] * dot_product * (1.0 - cos_a) + rPoints[idx][0] * cos_a
397 + (-unit_axis[2] * rPoints[idx][1] + unit_axis[1] * rPoints[idx][2]) * sin_a);
398 new_point[1] = (unit_axis[1] * dot_product * (1.0 - cos_a) + rPoints[idx][1] * cos_a
399 + (unit_axis[2] * rPoints[idx][0] - unit_axis[0] * rPoints[idx][2]) * sin_a);
400 new_point[2] = (unit_axis[2] * dot_product * (1.0 - cos_a) + rPoints[idx][2] * cos_a
401 + (-unit_axis[1] * rPoints[idx][0] + unit_axis[0] * rPoints[idx][1]) * sin_a);
403 rPoints[idx] = new_point;
407 template<
unsigned DIM>
409 c_vector<double, DIM> translationVector)
411 for (
unsigned idx = 0; idx < rPoints.size(); idx++)
413 rPoints[idx] += translationVector;
vtkSmartPointer< vtkPolyData > GetVtk()
std::vector< c_vector< double, DIM > > MakeCircle(double radius, unsigned numberOfSegments=16)
~VesselSurfaceGenerator()
vtkSmartPointer< vtkPolyData > mpSurface
std::vector< std::vector< boost::shared_ptr< Polygon< DIM > > > > GetSurface()
vtkSmartPointer< vtkPolyData > GetVtkSurface()
VesselSurfaceGenerator(boost::shared_ptr< VesselNetwork< DIM > > pVesselNetwork)
void RotateAboutAxis(std::vector< c_vector< double, DIM > > &rPoints, c_vector< double, DIM > axis, double angle)
void Translate(std::vector< c_vector< double, DIM > > &rPoints, c_vector< double, DIM > translationVector)
units::quantity< unit::length > mReferenceLength
boost::shared_ptr< VesselNetwork< DIM > > mpVesselNetwork
static boost::shared_ptr< Polygon > Create(std::vector< boost::shared_ptr< DimensionalChastePoint< DIM > > > vertices)
std::vector< boost::shared_ptr< Polygon< DIM > > > GetSurfacePolygons()
boost::shared_ptr< Polygon< DIM > > AddPolygon(std::vector< boost::shared_ptr< DimensionalChastePoint< DIM > > > vertices, bool newFacet=false, boost::shared_ptr< Facet< DIM > > pFacet=boost::shared_ptr< Facet< DIM > >())
std::vector< DimensionalChastePoint< DIM > > GetHoles()
void ProjectOnPlane(std::vector< c_vector< double, DIM > > &rPoints, c_vector< double, DIM > directionVector, double length, vtkSmartPointer< vtkPlane > pPlane)