1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkQuadraticPolygon.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkQuadraticPolygon.h"
16 
17 #include "vtkCellData.h"
18 #include "vtkDataArray.h"
19 #include "vtkIdTypeArray.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkPointData.h"
22 #include "vtkPoints.h"
23 #include "vtkPolygon.h"
24 #include "vtkQuadraticEdge.h"
25 
26 vtkStandardNewMacro(vtkQuadraticPolygon);
27 
28 //------------------------------------------------------------------------------
29 // Instantiate quadratic polygon.
vtkQuadraticPolygon()30 vtkQuadraticPolygon::vtkQuadraticPolygon()
31 {
32   this->Polygon = vtkPolygon::New();
33   this->Edge = vtkQuadraticEdge::New();
34   this->UseMVCInterpolation = true;
35 }
36 
37 //------------------------------------------------------------------------------
~vtkQuadraticPolygon()38 vtkQuadraticPolygon::~vtkQuadraticPolygon()
39 {
40   this->Polygon->Delete();
41   this->Edge->Delete();
42 }
43 
44 //------------------------------------------------------------------------------
GetEdge(int edgeId)45 vtkCell* vtkQuadraticPolygon::GetEdge(int edgeId)
46 {
47   int numEdges = this->GetNumberOfEdges();
48 
49   edgeId = (edgeId < 0 ? 0 : (edgeId > numEdges - 1 ? numEdges - 1 : edgeId));
50   int p = (edgeId + 1) % numEdges;
51 
52   // load point id's
53   this->Edge->PointIds->SetId(0, this->PointIds->GetId(edgeId));
54   this->Edge->PointIds->SetId(1, this->PointIds->GetId(p));
55   this->Edge->PointIds->SetId(2, this->PointIds->GetId(edgeId + numEdges));
56 
57   // load coordinates
58   this->Edge->Points->SetPoint(0, this->Points->GetPoint(edgeId));
59   this->Edge->Points->SetPoint(1, this->Points->GetPoint(p));
60   this->Edge->Points->SetPoint(2, this->Points->GetPoint(edgeId + numEdges));
61 
62   return this->Edge;
63 }
64 
65 //------------------------------------------------------------------------------
EvaluatePosition(const double x[3],double closestPoint[3],int & subId,double pcoords[3],double & minDist2,double weights[])66 int vtkQuadraticPolygon::EvaluatePosition(const double x[3], double closestPoint[3], int& subId,
67   double pcoords[3], double& minDist2, double weights[])
68 {
69   this->InitializePolygon();
70   int result = this->Polygon->EvaluatePosition(x, closestPoint, subId, pcoords, minDist2, weights);
71   vtkQuadraticPolygon::PermuteFromPolygon(this->GetNumberOfPoints(), weights);
72   return result;
73 }
74 
75 //------------------------------------------------------------------------------
EvaluateLocation(int & subId,const double pcoords[3],double x[3],double * weights)76 void vtkQuadraticPolygon::EvaluateLocation(
77   int& subId, const double pcoords[3], double x[3], double* weights)
78 {
79   this->InitializePolygon();
80   this->Polygon->EvaluateLocation(subId, pcoords, x, weights);
81   vtkQuadraticPolygon::PermuteFromPolygon(this->GetNumberOfPoints(), weights);
82 }
83 
84 //------------------------------------------------------------------------------
CellBoundary(int subId,const double pcoords[3],vtkIdList * pts)85 int vtkQuadraticPolygon::CellBoundary(int subId, const double pcoords[3], vtkIdList* pts)
86 {
87   this->InitializePolygon();
88   return this->Polygon->CellBoundary(subId, pcoords, pts);
89 }
90 
91 //------------------------------------------------------------------------------
Contour(double value,vtkDataArray * cellScalars,vtkIncrementalPointLocator * locator,vtkCellArray * verts,vtkCellArray * lines,vtkCellArray * polys,vtkPointData * inPd,vtkPointData * outPd,vtkCellData * inCd,vtkIdType cellId,vtkCellData * outCd)92 void vtkQuadraticPolygon::Contour(double value, vtkDataArray* cellScalars,
93   vtkIncrementalPointLocator* locator, vtkCellArray* verts, vtkCellArray* lines,
94   vtkCellArray* polys, vtkPointData* inPd, vtkPointData* outPd, vtkCellData* inCd, vtkIdType cellId,
95   vtkCellData* outCd)
96 {
97   this->InitializePolygon();
98 
99   vtkDataArray* convertedCellScalars = cellScalars->NewInstance();
100   vtkQuadraticPolygon::PermuteToPolygon(cellScalars, convertedCellScalars);
101 
102   this->Polygon->Contour(
103     value, convertedCellScalars, locator, verts, lines, polys, inPd, outPd, inCd, cellId, outCd);
104 
105   convertedCellScalars->Delete();
106 }
107 
108 //------------------------------------------------------------------------------
Clip(double value,vtkDataArray * cellScalars,vtkIncrementalPointLocator * locator,vtkCellArray * polys,vtkPointData * inPd,vtkPointData * outPd,vtkCellData * inCd,vtkIdType cellId,vtkCellData * outCd,int insideOut)109 void vtkQuadraticPolygon::Clip(double value, vtkDataArray* cellScalars,
110   vtkIncrementalPointLocator* locator, vtkCellArray* polys, vtkPointData* inPd, vtkPointData* outPd,
111   vtkCellData* inCd, vtkIdType cellId, vtkCellData* outCd, int insideOut)
112 {
113   this->InitializePolygon();
114 
115   vtkDataArray* convertedCellScalars = cellScalars->NewInstance();
116   vtkQuadraticPolygon::PermuteToPolygon(cellScalars, convertedCellScalars);
117 
118   this->Polygon->Clip(
119     value, convertedCellScalars, locator, polys, inPd, outPd, inCd, cellId, outCd, insideOut);
120 
121   convertedCellScalars->Delete();
122 }
123 
124 //------------------------------------------------------------------------------
IntersectWithLine(const double * p1,const double * p2,double tol,double & t,double * x,double * pcoords,int & subId)125 int vtkQuadraticPolygon::IntersectWithLine(
126   const double* p1, const double* p2, double tol, double& t, double* x, double* pcoords, int& subId)
127 {
128   this->InitializePolygon();
129   return this->Polygon->IntersectWithLine(p1, p2, tol, t, x, pcoords, subId);
130 }
131 
132 //------------------------------------------------------------------------------
Triangulate(vtkIdList * outTris)133 int vtkQuadraticPolygon::Triangulate(vtkIdList* outTris)
134 {
135   this->InitializePolygon();
136   int result = this->Polygon->Triangulate(outTris);
137   vtkQuadraticPolygon::ConvertFromPolygon(outTris);
138   return result;
139 }
140 
141 //------------------------------------------------------------------------------
Triangulate(int index,vtkIdList * ptIds,vtkPoints * pts)142 int vtkQuadraticPolygon::Triangulate(int index, vtkIdList* ptIds, vtkPoints* pts)
143 {
144   this->InitializePolygon();
145   return this->Polygon->Triangulate(index, ptIds, pts);
146 }
147 
148 //------------------------------------------------------------------------------
NonDegenerateTriangulate(vtkIdList * outTris)149 int vtkQuadraticPolygon::NonDegenerateTriangulate(vtkIdList* outTris)
150 {
151   this->InitializePolygon();
152   int result = this->Polygon->NonDegenerateTriangulate(outTris);
153   vtkQuadraticPolygon::ConvertFromPolygon(outTris);
154   return result;
155 }
156 
157 //------------------------------------------------------------------------------
InterpolateFunctions(const double x[3],double * weights)158 void vtkQuadraticPolygon::InterpolateFunctions(const double x[3], double* weights)
159 {
160   this->InitializePolygon();
161   this->Polygon->SetUseMVCInterpolation(UseMVCInterpolation);
162   this->Polygon->InterpolateFunctions(x, weights);
163   vtkQuadraticPolygon::PermuteFromPolygon(this->GetNumberOfPoints(), weights);
164 }
165 
166 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)167 void vtkQuadraticPolygon::PrintSelf(ostream& os, vtkIndent indent)
168 {
169   this->Superclass::PrintSelf(os, indent);
170 
171   os << indent << "UseMVCInterpolation: " << this->UseMVCInterpolation << "\n";
172   os << indent << "Edge:\n";
173   this->Edge->PrintSelf(os, indent.GetNextIndent());
174   os << indent << "Polygon:\n";
175   this->Polygon->PrintSelf(os, indent.GetNextIndent());
176 }
177 
178 //------------------------------------------------------------------------------
DistanceToPolygon(double x[3],int numPts,double * pts,double bounds[6],double closest[3])179 double vtkQuadraticPolygon::DistanceToPolygon(
180   double x[3], int numPts, double* pts, double bounds[6], double closest[3])
181 {
182   double* convertedPts = new double[numPts * 3];
183   vtkQuadraticPolygon::PermuteToPolygon(numPts, pts, convertedPts);
184 
185   double result = vtkPolygon::DistanceToPolygon(x, numPts, convertedPts, bounds, closest);
186 
187   delete[] convertedPts;
188 
189   return result;
190 }
191 
192 //------------------------------------------------------------------------------
ComputeCentroid(vtkIdTypeArray * ids,vtkPoints * p,double c[3])193 void vtkQuadraticPolygon::ComputeCentroid(vtkIdTypeArray* ids, vtkPoints* p, double c[3])
194 {
195   vtkPoints* convertedPts = vtkPoints::New();
196   vtkQuadraticPolygon::PermuteToPolygon(p, convertedPts);
197 
198   vtkIdTypeArray* convertedIds = vtkIdTypeArray::New();
199   vtkQuadraticPolygon::PermuteToPolygon(ids, convertedIds);
200 
201   vtkPolygon::ComputeCentroid(convertedIds, convertedPts, c);
202 
203   convertedPts->Delete();
204   convertedIds->Delete();
205 }
206 
207 //------------------------------------------------------------------------------
ParameterizePolygon(double * p0,double * p10,double & l10,double * p20,double & l20,double * n)208 int vtkQuadraticPolygon::ParameterizePolygon(
209   double* p0, double* p10, double& l10, double* p20, double& l20, double* n)
210 {
211   this->InitializePolygon();
212   return this->Polygon->ParameterizePolygon(p0, p10, l10, p20, l20, n);
213 }
214 
215 //------------------------------------------------------------------------------
IntersectPolygonWithPolygon(int npts,double * pts,double bounds[6],int npts2,double * pts2,double bounds2[6],double tol2,double x[3])216 int vtkQuadraticPolygon::IntersectPolygonWithPolygon(int npts, double* pts, double bounds[6],
217   int npts2, double* pts2, double bounds2[6], double tol2, double x[3])
218 {
219   double* convertedPts = new double[npts * 3];
220   vtkQuadraticPolygon::PermuteToPolygon(npts, pts, convertedPts);
221 
222   double* convertedPts2 = new double[npts2 * 3];
223   vtkQuadraticPolygon::PermuteToPolygon(npts2, pts2, convertedPts2);
224 
225   int result = vtkPolygon::IntersectPolygonWithPolygon(
226     npts, convertedPts, bounds, npts2, convertedPts2, bounds2, tol2, x);
227 
228   delete[] convertedPts;
229   delete[] convertedPts2;
230 
231   return result;
232 }
233 
234 //------------------------------------------------------------------------------
IntersectConvex2DCells(vtkCell * cell1,vtkCell * cell2,double tol,double p0[3],double p1[3])235 int vtkQuadraticPolygon::IntersectConvex2DCells(
236   vtkCell* cell1, vtkCell* cell2, double tol, double p0[3], double p1[3])
237 {
238   vtkPolygon* convertedCell1 = nullptr;
239   vtkPolygon* convertedCell2 = nullptr;
240 
241   vtkQuadraticPolygon* qp1 = dynamic_cast<vtkQuadraticPolygon*>(cell1);
242   if (qp1)
243   {
244     convertedCell1 = vtkPolygon::New();
245     vtkQuadraticPolygon::PermuteToPolygon(cell1, convertedCell1);
246   }
247 
248   vtkQuadraticPolygon* qp2 = dynamic_cast<vtkQuadraticPolygon*>(cell2);
249   if (qp2)
250   {
251     convertedCell2 = vtkPolygon::New();
252     vtkQuadraticPolygon::PermuteToPolygon(cell2, convertedCell2);
253   }
254 
255   int result = vtkPolygon::IntersectConvex2DCells((convertedCell1 ? convertedCell1 : cell1),
256     (convertedCell2 ? convertedCell2 : cell2), tol, p0, p1);
257 
258   if (convertedCell1)
259   {
260     convertedCell1->Delete();
261   }
262   if (convertedCell2)
263   {
264     convertedCell2->Delete();
265   }
266 
267   return result;
268 }
269 
270 //------------------------------------------------------------------------------
PointInPolygon(double x[3],int numPts,double * pts,double bounds[6],double * n)271 int vtkQuadraticPolygon::PointInPolygon(
272   double x[3], int numPts, double* pts, double bounds[6], double* n)
273 {
274   double* convertedPts = new double[numPts * 3];
275   vtkQuadraticPolygon::PermuteToPolygon(numPts, pts, convertedPts);
276 
277   int result = vtkPolygon::PointInPolygon(x, numPts, convertedPts, bounds, n);
278 
279   delete[] convertedPts;
280 
281   return result;
282 }
283 
284 //------------------------------------------------------------------------------
GetPermutationFromPolygon(vtkIdType nb,vtkIdList * permutation)285 void vtkQuadraticPolygon::GetPermutationFromPolygon(vtkIdType nb, vtkIdList* permutation)
286 {
287   permutation->SetNumberOfIds(nb);
288   for (vtkIdType i = 0; i < nb; i++)
289   {
290     permutation->SetId(i, ((i % 2) ? (i + nb) / 2 : i / 2));
291   }
292 }
293 
294 //------------------------------------------------------------------------------
PermuteToPolygon(vtkIdType nbPoints,double * inPoints,double * outPoints)295 void vtkQuadraticPolygon::PermuteToPolygon(vtkIdType nbPoints, double* inPoints, double* outPoints)
296 {
297   vtkIdList* permutation = vtkIdList::New();
298   vtkQuadraticPolygon::GetPermutationFromPolygon(nbPoints, permutation);
299 
300   for (vtkIdType i = 0; i < nbPoints; i++)
301   {
302     for (int j = 0; j < 3; j++)
303     {
304       outPoints[3 * i + j] = inPoints[3 * permutation->GetId(i) + j];
305     }
306   }
307 
308   permutation->Delete();
309 }
310 
311 //------------------------------------------------------------------------------
PermuteToPolygon(vtkPoints * inPoints,vtkPoints * outPoints)312 void vtkQuadraticPolygon::PermuteToPolygon(vtkPoints* inPoints, vtkPoints* outPoints)
313 {
314   vtkIdType nbPoints = inPoints->GetNumberOfPoints();
315 
316   vtkIdList* permutation = vtkIdList::New();
317   vtkQuadraticPolygon::GetPermutationFromPolygon(nbPoints, permutation);
318 
319   outPoints->SetNumberOfPoints(nbPoints);
320   for (vtkIdType i = 0; i < nbPoints; i++)
321   {
322     outPoints->SetPoint(i, inPoints->GetPoint(permutation->GetId(i)));
323   }
324 
325   permutation->Delete();
326 }
327 
328 //------------------------------------------------------------------------------
PermuteToPolygon(vtkIdTypeArray * inIds,vtkIdTypeArray * outIds)329 void vtkQuadraticPolygon::PermuteToPolygon(vtkIdTypeArray* inIds, vtkIdTypeArray* outIds)
330 {
331   vtkIdType nbIds = inIds->GetNumberOfTuples();
332 
333   vtkIdList* permutation = vtkIdList::New();
334   vtkQuadraticPolygon::GetPermutationFromPolygon(nbIds, permutation);
335 
336   outIds->SetNumberOfTuples(nbIds);
337   for (vtkIdType i = 0; i < nbIds; i++)
338   {
339     outIds->SetValue(i, inIds->GetValue(permutation->GetId(i)));
340   }
341 
342   permutation->Delete();
343 }
344 
345 //------------------------------------------------------------------------------
PermuteToPolygon(vtkDataArray * inDataArray,vtkDataArray * outDataArray)346 void vtkQuadraticPolygon::PermuteToPolygon(vtkDataArray* inDataArray, vtkDataArray* outDataArray)
347 {
348   vtkIdType nb = inDataArray->GetNumberOfTuples();
349 
350   vtkIdList* permutation = vtkIdList::New();
351   vtkQuadraticPolygon::GetPermutationFromPolygon(nb, permutation);
352 
353   outDataArray->SetNumberOfComponents(inDataArray->GetNumberOfComponents());
354   outDataArray->SetNumberOfTuples(nb);
355   inDataArray->GetTuples(permutation, outDataArray);
356 
357   permutation->Delete();
358 }
359 
360 //------------------------------------------------------------------------------
PermuteToPolygon(vtkCell * inCell,vtkCell * outCell)361 void vtkQuadraticPolygon::PermuteToPolygon(vtkCell* inCell, vtkCell* outCell)
362 {
363   vtkIdType nbPoints = inCell->GetNumberOfPoints();
364 
365   vtkIdList* permutation = vtkIdList::New();
366   vtkQuadraticPolygon::GetPermutationFromPolygon(nbPoints, permutation);
367 
368   outCell->Points->SetNumberOfPoints(nbPoints);
369   outCell->PointIds->SetNumberOfIds(nbPoints);
370 
371   for (vtkIdType i = 0; i < nbPoints; i++)
372   {
373     outCell->PointIds->SetId(i, inCell->PointIds->GetId(permutation->GetId(i)));
374     outCell->Points->SetPoint(i, inCell->Points->GetPoint(permutation->GetId(i)));
375   }
376 
377   permutation->Delete();
378 }
379 
380 //------------------------------------------------------------------------------
InitializePolygon()381 void vtkQuadraticPolygon::InitializePolygon()
382 {
383   vtkQuadraticPolygon::PermuteToPolygon(this, this->Polygon);
384 }
385 
386 //------------------------------------------------------------------------------
GetPermutationToPolygon(vtkIdType nb,vtkIdList * permutation)387 void vtkQuadraticPolygon::GetPermutationToPolygon(vtkIdType nb, vtkIdList* permutation)
388 {
389   permutation->SetNumberOfIds(nb);
390   for (vtkIdType i = 0; i < nb; i++)
391   {
392     permutation->SetId(i, (i < nb / 2) ? (i * 2) : (i * 2 + 1 - nb));
393   }
394 }
395 
396 //------------------------------------------------------------------------------
PermuteFromPolygon(vtkIdType nb,double * values)397 void vtkQuadraticPolygon::PermuteFromPolygon(vtkIdType nb, double* values)
398 {
399   vtkIdList* permutation = vtkIdList::New();
400   vtkQuadraticPolygon::GetPermutationToPolygon(nb, permutation);
401 
402   double* save = new double[nb];
403   for (vtkIdType i = 0; i < nb; i++)
404   {
405     save[i] = values[i];
406   }
407   for (vtkIdType i = 0; i < nb; i++)
408   {
409     values[i] = save[permutation->GetId(i)];
410   }
411 
412   permutation->Delete();
413   delete[] save;
414 }
415 
416 //------------------------------------------------------------------------------
ConvertFromPolygon(vtkIdList * ids)417 void vtkQuadraticPolygon::ConvertFromPolygon(vtkIdList* ids)
418 {
419   vtkIdType nbIds = ids->GetNumberOfIds();
420 
421   vtkIdList* permutation = vtkIdList::New();
422   vtkQuadraticPolygon::GetPermutationFromPolygon(nbIds, permutation);
423 
424   vtkIdList* saveList = vtkIdList::New();
425   saveList->SetNumberOfIds(nbIds);
426   ids->SetNumberOfIds(nbIds);
427 
428   for (vtkIdType i = 0; i < nbIds; i++)
429   {
430     saveList->SetId(i, ids->GetId(i));
431   }
432   for (vtkIdType i = 0; i < nbIds; i++)
433   {
434     ids->SetId(i, permutation->GetId(saveList->GetId(i)));
435   }
436 
437   permutation->Delete();
438   saveList->Delete();
439 }
440 
441 //------------------------------------------------------------------------------
Derivatives(int vtkNotUsed (subId),const double vtkNotUsed (pcoords)[3],const double * vtkNotUsed (values),int vtkNotUsed (dim),double * vtkNotUsed (derivs))442 void vtkQuadraticPolygon::Derivatives(int vtkNotUsed(subId), const double vtkNotUsed(pcoords)[3],
443   const double* vtkNotUsed(values), int vtkNotUsed(dim), double* vtkNotUsed(derivs))
444 {
445 }
446