ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
vtkDiscretizableColorTransferFunctionCustom.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include "vtkDoubleArray.h"
11 #include "vtkLookupTable.h"
12 #include "vtkNew.h"
13 #include "vtkObjectFactory.h"
14 #include "vtkStringArray.h"
15 #include "vtkVariantArray.h"
16 
18 
19 //-------------------------------------------------------------------------
22  this->AnnotatedValuesInFullSet = NULL;
23  this->AnnotationsInFullSet = NULL;
24  this->IndexedColorsInFullSet = vtkDoubleArray::New();
25  this->IndexedColorsInFullSet->SetNumberOfComponents(3);
26  this->IndexedOpacitiesInFullSet = vtkDoubleArray::New();
27  this->IndexedOpacitiesInFullSet->SetNumberOfComponents(1);
28 
29  this->ActiveAnnotatedValues = vtkVariantArray::New();
30 
31  this->UseActiveValues = 1;
32 }
33 
34 //-------------------------------------------------------------------------
37  if (this->AnnotatedValuesInFullSet) {
38  this->AnnotatedValuesInFullSet->Delete();
39  }
40 
41  if (this->AnnotationsInFullSet) {
42  this->AnnotationsInFullSet->Delete();
43  }
44 
45  if (this->IndexedOpacitiesInFullSet) {
46  this->IndexedOpacitiesInFullSet->Delete();
47  }
48 
49  if (this->IndexedColorsInFullSet) {
50  this->IndexedColorsInFullSet->Delete();
51  }
52 
53  if (this->ActiveAnnotatedValues) {
54  this->ActiveAnnotatedValues->Delete();
55  }
56 }
57 
58 //-------------------------------------------------------------------------
60  vtkAbstractArray* values, vtkStringArray* annotations) {
61  if ((values && !annotations) || (!values && annotations)) return;
62 
63  if (values && annotations &&
64  values->GetNumberOfTuples() != annotations->GetNumberOfTuples()) {
65  vtkErrorMacro(<< "Values and annotations do not have the same number "
66  "of tuples ("
67  << values->GetNumberOfTuples() << " and "
68  << annotations->GetNumberOfTuples()
69  << ", respectively. Ignoring.");
70  return;
71  }
72 
73  if (this->AnnotatedValuesInFullSet && !values) {
74  this->AnnotatedValuesInFullSet->Delete();
75  this->AnnotatedValuesInFullSet = 0;
76  } else if (values) { // Ensure arrays are of the same type before copying.
77  if (this->AnnotatedValuesInFullSet) {
78  if (this->AnnotatedValuesInFullSet->GetDataType() !=
79  values->GetDataType()) {
80  this->AnnotatedValuesInFullSet->Delete();
81  this->AnnotatedValuesInFullSet = 0;
82  }
83  }
84  if (!this->AnnotatedValuesInFullSet) {
85  this->AnnotatedValuesInFullSet =
86  vtkAbstractArray::CreateArray(values->GetDataType());
87  }
88  }
89  bool sameVals = (values == this->AnnotatedValuesInFullSet);
90  if (!sameVals && values) {
91  this->AnnotatedValuesInFullSet->DeepCopy(values);
92  }
93 
94  if (this->AnnotationsInFullSet && !annotations) {
95  this->AnnotationsInFullSet->Delete();
96  this->AnnotationsInFullSet = 0;
97  } else if (!this->AnnotationsInFullSet && annotations) {
98  this->AnnotationsInFullSet = vtkStringArray::New();
99  }
100  bool sameText = (annotations == this->AnnotationsInFullSet);
101  if (!sameText) {
102  this->AnnotationsInFullSet->DeepCopy(annotations);
103  }
104  // this->UpdateAnnotatedValueMap();
105  this->Modified();
106 }
107 
108 //----------------------------------------------------------------------------
110  vtkVariant value, std::string annotation) {
111  vtkIdType idx = -1;
112  bool modified = false;
113  if (this->AnnotatedValuesInFullSet) {
114  idx = this->AnnotatedValuesInFullSet->LookupValue(value);
115  if (idx >= 0) {
116  if (this->AnnotationsInFullSet->GetValue(idx) != annotation) {
117  this->AnnotationsInFullSet->SetValue(idx, annotation);
118  modified = true;
119  }
120  } else {
121  idx = this->AnnotationsInFullSet->InsertNextValue(annotation);
122  this->AnnotatedValuesInFullSet->InsertVariantValue(idx, value);
123  modified = true;
124  }
125  } else {
126  vtkErrorMacro(<< "AnnotatedValuesInFullSet is NULL");
127  }
128 
129  if (modified) {
130  this->Modified();
131  }
132 
133  return idx;
134 }
135 
136 //-------------------------------------------------------------------------
138  std::string value, std::string annotation) {
139  bool valid;
140  vtkVariant val(value);
141  double x;
142  x = val.ToDouble(&valid);
143  if (valid) {
144  return this->SetAnnotationInFullSet(x, annotation);
145  } else if (value == "") {
146  // NOTE: This prevents the value "" in vtkStringArrays from being
147  // annotated. Hopefully, that isn't a desired use case.
148  return -1;
149  }
150  return this->SetAnnotationInFullSet(val, annotation);
151 }
152 
153 //-------------------------------------------------------------------------
155  if (!this->AnnotationsInFullSet) {
156  vtkVariantArray* va = vtkVariantArray::New();
157  vtkStringArray* sa = vtkStringArray::New();
158  this->SetAnnotationsInFullSet(va, sa);
159  va->FastDelete();
160  sa->FastDelete();
161  }
162  this->AnnotatedValuesInFullSet->Initialize();
163  this->AnnotationsInFullSet->Initialize();
164  this->Modified();
165 }
166 
167 //-----------------------------------------------------------------------------
169  if (this->ActiveAnnotatedValues->GetNumberOfTuples() > 0) {
170  this->ActiveAnnotatedValues->Initialize();
171  this->Modified();
172  }
173 }
174 
175 //-----------------------------------------------------------------------------
177  std::string value) {
178  this->ActiveAnnotatedValues->InsertNextValue(value.c_str());
179  this->Modified();
180 }
181 
182 //-----------------------------------------------------------------------------
185  if (n !=
186  static_cast<int>(this->IndexedColorsInFullSet->GetNumberOfTuples())) {
187  vtkIdType old = this->IndexedColorsInFullSet->GetNumberOfTuples();
188  this->IndexedColorsInFullSet->SetNumberOfTuples(n);
189  if (old < n) {
190  for (int i = 0; i < 3; i++) {
191  this->IndexedColorsInFullSet->FillComponent(i, 0.0);
192  }
193  }
194  this->Modified();
195  }
196 }
197 
198 //-----------------------------------------------------------------------------
200  unsigned int index, double r, double g, double b) {
201  if (index >= static_cast<unsigned int>(
202  this->IndexedColorsInFullSet->GetNumberOfTuples())) {
203  this->SetNumberOfIndexedColorsInFullSet(static_cast<int>(index + 1));
204  this->Modified();
205  }
206 
207  // double *currentRGB =
208  // static_cast<double*>(this->IndexedColorsInFullSet->GetVoidPointer(index));
209  double currentRGB[3];
210  this->IndexedColorsInFullSet->GetTypedTuple(index, currentRGB);
211  if (currentRGB[0] != r || currentRGB[1] != g || currentRGB[2] != b) {
212  double rgb[3] = {r, g, b};
213  this->IndexedColorsInFullSet->SetTypedTuple(index, rgb);
214  this->Modified();
215  }
216 }
217 
218 //-----------------------------------------------------------------------------
221  return static_cast<int>(this->IndexedColorsInFullSet->GetNumberOfTuples());
222 }
223 
224 //-----------------------------------------------------------------------------
226  unsigned int index, double* rgb) {
227  if (index >= static_cast<unsigned int>(
228  this->IndexedColorsInFullSet->GetNumberOfTuples())) {
229  vtkErrorMacro(<< "Index out of range. Color not set.");
230  return;
231  }
232 
233  this->IndexedColorsInFullSet->GetTypedTuple(index, rgb);
234 }
235 
236 //-----------------------------------------------------------------------------
239  if (n != static_cast<int>(
240  this->IndexedOpacitiesInFullSet->GetNumberOfTuples())) {
241  vtkIdType old = this->IndexedOpacitiesInFullSet->GetNumberOfTuples();
242  this->IndexedOpacitiesInFullSet->SetNumberOfTuples(n);
243  if (old < n) {
244  this->IndexedOpacitiesInFullSet->FillComponent(0, 1.0);
245  }
246  this->Modified();
247  }
248 }
249 
250 //-----------------------------------------------------------------------------
252  unsigned int index, double alpha) {
253  if (index >=
254  static_cast<unsigned int>(
255  this->IndexedOpacitiesInFullSet->GetNumberOfTuples())) {
256  this->SetNumberOfIndexedOpacitiesInFullSet(static_cast<int>(index + 1));
257  this->Modified();
258  }
259 
260  double currentAlpha;
261  this->IndexedOpacitiesInFullSet->GetTypedTuple(index, &currentAlpha);
262  if (currentAlpha != alpha) {
263  this->IndexedOpacitiesInFullSet->SetTypedTuple(index, &alpha);
264  this->Modified();
265  }
266 }
267 
268 //-----------------------------------------------------------------------------
271  return static_cast<int>(
272  this->IndexedOpacitiesInFullSet->GetNumberOfTuples());
273 }
274 
275 //-----------------------------------------------------------------------------
277  unsigned int index, double* alpha) {
278  if (index >=
279  static_cast<unsigned int>(
280  this->IndexedOpacitiesInFullSet->GetNumberOfTuples())) {
281  vtkErrorMacro(<< "Index out of range. Opacity not set.");
282  return;
283  }
284 
285  this->IndexedOpacitiesInFullSet->GetTypedTuple(index, alpha);
286 }
287 
288 //-----------------------------------------------------------------------------
290  if (this->BuildTime > this->GetMTime()) {
291  // no need to rebuild anything.
292  return;
293  }
294 
295  this->ResetAnnotations();
296 
297  int annotationCount = 0;
298 
299  if (this->AnnotatedValuesInFullSet) {
300  vtkNew<vtkVariantArray> builtValues;
301  vtkNew<vtkStringArray> builtAnnotations;
302 
303  for (vtkIdType i = 0;
304  i < this->AnnotatedValuesInFullSet->GetNumberOfTuples(); ++i) {
305  std::string annotation = this->AnnotationsInFullSet->GetValue(i);
306  vtkVariant value =
307  this->AnnotatedValuesInFullSet->GetVariantValue(i);
308 
309  bool useAnnotation = true;
310  if (this->IndexedLookup && this->UseActiveValues) {
311  vtkIdType id = this->ActiveAnnotatedValues->LookupValue(value);
312  if (id < 0) {
313  useAnnotation = false;
314  }
315  }
316 
317  if (useAnnotation) {
318  builtValues->InsertNextValue(value);
319  builtAnnotations->InsertNextValue(annotation);
320 
321  if (i < this->IndexedColorsInFullSet->GetNumberOfTuples()) {
322  double color[4];
324  if (this->EnableOpacityMapping &&
325  i < this->IndexedOpacitiesInFullSet
326  ->GetNumberOfTuples()) {
327  this->GetIndexedOpacityInFullSet(i, &color[3]);
328  } else {
329  color[3] = 1.0;
330  }
331  this->SetIndexedColorRGBA(annotationCount, color);
332  annotationCount++;
333  }
334  }
335  }
336  this->SetAnnotations(builtValues.GetPointer(),
337  builtAnnotations.GetPointer());
338  }
339 
340  this->Superclass::Build();
341 
342  this->BuildTime.Modified();
343 }
344 
345 //-------------------------------------------------------------------------
347  vtkIndent indent) {
348  this->Superclass::PrintSelf(os, indent);
349 }
math::float4 color
#define NULL
void SetIndexedColorInFullSet(unsigned int index, double r, double g, double b)
virtual vtkIdType SetAnnotationInFullSet(vtkVariant value, std::string annotation)
void SetIndexedColorRGBA(unsigned int index, const double rgba[4])
virtual void SetAnnotationsInFullSet(vtkAbstractArray *values, vtkStringArray *annotations)
normal_z rgb
normal_z x
vtkStandardNewMacro(vtkDiscretizableColorTransferFunctionCustom)