use crate::data::{AnyDataArray, DataArray, PolyData, KdTree};
pub fn paint_sphere(input: &PolyData, array_name: &str, center: [f64;3], radius: f64, value: f64) -> PolyData {
let n = input.points.len();
if n == 0 { return input.clone(); }
let r2 = radius*radius;
let mut values: Vec<f64> = if let Some(arr) = input.point_data().get_array(array_name) {
let mut buf=[0.0f64];
(0..n).map(|i|{arr.tuple_as_f64(i,&mut buf);buf[0]}).collect()
} else {
vec![0.0; n]
};
for i in 0..n {
let p = input.points.get(i);
let d2 = (p[0]-center[0]).powi(2)+(p[1]-center[1]).powi(2)+(p[2]-center[2]).powi(2);
if d2 <= r2 { values[i] = value; }
}
let mut pd = input.clone();
let mut attrs = crate::data::DataSetAttributes::new();
let mut found = false;
for i in 0..input.point_data().num_arrays() {
let a = input.point_data().get_array_by_index(i).unwrap();
if a.name() == array_name {
attrs.add_array(AnyDataArray::F64(DataArray::from_vec(array_name, values.clone(), 1)));
found = true;
} else { attrs.add_array(a.clone()); }
}
if !found { attrs.add_array(AnyDataArray::F64(DataArray::from_vec(array_name, values, 1))); }
*pd.point_data_mut() = attrs;
pd
}
pub fn paint_sphere_smooth(input: &PolyData, array_name: &str, center: [f64;3], radius: f64, value: f64) -> PolyData {
let n = input.points.len();
if n == 0 { return input.clone(); }
let r2 = radius*radius;
let mut values: Vec<f64> = if let Some(arr) = input.point_data().get_array(array_name) {
let mut buf=[0.0f64];
(0..n).map(|i|{arr.tuple_as_f64(i,&mut buf);buf[0]}).collect()
} else {
vec![0.0; n]
};
for i in 0..n {
let p = input.points.get(i);
let d2 = (p[0]-center[0]).powi(2)+(p[1]-center[1]).powi(2)+(p[2]-center[2]).powi(2);
if d2 <= r2 {
let t = 1.0 - (d2/r2).sqrt(); let t = t*t*(3.0-2.0*t); values[i] = values[i]*(1.0-t) + value*t;
}
}
let mut pd = input.clone();
let mut attrs = crate::data::DataSetAttributes::new();
let mut found = false;
for i in 0..input.point_data().num_arrays() {
let a = input.point_data().get_array_by_index(i).unwrap();
if a.name() == array_name {
attrs.add_array(AnyDataArray::F64(DataArray::from_vec(array_name, values.clone(), 1)));
found = true;
} else { attrs.add_array(a.clone()); }
}
if !found { attrs.add_array(AnyDataArray::F64(DataArray::from_vec(array_name, values, 1))); }
*pd.point_data_mut() = attrs;
pd
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn paint_creates_array() {
let mut pd = PolyData::new();
pd.points.push([0.0,0.0,0.0]); pd.points.push([1.0,0.0,0.0]); pd.points.push([10.0,0.0,0.0]);
let result = paint_sphere(&pd, "paint", [0.0,0.0,0.0], 2.0, 1.0);
let arr = result.point_data().get_array("paint").unwrap();
let mut buf=[0.0f64];
arr.tuple_as_f64(0,&mut buf); assert_eq!(buf[0], 1.0); arr.tuple_as_f64(1,&mut buf); assert_eq!(buf[0], 1.0); arr.tuple_as_f64(2,&mut buf); assert_eq!(buf[0], 0.0); }
#[test]
fn smooth_paint_falloff() {
let mut pd = PolyData::new();
pd.points.push([0.0,0.0,0.0]); pd.points.push([0.5,0.0,0.0]); pd.points.push([0.9,0.0,0.0]);
let result = paint_sphere_smooth(&pd, "p", [0.0,0.0,0.0], 1.0, 10.0);
let arr = result.point_data().get_array("p").unwrap();
let mut buf=[0.0f64];
arr.tuple_as_f64(0,&mut buf); let v0=buf[0];
arr.tuple_as_f64(2,&mut buf); let v2=buf[0];
assert!(v0 > v2); }
#[test]
fn paint_updates_existing() {
let mut pd = PolyData::new();
pd.points.push([0.0,0.0,0.0]);
pd.point_data_mut().add_array(AnyDataArray::F64(DataArray::from_vec("val",vec![5.0],1)));
let result = paint_sphere(&pd, "val", [0.0,0.0,0.0], 1.0, 99.0);
let arr = result.point_data().get_array("val").unwrap();
let mut buf=[0.0f64];
arr.tuple_as_f64(0,&mut buf);
assert_eq!(buf[0], 99.0);
}
#[test]
fn empty_input() {
let pd = PolyData::new();
let result = paint_sphere(&pd, "p", [0.0;3], 1.0, 1.0);
assert_eq!(result.points.len(), 0);
}
}