ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
scalarfield.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 
8 #include <ecvPointCloud.h>
9 #include <ecvScalarField.h>
10 
12 #include "pybind/docstring.h"
13 
14 namespace cloudViewer {
15 namespace utility {
16 
17 void pybind_scalarfield(py::module& m) {
18  // cloudViewer.utility.ScalarField
19  py::class_<cloudViewer::ScalarField,
20  std::unique_ptr<cloudViewer::ScalarField>>
21  scalarfieldBase(m, "ScalarField",
22  "A simple scalar field (to be associated to a "
23  "point cloud).");
24  // py::detail::bind_copy_functions<cloudViewer::ScalarField>(scalarfieldBase);
25  scalarfieldBase
26  .def(py::init([](const std::string& name) {
27  return new cloudViewer::ScalarField(name.c_str());
28  }),
29  "name"_a = "ScalarField")
30  .def("__repr__",
31  [](const cloudViewer::ScalarField& sf) {
32  std::string info = fmt::format(
33  "ScalarField ({}) with {} scalars and range ({}, "
34  "{}) ",
35  sf.getName(), sf.currentSize(), sf.getMin(),
36  sf.getMax());
37  return info;
38  })
39  .def(
40  "set_name",
41  [](cloudViewer::ScalarField& sf, const std::string& name) {
42  sf.setName(name.c_str());
43  },
44  "Sets scalar field name.", "name"_a)
45  .def(
46  "get_name",
47  [](const cloudViewer::ScalarField& sf) {
48  return std::string(sf.getName());
49  },
50  "Returns scalar field name.")
51  .def(
52  "compute_mean_variance",
53  [](const cloudViewer::ScalarField& sf) {
54  ScalarType mean, variance;
55  sf.computeMeanAndVariance(mean, &variance);
56  return std::make_tuple(mean, variance);
57  },
58  "Computes the mean value (and optionally the variance "
59  "value) of the scalar field.")
60  .def("compute_min_max", &cloudViewer::ScalarField::computeMinAndMax,
61  "Determines the min and max values")
62  .def("invalid_value", &cloudViewer::ScalarField::flagValueAsInvalid,
63  "Sets the value as 'invalid' (i.e. NAN_VALUE).", "index"_a)
64  .def("get_min", &cloudViewer::ScalarField::getMin,
65  "Returns the minimum value.")
66  .def("get_max", &cloudViewer::ScalarField::getMax,
67  "Returns the maximum value.")
68  .def("fill", &cloudViewer::ScalarField::fill,
69  "Returns the maximum value.", "fill_value"_a = 0)
71  "Reserves memory (no exception thrown).", "count"_a)
73  "Resizes memory (no exception thrown).", "count"_a,
74  "is_fill"_a = false, "value"_a = 0)
75  .def("get_value",
76  py::overload_cast<std::size_t>(
78  "Gets value.", "index"_a)
79  .def("get_value",
80  py::overload_cast<std::size_t>(
82  "Gets value(const version).", "index"_a)
83  .def("set_value", &cloudViewer::ScalarField::setValue,
84  "Sets value.", "index"_a, "value"_a)
85  .def("add_element", &cloudViewer::ScalarField::addElement,
86  "Adds element.", "value"_a)
87  .def("current_size", &cloudViewer::ScalarField::currentSize,
88  "Returns current size.")
89  .def("link", &cloudViewer::ScalarField::link, "Increase counter.")
90  .def("release", &cloudViewer::ScalarField::release,
91  "Decrease counter and deletes object when 0.")
92  .def("get_link_count", &cloudViewer::ScalarField::getLinkCount,
93  "Returns the current link count.")
94  .def("swap", &cloudViewer::ScalarField::swap, "Swaps scalar value.",
95  "i1"_a, "i2"_a)
96  .def_static("Is_Valid_Value", &cloudViewer::ScalarField::ValidValue,
97  "Returns whether a scalar value is valid or not.",
98  "value"_a)
99  .def_static("Nan", &cloudViewer::ScalarField::NaN,
100  "Returns the specific NaN value");
101 
102  docstring::ClassMethodDocInject(m, "ScalarField", "link");
103  docstring::ClassMethodDocInject(m, "ScalarField", "release");
104  docstring::ClassMethodDocInject(m, "ScalarField", "get_link_count");
105  docstring::ClassMethodDocInject(m, "ScalarField", "invalid_value");
106  docstring::ClassMethodDocInject(m, "ScalarField", "set_name");
107  docstring::ClassMethodDocInject(m, "ScalarField", "get_name");
108  docstring::ClassMethodDocInject(m, "ScalarField", "get_min");
109  docstring::ClassMethodDocInject(m, "ScalarField", "get_max");
110  docstring::ClassMethodDocInject(m, "ScalarField", "compute_min_max");
111  docstring::ClassMethodDocInject(m, "ScalarField", "compute_mean_variance");
112  docstring::ClassMethodDocInject(m, "ScalarField", "fill");
113  docstring::ClassMethodDocInject(m, "ScalarField", "reserve");
114  docstring::ClassMethodDocInject(m, "ScalarField", "resize");
115  docstring::ClassMethodDocInject(m, "ScalarField", "get_value");
116  docstring::ClassMethodDocInject(m, "ScalarField", "set_value");
117  docstring::ClassMethodDocInject(m, "ScalarField", "add_element");
118  docstring::ClassMethodDocInject(m, "ScalarField", "current_size");
119  docstring::ClassMethodDocInject(m, "ScalarField", "swap");
120 
121  // cloudViewer.utility.Range
122  py::class_<ccScalarField::Range, std::shared_ptr<ccScalarField::Range>>
123  range(m, "Range", "Scalar field range structure.");
124  py::detail::bind_default_constructor<ccScalarField::Range>(range);
125  py::detail::bind_copy_functions<ccScalarField::Range>(range);
126  range.def(py::init<>())
127  .def("__repr__",
128  [](const ccScalarField::Range& rg) {
129  std::string info = fmt::format(
130  "Range with ({}, {}) in ({}, {})", rg.start(),
131  rg.stop(), rg.min(), rg.max());
132  return info;
133  })
134  .def("min", &ccScalarField::Range::min, "Returns the minimum value")
135  .def("max", &ccScalarField::Range::max, "Returns the maximum value")
136  .def("start", &ccScalarField::Range::start,
137  "Returns the current start value (in [min,max])")
138  .def("stop", &ccScalarField::Range::stop,
139  "Returns the current stop value (in [min,max])")
140  .def("range", &ccScalarField::Range::range,
141  "Returns the actual range: start-stop (but can't be ZERO!)")
142  .def("max_range", &ccScalarField::Range::maxRange,
143  "Returns the maximum range")
144  .def("set_bounds", &ccScalarField::Range::setBounds,
145  "Sets the bounds", "min_val"_a, "max_val"_a,
146  "reset_start_stop"_a = true)
147  .def("set_start", &ccScalarField::Range::setStart,
148  "Sets the current start value", "value"_a)
149  .def("set_stop", &ccScalarField::Range::setStop,
150  "Sets the current stop value", "value"_a)
151  .def("in_bound", &ccScalarField::Range::inbound,
152  "Returns the nearest inbound value", "value"_a)
153  .def("is_in_bound", &ccScalarField::Range::isInbound,
154  "Returns whether a value is inbound or not", "value"_a)
155  .def("is_in_range", &ccScalarField::Range::isInRange,
156  "Returns whether a value is inside range or not", "value"_a);
157  docstring::ClassMethodDocInject(m, "Range", "min");
158  docstring::ClassMethodDocInject(m, "Range", "max");
159  docstring::ClassMethodDocInject(m, "Range", "start");
160  docstring::ClassMethodDocInject(m, "Range", "stop");
161  docstring::ClassMethodDocInject(m, "Range", "range");
162  docstring::ClassMethodDocInject(m, "Range", "max_range");
163  docstring::ClassMethodDocInject(m, "Range", "set_bounds");
164  docstring::ClassMethodDocInject(m, "Range", "set_start");
165  docstring::ClassMethodDocInject(m, "Range", "set_stop");
166  docstring::ClassMethodDocInject(m, "Range", "in_bound");
167  docstring::ClassMethodDocInject(m, "Range", "is_in_bound");
168  docstring::ClassMethodDocInject(m, "Range", "is_in_range");
169 
170  // cloudViewer.utility.ccScalarField
171  py::class_<ccScalarField, std::unique_ptr<ccScalarField, py::nodelete>,
173  scalarfield(
174  m, "ccScalarField",
175  "A scalar field associated to display-related parameters.");
176  // py::detail::bind_copy_functions<ccScalarField>(scalarfield);
177  scalarfield
178  .def(py::init([](const std::string& name) {
179  return new ccScalarField(name.c_str());
180  }),
181  "Simplified constructor", "name"_a = "ScalarField")
182  .def("__repr__",
183  [](const ccScalarField& sf) {
184  std::string info = fmt::format(
185  "ScalarField ({}) with {} scalars and range ({}, "
186  "{}) ",
187  sf.getName(), sf.currentSize(), sf.getMin(),
188  sf.getMax());
189  return info;
190  })
191  .def("display_range", &ccScalarField::displayRange,
192  "Access to the range of displayed values.")
193  .def("saturation_range", &ccScalarField::saturationRange,
194  "Access to the range of saturation values.")
195  .def("log_saturation_range", &ccScalarField::logSaturationRange,
196  "Access to the range of log scale saturation values.")
197  .def("set_min_displayed", &ccScalarField::setMinDisplayed,
198  "Sets the minimum displayed value.", "value"_a)
199  .def("set_max_displayed", &ccScalarField::setMaxDisplayed,
200  "Sets the maximum displayed value.", "value"_a)
201  .def("set_saturation_start", &ccScalarField::setSaturationStart,
202  "Sets the value at which to start color gradient.", "value"_a)
203  .def("set_saturation_stop", &ccScalarField::setSaturationStop,
204  "Sets the value at which to stop color gradient.", "value"_a)
205  .def(
206  "get_color",
207  [](const ccScalarField& sf, ScalarType value) {
208  return ecvColor::Rgb::ToEigen(*sf.getColor(value));
209  },
210  "Returns the color corresponding to a given value (wrt to "
211  "the current display parameters).",
212  "value"_a)
213  .def(
214  "get_color_by_index",
215  [](const ccScalarField& sf, unsigned index) {
216  return ecvColor::Rgb::ToEigen(*sf.getValueColor(index));
217  },
218  "Shortcut to getColor.", "index"_a)
219  .def("show_nan_in_grey", &ccScalarField::showNaNValuesInGrey,
220  "Sets whether NaN/out of displayed range values should be "
221  "displayed in gray or hidden.")
222  .def("are_nan_shown_in_grey",
224  "Returns whether NaN values are displayed in gray or hidden.")
225  .def("always_show_zero", &ccScalarField::alwaysShowZero,
226  "Sets whether 0 should always appear in associated color ramp "
227  "or not.")
228  .def("is_zero_always_shown", &ccScalarField::isZeroAlwaysShown,
229  "Returns whether 0 should always appear in associated color "
230  "ramp or not.")
231  .def("set_symmetrical_scale", &ccScalarField::setSymmetricalScale,
232  "Sets whether the color scale should be symmetrical or not.")
233  .def("symmetrical_scale", &ccScalarField::symmetricalScale,
234  "Returns whether the color scale s symmetrical or not.")
235  .def("set_log_scale", &ccScalarField::setLogScale,
236  "Sets whether scale is logarithmic or not.")
237  .def("log_scale", &ccScalarField::logScale,
238  "Returns whether scalar field is logarithmic or not.")
239  .def("get_color_ramp_steps", &ccScalarField::getColorRampSteps,
240  "Returns number of color ramp steps.")
241  .def("set_color_ramp_steps", &ccScalarField::setColorRampSteps,
242  "Sets number of color ramp steps used for display.")
243  .def("may_have_hidden_values", &ccScalarField::mayHaveHiddenValues,
244  "Returns whether the scalar field in its current "
245  "configuration MAY have 'hidden' values or not.")
246  .def("set_modification_flag", &ccScalarField::setModificationFlag,
247  "Sets modification flag state.", "state"_a)
248  .def("get_modification_flag", &ccScalarField::getModificationFlag,
249  "Returns modification flag state.")
250  .def("get_global_shift", &ccScalarField::getGlobalShift,
251  "Returns the global shift (if any).")
252  .def("set_global_shift", &ccScalarField::setGlobalShift,
253  "Sets the global shift.")
254  .def("is_serializable", &ccScalarField::isSerializable,
255  "Returns whether object is serializable of not.")
256  .def(
257  "to_file",
258  [](const ccScalarField& sf, const std::string& filename,
259  short dataVersion) {
260  QFile out(filename.c_str());
261  if (!out.open(QIODevice::WriteOnly)) {
262  return false;
263  }
264  return sf.toFile(out, dataVersion);
265  },
266  "Saves data to binary stream", "filename"_a,
267  "data_version"_a)
268  .def("minimum_file_version", &ccScalarField::minimumFileVersion,
269  "Returns the minimum file version required to save this "
270  "object")
271  .def(
272  "from_file",
273  [](ccScalarField& sf, const std::string& filename,
274  short data_version, int flags) {
275  QFile in(filename.c_str());
276  if (!in.open(QIODevice::ReadOnly)) {
277  return false;
278  }
279  ccSerializableObject::LoadedIDMap oldToNewIDMap;
280  return sf.fromFile(in, data_version, flags,
281  oldToNewIDMap);
282  },
283  "Loads data from binary stream", "filename"_a,
284  "data_version"_a, "flags"_a)
285  .def(
286  "import_parameters_from",
287  [](ccScalarField& sf, const ccScalarField& source) {
288  sf.importParametersFrom(&source);
289  },
290  "Imports the parameters from another scalar field",
291  "source"_a);
292 
293  docstring::ClassMethodDocInject(m, "ccScalarField", "display_range");
294  docstring::ClassMethodDocInject(m, "ccScalarField", "saturation_range");
295  docstring::ClassMethodDocInject(m, "ccScalarField", "log_saturation_range");
296  docstring::ClassMethodDocInject(m, "ccScalarField", "set_min_displayed");
297  docstring::ClassMethodDocInject(m, "ccScalarField", "set_max_displayed");
298  docstring::ClassMethodDocInject(m, "ccScalarField", "set_saturation_start");
299  docstring::ClassMethodDocInject(m, "ccScalarField", "set_saturation_stop");
300  docstring::ClassMethodDocInject(m, "ccScalarField", "get_color");
301  docstring::ClassMethodDocInject(m, "ccScalarField", "get_color_by_index");
302  docstring::ClassMethodDocInject(m, "ccScalarField", "show_nan_in_grey");
303  docstring::ClassMethodDocInject(m, "ccScalarField",
304  "are_nan_shown_in_grey");
305  docstring::ClassMethodDocInject(m, "ccScalarField", "always_show_zero");
306  docstring::ClassMethodDocInject(m, "ccScalarField", "is_zero_always_shown");
307  docstring::ClassMethodDocInject(m, "ccScalarField",
308  "set_symmetrical_scale");
309  docstring::ClassMethodDocInject(m, "ccScalarField", "symmetrical_scale");
310  docstring::ClassMethodDocInject(m, "ccScalarField", "set_log_scale");
311  docstring::ClassMethodDocInject(m, "ccScalarField", "log_scale");
312  docstring::ClassMethodDocInject(m, "ccScalarField", "get_color_ramp_steps");
313  docstring::ClassMethodDocInject(m, "ccScalarField", "set_color_ramp_steps");
314  docstring::ClassMethodDocInject(m, "ccScalarField",
315  "may_have_hidden_values");
316  docstring::ClassMethodDocInject(m, "ccScalarField",
317  "set_modification_flag");
318  docstring::ClassMethodDocInject(m, "ccScalarField",
319  "get_modification_flag");
320  docstring::ClassMethodDocInject(m, "ccScalarField", "get_global_shift");
321  docstring::ClassMethodDocInject(m, "ccScalarField", "set_global_shift");
322  docstring::ClassMethodDocInject(m, "ccScalarField", "is_serializable");
323  docstring::ClassMethodDocInject(m, "ccScalarField", "to_file");
324  docstring::ClassMethodDocInject(m, "ccScalarField", "from_file");
325  docstring::ClassMethodDocInject(m, "ccScalarField",
326  "import_parameters_from");
327 }
328 
329 } // namespace utility
330 } // namespace cloudViewer
std::string filename
filament::Texture::InternalFormat format
std::string name
virtual void link()
Increase counter.
Definition: CVShareable.cpp:33
virtual void release()
Decrease counter and deletes object when 0.
Definition: CVShareable.cpp:35
virtual unsigned getLinkCount() const
Returns the current link count.
Definition: CVShareable.h:40
Scalar field range structure.
void setStop(ScalarType value)
ScalarType stop() const
bool isInbound(ScalarType val) const
Returns whether a value is inbound or not.
ScalarType min() const
ScalarType maxRange() const
ScalarType inbound(ScalarType val) const
Returns the nearest inbound value.
bool isInRange(ScalarType val) const
Returns whether a value is inside range or not.
ScalarType max() const
void setBounds(ScalarType minVal, ScalarType maxVal, bool resetStartStop=true)
void setStart(ScalarType value)
ScalarType range() const
ScalarType start() const
A scalar field associated to display-related parameters.
void setSaturationStop(ScalarType val)
Sets the value at which to stop color gradient.
void setColorRampSteps(unsigned steps)
Sets number of color ramp steps used for display.
bool getModificationFlag() const
Returns modification flag state.
short minimumFileVersion() const override
Returns the minimum file version required to save this instance.
void setMinDisplayed(ScalarType val)
Sets the minimum displayed value.
bool isSerializable() const override
Returns whether object is serializable of not.
bool logScale() const
Returns whether scalar field is logarithmic or not.
void alwaysShowZero(bool state)
Sets whether 0 should always appear in associated color ramp or not.
void setGlobalShift(double shift)
Sets the global shift.
unsigned getColorRampSteps() const
Returns number of color ramp steps.
void setLogScale(bool state)
Sets whether scale is logarithmic or not.
double getGlobalShift() const
Returns the global shift (if any)
void setSymmetricalScale(bool state)
Sets whether the color scale should be symmetrical or not.
const Range & saturationRange() const
Access to the range of saturation values.
void showNaNValuesInGrey(bool state)
const Range & displayRange() const
Access to the range of displayed values.
void setModificationFlag(bool state)
Sets modification flag state.
bool symmetricalScale() const
Returns whether the color scale s symmetrical or not.
const Range & logSaturationRange() const
Access to the range of log scale saturation values.
bool mayHaveHiddenValues() const
void setSaturationStart(ScalarType val)
Sets the value at which to start color gradient.
void setMaxDisplayed(ScalarType val)
Sets the maximum displayed value.
bool areNaNValuesShownInGrey() const
Returns whether NaN values are displayed in gray or hidden.
bool isZeroAlwaysShown() const
Returns whether 0 should always appear in associated color ramp or not.
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
A simple scalar field (to be associated to a point cloud)
Definition: ScalarField.h:25
void fill(ScalarType fillValue=0)
Fills the array with a particular value.
Definition: ScalarField.h:77
virtual void computeMinAndMax()
Determines the min and max values.
Definition: ScalarField.h:123
ScalarType getMin() const
Returns the minimum value.
Definition: ScalarField.h:72
void addElement(ScalarType value)
Definition: ScalarField.h:99
static ScalarType NaN()
Returns the specific NaN value.
Definition: ScalarField.h:46
ScalarType & getValue(std::size_t index)
Definition: ScalarField.h:92
void computeMeanAndVariance(ScalarType &mean, ScalarType *variance=nullptr) const
Definition: ScalarField.cpp:41
void setValue(std::size_t index, ScalarType value)
Definition: ScalarField.h:96
void flagValueAsInvalid(std::size_t index)
Sets the value as 'invalid' (i.e. NAN_VALUE)
Definition: ScalarField.h:66
const char * getName() const
Returns scalar field name.
Definition: ScalarField.h:43
bool reserveSafe(std::size_t count)
Reserves memory (no exception thrown)
Definition: ScalarField.cpp:71
void setName(const char *name)
Sets scalar field name.
Definition: ScalarField.cpp:22
bool resizeSafe(std::size_t count, bool initNewElements=false, ScalarType valueForNewElements=0)
Resizes memory (no exception thrown)
Definition: ScalarField.cpp:81
static bool ValidValue(ScalarType value)
Returns whether a scalar value is valid or not.
Definition: ScalarField.h:61
void swap(std::size_t i1, std::size_t i2)
Definition: ScalarField.h:103
unsigned currentSize() const
Definition: ScalarField.h:100
ScalarType getMax() const
Returns the maximum value.
Definition: ScalarField.h:74
static Eigen::Vector3d ToEigen(const Type col[3])
Definition: ecvColorTypes.h:72
void ClassMethodDocInject(py::module &pybind_module, const std::string &class_name, const std::string &function_name, const std::unordered_map< std::string, std::string > &map_parameter_body_docs)
Definition: docstring.cpp:27
void pybind_scalarfield(py::module &m)
Definition: scalarfield.cpp:17
Generic file read and write utility for python interface.