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