22 #include <vtkCellArray.h>
23 #include <vtkClipPolyData.h>
24 #include <vtkLinearExtrusionFilter.h>
25 #include <vtkPlanes.h>
26 #include <vtkPoints.h>
27 #include <vtkPolyData.h>
29 #include <vtkDoubleArray.h>
30 #include <vtkFloatArray.h>
32 #include <vtkPolygon.h>
35 #include <vtkCubeSource.h>
36 #include <vtkImageData.h>
37 #include <vtkLinearSubdivisionFilter.h>
38 #include <vtkSampleFunction.h>
39 #include <vtkTriangleFilter.h>
42 : m_Contour(nullptr), m_ClippingGeometry(nullptr), m_AutomaticVectorGeneration(false)
45 timeGeometry->Initialize(1);
56 double vtkvector[3] = {0, 0, 1};
81 m_ClipPolyDataFilter->Delete();
82 m_ClippingBox->Delete();
83 m_SubdivisionFilter->Delete();
84 m_TriangleFilter->Delete();
85 m_ExtrusionFilter->Delete();
91 static double polygonNormal[3] = {0.0, 0.0, 1.0};
97 xt[0] = worldPoint[0] - m_Origin[0];
98 xt[1] = worldPoint[1] - m_Origin[1];
99 xt[2] = worldPoint[2] - m_Origin[2];
101 float dist = xt[0] * m_Normal[0] + xt[1] * m_Normal[1] + xt[2] * m_Normal[2];
102 xt[0] -= dist * m_Normal[0];
103 xt[1] -= dist * m_Normal[1];
104 xt[2] -= dist * m_Normal[2];
108 x[0] = xt[0] * m_Right[0] + xt[1] * m_Right[1] + xt[2] * m_Right[2];
109 x[1] = xt[0] * m_Down[0] + xt[1] * m_Down[1] + xt[2] * m_Down[2];
114 if (x[0] >= this->m_ProjectedContourBounds[0] && x[0] <= this->m_ProjectedContourBounds[1] &&
115 x[1] >= this->m_ProjectedContourBounds[2] && x[1] <= this->m_ProjectedContourBounds[3] &&
116 this->m_Polygon->PointInPolygon(x,
117 m_Polygon->Points->GetNumberOfPoints(),
118 ((vtkDoubleArray *)this->m_Polygon->Points->GetData())->GetPointer(0),
119 (
double *)const_cast<mitk::ExtrudedContour *>(
this)->m_ProjectedContourBounds,
133 if (this->GetSource())
135 this->GetSource()->UpdateOutputInformation();
137 if (GetMTime() > m_LastCalculateExtrusionTime)
148 if (m_Contour.IsNull())
150 SetVtkPolyData(
nullptr);
158 polys->InsertNextCell(m_Polygon->GetPointIds());
159 polyData->SetPoints(m_Polygon->GetPoints());
173 polyData->SetPolys(polys);
176 m_ExtrusionFilter->SetInputData(polyData);
181 m_ExtrusionFilter->SetScaleFactor(GetGeometry()->GetExtentInMM(2));
182 SetVtkPolyData(m_SubdivisionFilter->GetOutput());
199 m_LastCalculateExtrusionTime.Modified();
204 if (m_Contour.IsNull())
210 nullvector.Fill(0.0);
213 unsigned int numPts = 20;
215 mitk::Contour::PathType::InputType cstart = path->StartOfInput();
216 mitk::Contour::PathType::InputType cend = path->EndOfInput();
217 mitk::Contour::PathType::InputType cstep = (cend - cstart) / numPts;
218 mitk::Contour::PathType::InputType ccur;
222 m_Vector.Normalize();
225 if (
mitk::Equal(m_Vector, nullvector) || m_AutomaticVectorGeneration)
227 if (m_AutomaticVectorGeneration ==
false)
228 itkWarningMacro(
"Extrusion vector is 0 (" << m_Vector <<
"); trying to use normal of polygon");
235 for (i = 0, ccur = cstart; i < numPts; ++i, ccur += cstep)
237 itk2vtk(path->Evaluate(ccur), vtkpoint);
238 loopPoints->InsertNextPoint(vtkpoint);
242 vtkPolygon::ComputeNormal(loopPoints, m_Normal);
243 loopPoints->Delete();
248 itkExceptionMacro(
"Cannot calculate normal of polygon");
256 itkDebugMacro(
"Right vector is 0. Calculating.");
260 itkWarningMacro(
"Right vector (" << m_RightVector <<
") not perpendicular to extrusion vector " << m_Vector
262 << m_RightVector * m_Vector);
267 FillVector3D(m_RightVector, 1.0f, -m_Vector[0] / m_Vector[1], 0.0f);
268 m_RightVector.Normalize();
277 VnlVector rightDV = m_RightVector.GetVnlVector();
280 VnlVector downDV = vnl_cross_3d(m_Vector.GetVnlVector(), rightDV);
288 m_ProjectionPlane->InitializeStandardPlane(rightDV, downDV);
293 m_Polygon->Points->Reset();
294 m_Polygon->Points->SetNumberOfPoints(numPts);
295 m_Polygon->PointIds->Reset();
296 m_Polygon->PointIds->SetNumberOfIds(numPts);
303 for (i = 0, ccur = cstart; i < numPts; ++i, ccur += cstep)
305 pt3d.CastFrom(path->Evaluate(ccur));
306 m_ProjectionPlane->Map(pt3d, pt2d);
308 if (pt2d[0] < min[0])
310 if (pt2d[0] > max[0])
313 if (pt2d[1] < min[1])
315 if (pt2d[1] > max[1])
317 m_Polygon->Points->SetPoint(i, xProj);
318 m_Polygon->PointIds->SetId(i, i);
321 for (i = 0; i < numPts; ++i)
323 double *pt = this->m_Polygon->Points->GetPoint(i);
327 itkDebugMacro(<< i <<
": (" << pt[0] <<
"," << pt[1] <<
"," << pt[2] <<
")");
329 this->m_Polygon->GetBounds(m_ProjectedContourBounds);
337 m_ProjectionPlane->Map(min, origin);
338 ScalarType bounds[6] = {0, max[0] - min[0], 0, max[1] - min[1], 0, 1};
339 m_ProjectionPlane->SetBounds(bounds);
340 m_ProjectionPlane->SetOrigin(origin);
343 if (m_ClippingGeometry.IsNotNull())
348 for (i = 0; i < 8; ++i)
350 dist = m_ProjectionPlane->SignedDistance(m_ClippingGeometry->GetCornerPoint(i));
357 origin = origin + m_Vector * min_dist;
358 m_ProjectionPlane->SetOrigin(origin);
359 bounds[5] = max_dist - min_dist;
367 assert(g3d.IsNotNull());
368 g3d->SetBounds(bounds);
369 g3d->SetIndexToWorldTransform(m_ProjectionPlane->GetIndexToWorldTransform());
372 timeGeometry->Initialize(g3d, 1);
373 SetTimeGeometry(timeGeometry);
378 unsigned long latestTime = Superclass::GetMTime();
379 if (m_Contour.IsNotNull())
381 unsigned long localTime;
382 localTime = m_Contour->GetMTime();
383 if (localTime > latestTime)
384 latestTime = localTime;
virtual ~ExtrudedContour()
vnl_vector< ScalarType > VnlVector
virtual mitk::ScalarType GetVolume() override
vtkLinearSubdivisionFilter * m_SubdivisionFilter
vtkPlanes * m_ClippingBox
virtual void SetTimeGeometry(TimeGeometry *geometry)
Set the TimeGeometry of the data, which will be referenced (not copied!).
vtkLinearExtrusionFilter * m_ExtrusionFilter
mitk::PlaneGeometry::Pointer m_ProjectionPlane
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
mitk::Vector3D m_RightVector
void vnl2vtk(const vnl_vector< Tin > &in, Tout *out)
virtual unsigned long GetMTime() const override
Get the modified time of the last change of the contents this data object or its geometry.
void vtk2itk(const Tin &in, Tout &out)
virtual void UpdateOutputInformation() override
PathType::Pointer PathPointer
void itk2vtk(const Tin &in, Tout &out)
vtkClipPolyData * m_ClipPolyDataFilter
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
virtual bool IsInside(const Point3D &p) const override
vtkTriangleFilter * m_TriangleFilter
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.