1#include <vtkCellArray.h>
2#include <vtkCellData.h>
3#include <vtkDoubleArray.h>
4#include <vtkInformation.h>
6#include <vtkObjectFactory.h>
7#include <vtkPointData.h>
8#include <vtkPolyData.h>
9#include <vtkUnstructuredGrid.h>
18 this->SetNumberOfInputPorts(2);
19 this->SetNumberOfOutputPorts(1);
24 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),
"vtkDataSet");
26 }
else if(port == 1) {
27 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),
"vtkUnstructuredGrid");
35 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkPolyData");
41template <
typename VTK_T1,
typename VTK_T2>
44#ifdef TTK_ENABLE_FIBER_SURFACE_WITH_RANGE_OCTREE
47 (this->buildOctree<VTK_T1, VTK_T2>(
48 static_cast<TTK_TT *
>(triangulation->
getData()))));
53 (this->computeSurface<VTK_T1, VTK_T2>(
54 static_cast<TTK_TT *
>(triangulation->
getData()))));
59 vtkInformationVector **inputVector,
60 vtkInformationVector *outputVector) {
65 const auto input = vtkDataSet::GetData(inputVector[0]);
66 const auto polygon = vtkUnstructuredGrid::GetData(inputVector[1]);
67 auto output = vtkPolyData::GetData(outputVector);
69 const auto dataUfield = this->GetInputArrayToProcess(0, input);
70 const auto dataVfield = this->GetInputArrayToProcess(1, input);
71 const auto polygonUfield = this->GetInputArrayToProcess(2, polygon);
72 const auto polygonVfield = this->GetInputArrayToProcess(3, polygon);
74 if(dataUfield ==
nullptr || dataVfield ==
nullptr || polygonUfield ==
nullptr
75 || polygonVfield ==
nullptr) {
76 this->
printErr(
"Could not find data array");
80 if(!(input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID
81 || input->GetDataObjectType() == VTK_IMAGE_DATA)) {
82 this->
printErr(
"Unsupported VTK data structure");
87 if(triangulation ==
nullptr) {
92 outputVertexList_.clear();
97 threadedTriangleList_.resize(polygon->GetNumberOfCells());
98 threadedVertexList_.resize(polygon->GetNumberOfCells());
104#ifdef TTK_ENABLE_FIBER_SURFACE_WITH_RANGE_OCTREE
105 if((!RangeOctree) || (dataUfield->GetMTime() > GetMTime())
106 || (dataVfield->GetMTime() > GetMTime())) {
108 this->
printMsg(
"Resetting octree...");
115 inputPolygon_.clear();
117#if !defined(_WIN32) || defined(_WIN32) && defined(VTK_USE_64BIT_IDS)
118 const long long int *cellArray
119 = polygon->GetCells()->GetData()->GetPointer(0);
121 int *pt = polygon->GetCells()->GetPointer();
122 long long extra_pt = *pt;
123 const long long int *cellArray = &extra_pt;
125 SimplexId cellNumber = polygon->GetNumberOfCells();
127 SimplexId vertexId0, vertexId1;
128 std::pair<std::pair<double, double>, std::pair<double, double>> rangeEdge;
130 for(SimplexId i = 0; i < cellNumber; i++) {
132 vertexId0 = cellArray[3 * i + 1];
133 vertexId1 = cellArray[3 * i + 2];
135 rangeEdge.first.first = polygonUfield->GetTuple1(vertexId0);
136 rangeEdge.first.second = polygonVfield->GetTuple1(vertexId0);
138 rangeEdge.second.first = polygonUfield->GetTuple1(vertexId1);
139 rangeEdge.second.second = polygonVfield->GetTuple1(vertexId1);
141 inputPolygon_.push_back(rangeEdge);
144 for(
size_t i = 0; i < threadedTriangleList_.size(); i++) {
145 threadedTriangleList_[i].clear();
147 threadedVertexList_[i].clear();
151#ifndef TTK_ENABLE_DOUBLE_TEMPLATING
152 if(dataUfield->GetDataType() != dataVfield->GetDataType()) {
154 "Scalar fields should have same input type. Use TTKPointDataConverter or "
155 "TTKArrayEditor to convert array types.");
158 switch(dataUfield->GetDataType()) {
159 vtkTemplateMacro((dispatch<VTK_TT, VTK_TT>(triangulation)));
162 switch(vtkTemplate2PackMacro(
163 dataUfield->GetDataType(), dataVfield->GetDataType())) {
164 vtkTemplate2Macro((dispatch<VTK_T1, VTK_T2>(triangulation)));
172 size_t triangleNumber = 0;
174 for(
size_t i = 0; i < threadedTriangleList_.size(); i++) {
175 triangleNumber += threadedTriangleList_[i].size();
178 vtkNew<vtkPoints> outputVertexList{};
179 vtkNew<vtkDoubleArray> outputU{};
180 vtkNew<vtkDoubleArray> outputV{};
181 vtkNew<vtkDoubleArray> outputParameterization{};
182 vtkNew<vtkCellArray> outputTriangleList{};
183 vtkNew<ttkSimplexIdTypeArray> outputEdgeIds{};
184 vtkNew<ttkSimplexIdTypeArray> outputTetIds{};
185 vtkNew<ttkSimplexIdTypeArray> outputCaseIds{};
187 if(RangeCoordinates) {
188 outputU->SetName(dataUfield->GetName());
189 outputU->SetNumberOfTuples(outputVertexList_.size());
191 outputV->SetName(dataVfield->GetName());
192 outputV->SetNumberOfTuples(outputVertexList_.size());
195 if(EdgeParameterization) {
196 outputParameterization->SetName(
"EdgeParameterization");
197 outputParameterization->SetNumberOfTuples(outputVertexList_.size());
200 outputVertexList->SetNumberOfPoints(outputVertexList_.size());
201 output->SetPoints(outputVertexList);
203#ifdef TTK_ENABLE_OPENMP
204#pragma omp parallel for num_threads(threadNumber_)
206 for(
size_t i = 0; i < outputVertexList_.size(); i++) {
207 outputVertexList->SetPoint(i, outputVertexList_[i].p_[0],
208 outputVertexList_[i].p_[1],
209 outputVertexList_[i].p_[2]);
210 if(RangeCoordinates) {
211 outputU->SetTuple1(i, outputVertexList_[i].uv_.first);
212 outputV->SetTuple1(i, outputVertexList_[i].uv_.second);
214 if(EdgeParameterization) {
215 outputParameterization->SetTuple1(i, outputVertexList_[i].t_);
218 if(RangeCoordinates) {
219 output->GetPointData()->AddArray(outputU);
220 output->GetPointData()->AddArray(outputV);
222 output->GetPointData()->RemoveArray(dataUfield->GetName());
223 output->GetPointData()->RemoveArray(dataVfield->GetName());
225 if(EdgeParameterization) {
226 output->GetPointData()->AddArray(outputParameterization);
228 output->GetPointData()->RemoveArray(
"EdgeParameterization");
232 outputEdgeIds->SetName(
"EdgeIds");
233 outputEdgeIds->SetNumberOfTuples(triangleNumber);
237 outputTetIds->SetName(
"TetIds");
238 outputTetIds->SetNumberOfTuples(triangleNumber);
242 outputCaseIds->SetName(
"CaseIds");
243 outputCaseIds->SetNumberOfTuples(triangleNumber);
246 vtkNew<vtkIdList> idList{};
247 idList->SetNumberOfIds(3);
250 for(
size_t i = 0; i < threadedTriangleList_.size(); i++) {
251 for(
size_t j = 0; j < threadedTriangleList_[i].size(); j++) {
252 for(
int k = 0; k < 3; k++) {
253 idList->SetId(k, threadedTriangleList_[i][j].vertexIds_[k]);
255 outputTriangleList->InsertNextCell(idList);
257 outputEdgeIds->SetTuple1(triangleNumber, i);
260 outputTetIds->SetTuple1(
261 triangleNumber, threadedTriangleList_[i][j].tetId_);
264 outputCaseIds->SetTuple1(
265 triangleNumber, threadedTriangleList_[i][j].caseId_);
270 output->SetPolys(outputTriangleList);
272 output->GetCellData()->AddArray(outputEdgeIds);
274 output->GetCellData()->RemoveArray(
"EdgeIds");
277 output->GetCellData()->AddArray(outputTetIds);
279 output->GetCellData()->RemoveArray(
"TetIds");
282 output->GetCellData()->AddArray(outputCaseIds);
284 output->GetCellData()->RemoveArray(
"CaseIds");
#define ttkTemplateMacro(triangulationType, call)
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
TTK VTK-filter that computes fiber surfaces.
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillInputPortInformation(int port, vtkInformation *info) override
int FillOutputPortInformation(int port, vtkInformation *info) override
int dispatch(ttk::Triangulation *const triangulation)
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
int printMsg(const std::string &msg, const debug::Priority &priority=debug::Priority::INFO, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cout) const
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
int setGlobalVertexList(std::vector< Vertex > *globalList)
int setInputField(const void *uField, const void *vField)
int setPolygonEdgeNumber(const SimplexId &polygonEdgeNumber)
int setPointMerging(const bool &onOff)
int setPointMergingThreshold(const double &threshold)
int setPolygon(const std::vector< std::pair< std::pair< double, double >, std::pair< double, double > > > *polygon)
int setVertexList(const SimplexId &polygonEdgeId, std::vector< Vertex > *vertexList)
int setTriangleList(const SimplexId &polygonEdgeId, std::vector< Triangle > *triangleList)
void preconditionTriangulation(AbstractTriangulation *triangulation)
Triangulation is a class that provides time and memory efficient traversal methods on triangulations ...
AbstractTriangulation * getData()
Triangulation::Type getType() const
int SimplexId
Identifier type for simplices of any dimension.
vtkStandardNewMacro(ttkFiberSurface)