engeom 0.2.5__tar.gz → 0.2.7__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.
Files changed (155) hide show
  1. {engeom-0.2.5 → engeom-0.2.7}/Cargo.lock +1 -1
  2. {engeom-0.2.5 → engeom-0.2.7}/Cargo.toml +1 -1
  3. {engeom-0.2.5 → engeom-0.2.7}/PKG-INFO +1 -1
  4. engeom-0.2.7/docs/api/airfoil.md +3 -0
  5. engeom-0.2.7/docs/api/engeom.md +5 -0
  6. engeom-0.2.7/docs/api/geom2.md +3 -0
  7. engeom-0.2.7/docs/api/geom3.md +4 -0
  8. engeom-0.2.7/docs/api/metrology.md +9 -0
  9. engeom-0.2.7/docs/api/plot.md +15 -0
  10. {engeom-0.2.5 → engeom-0.2.7}/docs/metrology.md +0 -1
  11. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/airfoil/camber.rs +26 -17
  12. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/airfoil.rs +7 -7
  13. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/func1/series1.rs +1 -1
  14. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh/measurement.rs +3 -3
  15. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/lib.rs +1 -0
  16. engeom-0.2.7/engeom/src/metrology/dimension.rs +97 -0
  17. engeom-0.2.7/engeom/src/metrology.rs +58 -0
  18. engeom-0.2.7/engeom/src/raster3.rs +60 -0
  19. {engeom-0.2.5 → engeom-0.2.7}/mkdocs.yml +15 -0
  20. engeom-0.2.7/python/engeom/_plot/__init__.py +1 -0
  21. engeom-0.2.7/python/engeom/_plot/common.py +17 -0
  22. {engeom-0.2.5/python/engeom → engeom-0.2.7/python/engeom/_plot}/matplotlib.py +88 -45
  23. engeom-0.2.7/python/engeom/_plot/pyvista.py +256 -0
  24. {engeom-0.2.5 → engeom-0.2.7}/python/engeom/airfoil/__init__.py +4 -0
  25. engeom-0.2.7/python/engeom/airfoil.pyi +485 -0
  26. engeom-0.2.7/python/engeom/engeom.pyi +46 -0
  27. engeom-0.2.7/python/engeom/geom2/__init__.py +10 -0
  28. {engeom-0.2.5 → engeom-0.2.7}/python/engeom/geom2.pyi +323 -85
  29. engeom-0.2.7/python/engeom/geom3/__init__.py +10 -0
  30. {engeom-0.2.5 → engeom-0.2.7}/python/engeom/geom3.pyi +406 -117
  31. {engeom-0.2.5 → engeom-0.2.7}/python/engeom/metrology/__init__.py +4 -0
  32. engeom-0.2.7/python/engeom/metrology.pyi +137 -0
  33. engeom-0.2.7/python/engeom/plot.py +26 -0
  34. engeom-0.2.7/python/engeom/raster3/__init__.py +9 -0
  35. engeom-0.2.7/python/engeom/raster3.pyi +19 -0
  36. {engeom-0.2.5 → engeom-0.2.7}/src/airfoil.rs +5 -5
  37. {engeom-0.2.5 → engeom-0.2.7}/src/geom2.rs +8 -0
  38. {engeom-0.2.5 → engeom-0.2.7}/src/lib.rs +15 -3
  39. {engeom-0.2.5 → engeom-0.2.7}/src/mesh.rs +20 -11
  40. {engeom-0.2.5 → engeom-0.2.7}/src/metrology.rs +25 -17
  41. engeom-0.2.7/src/raster.rs +40 -0
  42. engeom-0.2.5/engeom/src/metrology/dimension.rs +0 -45
  43. engeom-0.2.5/engeom/src/metrology.rs +0 -18
  44. engeom-0.2.5/python/engeom/airfoil.pyi +0 -334
  45. engeom-0.2.5/python/engeom/engeom.pyi +0 -13
  46. engeom-0.2.5/python/engeom/geom2/__init__.py +0 -5
  47. engeom-0.2.5/python/engeom/geom3/__init__.py +0 -5
  48. engeom-0.2.5/python/engeom/metrology.pyi +0 -64
  49. engeom-0.2.5/python/engeom/pyvista.py +0 -178
  50. {engeom-0.2.5 → engeom-0.2.7}/.github/workflows/CI.yml +0 -0
  51. {engeom-0.2.5 → engeom-0.2.7}/.gitignore +0 -0
  52. {engeom-0.2.5 → engeom-0.2.7}/.gitmodules +0 -0
  53. {engeom-0.2.5 → engeom-0.2.7}/README.md +0 -0
  54. {engeom-0.2.5 → engeom-0.2.7}/docs/airfoils/intro.md +0 -0
  55. {engeom-0.2.5 → engeom-0.2.7}/docs/bounding_volumes.md +0 -0
  56. {engeom-0.2.5 → engeom-0.2.7}/docs/curves.md +0 -0
  57. {engeom-0.2.5 → engeom-0.2.7}/docs/images/surface_point_meas.svg +0 -0
  58. {engeom-0.2.5 → engeom-0.2.7}/docs/index.md +0 -0
  59. {engeom-0.2.5 → engeom-0.2.7}/docs/isometries.md +0 -0
  60. {engeom-0.2.5 → engeom-0.2.7}/docs/meshes.md +0 -0
  61. {engeom-0.2.5 → engeom-0.2.7}/docs/numpy.md +0 -0
  62. {engeom-0.2.5 → engeom-0.2.7}/docs/planes_circles_lines.md +0 -0
  63. {engeom-0.2.5 → engeom-0.2.7}/docs/points_vectors.md +0 -0
  64. {engeom-0.2.5 → engeom-0.2.7}/docs/surf_points.md +0 -0
  65. {engeom-0.2.5 → engeom-0.2.7}/docs/svd_basis.md +0 -0
  66. {engeom-0.2.5 → engeom-0.2.7}/engeom/.gitignore +0 -0
  67. {engeom-0.2.5 → engeom-0.2.7}/engeom/Cargo.lock +0 -0
  68. {engeom-0.2.5 → engeom-0.2.7}/engeom/Cargo.toml +0 -0
  69. {engeom-0.2.5 → engeom-0.2.7}/engeom/README.md +0 -0
  70. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/airfoils/camber.md +0 -0
  71. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/airfoils/overview.md +0 -0
  72. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/common/angles.md +0 -0
  73. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/common/core_space.md +0 -0
  74. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/common/discrete_domain.md +0 -0
  75. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/common/images/surface_point_meas.svg +0 -0
  76. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/common/svd_basis.md +0 -0
  77. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/geom2/alignment.md +0 -0
  78. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/geom2/curve.md +0 -0
  79. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/geom2/point_collections.md +0 -0
  80. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/geom2/shapes.md +0 -0
  81. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/index.md +0 -0
  82. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/javascripts/mathjax.js +0 -0
  83. {engeom-0.2.5 → engeom-0.2.7}/engeom/docs/python_rust.md +0 -0
  84. {engeom-0.2.5 → engeom-0.2.7}/engeom/mkdocs.yml +0 -0
  85. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/airfoil/edges.rs +0 -0
  86. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/airfoil/helpers.rs +0 -0
  87. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/airfoil/inscribed_circle.rs +0 -0
  88. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/airfoil/orientation.rs +0 -0
  89. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/align.rs +0 -0
  90. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/angles.rs +0 -0
  91. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/convert_2d_3d.rs +0 -0
  92. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/discrete_domain.rs +0 -0
  93. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/indices.rs +0 -0
  94. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/interval.rs +0 -0
  95. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/kd_tree.rs +0 -0
  96. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/points.rs +0 -0
  97. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/poisson_disk.rs +0 -0
  98. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/surface_point.rs +0 -0
  99. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/svd_basis.rs +0 -0
  100. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common/vec_f64.rs +0 -0
  101. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/common.rs +0 -0
  102. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/errors.rs +0 -0
  103. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/func1/common_functions.rs +0 -0
  104. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/func1/polynomial.rs +0 -0
  105. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/func1.rs +0 -0
  106. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/aabb2.rs +0 -0
  107. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/align2/jacobian.rs +0 -0
  108. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/align2/points_to_curve.rs +0 -0
  109. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/align2/rc_params2.rs +0 -0
  110. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/align2.rs +0 -0
  111. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/angles2.rs +0 -0
  112. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/circle2.rs +0 -0
  113. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/curve2.rs +0 -0
  114. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/hull.rs +0 -0
  115. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/line2.rs +0 -0
  116. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2/polyline2.rs +0 -0
  117. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom2.rs +0 -0
  118. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/align3/jacobian.rs +0 -0
  119. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/align3/multi_param.rs +0 -0
  120. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/align3/points_to_mesh.rs +0 -0
  121. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/align3/rotations.rs +0 -0
  122. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/align3.rs +0 -0
  123. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/curve3.rs +0 -0
  124. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh/conformal.rs +0 -0
  125. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh/edges.rs +0 -0
  126. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh/faces.rs +0 -0
  127. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh/filtering.rs +0 -0
  128. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh/patches.rs +0 -0
  129. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh/queries.rs +0 -0
  130. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh/sampling.rs +0 -0
  131. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh/uv_mapping.rs +0 -0
  132. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/mesh.rs +0 -0
  133. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/plane3.rs +0 -0
  134. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3/point_cloud.rs +0 -0
  135. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/geom3.rs +0 -0
  136. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/io.rs +0 -0
  137. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/metrology/line_profiles.rs +0 -0
  138. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/metrology/surface_deviation.rs +0 -0
  139. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/metrology/tolerance.rs +0 -0
  140. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/metrology/tolerance_map.rs +0 -0
  141. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/stats.rs +0 -0
  142. {engeom-0.2.5 → engeom-0.2.7}/engeom/src/utility.rs +0 -0
  143. {engeom-0.2.5 → engeom-0.2.7}/pyproject.toml +0 -0
  144. {engeom-0.2.5 → engeom-0.2.7}/python/engeom/__init__.py +0 -0
  145. {engeom-0.2.5 → engeom-0.2.7}/python/engeom/align/__init__.py +0 -0
  146. {engeom-0.2.5 → engeom-0.2.7}/python/engeom/align.pyi +0 -0
  147. {engeom-0.2.5 → engeom-0.2.7}/python/tests/test_all.py +0 -0
  148. {engeom-0.2.5 → engeom-0.2.7}/python/tests/test_geom2_simple.py +0 -0
  149. {engeom-0.2.5 → engeom-0.2.7}/python/tests/test_geom3_simple.py +0 -0
  150. {engeom-0.2.5 → engeom-0.2.7}/src/alignments.rs +0 -0
  151. {engeom-0.2.5 → engeom-0.2.7}/src/bounding.rs +0 -0
  152. {engeom-0.2.5 → engeom-0.2.7}/src/common.rs +0 -0
  153. {engeom-0.2.5 → engeom-0.2.7}/src/conversions.rs +0 -0
  154. {engeom-0.2.5 → engeom-0.2.7}/src/geom3.rs +0 -0
  155. {engeom-0.2.5 → engeom-0.2.7}/src/svd_basis.rs +1 -1
@@ -1024,7 +1024,7 @@ dependencies = [
1024
1024
 
1025
1025
  [[package]]
1026
1026
  name = "py-engeom"
1027
- version = "0.2.5"
1027
+ version = "0.2.7"
1028
1028
  dependencies = [
1029
1029
  "engeom",
1030
1030
  "numpy",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "py-engeom"
3
- version = "0.2.5"
3
+ version = "0.2.7"
4
4
  edition = "2021"
5
5
 
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: engeom
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -0,0 +1,3 @@
1
+ # Airfoil Module
2
+
3
+ ::: engeom.airfoil
@@ -0,0 +1,5 @@
1
+ # Engeom
2
+
3
+ The `engeom` main module has a handful of common entities shared across other parts of the library.
4
+
5
+ ::: engeom
@@ -0,0 +1,3 @@
1
+ # Geom2 Module
2
+
3
+ ::: engeom.geom2
@@ -0,0 +1,4 @@
1
+ # Geom3 Module
2
+
3
+ ::: engeom.geom3
4
+
@@ -0,0 +1,9 @@
1
+ # Metrology Module
2
+
3
+ !!! warning
4
+ The metrology feature set is still experimental and is under heavy development in the Rust `engeom` library.
5
+ Expect significant changes to the API in the future.
6
+
7
+ ::: engeom.metrology
8
+ options:
9
+ show_source: false
@@ -0,0 +1,15 @@
1
+ # Plot Module
2
+
3
+ !!! warning
4
+ This module's API is still under development and will likely change in the future.
5
+
6
+ ::: engeom.plot
7
+ options:
8
+ show_source: false
9
+ members:
10
+ - LabelPlace
11
+ - PyvistaPlotterHelper
12
+ - GOM_CMAP
13
+ - GomColorMap
14
+ - MatplotlibAxesHelper
15
+
@@ -9,4 +9,3 @@
9
9
  The metrology features of the `engeom` library are designed to provide a common set of tools for actual measurements,
10
10
  separate from the geometry tools. For example, measurements like scalar distances, areas, GD&T form and position
11
11
  measurements, and more, will be consolidated as entities and operations in the metrology features.
12
-
@@ -5,39 +5,48 @@ use super::helpers::{
5
5
  };
6
6
  use crate::airfoil::inscribed_circle::InscribedCircle;
7
7
  use crate::common::points::{dist, mid_point};
8
- use crate::common::BestFit;
9
8
  use crate::common::Resample::ByCount;
10
9
  use crate::geom2::hull::farthest_pair_indices;
11
10
  use crate::geom2::polyline2::SpanningRay;
12
- use crate::geom2::{rot90, Line2};
11
+ use crate::geom2::{rot90, Line2, Segment2};
13
12
  use crate::AngleDir::{Ccw, Cw};
13
+ use crate::{Curve2, UnitVec2};
14
14
  use crate::Result;
15
- use crate::{Circle2, Curve2, UnitVec2};
16
15
  use parry2d_f64::query::Ray;
17
16
  use parry2d_f64::shape::ConvexPolygon;
18
17
 
19
18
  /// Given a curve representing a camber line, attempt to detect the direction of the upper
20
- /// (suction, convex) side of the airfoil section. To do so, we will resample the curve to a
21
- /// finite number of points and then best-fit a circle to the points. The circle center should be
22
- /// on the concave (lower, pressure) side of the camber curve, so the direction from the circle
23
- /// center to the center of the camber curve will be the direction of the upper airfoil side.
24
- ///
19
+ /// (suction, convex) side of the airfoil section.
25
20
  /// # Arguments
26
21
  ///
27
22
  /// * `camber_line`: the curve representing the camber line of the airfoil section
28
23
  ///
29
24
  /// returns: Result<Unit<Matrix<f64, Const<2>, Const<1>, ArrayStorage<f64, 2, 1>>>, Box<dyn Error, Global>>
30
25
  pub fn camber_detect_upper_dir(camber_line: &Curve2) -> Result<UnitVec2> {
31
- let mid_point = camber_line.at_fraction(0.5).unwrap().point();
26
+ let check = Segment2::try_new(camber_line.at_front().point(), camber_line.at_back().point())
27
+ .map_err(|_| "Failed to create segment from camber line while detecting face orientation")?;
28
+
32
29
  let resampled = camber_line.resample(ByCount(50))?;
33
- let guess = Circle2::from_3_points(
34
- camber_line.at_front().point(),
35
- mid_point,
36
- camber_line.at_back().point(),
37
- )?;
38
- let circle = Circle2::fitting_circle(resampled.points(), &guess, BestFit::All)?;
39
-
40
- Ok(UnitVec2::new_normalize(mid_point - circle.center))
30
+
31
+ let mut best = 0.0;
32
+ let mut best_point = None;
33
+
34
+ for p in resampled.points() {
35
+ let cp = check.projected_point(p);
36
+ let d = dist(p, &cp);
37
+ if d > best {
38
+ best = d;
39
+ best_point = Some(p);
40
+ }
41
+ }
42
+
43
+ if let Some(point) = best_point {
44
+ let cp = check.projected_point(point);
45
+ let dir = point - cp;
46
+ Ok(UnitVec2::new_normalize(dir))
47
+ } else {
48
+ Err("Failed to find point on camber line for face orientation detection".into())
49
+ }
41
50
  }
42
51
 
43
52
  /// Attempts to calculate and extract the mean camber line from an airfoil section curve and its
@@ -14,7 +14,7 @@ use crate::airfoil::camber::camber_detect_upper_dir;
14
14
  use crate::common::points::dist;
15
15
  use crate::common::Intersection;
16
16
  use crate::geom2::hull::convex_hull_2d;
17
- use crate::metrology::Length2;
17
+ use crate::metrology::Distance2;
18
18
  use crate::stats::compute_mean;
19
19
  pub use camber::extract_camber_line;
20
20
  pub use edges::{
@@ -358,14 +358,14 @@ impl AirfoilGeometry {
358
358
  ///
359
359
  /// * `gage`:
360
360
  ///
361
- /// returns: Result<Length2, Box<dyn Error, Global>>
361
+ /// returns: Result<Distance2, Box<dyn Error, Global>>
362
362
  ///
363
363
  /// # Examples
364
364
  ///
365
365
  /// ```
366
366
  ///
367
367
  /// ```
368
- pub fn get_thickness(&self, gage: AfGage) -> Result<Length2> {
368
+ pub fn get_thickness(&self, gage: AfGage) -> Result<Distance2> {
369
369
  let (upper, lower) = match gage {
370
370
  AfGage::OnCamber(x) => {
371
371
  let l = if x < 0.0 { self.camber.length() + x } else { x };
@@ -463,13 +463,13 @@ impl AirfoilGeometry {
463
463
  }
464
464
  };
465
465
 
466
- Ok(Length2::new(upper, lower, None))
466
+ Ok(Distance2::new(lower, upper, None))
467
467
  }
468
468
 
469
- pub fn get_thickness_max(&self) -> Result<Length2> {
469
+ pub fn get_thickness_max(&self) -> Result<Distance2> {
470
470
  let tmax = self.find_tmax();
471
471
  let (upper, lower) = self.order_points(&tmax.contact_neg, &tmax.contact_pos)?;
472
- Ok(Length2::new(upper, lower, None))
472
+ Ok(Distance2::new(lower, upper, None))
473
473
  }
474
474
 
475
475
  /// Order the points so that the first point returned is on the upper surface and the second
@@ -525,7 +525,7 @@ fn order_faces(
525
525
  // We should have intersections with both curves. If the outline is clean, we will have exactly
526
526
  // one intersection with each, but if not we might have more than one at a similar distance.
527
527
  if a_t.is_empty() || b_t.is_empty() {
528
- Err("Failed to find intersections with the test point".into())
528
+ Err("Failed to find intersections with the test point while ordering faces".into())
529
529
  } else {
530
530
  let a_m = compute_mean(&a_t)?;
531
531
  let b_m = compute_mean(&b_t)?;
@@ -640,7 +640,7 @@ impl Series1 {
640
640
  clusters.push(current);
641
641
  }
642
642
 
643
- // Now go through each cluster and if it is large enough, add all of the indices to the
643
+ // Now go through each cluster and if it is large enough, add all the indices to the
644
644
  // result vector
645
645
  let mut results = Vec::new();
646
646
  for cluster in clusters {
@@ -1,7 +1,7 @@
1
1
  //! This module contains features for taking measurements on meshes
2
2
 
3
3
  use crate::common::DistMode;
4
- use crate::metrology::Length3;
4
+ use crate::metrology::Distance3;
5
5
  use crate::{Mesh, Point3, UnitVec3};
6
6
 
7
7
  impl Mesh {
@@ -33,7 +33,7 @@ impl Mesh {
33
33
  /// ```
34
34
  ///
35
35
  /// ```
36
- pub fn measure_point_deviation(&self, point: &Point3, dist_mode: DistMode) -> Length3 {
36
+ pub fn measure_point_deviation(&self, point: &Point3, dist_mode: DistMode) -> Distance3 {
37
37
  let closest = self.surf_closest_to(point);
38
38
 
39
39
  // In both cases, the measurement point `b` will remain the test point and `a` will be the
@@ -53,6 +53,6 @@ impl Mesh {
53
53
  DistMode::ToPlane => closest.normal,
54
54
  };
55
55
 
56
- Length3::new(closest.point, *point, Some(d))
56
+ Distance3::new(closest.point, *point, Some(d))
57
57
  }
58
58
  }
@@ -10,6 +10,7 @@ pub mod io;
10
10
  pub mod metrology;
11
11
  pub mod stats;
12
12
  pub mod utility;
13
+ pub mod raster3;
13
14
 
14
15
  pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
15
16
 
@@ -0,0 +1,97 @@
1
+ //! This module has representations of different types of dimensions
2
+
3
+ use crate::common::surface_point::SurfacePoint;
4
+ use parry3d_f64::na::{Point, SVector, Unit};
5
+ use crate::common::points::mid_point;
6
+
7
+ pub trait Measurement {
8
+ fn value(&self) -> f64;
9
+ }
10
+
11
+ /// Represents a signed distance between two points in space along a specific direction. The value
12
+ /// of the measurement will be the vector from `a` to `b` projected onto the direction vector,
13
+ /// meaning that the value will be positive if `b` is in the direction of the vector and negative
14
+ /// if `b` is in the opposite direction.
15
+ pub struct Distance<const D: usize> {
16
+ /// The starting point of the distance measurement
17
+ pub a: Point<f64, D>,
18
+
19
+ /// The ending point of the distance measurement
20
+ pub b: Point<f64, D>,
21
+
22
+ /// The direction of the distance measurement
23
+ pub direction: Unit<SVector<f64, D>>,
24
+ }
25
+
26
+ impl<const D: usize> Distance<D> {
27
+ /// Create a new signed distance measurement between two points in space along a specific
28
+ /// direction. The value of the measurement will be the vector from `a` to `b` projected onto
29
+ /// the direction vector, meaning that the value will be positive if `b - a` is in the
30
+ /// direction of the vector and negative if not.
31
+ ///
32
+ /// # Arguments
33
+ ///
34
+ /// * `a`: The start point of the distance measurement
35
+ /// * `b`: The end point of the distance measurement
36
+ /// * `direction`: A unit vector representing the direction of the distance measurement. The
37
+ /// default value is `None`, in which case the direction will be calculated as the normalized
38
+ /// vector from `a` to `b`, resulting in a positive value with the full magnitude of the
39
+ /// distance between the two points.
40
+ ///
41
+ /// returns: Distance<{ D }>
42
+ ///
43
+ /// # Examples
44
+ ///
45
+ /// ```
46
+ /// use engeom::{Point2, UnitVec2, Vector2};
47
+ /// use engeom::metrology::{Distance2, Measurement};
48
+ /// use approx::assert_relative_eq;
49
+ ///
50
+ /// let a = Point2::new(0.0, 0.0);
51
+ /// let b = Point2::new(1.0, 1.0);
52
+ ///
53
+ /// let d1 = Distance2::new(a, b, None);
54
+ /// let d2 = Distance2::new(b, a, None);
55
+ ///
56
+ /// assert_relative_eq!(d1.value(), 2_f64.sqrt());
57
+ /// assert_relative_eq!(d2.value(), 2_f64.sqrt());
58
+ ///
59
+ /// let dir = UnitVec2::new_unchecked(Vector2::x());
60
+ /// let d3 = Distance2::new(a, b, Some(dir));
61
+ /// let d4 = Distance2::new(b, a, Some(dir));
62
+ ///
63
+ /// assert_relative_eq!(d3.value(), 1.0);
64
+ /// assert_relative_eq!(d4.value(), -1.0);
65
+ /// ```
66
+ pub fn new(
67
+ a: Point<f64, D>,
68
+ b: Point<f64, D>,
69
+ direction: Option<Unit<SVector<f64, D>>>,
70
+ ) -> Self {
71
+ let direction = direction.unwrap_or(Unit::new_normalize(b - a));
72
+ Self { a, b, direction }
73
+ }
74
+
75
+ /// Reverse the distance measurement by swapping start and end points and flipping the direction
76
+ /// of measurement. The value and sign of the measurement will be the same after the operation,
77
+ /// but the points will have been swapped.
78
+ pub fn reversed(&self) -> Self {
79
+ Self {
80
+ a: self.b,
81
+ b: self.a,
82
+ direction: -self.direction,
83
+ }
84
+ }
85
+
86
+ /// Compute a SurfacePoint that is located halfway between point `a` and `b` and whose normal
87
+ /// vector is the direction of the distance measurement.
88
+ pub fn center(&self) -> SurfacePoint<D> {
89
+ SurfacePoint::new(mid_point(&self.a, &self.b), self.direction)
90
+ }
91
+ }
92
+
93
+ impl<const D: usize> Measurement for Distance<D> {
94
+ fn value(&self) -> f64 {
95
+ self.direction.dot(&(self.b - self.a))
96
+ }
97
+ }
@@ -0,0 +1,58 @@
1
+ mod dimension;
2
+ pub mod line_profiles;
3
+ mod surface_deviation;
4
+ mod tolerance;
5
+ mod tolerance_map;
6
+
7
+ pub use tolerance::Tolerance;
8
+ pub use tolerance_map::{ConstantTolMap, DiscreteDomainTolMap, ToleranceMap};
9
+
10
+ pub use dimension::Measurement;
11
+ use crate::{Iso3, To2D, To3D};
12
+
13
+ pub type SurfaceDeviation2 = surface_deviation::SurfaceDeviation<2>;
14
+ pub type SurfaceDeviationSet2 = surface_deviation::SurfaceDeviationSet<2>;
15
+ pub type SurfaceDeviation3 = surface_deviation::SurfaceDeviation<3>;
16
+ pub type SurfaceDeviationSet3 = surface_deviation::SurfaceDeviationSet<3>;
17
+
18
+ pub type Distance2 = dimension::Distance<2>;
19
+ pub type Distance3 = dimension::Distance<3>;
20
+
21
+
22
+ // Conversions between 2D and 3D distances
23
+ impl Distance2 {
24
+ /// Convert a 2D distance to a 3D distance using an isometry transformation. The 2D distance
25
+ /// is converted to 3D by adding a zero z-component, and then it is transformed by the provided
26
+ /// isometry to move it to some other location in 3D space.
27
+ ///
28
+ /// # Arguments
29
+ ///
30
+ /// * `iso`: The isometry transformation to apply to the 2D distance
31
+ ///
32
+ /// returns: Distance<3>
33
+ pub fn to_3d(&self, iso: &Iso3) -> Distance3 {
34
+ let a = iso * self.a.to_3d();
35
+ let b = iso * self.b.to_3d();
36
+ let direction = iso * self.direction.to_3d();
37
+ Distance3::new(a, b, Some(direction))
38
+ }
39
+ }
40
+
41
+ impl Distance3 {
42
+ /// Convert a 3D distance to a 2D distance using an isometry transformation. The 3D distance
43
+ /// is first transformed by the provided isometry, and then it is converted to 2D by dropping
44
+ /// the z-component.
45
+ ///
46
+ /// # Arguments
47
+ ///
48
+ /// * `iso`: The isometry transformation to apply to the 3D distance before dropping the
49
+ /// z-component
50
+ ///
51
+ /// returns: Distance<2>
52
+ pub fn to_2d(&self, iso: &Iso3) -> Distance2 {
53
+ let a = (iso * self.a).to_2d();
54
+ let b = (iso * self.b).to_2d();
55
+ let direction = (iso * self.direction).to_2d();
56
+ Distance2::new(a, b, Some(direction))
57
+ }
58
+ }
@@ -0,0 +1,60 @@
1
+ //! This module contains tools for working with 3D voxel grids.
2
+
3
+
4
+ use std::collections::HashSet;
5
+
6
+
7
+ /// This function takes a set of coordinates in a 3D grid and returns a list of clusters of
8
+ /// connected voxel coordinates.
9
+ ///
10
+ /// # Arguments
11
+ ///
12
+ /// * `indices`:
13
+ ///
14
+ /// returns: Vec<Vec<(u32, u32, u32), Global>, Global>
15
+ ///
16
+ /// # Examples
17
+ ///
18
+ /// ```
19
+ ///
20
+ /// ```
21
+ pub fn clusters_from_sparse(mut indices: HashSet<(i32, i32, i32)>) -> Vec<Vec<(i32, i32, i32)>> {
22
+ let mut results = Vec::new();
23
+
24
+ while !indices.is_empty() {
25
+ let mut working = Vec::new();
26
+ let mut to_visit = Vec::new();
27
+
28
+ to_visit.push(pop_index(&mut indices));
29
+
30
+ while !to_visit.is_empty() {
31
+ let current = to_visit.pop().unwrap();
32
+ working.push(current);
33
+
34
+ for x in -1..=1 {
35
+ for y in -1..=1 {
36
+ for z in -1..=1 {
37
+ if x == 0 && y == 0 && z == 0 {
38
+ continue;
39
+ }
40
+
41
+ let neighbor = (current.0 + x, current.1 + y, current.2 + z);
42
+ if indices.remove(&neighbor) {
43
+ to_visit.push(neighbor);
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+
50
+ results.push(working.into_iter().collect());
51
+ }
52
+
53
+ results
54
+ }
55
+
56
+ fn pop_index(indices: &mut HashSet<(i32, i32, i32)>) -> (i32, i32, i32) {
57
+ let result = indices.iter().next().unwrap().clone();
58
+ indices.remove(&result);
59
+ result
60
+ }
@@ -17,6 +17,13 @@ nav:
17
17
  - Airfoils:
18
18
  - Introduction: airfoils/intro.md
19
19
  - Metrology: metrology.md
20
+ - API Reference:
21
+ - Common: api/engeom.md
22
+ - Geom2: api/geom2.md
23
+ - Geom3: api/geom3.md
24
+ - Metrology: api/metrology.md
25
+ - Airfoil: api/airfoil.md
26
+ - Plot: api/plot.md
20
27
 
21
28
  markdown_extensions:
22
29
  - pymdownx.arithmatex:
@@ -34,6 +41,14 @@ markdown_extensions:
34
41
  - pymdownx.superfences
35
42
  - admonition
36
43
 
44
+ plugins:
45
+ - mkdocstrings:
46
+ handlers:
47
+ python:
48
+ options:
49
+ docstring_style: sphinx
50
+ paths: [python]
51
+
37
52
  extra_javascript:
38
53
  - javascripts/mathjax.js
39
54
  - https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js
@@ -0,0 +1 @@
1
+ from .common import LabelPlace
@@ -0,0 +1,17 @@
1
+ from enum import Enum
2
+
3
+ class LabelPlace(Enum):
4
+ """
5
+ Represents the different locations where a label can be placed between its anchor points.
6
+ """
7
+
8
+ Outside = 1
9
+ """ The label is placed outside the anchor points, on the side of the second point in the measurement. """
10
+
11
+ Inside = 2
12
+ """ The label is placed between the two anchor points. """
13
+
14
+ OutsideRev = 3
15
+ """ The label is placed outside the two anchor points, on the side of the first point in the measurement. """
16
+
17
+