engeom 0.2.10__tar.gz → 0.2.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {engeom-0.2.10 → engeom-0.2.11}/Cargo.lock +1 -1
- {engeom-0.2.10 → engeom-0.2.11}/Cargo.toml +1 -1
- {engeom-0.2.10 → engeom-0.2.11}/PKG-INFO +1 -1
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh.rs +68 -21
- engeom-0.2.11/engeom/src/geom3/xyzwpr.rs +141 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3.rs +2 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/lib.rs +4 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/geom3.pyi +123 -14
- {engeom-0.2.10 → engeom-0.2.11}/src/geom3.rs +91 -2
- {engeom-0.2.10 → engeom-0.2.11}/src/mesh.rs +72 -12
- {engeom-0.2.10 → engeom-0.2.11}/.github/workflows/CI.yml +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/.gitignore +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/.gitmodules +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/README.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/airfoils/intro.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/api/airfoil.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/api/engeom.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/api/geom2.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/api/geom3.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/api/metrology.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/api/plot.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/bounding_volumes.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/curves.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/images/surface_point_meas.svg +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/index.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/isometries.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/meshes.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/metrology.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/numpy.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/planes_circles_lines.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/points_vectors.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/surf_points.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/docs/svd_basis.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/.gitignore +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/Cargo.lock +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/Cargo.toml +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/README.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/airfoils/camber.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/airfoils/overview.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/common/angles.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/common/core_space.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/common/discrete_domain.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/common/images/surface_point_meas.svg +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/common/svd_basis.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/geom2/alignment.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/geom2/curve.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/geom2/point_collections.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/geom2/shapes.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/index.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/javascripts/mathjax.js +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/docs/python_rust.md +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/mkdocs.yml +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/airfoil/camber.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/airfoil/edges.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/airfoil/helpers.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/airfoil/inscribed_circle.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/airfoil/orientation.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/airfoil.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/align.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/angles.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/convert_2d_3d.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/discrete_domain.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/indices.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/interval.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/kd_tree.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/points.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/poisson_disk.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/surface_point.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/svd_basis.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common/vec_f64.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/common.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/errors.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/func1/common_functions.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/func1/polynomial.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/func1/series1.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/func1.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/aabb2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/align2/jacobian.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/align2/points_to_curve.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/align2/rc_params2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/align2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/angles2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/circle2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/curve2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/hull.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/line2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2/polyline2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/align3/jacobian.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/align3/multi_param.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/align3/points_to_mesh.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/align3/rotations.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/align3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/curve3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/iso3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/collisions.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/conformal.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/edges.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/faces.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/filtering.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/measurement.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/outline.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/patches.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/queries.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/sampling.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/mesh/uv_mapping.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/plane3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/geom3/point_cloud.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/io.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/metrology/dimension.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/metrology/line_profiles.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/metrology/surface_deviation.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/metrology/tolerance.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/metrology/tolerance_map.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/metrology.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/raster3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/sensor.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/stats.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/engeom/src/utility.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/mkdocs.yml +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/pyproject.toml +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/_plot/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/_plot/common.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/_plot/matplotlib.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/_plot/pyvista.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/airfoil/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/airfoil.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/align/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/align.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/engeom.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/geom2/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/geom2.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/geom3/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/metrology/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/metrology.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/plot.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/raster3/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/raster3.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/sensor/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/engeom/sensor.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/tests/test_all.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/tests/test_geom2_simple.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/python/tests/test_geom3_simple.py +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/airfoil.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/alignments.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/bounding.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/common.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/conversions.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/geom2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/lib.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/metrology.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/raster.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/ray_casting.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/sensor.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.11}/src/svd_basis.rs +0 -0
@@ -2,6 +2,7 @@
|
|
2
2
|
//! indices into the vertex list. This abstraction is built around the `TriMesh` type from the
|
3
3
|
//! `parry3d` crate.
|
4
4
|
|
5
|
+
mod collisions;
|
5
6
|
mod conformal;
|
6
7
|
mod edges;
|
7
8
|
mod faces;
|
@@ -12,15 +13,14 @@ mod patches;
|
|
12
13
|
mod queries;
|
13
14
|
mod sampling;
|
14
15
|
mod uv_mapping;
|
15
|
-
mod collisions;
|
16
16
|
|
17
|
-
pub use self::uv_mapping::UvMapping;
|
18
17
|
pub use self::collisions::MeshCollisionSet;
|
19
|
-
use
|
18
|
+
pub use self::uv_mapping::UvMapping;
|
19
|
+
use crate::geom3::{Aabb3, IsoExtensions3};
|
20
20
|
use crate::{Iso3, Point2, Point3, Result, SurfacePoint3, UnitVec3, Vector3};
|
21
21
|
pub use edges::MeshEdges;
|
22
22
|
use parry3d_f64::shape::{TriMesh, TriMeshFlags};
|
23
|
-
use parry3d_f64::transformation;
|
23
|
+
use parry3d_f64::{shape, transformation};
|
24
24
|
|
25
25
|
#[derive(Clone)]
|
26
26
|
pub struct Mesh {
|
@@ -204,32 +204,79 @@ impl Mesh {
|
|
204
204
|
}
|
205
205
|
}
|
206
206
|
|
207
|
-
pub fn
|
208
|
-
let
|
207
|
+
pub fn create_cone(half_height: f64, radius: f64, steps: usize) -> Self {
|
208
|
+
let cone = shape::Cone::new(half_height, radius);
|
209
|
+
let (vertices, faces) = cone.to_trimesh(steps as u32);
|
210
|
+
|
211
|
+
Self::new(vertices, faces, true)
|
212
|
+
}
|
213
|
+
|
214
|
+
pub fn create_capsule(
|
215
|
+
p0: &Point3,
|
216
|
+
p1: &Point3,
|
217
|
+
radius: f64,
|
218
|
+
n_theta: usize,
|
219
|
+
n_phi: usize,
|
220
|
+
) -> Self {
|
221
|
+
let capsule = shape::Capsule::new(*p0, *p1, radius);
|
222
|
+
let (vertices, faces) = capsule.to_trimesh(n_theta as u32, n_phi as u32);
|
223
|
+
|
224
|
+
Self::new(vertices, faces, true)
|
225
|
+
}
|
226
|
+
|
227
|
+
pub fn create_sphere(radius: f64, n_theta: usize, n_phi: usize) -> Self {
|
228
|
+
let sphere = shape::Ball::new(radius);
|
229
|
+
let (vertices, faces) = sphere.to_trimesh(n_theta as u32, n_phi as u32);
|
230
|
+
|
231
|
+
Self::new(vertices, faces, true)
|
232
|
+
}
|
233
|
+
|
234
|
+
pub fn create_box(length: f64, width: f64, height: f64, is_solid: bool) -> Self {
|
235
|
+
let bx = shape::Cuboid::new(Vector3::new(length / 2.0, width / 2.0, height / 2.0));
|
236
|
+
let (vertices, triangles) = bx.to_trimesh();
|
209
237
|
Self::new(vertices, triangles, is_solid)
|
210
238
|
}
|
211
239
|
|
212
240
|
pub fn create_cylinder(radius: f64, height: f64, steps: usize) -> Self {
|
213
|
-
let
|
214
|
-
let
|
241
|
+
let cyl = shape::Cylinder::new(height / 2.0, radius);
|
242
|
+
let (vertices, faces) = cyl.to_trimesh(steps as u32);
|
243
|
+
|
244
|
+
Self::new(vertices, faces, true)
|
245
|
+
}
|
246
|
+
|
247
|
+
pub fn create_rect_beam_between(
|
248
|
+
p0: &Point3,
|
249
|
+
p1: &Point3,
|
250
|
+
width: f64,
|
251
|
+
height: f64,
|
252
|
+
up: &Vector3,
|
253
|
+
) -> Result<Self> {
|
254
|
+
let v = *p1 - *p0;
|
255
|
+
let pc = *p0 + v / 2.0;
|
256
|
+
let box_geom = shape::Cuboid::new(Vector3::new(width / 2.0, height / 2.0, v.norm() / 2.0));
|
215
257
|
|
216
|
-
|
217
|
-
|
218
|
-
let x = radius * angle.cos();
|
219
|
-
let y = radius * angle.sin();
|
258
|
+
// I think this is OK?
|
259
|
+
let transform = Iso3::try_from_basis_zy(&v, up, Some(pc))?;
|
220
260
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
261
|
+
let (vertices, faces) = box_geom.to_trimesh();
|
262
|
+
let mut mesh = Self::new(vertices, faces, true);
|
263
|
+
mesh.transform(&transform);
|
264
|
+
Ok(mesh)
|
265
|
+
}
|
225
266
|
|
226
|
-
|
267
|
+
pub fn create_cylinder_between(p0: &Point3, p1: &Point3, radius: f64, steps: usize) -> Self {
|
268
|
+
let v = *p1 - *p0;
|
269
|
+
let pc = *p0 + v / 2.0;
|
270
|
+
let cyl = shape::Cylinder::new(v.norm() / 2.0, radius);
|
227
271
|
|
228
|
-
|
229
|
-
|
230
|
-
|
272
|
+
// I think this is OK?
|
273
|
+
let transform = Iso3::try_from_basis_yz(&v, &Vector3::z(), Some(pc))
|
274
|
+
.unwrap_or(Iso3::try_from_basis_yx(&v, &Vector3::x(), Some(pc)).unwrap());
|
231
275
|
|
232
|
-
|
276
|
+
let (vertices, faces) = cyl.to_trimesh(steps as u32);
|
277
|
+
let mut mesh = Self::new(vertices, faces, true);
|
278
|
+
mesh.transform(&transform);
|
279
|
+
mesh
|
233
280
|
}
|
234
281
|
|
235
282
|
pub fn get_patches(&self) -> Vec<Vec<usize>> {
|
@@ -0,0 +1,141 @@
|
|
1
|
+
use serde::{Deserialize, Serialize};
|
2
|
+
use crate::{Iso3, Vector3};
|
3
|
+
use crate::na::{Translation3, UnitQuaternion};
|
4
|
+
|
5
|
+
/// A struct representing a 6D pose in XYZ and WPR (Yaw, Pitch, Roll) format, commonly used by
|
6
|
+
/// FANUC robots. Angles are represented in degrees.
|
7
|
+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
8
|
+
pub struct XyzWpr {
|
9
|
+
pub x: f64,
|
10
|
+
pub y: f64,
|
11
|
+
pub z: f64,
|
12
|
+
pub w: f64,
|
13
|
+
pub p: f64,
|
14
|
+
pub r: f64,
|
15
|
+
}
|
16
|
+
|
17
|
+
impl XyzWpr {
|
18
|
+
pub fn new(x: f64, y: f64, z: f64, w: f64, p: f64, r: f64) -> Self {
|
19
|
+
XyzWpr { x, y, z, w, p, r }
|
20
|
+
}
|
21
|
+
|
22
|
+
pub fn from_isometry(isometry: &Iso3) -> Self {
|
23
|
+
let translation = isometry.translation.vector;
|
24
|
+
let rotation = isometry.rotation;
|
25
|
+
let (r, p, w) = rotation.euler_angles();
|
26
|
+
XyzWpr::new(
|
27
|
+
translation.x,
|
28
|
+
translation.y,
|
29
|
+
translation.z,
|
30
|
+
w.to_degrees(),
|
31
|
+
p.to_degrees(),
|
32
|
+
r.to_degrees(),
|
33
|
+
)
|
34
|
+
}
|
35
|
+
|
36
|
+
pub fn to_isometry(&self) -> Iso3 {
|
37
|
+
let translation = Vector3::new(self.x, self.y, self.z);
|
38
|
+
let rotation = UnitQuaternion::from_euler_angles(
|
39
|
+
self.r.to_radians(),
|
40
|
+
self.p.to_radians(),
|
41
|
+
self.w.to_radians(),
|
42
|
+
);
|
43
|
+
Iso3::from_parts(Translation3::from(translation), rotation)
|
44
|
+
}
|
45
|
+
|
46
|
+
pub fn approx_eq(&self, other: &XyzWpr, epsilon: f64) -> bool {
|
47
|
+
let m0 = self.to_isometry().to_matrix();
|
48
|
+
let m1 = other.to_isometry().to_matrix();
|
49
|
+
let diff = m0 - m1;
|
50
|
+
diff.amax() < epsilon
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
impl std::fmt::Display for XyzWpr {
|
55
|
+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
56
|
+
write!(
|
57
|
+
f,
|
58
|
+
"XyzWpr {{ x: {}, y: {}, z: {}, w: {}, p: {}, r: {} }}",
|
59
|
+
self.x, self.y, self.z, self.w, self.p, self.r
|
60
|
+
)
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
#[cfg(test)]
|
65
|
+
mod tests {
|
66
|
+
use super::*;
|
67
|
+
use crate::na::{try_convert, Matrix4};
|
68
|
+
use approx::assert_relative_eq;
|
69
|
+
use test_case::test_case;
|
70
|
+
|
71
|
+
#[test_case((-0.8156824504, -0.5743236360, -0.0693866068, -413.8635232282, 0.0004524620, 0.1193088953, -0.9928570807, 263.1863811434, 0.5784997281, -0.8098874913, -0.0970583124, 291.9820746748, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-413.8635232282, 263.1863811434, 291.9820746748, -96.8338333769, -35.3450905433, 179.9682178248))]
|
72
|
+
#[test_case((-0.1500516217, 0.5455385155, -0.8245436550, -149.1668440821, 0.9459952737, -0.1631791693, -0.2801169415, 59.3543506644, -0.2873629291, -0.8220464019, -0.4915915582, 543.2838251943, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-149.1668440821, 59.3543506644, 543.2838251943, -120.8798246395, 16.7001441168, 99.0130388728))]
|
73
|
+
#[test_case((0.5009445358, 0.6825401810, 0.5321592557, 31.0642288750, -0.8639774486, 0.3581642754, 0.3539227601, -26.7743169615, 0.0509660705, -0.6370692687, 0.7691197609, 37.9006405971, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (31.0642288750, -26.7743169615, 37.9006405971, -39.6352782596, -2.9214064154, -59.8943255222))]
|
74
|
+
#[test_case((0.9089103503, -0.4069146210, 0.0911178708, 33.5138781088, -0.0854907806, 0.0320310501, 0.9958239494, 96.1164814542, -0.4081339260, -0.9129044326, -0.0056740956, -300.9032245106, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (33.5138781088, 96.1164814542, -300.9032245106, -90.3561134473, 24.0876647389, -5.3733485621))]
|
75
|
+
#[test_case((-0.1653518888, 0.9687851465, -0.1847000075, 77.8658952620, 0.9532759246, 0.2050088803, 0.2218927005, 100.2923343848, 0.2528314941, -0.1393796933, -0.9574181619, -127.6541936118, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (77.8658952620, 100.2923343848, -127.6541936118, -171.7171410357, -14.6451288996, 99.8404139441))]
|
76
|
+
#[test_case((-0.4118951499, 0.3279601759, -0.8501673415, -70.6389144769, -0.3403719856, -0.9208299694, -0.1903131075, 22.3217390074, -0.8452746873, 0.2109841002, 0.4909138545, 18.1798498130, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-70.6389144769, 22.3217390074, 18.1798498130, 23.2569815201, 57.7013782986, -140.4311743532))]
|
77
|
+
#[test_case((-0.7479917678, -0.6191725989, -0.2390263753, 604.2872268462, -0.4057545090, 0.1415967662, 0.9029471935, -20.9333741686, -0.5252347986, 0.7723830970, -0.3571452893, 30.4479677368, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (604.2872268462, -20.9333741686, 30.4479677368, 114.8155367373, 31.6840511268, -151.5220050073))]
|
78
|
+
#[test_case((0.4873440333, 0.6172398073, 0.6176656163, 77.4016768659, 0.3323406191, 0.5230063131, -0.7848656633, -28.4720503689, -0.8074933474, 0.5877749712, 0.0497501464, -19.7908480100, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (77.4016768659, -28.4720503689, -19.7908480100, 85.1619317507, 53.8517426985, 34.2917400153))]
|
79
|
+
#[test_case((0.0833272687, 0.6836449300, 0.7250421891, 471.9320306822, -0.8519144952, -0.3286045615, 0.4077508246, -102.6726730677, 0.5170089546, -0.6516507130, 0.5550253049, 588.5120154719, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (471.9320306822, -102.6726730677, 588.5120154719, -49.5782300627, -31.1318310910, -84.4135682965))]
|
80
|
+
#[test_case((-0.2510504585, 0.9157805028, -0.3135597837, -577.6445766741, -0.0345374583, -0.3322023607, -0.9425755967, -216.2517731052, -0.9673576543, -0.2258044778, 0.1150282859, 240.9460890915, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-577.6445766741, -216.2517731052, 240.9460890915, -63.0050045001, 75.3203125033, -172.1668871906))]
|
81
|
+
#[test_case((0.1791056335, -0.5890186234, -0.7880217213, 411.6803610302, 0.6839325663, -0.5012295385, 0.5300992308, 331.0434986878, -0.7072180829, -0.6338974767, 0.3130759848, -361.9951518329, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (411.6803610302, 331.0434986878, -361.9951518329, -63.7156683382, 45.0090193165, 75.3251405039))]
|
82
|
+
#[test_case((-0.7389487926, -0.6540675080, 0.1617107816, 5.4890201453, -0.6393453686, 0.7564348576, 0.1379992968, -26.5744088848, -0.2125845282, -0.0014146255, -0.9771416567, -99.6628429743, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (5.4890201453, -26.5744088848, -99.6628429743, -179.9170519309, 12.2738553488, -139.1333357015))]
|
83
|
+
#[test_case((-0.2037395422, 0.6790363200, -0.7052658187, -1.7434467919, -0.8508250650, -0.4791894336, -0.2155787453, -14.7633944063, -0.4843417261, 0.5561359212, 0.6753709570, -79.9344894886, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-1.7434467919, -14.7633944063, -79.9344894886, 39.4698348110, 28.9693530939, -103.4665369616))]
|
84
|
+
#[test_case((0.7230637290, 0.1432361537, -0.6757678952, -49.7118498703, 0.5101470443, 0.5488670300, 0.6621895322, 20.3765636776, 0.4657561992, -0.8235462268, 0.3237943410, 8.4422995188, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-49.7118498703, 20.3765636776, 8.4422995188, -68.5366961539, -27.7591729450, 35.2043221840))]
|
85
|
+
#[test_case((0.9572590453, -0.2498925755, 0.1456324858, 59.5794643289, -0.2886479285, -0.7934076632, 0.5358979878, 6.7548483372, -0.0183709982, -0.5550297115, -0.8316276365, -88.8341095469, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (59.5794643289, 6.7548483372, -88.8341095469, -146.2807856754, 1.0526398756, -16.7799423973))]
|
86
|
+
fn xyzwpr_to_isometry(
|
87
|
+
mf: (
|
88
|
+
f64,
|
89
|
+
f64,
|
90
|
+
f64,
|
91
|
+
f64,
|
92
|
+
f64,
|
93
|
+
f64,
|
94
|
+
f64,
|
95
|
+
f64,
|
96
|
+
f64,
|
97
|
+
f64,
|
98
|
+
f64,
|
99
|
+
f64,
|
100
|
+
f64,
|
101
|
+
f64,
|
102
|
+
f64,
|
103
|
+
f64,
|
104
|
+
),
|
105
|
+
pf: (f64, f64, f64, f64, f64, f64),
|
106
|
+
) {
|
107
|
+
let m = Matrix4::new(
|
108
|
+
mf.0, mf.1, mf.2, mf.3, mf.4, mf.5, mf.6, mf.7, mf.8, mf.9, mf.10, mf.11, mf.12, mf.13,
|
109
|
+
mf.14, mf.15,
|
110
|
+
);
|
111
|
+
let p = XyzWpr::new(pf.0, pf.1, pf.2, pf.5, pf.4, pf.3);
|
112
|
+
let t = p.to_isometry();
|
113
|
+
let m_ = t.to_matrix();
|
114
|
+
assert_relative_eq!(m, m_, epsilon = 1e-5);
|
115
|
+
}
|
116
|
+
|
117
|
+
#[test_case((213.3455874397, -541.8828362001, -95.1324602951, -164.2348619634, 24.0489557219, -170.7519141710))]
|
118
|
+
#[test_case((70.6318465112, 113.6560228546, 346.7855689786, -26.3445451403, -30.6825741682, -92.3381779921))]
|
119
|
+
#[test_case((-18.5208462508, 554.3972482202, 531.8505273397, 24.9359848528, -20.6580074641, -118.2163130322))]
|
120
|
+
#[test_case((-279.4908707038, 107.0379921066, 347.6153730196, 141.6846980303, 42.9511504078, 21.8352677126))]
|
121
|
+
#[test_case((61.7823486174, 39.0960520469, 7.1731831514, 63.6707920489, 28.5547935126, 65.2651276746))]
|
122
|
+
#[test_case((17.8583707934, -103.5277608846, -41.9211021563, -129.0763419754, -64.3075695674, -119.6216242866))]
|
123
|
+
#[test_case((381.5649351646, -118.4073378481, 86.8318954547, -69.6420826640, 50.3520931676, -113.9445091815))]
|
124
|
+
#[test_case((-46.1766927642, -55.8019771470, -84.1930750980, -148.4720043329, 11.1136514360, 139.1677460882))]
|
125
|
+
#[test_case((222.2302724845, -372.5432843996, 266.9542861389, 88.4476440066, 35.3943355124, -166.3788546777))]
|
126
|
+
#[test_case((459.8055541953, 401.5061123248, 180.9052529976, 121.5295678361, -30.3457576176, 66.0945383908))]
|
127
|
+
#[test_case((-68.9503102461, -79.4547936268, -62.0503091459, 121.1860503955, 5.5438249089, -33.3572843285))]
|
128
|
+
fn xyzwpr_from_isometry(pf: (f64, f64, f64, f64, f64, f64)) {
|
129
|
+
let p = XyzWpr::new(pf.0, pf.1, pf.2, pf.5, pf.4, pf.3);
|
130
|
+
let i = p.to_isometry();
|
131
|
+
|
132
|
+
let p_ = XyzWpr::from_isometry(&i);
|
133
|
+
|
134
|
+
assert_relative_eq!(p.x, p_.x, epsilon = 1e-5);
|
135
|
+
assert_relative_eq!(p.y, p_.y, epsilon = 1e-5);
|
136
|
+
assert_relative_eq!(p.z, p_.z, epsilon = 1e-5);
|
137
|
+
assert_relative_eq!(p.w, p_.w, epsilon = 1e-5);
|
138
|
+
assert_relative_eq!(p.p, p_.p, epsilon = 1e-5);
|
139
|
+
assert_relative_eq!(p.r, p_.r, epsilon = 1e-5);
|
140
|
+
}
|
141
|
+
}
|
@@ -4,6 +4,7 @@ pub mod mesh;
|
|
4
4
|
mod plane3;
|
5
5
|
mod point_cloud;
|
6
6
|
mod iso3;
|
7
|
+
mod xyzwpr;
|
7
8
|
|
8
9
|
use parry3d_f64::na::UnitQuaternion;
|
9
10
|
|
@@ -17,6 +18,7 @@ pub use mesh::{Mesh, UvMapping, MeshCollisionSet};
|
|
17
18
|
pub use plane3::Plane3;
|
18
19
|
pub use point_cloud::{PointCloud, PointCloudFeatures, PointCloudKdTree};
|
19
20
|
pub use iso3::IsoExtensions3;
|
21
|
+
pub use xyzwpr::XyzWpr;
|
20
22
|
|
21
23
|
pub type Point3 = parry3d_f64::na::Point3<f64>;
|
22
24
|
pub type Vector3 = parry3d_f64::na::Vector3<f64>;
|
@@ -15,6 +15,10 @@ pub mod sensor;
|
|
15
15
|
|
16
16
|
pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
17
17
|
|
18
|
+
// Re-export parry and nalgebra
|
19
|
+
pub use parry3d_f64::na as na;
|
20
|
+
pub use parry3d_f64 as parry3d;
|
21
|
+
|
18
22
|
// Common one dimensional functions
|
19
23
|
pub use func1::{Func1, Gaussian1, Line1, Polynomial, Series1};
|
20
24
|
|
@@ -461,6 +461,29 @@ class Iso3:
|
|
461
461
|
"""
|
462
462
|
...
|
463
463
|
|
464
|
+
@staticmethod
|
465
|
+
def from_xyzwpr(x: float, y: float, z: float, w: float, p: float, r: float) -> Iso3:
|
466
|
+
"""
|
467
|
+
Create an isometry from the specified translation and rotation angles in yaw, pitch, and roll format, following
|
468
|
+
the convention typically used in robotics. The angles are specified in degrees.
|
469
|
+
:param x:
|
470
|
+
:param y:
|
471
|
+
:param z:
|
472
|
+
:param w:
|
473
|
+
:param p:
|
474
|
+
:param r:
|
475
|
+
:return:
|
476
|
+
"""
|
477
|
+
...
|
478
|
+
|
479
|
+
def to_xyzwpr(self) -> List[float]:
|
480
|
+
"""
|
481
|
+
Convert the isometry to a list of translation and rotation angles in yaw, pitch, and roll format, following the
|
482
|
+
convention typically used in robotics. The angles are returned in degrees.
|
483
|
+
:return: a list of 6 floats representing the translation and rotation angles.
|
484
|
+
"""
|
485
|
+
...
|
486
|
+
|
464
487
|
def __matmul__(self, other: Transformable3) -> Transformable3:
|
465
488
|
"""
|
466
489
|
Multiply another object by the isometry, transforming it and returning a new object of the same type.
|
@@ -537,6 +560,14 @@ class Iso3:
|
|
537
560
|
"""
|
538
561
|
...
|
539
562
|
|
563
|
+
@property
|
564
|
+
def origin(self) -> Point3:
|
565
|
+
"""
|
566
|
+
Get the origin of the isometry as a Point3 object.
|
567
|
+
:return: a Point3 object representing the origin of the isometry.
|
568
|
+
"""
|
569
|
+
...
|
570
|
+
|
540
571
|
def translation(self) -> Iso3:
|
541
572
|
"""
|
542
573
|
Return the translation component of the isometry as a separate isometry.
|
@@ -1157,14 +1188,14 @@ class Mesh:
|
|
1157
1188
|
...
|
1158
1189
|
|
1159
1190
|
@staticmethod
|
1160
|
-
def create_box(
|
1191
|
+
def create_box(length: float, width: float, height: float) -> Mesh:
|
1161
1192
|
"""
|
1162
|
-
Creates a box with the
|
1193
|
+
Creates a box with the center at the origin and the specified length, width, and height
|
1163
1194
|
|
1164
|
-
:param
|
1165
|
-
:param
|
1166
|
-
:param
|
1167
|
-
:return:
|
1195
|
+
:param length: the size of the box along the X-axis
|
1196
|
+
:param width: the size of the box along the Y-axis
|
1197
|
+
:param height: the size of the box along the Z-axis
|
1198
|
+
:return: a new `Mesh` object representing the box
|
1168
1199
|
"""
|
1169
1200
|
...
|
1170
1201
|
|
@@ -1172,14 +1203,91 @@ class Mesh:
|
|
1172
1203
|
def create_cylinder(radius: float, height: float, steps: int) -> Mesh:
|
1173
1204
|
"""
|
1174
1205
|
Creates a cylinder with a radius and height. The cylinder will be centered at the origin and oriented along the
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
:param
|
1180
|
-
|
1181
|
-
:
|
1182
|
-
|
1206
|
+
Y-axis.
|
1207
|
+
|
1208
|
+
:param radius: the radius of the cylinder
|
1209
|
+
:param height: the size of the cylinder along the Y-axis
|
1210
|
+
:param steps: the number of subdivisions to create vertices around the cylinder. The more steps the smoother the
|
1211
|
+
cylinder will be.
|
1212
|
+
:return: a new `Mesh` object representing the cylinder
|
1213
|
+
"""
|
1214
|
+
...
|
1215
|
+
|
1216
|
+
@staticmethod
|
1217
|
+
def create_sphere(radius: float, n_theta: int, n_phi: int) -> Mesh:
|
1218
|
+
"""
|
1219
|
+
Creates a sphere with a radius. The sphere will be centered at the origin. The step counts `n_theta` and `n_phi`
|
1220
|
+
will determine the smoothness of the sphere in the radial (n_theta) and polar (n_phi) directions. The poles
|
1221
|
+
will be located at Y=+radius and Y=-radius, and the equator will lie in the XZ plane.
|
1222
|
+
|
1223
|
+
:param radius: the radius of the sphere
|
1224
|
+
:param n_theta: the number of subdivisions to create vertices around the sphere in the theta direction
|
1225
|
+
:param n_phi: the number of subdivisions to create vertices around the sphere in the phi direction
|
1226
|
+
:return: a new `Mesh` object representing the sphere
|
1227
|
+
"""
|
1228
|
+
...
|
1229
|
+
|
1230
|
+
@staticmethod
|
1231
|
+
def create_cone(radius: float, height: float, steps: int) -> Mesh:
|
1232
|
+
"""
|
1233
|
+
Creates a cone with a radius and height. The cone will be centered at the origin and oriented so that the
|
1234
|
+
point of the cone is located at Y=height/2 and the base is located at Y=-height/2.
|
1235
|
+
|
1236
|
+
:param radius: the radius of the base of the cone
|
1237
|
+
:param height: the size of the cone along the Y-axis
|
1238
|
+
:param steps: the number of subdivisions to create vertices around the cone. The more steps the smoother the
|
1239
|
+
cone will be.
|
1240
|
+
:return: a new `Mesh` object representing the cone
|
1241
|
+
"""
|
1242
|
+
...
|
1243
|
+
|
1244
|
+
@staticmethod
|
1245
|
+
def create_capsule(p0: Point3, p1: Point3, radius: float, n_theta: int, n_phi: int) -> Mesh:
|
1246
|
+
"""
|
1247
|
+
Creates a capsule shape between two points with a specified radius. The capsule will be centered between the two
|
1248
|
+
points and oriented along the line connecting them. The step counts `n_theta` and `n_phi` will determine the
|
1249
|
+
smoothness of the sphere in the radial (n_theta) and polar (n_phi) directions.
|
1250
|
+
|
1251
|
+
:param p0: the first point of the capsule
|
1252
|
+
:param p1: the second point of the capsule
|
1253
|
+
:param radius: the radius of the capsule
|
1254
|
+
:param n_theta: the number of subdivisions to create vertices around the sphere in the theta direction
|
1255
|
+
:param n_phi: the number of subdivisions to create vertices around the sphere in the phi direction
|
1256
|
+
:return: a new `Mesh` object representing the capsule
|
1257
|
+
"""
|
1258
|
+
...
|
1259
|
+
|
1260
|
+
@staticmethod
|
1261
|
+
def create_cylinder_between(p0: Point3, p1: Point3, radius: float, steps: int) -> Mesh:
|
1262
|
+
"""
|
1263
|
+
Creates a cylinder between two points with a specified radius. The cylinder will be centered between the two
|
1264
|
+
points and oriented along the line connecting them.
|
1265
|
+
|
1266
|
+
:param p0: the first point of the cylinder
|
1267
|
+
:param p1: the second point of the cylinder
|
1268
|
+
:param radius: the radius of the cylinder
|
1269
|
+
:param steps: the number of subdivisions to create vertices around the cylinder. The more steps the smoother the
|
1270
|
+
cylinder will be.
|
1271
|
+
:return: a new `Mesh` object representing the cylinder
|
1272
|
+
"""
|
1273
|
+
...
|
1274
|
+
|
1275
|
+
@staticmethod
|
1276
|
+
def create_rect_beam_between(p0: Point3, p1: Point3, width: float, height: float, up: Vector3 | None = None) -> Mesh:
|
1277
|
+
"""
|
1278
|
+
Create a rectangular cross-sectioned prism between two points with a specified width and height. The prism will
|
1279
|
+
be centered between the two points and oriented along the line connecting them. The up vector's projection onto
|
1280
|
+
the line connecting the two end points will determine the direction of the height of the prism. If None, the
|
1281
|
+
height will be aligned with the projection of the Z-axis.
|
1282
|
+
|
1283
|
+
If the up vector is parallel to the line connecting the two points, an error will be thrown.
|
1284
|
+
|
1285
|
+
:param p0: the first point of the prism
|
1286
|
+
:param p1: the second point of the prism
|
1287
|
+
:param width: the width of the prism
|
1288
|
+
:param height: the height of the prism
|
1289
|
+
:param up: the up vector to use for the height direction. If None, the Z-axis will be used
|
1290
|
+
:return: a new `Mesh` object representing the prism
|
1183
1291
|
"""
|
1184
1292
|
...
|
1185
1293
|
|
@@ -1304,6 +1412,7 @@ class MeshCollisionSet:
|
|
1304
1412
|
"""
|
1305
1413
|
...
|
1306
1414
|
|
1415
|
+
|
1307
1416
|
class CurveStation3:
|
1308
1417
|
"""
|
1309
1418
|
A class representing a station along a curve in 3D space. The station is represented by a point on the curve, a
|
@@ -614,6 +614,74 @@ impl From<engeom::CurveStation3<'_>> for CurveStation3 {
|
|
614
614
|
// Transformations
|
615
615
|
// ================================================================================================
|
616
616
|
|
617
|
+
#[pyclass]
|
618
|
+
#[derive(Clone, Debug)]
|
619
|
+
pub struct XyzWpr {
|
620
|
+
inner: engeom::geom3::XyzWpr,
|
621
|
+
}
|
622
|
+
|
623
|
+
impl XyzWpr {
|
624
|
+
pub fn get_inner(&self) -> &engeom::geom3::XyzWpr {
|
625
|
+
&self.inner
|
626
|
+
}
|
627
|
+
|
628
|
+
pub fn from_inner(inner: engeom::geom3::XyzWpr) -> Self {
|
629
|
+
Self { inner }
|
630
|
+
}
|
631
|
+
}
|
632
|
+
|
633
|
+
// #[pymethods]
|
634
|
+
// impl XyzWpr {
|
635
|
+
// #[new]
|
636
|
+
// fn new(x: f64, y: f64, z: f64, w: f64, p: f64, r: f64) -> Self {
|
637
|
+
// Self {
|
638
|
+
// inner: engeom::geom3::XyzWpr::new(x, y, z, w, p, r),
|
639
|
+
// }
|
640
|
+
// }
|
641
|
+
//
|
642
|
+
// #[getter]
|
643
|
+
// fn values(&self) -> Vec<f64> {
|
644
|
+
// vec![
|
645
|
+
// self.inner.x,
|
646
|
+
// self.inner.y,
|
647
|
+
// self.inner.z,
|
648
|
+
// self.inner.w,
|
649
|
+
// self.inner.p,
|
650
|
+
// self.inner.r,
|
651
|
+
// ]
|
652
|
+
// }
|
653
|
+
//
|
654
|
+
// #[getter]
|
655
|
+
// fn x(&self) -> f64 {
|
656
|
+
// self.inner.x
|
657
|
+
// }
|
658
|
+
//
|
659
|
+
// #[getter]
|
660
|
+
// fn y(&self) -> f64 {
|
661
|
+
// self.inner.y
|
662
|
+
// }
|
663
|
+
//
|
664
|
+
// #[getter]
|
665
|
+
// fn z(&self) -> f64 {
|
666
|
+
// self.inner.z
|
667
|
+
// }
|
668
|
+
//
|
669
|
+
// #[getter]
|
670
|
+
// fn w(&self) -> f64 {
|
671
|
+
// self.inner.w
|
672
|
+
// }
|
673
|
+
//
|
674
|
+
// #[getter]
|
675
|
+
// fn p(&self) -> f64 {
|
676
|
+
// self.inner.p
|
677
|
+
// }
|
678
|
+
//
|
679
|
+
// #[getter]
|
680
|
+
// fn r(&self) -> f64 {
|
681
|
+
// self.inner.r
|
682
|
+
// }
|
683
|
+
// }
|
684
|
+
|
617
685
|
#[derive(FromPyObject)]
|
618
686
|
enum Transformable3 {
|
619
687
|
Iso(Iso3),
|
@@ -654,6 +722,27 @@ impl Iso3 {
|
|
654
722
|
)
|
655
723
|
}
|
656
724
|
|
725
|
+
#[getter]
|
726
|
+
fn origin(&self) -> Point3 {
|
727
|
+
Point3::from_inner(engeom::Point3::new(
|
728
|
+
self.inner.translation.x,
|
729
|
+
self.inner.translation.y,
|
730
|
+
self.inner.translation.z,
|
731
|
+
))
|
732
|
+
}
|
733
|
+
|
734
|
+
#[staticmethod]
|
735
|
+
fn from_xyzwpr(x: f64, y: f64, z: f64, w: f64, p: f64, r: f64) -> Self {
|
736
|
+
Self {
|
737
|
+
inner: engeom::geom3::XyzWpr::new(x, y, z, w, p, r).to_isometry(),
|
738
|
+
}
|
739
|
+
}
|
740
|
+
|
741
|
+
fn to_xyzwpr(&self) -> Vec<f64> {
|
742
|
+
let v = engeom::geom3::XyzWpr::from_isometry(&self.inner);
|
743
|
+
vec![v.x, v.y, v.z, v.w, v.p, v.r]
|
744
|
+
}
|
745
|
+
|
657
746
|
#[new]
|
658
747
|
fn new(matrix: PyReadonlyArrayDyn<'_, f64>) -> PyResult<Self> {
|
659
748
|
if matrix.shape().len() != 2 || matrix.shape()[0] != 4 || matrix.shape()[1] != 4 {
|
@@ -769,13 +858,13 @@ impl Iso3 {
|
|
769
858
|
|
770
859
|
fn translation(&self) -> Iso3 {
|
771
860
|
Self {
|
772
|
-
inner: engeom::Iso3::from_parts(self.inner.translation, UnitQuaternion::identity())
|
861
|
+
inner: engeom::Iso3::from_parts(self.inner.translation, UnitQuaternion::identity()),
|
773
862
|
}
|
774
863
|
}
|
775
864
|
|
776
865
|
fn rotation(&self) -> Iso3 {
|
777
866
|
Self {
|
778
|
-
inner: engeom::Iso3::from_parts(Translation3::identity(), self.inner.rotation)
|
867
|
+
inner: engeom::Iso3::from_parts(Translation3::identity(), self.inner.rotation),
|
779
868
|
}
|
780
869
|
}
|
781
870
|
|