use molar::prelude::*;
use numpy::{
nalgebra::{self, Const},
npyffi, Element, PyArray1, PyArrayMethods, ToNpyDims, PY_ARRAY_API,
};
use pyo3::prelude::*;
use std::ffi::c_void;
use crate::topology_state::StatePy;
pub(crate) fn to_py_value_err<E: std::fmt::Display>(e: E) -> pyo3::PyErr {
pyo3::exceptions::PyValueError::new_err(e.to_string())
}
pub(crate) fn to_py_io_err<E: std::fmt::Display>(e: E) -> pyo3::PyErr {
pyo3::exceptions::PyIOError::new_err(e.to_string())
}
pub(crate) fn to_py_runtime_err<E: std::fmt::Display>(e: E) -> pyo3::PyErr {
pyo3::exceptions::PyRuntimeError::new_err(e.to_string())
}
pub(crate) unsafe fn map_pyarray_to_pos<'py>(
st: &Bound<'py,StatePy>,
id: usize,
) -> Bound<'py, PyArray1<f32>> {
use numpy::Element;
use numpy::PyArrayDescrMethods;
let py = st.py();
let mut dims = numpy::ndarray::Dim(3);
unsafe {
let ptr = PY_ARRAY_API.PyArray_NewFromDescr(
py,
PY_ARRAY_API.get_type_object(py, npyffi::NpyTypes::PyArray_Type),
f32::get_dtype(py).into_dtype_ptr(),
dims.ndim_cint(),
dims.as_dims_ptr(),
std::ptr::null_mut(), st.get().inner_mut().coords.as_mut_ptr().add(id) as *mut c_void, npyffi::NPY_ARRAY_WRITEABLE
| npyffi::NPY_ARRAY_ALIGNED
| npyffi::NPY_ARRAY_C_CONTIGUOUS, std::ptr::null_mut(), );
pyo3::ffi::Py_IncRef(st.as_ptr());
PY_ARRAY_API.PyArray_SetBaseObject(py, ptr.cast(), st.as_ptr());
let any = Bound::from_owned_ptr(py, ptr.cast::<pyo3::ffi::PyObject>());
any.cast_into::<PyArray1<f32>>().unwrap()
}
}
pub(crate) fn map_const_pyarray_to_vec3<'py>(
py: Python<'py>,
data: &Vector3f,
parent: &Bound<'py, PyAny>,
) -> *mut npyffi::PyArrayObject {
use numpy::Element;
use numpy::PyArrayDescrMethods;
let mut dims = numpy::ndarray::Dim(3);
unsafe {
let ptr = PY_ARRAY_API.PyArray_NewFromDescr(
py,
PY_ARRAY_API.get_type_object(py, npyffi::NpyTypes::PyArray_Type),
f32::get_dtype(py).into_dtype_ptr(),
dims.ndim_cint(),
dims.as_dims_ptr(),
std::ptr::null_mut(), data.as_ptr() as *mut c_void, 0, std::ptr::null_mut(), );
PY_ARRAY_API.PyArray_SetBaseObject(py, ptr.cast(), parent.as_ptr());
pyo3::ffi::Py_IncRef(parent.as_ptr());
ptr.cast()
}
}
pub(crate) fn clone_vec_to_pyarray1<'py, N, R, S>(
v: &nalgebra::Matrix<N, R, Const<1>, S>,
py: Python<'py>,
) -> Bound<'py, PyArray1<N>>
where
N: nalgebra::Scalar + Element,
R: nalgebra::Dim,
S: nalgebra::Storage<N, R, Const<1>>,
{
unsafe {
let array = PyArray1::<N>::new(py, (v.nrows(),), true);
let mut data_ptr = array.data();
if v.data.is_contiguous() {
std::ptr::copy_nonoverlapping(v.data.ptr(), data_ptr, v.len());
} else {
for item in v.iter() {
data_ptr.write(item.clone_ref(py));
data_ptr = data_ptr.add(1);
}
}
array
}
}