add support for Point3
MODIFY
gen_rust.py
gen_rust.py
@@ -109,6 +109,9 @@ decls_manual_pre = {
("class cv.utils.logging.LogTag", "", ["/Ghost"], []),
("class cv.FileNode", "", ["/Ghost"], []),
("class cv.FileStorage", "", ["/Ghost"], []),
+ ("typedef DummyVectorOfPoint3i", "std::vector<Point3i>", [], []),
+ ("typedef DummyVectorOfPoint3f", "std::vector<Point3f>", [], []),
+ ("typedef DummyVectorOfPoint3d", "std::vector<Point3d>", [], []),
],
"dnn": [
("class cv.dnn.LayerParams", "", ["/Ghost"], []),
@@ -672,6 +675,9 @@ type_replace = {
"Point_<int64>": "Point2l",
"Point_<float>": "Point2f",
"Point_<double>": "Point2d",
+ "Point3_<int>": "Point3i",
+ "Point3_<float>": "Point3f",
+ "Point3_<double>": "Point3d",
"Rect_<int>": "Rect2i",
"Rect_<float>": "Rect2f",
"Rect_<double>": "Rect2d",
@@ -819,6 +825,8 @@ for s in (2, 3, 4, 6, 8):
if t[0] in ("i", "l", "f", "d"):
_base_type_alias("core", "Point{}{}".format(s, t[0]), "core::Point_<{}>".format(rust_local), t[1], ("x", "y"))
_base_type_alias("core", "Size{}{}".format(s, t[0]), "core::Size_<{}>".format(rust_local), t[1], ("width", "height"))
+ elif s == 3 and t[0] in ("i", "f", "d"):
+ _base_type_alias("core", "Point{}{}".format(s, t[0]), "core::Point3_<{}>".format(rust_local), t[1], ("x", "y", "z"))
if t[0] != "l":
_base_type_alias("core", "Vec{}{}".format(s, t[0]), "core::Vec{}<{}>".format(s, rust_local), t[1], ("data[{}]".format(s),))
@@ -985,15 +993,16 @@ static_modules = ("core", "sys", "types")
data_type_typeids = {
"uchar", "char", "ushort", "short", "int",
"float", "double",
- "cv::Vec2b", "core::Vec3b", "cv::Vec4b",
- "cv::Vec2s", "core::Vec3s", "cv::Vec4s",
- "cv::Vec2i", "core::Vec3i", "cv::Vec4i",
- "cv::Vec2f", "core::Vec3f", "cv::Vec4f",
- "cv::Vec2d", "core::Vec3d", "cv::Vec4d",
+ "cv::Vec2b", "cv::Vec3b", "cv::Vec4b",
+ "cv::Vec2s", "cv::Vec3s", "cv::Vec4s",
+ "cv::Vec2i", "cv::Vec3i", "cv::Vec4i",
+ "cv::Vec2f", "cv::Vec3f", "cv::Vec4f",
+ "cv::Vec2d", "cv::Vec3d", "cv::Vec4d",
"cv::Scalar",
- "cv::Point", "core::Point2i", "cv::Point2f", "cv::Point2d",
- "cv::Size", "core::Size2i", "cv::Size2f", "cv::Size2d",
- "cv::Rect", "core::Rect2i", "cv::Rect2f", "cv::Rect2d",
+ "cv::Point", "cv::Point2i", "cv::Point2f", "cv::Point2d",
+ "cv::Point3i", "cv::Point3f", "cv::Point3d",
+ "cv::Size", "cv::Size2i", "cv::Size2f", "cv::Size2d",
+ "cv::Rect", "cv::Rect2i", "cv::Rect2f", "cv::Rect2d",
}

MODIFY
src/manual/core.rs
src/manual/core.rs
pub use self::input_output_array::*;
pub use self::mat::*;
pub use self::point::*;
+pub use self::point3::*;
pub use self::rect::*;
pub use self::size::*;
pub use self::vec::*;
@@ -24,6 +25,7 @@ macro_rules! valid_types {
mod input_output_array;
mod mat;
mod point;
+mod point3;
mod rect;
mod size;
mod vec;

MODIFY
src/manual/core/mat.rs
src/manual/core/mat.rs
@@ -96,6 +96,11 @@ data_type!(core::Point2i, core::CV_32S, 2);
data_type!(core::Point2f, core::CV_32F, 2);
data_type!(core::Point2d, core::CV_64F, 2);
+// point3
+data_type!(core::Point3i, core::CV_32S, 2);
+data_type!(core::Point3f, core::CV_32F, 2);
+data_type!(core::Point3d, core::CV_64F, 2);
+
// size
data_type!(core::Size2i, core::CV_32S, 2);
data_type!(core::Size2f, core::CV_32F, 2);

ADD
src/manual/core/point3.rs
+use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
+
+use num::{NumCast, ToPrimitive, Zero};
+
+use crate::core::{Point_, ValidPointType, ValidVecType, Vec3};
+
+valid_types!(ValidPoint3Type, i32, f32, f64);
+
+#[repr(C)]
+#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
+/// [docs.opencv.org](https://docs.opencv.org/master/df/d6c/classcv_1_1Point3__.html)
+pub struct Point3_<T: ValidPoint3Type> {
+ pub x: T,
+ pub y: T,
+ pub z: T,
+}
+
+impl<T: ValidPoint3Type> Point3_<T> {
+ #[inline]
+ pub fn new(x: T, y: T, z: T) -> Self {
+ Self { x, y, z }
+ }
+
+ #[inline]
+ pub fn from_vec3(vec: Vec3<T>) -> Self where T: ValidVecType {
+ Self::new(vec[0], vec[1], vec[2])
+ }
+
+ #[inline]
+ pub fn from_point(pt: Point_<T>) -> Self where T: ValidPointType + Zero {
+ Self::new(pt.x, pt.y, T::zero())
+ }
+
+ #[inline]
+ pub fn cross(self, pt: Point3_<T>) -> Point3_<T> {
+ Self::new(
+ self.y * pt.z - self.z * pt.y,
+ self.z * pt.x - self.x * pt.z,
+ self.x * pt.y - self.y * pt.x,
+ )
+ }
+
+ #[inline]
+ pub fn dot(self, pt: Point3_<T>) -> T {
+ self.x * pt.x + self.y * pt.y + self.z * pt.z
+ }
+
+ #[inline]
+ pub fn ddot(self, pt: Point3_<T>) -> f64 where f64: From<T> {
+ let self_x: f64 = From::from(self.x);
+ let self_y: f64 = From::from(self.y);
+ let self_z: f64 = From::from(self.z);
+ let pt_x: f64 = From::from(pt.x);
+ let pt_y: f64 = From::from(pt.y);
+ let pt_z: f64 = From::from(pt.z);
+ self_x * pt_x + self_y * pt_y + self_z * pt_z
+ }
+
+ #[inline]
+ pub fn norm(self) -> f64 where f64: From<T> {
+ let self_x: f64 = From::from(self.x);
+ let self_y: f64 = From::from(self.y);
+ let self_z: f64 = From::from(self.z);
+ (self_x.powi(2) + self_y.powi(2) + self_z.powi(2)).sqrt()
+ }
+
+ #[inline]
+ pub fn to<D: ValidPoint3Type + NumCast>(self) -> Option<Point3_<D>> where T: ToPrimitive {
+ Some(Point3_::new(D::from(self.x)?, D::from(self.y)?, D::from(self.z)?))
+ }
+}
+
+impl<T> Add for Point3_<T>
+ where
+ T: ValidPoint3Type + AddAssign,
+{
+ type Output = Point3_<T>;
+
+ fn add(mut self, rhs: Point3_<T>) -> Self::Output {
+ self += rhs;
+ self
+ }
+}
+
+impl<T> Sub for Point3_<T>
+ where
+ T: ValidPoint3Type + SubAssign,
+{
+ type Output = Point3_<T>;
+
+ fn sub(mut self, rhs: Point3_<T>) -> Self::Output {
+ self -= rhs;
+ self
+ }
+}
+
+impl<T> Mul<T> for Point3_<T>
+ where
+ T: ValidPoint3Type + MulAssign
+{
+ type Output = Point3_<T>;
+
+ fn mul(mut self, rhs: T) -> Self::Output {
+ self *= rhs;
+ self
+ }
+}
+
+impl<T> Div<T> for Point3_<T>
+ where
+ T: ValidPoint3Type + DivAssign
+{
+ type Output = Point3_<T>;
+
+ fn div(mut self, rhs: T) -> Self::Output {
+ self /= rhs;
+ self
+ }
+}
+
+impl<T> AddAssign for Point3_<T>
+ where
+ T: ValidPoint3Type + AddAssign,
+{
+ fn add_assign(&mut self, rhs: Point3_<T>) {
+ self.x += rhs.x;
+ self.y += rhs.y;
+ self.z += rhs.z;
+ }
+}
+
+impl<T> SubAssign for Point3_<T>
+ where
+ T: ValidPoint3Type + SubAssign,
+{
+ fn sub_assign(&mut self, rhs: Point3_<T>) {
+ self.x -= rhs.x;
+ self.y -= rhs.y;
+ self.z -= rhs.z;
+ }
+}
+
+impl<T> MulAssign<T> for Point3_<T>
+ where
+ T: ValidPoint3Type + MulAssign
+{
+ fn mul_assign(&mut self, rhs: T) {
+ self.x *= rhs;
+ self.y *= rhs;
+ self.z *= rhs;
+ }
+}
+
+impl<T> DivAssign<T> for Point3_<T>
+ where
+ T: ValidPoint3Type + DivAssign
+{
+ fn div_assign(&mut self, rhs: T) {
+ self.x /= rhs;
+ self.y /= rhs;
+ self.z /= rhs;
+ }
+}

ADD
tests/point3.rs
+use opencv::core::{Point2d, Point3d, Point3f, Point3i};
+
+#[test]
+fn point3_add() {
+ let src = Point3i::new(1, 2, 3);
+
+ let res = Point3i::new(11, 22, 33);
+ {
+ let src = src.clone();
+ let out = src + Point3i::new(10, 20, 30);
+ assert_eq!(out, res);
+ }
+
+ {
+ let mut out = src.clone();
+ out += Point3i::new(10, 20, 30);
+ assert_eq!(out, res);
+ }
+}
+
+#[test]
+fn point3_sub() {
+ let src = Point3i::new(10, 20, 30);
+
+ let res = Point3i::new(9, 18, 27);
+ {
+ let src = src.clone();
+ let out = src - Point3i::new(1, 2, 3);
+ assert_eq!(out, res);
+ }
+
+ {
+ let mut out = src.clone();
+ out -= Point3i::new(1, 2, 3);
+ assert_eq!(out, res);
+ }
+}
+
+#[test]
+fn point3_mul() {
+ let src = Point3f::new(10., 20., 30.);
+
+ let res = Point3f::new(20., 40., 60.);
+ {
+ let src = src.clone();
+ let out = src * 2.;
+ assert_eq!(out, res);
+ }
+
+ {
+ let mut out = src.clone();
+ out *= 2.;
+ assert_eq!(out, res);
+ }
+}
+
+#[test]
+fn point3_div() {
+ let src = Point3i::new(10, 20, 30);
+
+ let res = Point3i::new(5, 10, 15);
+ {
+ let src = src.clone();
+ let out = src / 2;
+ assert_eq!(out, res);
+ }
+
+ {
+ let mut out = src.clone();
+ out /= 2;
+ assert_eq!(out, res);
+ }
+}
+
+#[test]
+fn point3_constructor() {
+ let r = Point3d::from_point(Point2d::new(10., 20.));
+ assert_eq!(10., r.x);
+ assert_eq!(20., r.y);
+ assert_eq!(0., r.z);
+}
+
+#[test]
+fn point3_methods() {
+ let pt = Point3i::new(2, 3, 4);
+ assert_eq!(5.385164807134504, pt.norm());
+
+ assert_eq!(Point3i::new(1, -2, 1), pt.cross(Point3i::new(1, 2, 3)));
+ assert_eq!(Point3i::new(2, -4, 2), pt.cross(Point3i::new(-4, -5, -6)));
+ assert_eq!(Point3i::new(-2, -28, 22), pt.cross(Point3i::new(-4, 5, 6)));
+
+ assert_eq!(20, pt.dot(Point3i::new(1, 2, 3)));
+ assert_eq!(29., pt.ddot(Point3i::new(2, 3, 4)));
+}
+
+#[test]
+fn point3_conv() {
+ let ptf = Point3d::new(1.2, 2.3, 3.4);
+ assert_eq!(Point3i::new(1, 2, 3), ptf.to::<i32>().unwrap());
+ assert_eq!(Point3f::new(1.2, 2.3, 3.4), ptf.to::<f32>().unwrap());
+ let pti = Point3i::new(1, 2, 3);
+ assert_eq!(Point3f::new(1., 2., 3.), pti.to::<f32>().unwrap());
+}

add support for Point3