TTK
Loading...
Searching...
No Matches
ttkSignedDistanceField.cpp
Go to the documentation of this file.
1#include <vtkFloatArray.h>
2#include <vtkImageData.h>
3#include <vtkInformation.h>
4#include <vtkInformationVector.h>
5#include <vtkIntArray.h>
6#include <vtkPointData.h>
7#include <vtkStreamingDemandDrivenPipeline.h>
8
9#include <ttkMacros.h>
11#include <ttkUtils.h>
12
13// vtkObjectFactoryNewMacro(vtkResampleToImage);
15
16//------------------------------------------------------------------------------
18 this->SetNumberOfInputPorts(1);
19 this->SetNumberOfOutputPorts(1);
20}
21
22//------------------------------------------------------------------------------
24 return vtkImageData::SafeDownCast(this->GetOutputDataObject(0));
25}
26
27//------------------------------------------------------------------------------
28vtkTypeBool
30 vtkInformationVector **inputVector,
31 vtkInformationVector *outputVector) {
32 // generate the data
33 if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA())) {
34 return this->RequestData(request, inputVector, outputVector);
35 }
36
37 // execute information
38 if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION())) {
39 return this->RequestInformation(request, inputVector, outputVector);
40 }
41
42 // propagate update extent
43 if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT())) {
44 return this->RequestUpdateExtent(request, inputVector, outputVector);
45 }
46
47 return this->Superclass::ProcessRequest(request, inputVector, outputVector);
48}
49
50//------------------------------------------------------------------------------
52 vtkInformation *,
53 vtkInformationVector **,
54 vtkInformationVector *outputVector) {
55 int wholeExtent[6]
56 = {0, this->SamplingDimensions[0] - 1, 0, this->SamplingDimensions[1] - 1,
57 0, this->SamplingDimensions[2] - 1};
58
59 vtkInformation *outInfo = outputVector->GetInformationObject(0);
60 outInfo->Set(
61 vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wholeExtent, 6);
62
63 return 1;
64}
65
66//------------------------------------------------------------------------------
68 vtkInformation *,
69 vtkInformationVector **inputVector,
70 vtkInformationVector *) {
71 // This filter always asks for whole extent downstream. To resample
72 // a subset of a structured input, you need to use ExtractVOI.
73 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
74 inInfo->Remove(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT());
75 if(inInfo->Has(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT())) {
76 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
77 inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()),
78 6);
79 }
80
81 return 1;
82}
83
84//------------------------------------------------------------------------------
86 vtkInformation *info) {
87 if(port == 0) {
88 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
89 return 1;
90 }
91 return 0;
92}
93
94//------------------------------------------------------------------------------
96 vtkInformation *info) {
97 if(port == 0) {
98 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkImageData");
99 } else
100 return 0;
101 return 1;
102}
103
104//------------------------------------------------------------------------------
106 vtkInformationVector **inputVector) {
110 const auto domain = vtkDataSet::GetData(inputVector[0]);
111 double bounds[6];
112 domain->GetBounds(bounds);
113 DataExtent[1] = xResolution_;
114 DataExtent[3] = yResolution_;
115 DataExtent[5] = zResolution_;
116 int shift = (ExpandBox ? 2 : 0);
117 spacing_[0] = (bounds[1] - bounds[0]) / (DataExtent[1] - 1 - shift);
118 spacing_[1] = (bounds[3] - bounds[2]) / (DataExtent[3] - 1 - shift);
119 spacing_[2] = (bounds[5] - bounds[4]) / (DataExtent[5] - 1 - shift);
120 for(unsigned int i = 0; i < spacing_.size(); ++i)
121 invSpacingSquared_[i] = 1.0 / spacing_[i] / spacing_[i];
122 std::stringstream ss;
123 ss << "Resolution : " << DataExtent[1] << ", " << DataExtent[3] << ", "
124 << DataExtent[5];
125 printMsg(ss.str());
126 ss.str("");
127 ss << "Spacing : " << spacing_[0] << ", " << spacing_[1] << ", "
128 << spacing_[2];
129 printMsg(ss.str());
130 ss.str("");
131 ss << "Extent : " << spacing_[0] * xResolution_ << ", "
132 << spacing_[1] * yResolution_ << ", " << spacing_[2] * zResolution_;
133 printMsg(ss.str());
134 Origin[0] = bounds[0];
135 Origin[1] = bounds[2];
136 Origin[2] = bounds[4];
137 if(ExpandBox) {
138 Origin[0] -= spacing_[0];
139 Origin[1] -= spacing_[1];
140 Origin[2] -= spacing_[2];
141 }
142}
143
145 vtkInformationVector **inputVector,
146 vtkInformationVector *outputVector) {
147 using ttk::SimplexId;
148
149 const auto domain = vtkDataSet::GetData(inputVector[0]);
150
151 if(!domain)
152 return !this->printErr("Unable to retrieve required input data object.");
153
154 // triangulation Domain
155 auto triangulation = ttkAlgorithm::GetTriangulation(domain);
156 if(!triangulation) {
157 this->printErr("Input triangulation pointer is NULL.");
158 return -1;
159 }
160
161 this->preconditionTriangulation(triangulation);
162
163 if(triangulation->isEmpty()) {
164 this->printErr("Triangulation allocation problem.");
165 return -2;
166 }
167
168 if(!domain) {
169 this->printErr("Input pointer is NULL.");
170 return -3;
171 }
172
173 const auto numberOfVertices = domain->GetNumberOfPoints();
174 if(numberOfVertices <= 0) {
175 this->printErr("Domain has no points.");
176 return -4;
177 }
178
179 std::stringstream ss;
180 ss << "Surface number of vertices : " << triangulation->getNumberOfVertices();
181 printMsg(ss.str());
182
183 ss.str("");
184 ss << "Surface number of triangles : "
185 << triangulation->getNumberOfTriangles();
186 printMsg(ss.str());
187
188 // Create bounding triangulation
189 computeOutputInformation(inputVector);
192 imageData->SetOrigin(Origin[0], Origin[1], Origin[2]);
193 imageData->SetSpacing(spacing_[0], spacing_[1], spacing_[2]);
194 imageData->SetDimensions(DataExtent[1], DataExtent[3], DataExtent[5]);
195
196 auto boundingTriangulation = ttkAlgorithm::GetTriangulation(imageData);
197 if(!boundingTriangulation) {
198 this->printErr("Input bounding triangulation pointer is NULL.");
199 return -5;
200 }
201
202 if(boundingTriangulation->isEmpty()) {
203 this->printErr("Encompassing triangulation allocation problem.");
204 return -6;
205 }
206
207 ss.str("");
208 ss << "Field number of vertices : "
209 << boundingTriangulation->getNumberOfVertices();
210 printMsg(ss.str());
211
212 ss.str("");
213 ss << "Field number of edges : " << boundingTriangulation->getNumberOfEdges();
214 printMsg(ss.str());
215
216 // create output arrays
217 auto outputNoPoints = imageData->GetNumberOfPoints();
218
219 vtkNew<vtkFloatArray> outputScalars{};
220 outputScalars->SetNumberOfTuples(outputNoPoints);
221 outputScalars->SetName("signedDistanceField");
222
223 vtkNew<vtkIntArray> edgeCrossing{};
224 edgeCrossing->SetNumberOfTuples(outputNoPoints);
225 edgeCrossing->SetName("edgeCrossing");
226
227 vtkNew<vtkIntArray> isInterior{};
228 isInterior->SetNumberOfTuples(outputNoPoints);
229 isInterior->SetName("isInterior");
230
231 int ret{};
232
237 triangulation->getType(), boundingTriangulation->getType(),
238 (ret
239 = this->execute(ttkUtils::GetPointer<float>(outputScalars),
240 (static_cast<TTK_TT1 *>(triangulation->getData())),
241 (static_cast<TTK_TT2 *>(boundingTriangulation->getData())),
242 ttkUtils::GetPointer<int>(edgeCrossing),
243 ttkUtils::GetPointer<int>(isInterior))));
244
245 // something wrong in baseCode
246 if(ret) {
247 this->printErr("SignedDistanceField.execute() error code: "
248 + std::to_string(ret));
249 return -7;
250 }
251
252 imageData->GetPointData()->AddArray(outputScalars);
253 imageData->GetPointData()->AddArray(edgeCrossing);
254 imageData->GetPointData()->AddArray(isInterior);
255
256 // Set the output
257 auto output = vtkImageData::GetData(outputVector);
258 output->ShallowCopy(imageData);
259
260 return 1;
261}
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition BaseClass.h:47
int ProcessRequest(vtkInformation *request, vtkInformationVector **inputVectors, vtkInformationVector *outputVector) override
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
This filter computes a signed distance field given a surface in input.
int FillInputPortInformation(int, vtkInformation *) override
void computeOutputInformation(vtkInformationVector **inputVector)
int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
vtkTypeBool ProcessRequest(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override
int FillOutputPortInformation(int, vtkInformation *) override
int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
std::array< double, 3 > invSpacingSquared_
std::array< double, 3 > spacing_
int preconditionTriangulation(AbstractTriangulation *triangulation) const
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22
#define ttkVtkTemplate2Macro(triangulationType1, triangulationType2, call)
Definition ttkMacros.h:120
vtkStandardNewMacro(ttkSignedDistanceField)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)