Skip to content

Commit

Permalink
Adapt to sf changes
Browse files Browse the repository at this point in the history
  • Loading branch information
tmontaigu committed Nov 24, 2024
1 parent b4bb2a9 commit 92c0acc
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 21 deletions.
2 changes: 0 additions & 2 deletions wrapper/cccorelib/src/GenericDistribution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,4 @@ void define_GenericDistribution(py::module &cccorelib)
"Yk"_a,
"numberOfClasses"_a,
"histo"_a = nullptr);

py::bind_vector<CCCoreLib::GenericDistribution::ScalarContainer>(GenericDistribution, "ScalarContainer");
}
191 changes: 180 additions & 11 deletions wrapper/cccorelib/src/ScalarField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,143 @@
#include "wrappers.h"

#include <ScalarField.h>
#include <stdio.h>

namespace py = pybind11;
using namespace pybind11::literals;

class ScalarFieldView
{
public:
explicit ScalarFieldView(CCCoreLib::ScalarField &field)
: m_field(field), m_start(0), m_stop(field.currentSize()), m_step(1), m_len(field.currentSize())
{
}

explicit ScalarFieldView(const ScalarFieldView view, const py::slice &slice) : ScalarFieldView(view)
{
applySlicing(slice);
}

explicit ScalarFieldView(CCCoreLib::ScalarField &field, const py::slice &slice) : ScalarFieldView(field)
{
}

py::object get_item(const py::object &index)
{
if (py::isinstance<py::int_>(index))
{
return py::cast(m_field.getValue((index.cast<size_t>() * m_step) + m_start));
}

if (py::isinstance<py::slice>(index))
{
const auto slice = index.cast<py::slice>();
return py::cast(ScalarFieldView(m_field, slice));
}

if (py::isinstance<py::sequence>(index))
{
const auto sequence = index.cast<py::sequence>();
py::array_t<double> result(sequence.size());
auto setter = result.mutable_unchecked<1>();
for (size_t i = 0; i < sequence.size(); ++i)
{
setter[i] = m_field.getValue((sequence[i].cast<size_t>() * m_step) + m_start);
}
return result;
}
}

void set_item(const py::object &index, const py::object &value)
{
if (py::isinstance<py::int_>(index))
{
m_field.setValue(index.cast<size_t>() + m_start, value.cast<double>());
return;
}

if (py::isinstance<py::slice>(index))
{
const auto slice = index.cast<py::slice>();

// view[some_slice] = some_unique_value
if (py::isinstance<py::float_>(value) || py::isinstance<py::int_>(value))
{
const auto floatValue = value.cast<double>();
for (size_t i = 0; i < m_len; ++i)
{
m_field.setValue((i * m_step) + m_start, floatValue);
}
return;
}

const auto sequence = value.cast<py::sequence>();
if (sequence.size() != m_len)
{
throw py::index_error("Incorrect number of new values");
}

for (size_t i = 0; i < m_len; ++i)
{
m_field.setValue((i * m_step) + m_start, sequence[i].cast<double>());
}

return;
}

if (py::isinstance<py::sequence>(index))
{
const auto sequence = index.cast<py::sequence>();

// view[some_sequence] = some_unique_value
if (py::isinstance<py::float_>(value) || py::isinstance<py::int_>(value))
{
const auto floatValue = value.cast<double>();
for (size_t i = 0; i < m_len; ++i)
{
m_field.setValue((i * m_step) + m_start, floatValue);
}
return;
}
if (sequence.size() != m_len)
{
throw py::index_error("Incorrect number of new values");
}

for (size_t i = 0; i < m_len; ++i)
{
m_field.setValue((i * m_step) + m_start, sequence[i].cast<double>());
}
}
}

void applySlicing(const py::slice &slice)
{
size_t start, stop, step, len = 0;
if (!slice.compute(m_len, &start, &stop, &step, &len))
{
throw py::index_error();
}

m_len = len;
m_start += start;
m_stop = stop;
m_step += step;
}

private:
CCCoreLib::ScalarField &m_field;
size_t m_start;
size_t m_stop;
size_t m_step;
size_t m_len;
};

void define_ScalarField(py::module &cccorelib)
{
py::class_<ScalarFieldView>(cccorelib, "ScalarFieldView").def("__getitem__", &ScalarFieldView::get_item);

py::class_<CCCoreLib::ScalarField, CCShareable, CCShareableHolder<CCCoreLib::ScalarField>>(cccorelib,
"ScalarField",
R"doc(
Expand Down Expand Up @@ -89,7 +220,7 @@ void define_ScalarField(py::module &cccorelib)
'name'
)doc")
.def("size",
&CCCoreLib::ScalarField::size,
&CCCoreLib::ScalarField::currentSize,
"Returns the number of elements (values) in the scalar field")
.def("computeMeanAndVariance",
&CCCoreLib::ScalarField::computeMeanAndVariance,
Expand Down Expand Up @@ -117,7 +248,11 @@ void define_ScalarField(py::module &cccorelib)
&CCCoreLib::ScalarField::fill,
"fillValue"_a = 0,
"Fills the scalar field with the given value")
.def("reserve", &CCCoreLib::ScalarField::reserve, "count"_a, R"doc(
.def(
"reserve",
[](CCCoreLib::ScalarField &field, const size_t size) { field.reserve(size); },
"count"_a,
R"doc(
Reserves space for ``count`` element, but does not change the size.
Will raise an exception if allocation failed
Expand All @@ -132,10 +267,10 @@ void define_ScalarField(py::module &cccorelib)
)doc")
.def(
"resize",
[](CCCoreLib::ScalarField &self, size_t count, ScalarType valueForNewElements)
[](CCCoreLib::ScalarField &self, const size_t count, const ScalarType valueForNewElements)
{
// pybind11 will convert exceptions
self.resize(count, valueForNewElements);
self.resizeSafe(count, true /* always init values */, valueForNewElements);
},
"count"_a,
"valueForNewElements"_a = 0,
Expand All @@ -158,8 +293,7 @@ void define_ScalarField(py::module &cccorelib)
Prefer use of :meth:`cccorelib.ScalarField.resize`.
)doc")
.def("getValue",
static_cast<ScalarType &(CCCoreLib::ScalarField::*)(std::size_t)>(
&CCCoreLib::ScalarField::getValue),
&CCCoreLib::ScalarField::getValue,
"index"_a,
R"doc(
Returns the value at the given index.
Expand Down Expand Up @@ -198,7 +332,7 @@ void define_ScalarField(py::module &cccorelib)
)doc")
.def(
"asArray",
[](CCCoreLib::ScalarField &self) { return PyCC::VectorAsNumpyArray(self); },
[](CCCoreLib::ScalarField &self) { return ScalarFieldView(self); },
R"doc(
Returns the scalar field viewed as a numpy array.
Expand All @@ -221,10 +355,45 @@ void define_ScalarField(py::module &cccorelib)
array[:] = 2.0
assert scalar_field[0] == 2.0
)doc")
.def("__getitem__",
static_cast<ScalarType &(CCCoreLib::ScalarField::*)(std::size_t)>(
&CCCoreLib::ScalarField::getValue))
.def("__setitem__", &CCCoreLib::ScalarField::setValue)
.def(
"__getitem__",
[](CCCoreLib::ScalarField &self, const py::object &index)
{ return ScalarFieldView(self).get_item(index); },
py::return_value_policy::reference_internal)
.def(
"toArray",
[](const CCCoreLib::ScalarField &self)
{
py::array_t<double> copy(self.currentSize());
auto access = copy.mutable_unchecked<1>();
for (size_t i = 0; i < self.currentSize(); ++i)
{
access[i] = self.getValue(i);
}
return copy;
},
R"doc(
Copies the content into an array
)doc")
.def(
"__array__",
[](const CCCoreLib::ScalarField &self)
{
// TODO this is a copy-paste from toArray, should only have 1 definition of this
py::array_t<double> copy(self.currentSize());
auto access = copy.mutable_unchecked<1>();
for (size_t i = 0; i < self.currentSize(); ++i)
{
access[i] = self.getValue(i);
}
return copy;
},
R"doc(
Copies the content into an array
)doc")
.def("__setitem__",
[](CCCoreLib::ScalarField &self, const py::object &index, const py::object &value)
{ return ScalarFieldView(self).set_item(index, value); })
.def("__repr__",
[](const CCCoreLib::ScalarField &self)
{ return std::string("<ScalarField(name=") + self.getName() + ")>"; });
Expand Down
4 changes: 2 additions & 2 deletions wrapper/cccorelib/src/wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void addPointsFromArrays(PointCloudType &self,
throw py::value_error("xs, ys, zs must have the same size");
}

py::ssize_t numToReserve = self.size() + xs.size();
const py::ssize_t numToReserve = self.size() + xs.size();
if (numToReserve > std::numeric_limits<unsigned int>::max())
{
throw std::out_of_range(std::to_string(numToReserve) + " cannot be casted to unsigned int");
Expand Down Expand Up @@ -258,7 +258,7 @@ static const constexpr char SIZE_SCALAR_FIELD_DOCSTRING[] = R"doc(
CCCoreLib::ScalarField *sf = self.getScalarField(idx); \
for (py::ssize_t i{0}; i < values.size(); ++i) \
{ \
(*sf)[i] = values_u(i); \
sf->setValue(i, values_u(i)); \
} \
} \
return idx; \
Expand Down
1 change: 1 addition & 0 deletions wrapper/pycc/src/qcc_db/cc2DLabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void define_cc2DLabel(py::module &m)
Pycc2DLabel.def("isPointLegendDisplayed", &cc2DLabel::isPointLegendDisplayed);
Pycc2DLabel.def("setDisplayedIn2D", &cc2DLabel::setDisplayedIn2D, "state"_a);
Pycc2DLabel.def("isDisplayedIn2D", &cc2DLabel::isDisplayedIn2D);
Pycc2DLabel.def("setRelativeMarkerScale", &cc2DLabel::setRelativeMarkerScale, "value"_a);

py::class_<cc2DLabel::PickedPoint>(Pycc2DLabel, "PickedPoint")
.def_readwrite(
Expand Down
4 changes: 1 addition & 3 deletions wrapper/pycc/src/qcc_db/ccGLMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ static void define_ccGLMatrixClass(py::module &m, const char *name)
.def("scaleRow", &ccGLMatrixType::scaleRow, "rowIndex"_a, "coef"_a)
.def("scaleColumn", &ccGLMatrixType::scaleColumn, "rowIndex"_a, "coef"_a)
.def("asArray",
[](ccGLMatrixType &self) {
return PyCC::SpanAsNumpyArray(self.data(), {4, 4});
});
[](ccGLMatrixType &self) { return PyCC::SpanAsNumpyArray(self.data(), {4, 4}); });
}

void define_ccGLMatrix(py::module &m)
Expand Down
4 changes: 1 addition & 3 deletions wrapper/pycc/src/qcc_db/ccScalarField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,5 @@ void define_ccScalarField(py::module &m)
.def("mayHaveHiddenValues", &ccScalarField::mayHaveHiddenValues)
.def("setModificationFlag", &ccScalarField::setModificationFlag, "state"_a)
.def("getModificationFlag", &ccScalarField::getModificationFlag)
.def("importParametersFrom", &ccScalarField::importParametersFrom, "sf"_a)
.def("getGlobalShift", &ccScalarField::getGlobalShift)
.def("setGlobalShift", &ccScalarField::setGlobalShift, "state"_a);
.def("importParametersFrom", &ccScalarField::importParametersFrom, "sf"_a);
}

0 comments on commit 92c0acc

Please sign in to comment.