/*========================================================================= Program: Visualization Toolkit Module: vtkQuadraticPolygon.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkQuadraticPolygon.h" #include "vtkCellData.h" #include "vtkDataArray.h" #include "vtkIdTypeArray.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkPoints.h" #include "vtkPolygon.h" #include "vtkQuadraticEdge.h" vtkStandardNewMacro(vtkQuadraticPolygon); //---------------------------------------------------------------------------- // Instantiate quadratic polygon. vtkQuadraticPolygon::vtkQuadraticPolygon() { this->Polygon = vtkPolygon::New(); this->Edge = vtkQuadraticEdge::New(); this->UseMVCInterpolation = true; } //---------------------------------------------------------------------------- vtkQuadraticPolygon::~vtkQuadraticPolygon() { this->Polygon->Delete(); this->Edge->Delete(); } //---------------------------------------------------------------------------- vtkCell *vtkQuadraticPolygon::GetEdge(int edgeId) { int numEdges = this->GetNumberOfEdges(); edgeId = (edgeId < 0 ? 0 : (edgeId > numEdges - 1 ? numEdges - 1 : edgeId )); int p = (edgeId + 1) % numEdges; // load point id's this->Edge->PointIds->SetId(0, this->PointIds->GetId(edgeId)); this->Edge->PointIds->SetId(1, this->PointIds->GetId(p)); this->Edge->PointIds->SetId(2, this->PointIds->GetId(edgeId + numEdges)); // load coordinates this->Edge->Points->SetPoint(0, this->Points->GetPoint(edgeId)); this->Edge->Points->SetPoint(1, this->Points->GetPoint(p)); this->Edge->Points->SetPoint(2, this->Points->GetPoint(edgeId + numEdges)); return this->Edge; } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::EvaluatePosition(double* x, double* closestPoint, int& subId, double pcoords[3], double& minDist2, double *weights) { this->InitializePolygon(); int result = this->Polygon->EvaluatePosition(x, closestPoint, subId, pcoords, minDist2, weights); vtkQuadraticPolygon::PermuteFromPolygon(this->GetNumberOfPoints(), weights); return result; } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::EvaluateLocation(int& subId, double pcoords[3], double x[3], double *weights) { this->InitializePolygon(); this->Polygon->EvaluateLocation(subId, pcoords, x, weights); vtkQuadraticPolygon::PermuteFromPolygon(this->GetNumberOfPoints(), weights); } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::CellBoundary(int subId, double pcoords[3], vtkIdList *pts) { this->InitializePolygon(); return this->Polygon->CellBoundary(subId, pcoords, pts); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::Contour(double value, vtkDataArray* cellScalars, vtkIncrementalPointLocator* locator, vtkCellArray *verts, vtkCellArray* lines, vtkCellArray* polys, vtkPointData* inPd, vtkPointData* outPd, vtkCellData* inCd, vtkIdType cellId, vtkCellData* outCd) { this->InitializePolygon(); vtkDataArray *convertedCellScalars = cellScalars->NewInstance(); vtkQuadraticPolygon::PermuteToPolygon(cellScalars, convertedCellScalars); this->Polygon->Contour(value, convertedCellScalars, locator, verts, lines, polys, inPd, outPd, inCd, cellId, outCd); convertedCellScalars->Delete(); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::Clip(double value, vtkDataArray* cellScalars, vtkIncrementalPointLocator* locator, vtkCellArray* polys, vtkPointData* inPd, vtkPointData* outPd, vtkCellData* inCd, vtkIdType cellId, vtkCellData* outCd, int insideOut) { this->InitializePolygon(); vtkDataArray *convertedCellScalars = cellScalars->NewInstance(); vtkQuadraticPolygon::PermuteToPolygon(cellScalars, convertedCellScalars); this->Polygon->Clip(value, convertedCellScalars, locator, polys, inPd, outPd, inCd, cellId, outCd, insideOut); convertedCellScalars->Delete(); } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::IntersectWithLine(double* p1, double* p2, double tol, double& t, double* x, double* pcoords, int& subId) { this->InitializePolygon(); return this->Polygon->IntersectWithLine(p1, p2, tol, t, x, pcoords, subId); } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::Triangulate(vtkIdList *outTris) { this->InitializePolygon(); int result = this->Polygon->Triangulate(outTris); vtkQuadraticPolygon::ConvertFromPolygon(outTris); return result; } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::Triangulate(int index, vtkIdList *ptIds, vtkPoints *pts) { this->InitializePolygon(); return this->Polygon->Triangulate(index, ptIds, pts); } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::NonDegenerateTriangulate(vtkIdList *outTris) { this->InitializePolygon(); int result = this->Polygon->NonDegenerateTriangulate(outTris); vtkQuadraticPolygon::ConvertFromPolygon(outTris); return result; } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::InterpolateFunctions(double x[3], double *weights) { this->InitializePolygon(); this->Polygon->SetUseMVCInterpolation(UseMVCInterpolation); this->Polygon->InterpolateFunctions(x, weights); vtkQuadraticPolygon::PermuteFromPolygon(this->GetNumberOfPoints(), weights); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); os << indent << "UseMVCInterpolation: " << this->UseMVCInterpolation << "\n"; os << indent << "Edge:\n"; this->Edge->PrintSelf(os,indent.GetNextIndent()); os << indent << "Polygon:\n"; this->Polygon->PrintSelf(os,indent.GetNextIndent()); } //---------------------------------------------------------------------------- double vtkQuadraticPolygon::DistanceToPolygon(double x[3], int numPts, double *pts, double bounds[6], double closest[3]) { double *convertedPts = new double[numPts * 3]; vtkQuadraticPolygon::PermuteToPolygon(numPts, pts, convertedPts); double result = vtkPolygon::DistanceToPolygon(x, numPts, convertedPts, bounds, closest); delete[] convertedPts; return result; } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::ComputeCentroid(vtkIdTypeArray *ids, vtkPoints *p, double c[3]) { vtkPoints *convertedPts = vtkPoints::New(); vtkQuadraticPolygon::PermuteToPolygon(p, convertedPts); vtkIdTypeArray *convertedIds = vtkIdTypeArray::New(); vtkQuadraticPolygon::PermuteToPolygon(ids, convertedIds); vtkPolygon::ComputeCentroid(convertedIds, convertedPts, c); convertedPts->Delete(); convertedIds->Delete(); } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::ParameterizePolygon(double *p0, double *p10, double& l10, double *p20, double &l20, double *n) { this->InitializePolygon(); return this->Polygon->ParameterizePolygon(p0, p10, l10, p20, l20, n); } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::IntersectPolygonWithPolygon(int npts, double *pts, double bounds[6], int npts2, double *pts2, double bounds2[6], double tol2, double x[3]) { double *convertedPts = new double[npts*3]; vtkQuadraticPolygon::PermuteToPolygon(npts, pts, convertedPts); double *convertedPts2 = new double[npts2*3]; vtkQuadraticPolygon::PermuteToPolygon(npts2, pts2, convertedPts2); int result = vtkPolygon::IntersectPolygonWithPolygon( npts, convertedPts, bounds, npts2, convertedPts2, bounds2, tol2, x); delete[] convertedPts; delete[] convertedPts2; return result; } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::IntersectConvex2DCells(vtkCell *cell1, vtkCell *cell2, double tol, double p0[3], double p1[3]) { vtkPolygon *convertedCell1 = nullptr; vtkPolygon *convertedCell2 = nullptr; vtkQuadraticPolygon *qp1 = dynamic_cast(cell1); if (qp1) { convertedCell1 = vtkPolygon::New(); vtkQuadraticPolygon::PermuteToPolygon(cell1, convertedCell1); } vtkQuadraticPolygon *qp2 = dynamic_cast(cell2); if (qp2) { convertedCell2 = vtkPolygon::New(); vtkQuadraticPolygon::PermuteToPolygon(cell2, convertedCell2); } int result = vtkPolygon::IntersectConvex2DCells( (convertedCell1 ? convertedCell1 : cell1), (convertedCell2 ? convertedCell2 : cell2), tol, p0, p1); if (convertedCell1) { convertedCell1->Delete(); } if (convertedCell2) { convertedCell2->Delete(); } return result; } //---------------------------------------------------------------------------- int vtkQuadraticPolygon::PointInPolygon (double x[3], int numPts, double *pts, double bounds[6], double *n) { double *convertedPts = new double[numPts * 3]; vtkQuadraticPolygon::PermuteToPolygon(numPts, pts, convertedPts); int result = vtkPolygon::PointInPolygon(x, numPts, convertedPts, bounds, n); delete[] convertedPts; return result; } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::GetPermutationFromPolygon(vtkIdType nb, vtkIdList *permutation) { permutation->SetNumberOfIds(nb); for (vtkIdType i = 0; i < nb; i++) { permutation->SetId(i, ((i % 2) ? (i + nb)/2 : i/2)); } } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::PermuteToPolygon(vtkIdType nbPoints, double *inPoints, double *outPoints) { vtkIdList *permutation = vtkIdList::New(); vtkQuadraticPolygon::GetPermutationFromPolygon(nbPoints, permutation); for (vtkIdType i = 0; i < nbPoints; i++) { for (int j = 0; j < 3; j++) { outPoints[3 * i + j] = inPoints[3 * permutation->GetId(i) + j]; } } permutation->Delete(); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::PermuteToPolygon(vtkPoints *inPoints, vtkPoints *outPoints) { vtkIdType nbPoints = inPoints->GetNumberOfPoints(); vtkIdList *permutation = vtkIdList::New(); vtkQuadraticPolygon::GetPermutationFromPolygon(nbPoints, permutation); outPoints->SetNumberOfPoints(nbPoints); for (vtkIdType i = 0; i < nbPoints; i++) { outPoints->SetPoint(i, inPoints->GetPoint(permutation->GetId(i))); } permutation->Delete(); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::PermuteToPolygon(vtkIdTypeArray *inIds, vtkIdTypeArray *outIds) { vtkIdType nbIds = inIds->GetNumberOfTuples(); vtkIdList *permutation = vtkIdList::New(); vtkQuadraticPolygon::GetPermutationFromPolygon(nbIds, permutation); outIds->SetNumberOfTuples(nbIds); for (vtkIdType i = 0; i < nbIds; i++) { outIds->SetValue(i, inIds->GetValue(permutation->GetId(i))); } permutation->Delete(); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::PermuteToPolygon(vtkDataArray *inDataArray, vtkDataArray *outDataArray) { vtkIdType nb = inDataArray->GetNumberOfTuples(); vtkIdList *permutation = vtkIdList::New(); vtkQuadraticPolygon::GetPermutationFromPolygon(nb, permutation); outDataArray->SetNumberOfComponents(inDataArray->GetNumberOfComponents()); outDataArray->SetNumberOfTuples(nb); inDataArray->GetTuples(permutation, outDataArray); permutation->Delete(); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::PermuteToPolygon(vtkCell *inCell, vtkCell *outCell) { vtkIdType nbPoints = inCell->GetNumberOfPoints(); vtkIdList *permutation = vtkIdList::New(); vtkQuadraticPolygon::GetPermutationFromPolygon(nbPoints, permutation); outCell->Points->SetNumberOfPoints(nbPoints); outCell->PointIds->SetNumberOfIds(nbPoints); for (vtkIdType i = 0; i < nbPoints; i++) { outCell->PointIds->SetId(i, inCell->PointIds->GetId(permutation->GetId(i))); outCell->Points->SetPoint(i, inCell->Points->GetPoint(permutation->GetId(i))); } permutation->Delete(); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::InitializePolygon() { vtkQuadraticPolygon::PermuteToPolygon(this, this->Polygon); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::GetPermutationToPolygon(vtkIdType nb, vtkIdList *permutation) { permutation->SetNumberOfIds(nb); for (vtkIdType i = 0; i < nb; i++) { permutation->SetId(i, (i < nb / 2) ? (i * 2) : (i * 2 + 1 - nb)); } } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::PermuteFromPolygon(vtkIdType nb, double *values) { vtkIdList *permutation = vtkIdList::New(); vtkQuadraticPolygon::GetPermutationToPolygon(nb, permutation); double *save = new double[nb]; for (vtkIdType i = 0; i < nb; i++) { save[i] = values[i]; } for (vtkIdType i = 0; i < nb; i++) { values[i] = save[permutation->GetId(i)]; } permutation->Delete(); delete[] save; } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::ConvertFromPolygon(vtkIdList *ids) { vtkIdType nbIds = ids->GetNumberOfIds(); vtkIdList *permutation = vtkIdList::New(); vtkQuadraticPolygon::GetPermutationFromPolygon(nbIds, permutation); vtkIdList *saveList = vtkIdList::New(); saveList->SetNumberOfIds(nbIds); ids->SetNumberOfIds(nbIds); for (vtkIdType i = 0; i < nbIds; i++) { saveList->SetId(i, ids->GetId(i)); } for (vtkIdType i = 0; i < nbIds; i++) { ids->SetId(i, permutation->GetId(saveList->GetId(i))); } permutation->Delete(); saveList->Delete(); } //---------------------------------------------------------------------------- void vtkQuadraticPolygon::Derivatives(int vtkNotUsed(subId), double vtkNotUsed(pcoords)[3], double *vtkNotUsed(values), int vtkNotUsed(dim), double *vtkNotUsed(derivs)) { }