From 313ed54f858ab667380088863e48d682b271f3f5 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 24 Jul 2026 18:56:22 +0200 Subject: [PATCH 1/6] Rename `float` module to `generic` We will support both integer and float coordinates. --- editor/src/draw/path.rs | 4 ++-- editor/src/mesh/path_builder.rs | 2 +- iTriangle/src/{float => generic}/builder.rs | 2 +- iTriangle/src/{float => generic}/centroid_net.rs | 2 +- iTriangle/src/{float => generic}/circumcenter.rs | 2 +- iTriangle/src/{float => generic}/convex.rs | 2 +- iTriangle/src/{float => generic}/custom.rs | 2 +- iTriangle/src/{float => generic}/delaunay.rs | 2 +- iTriangle/src/{float => generic}/locator.rs | 4 ++-- iTriangle/src/{float => generic}/mod.rs | 0 iTriangle/src/{float => generic}/triangulatable.rs | 2 +- iTriangle/src/{float => generic}/triangulation.rs | 2 +- iTriangle/src/{float => generic}/triangulator.rs | 2 +- iTriangle/src/{float => generic}/unchecked.rs | 2 +- iTriangle/src/lib.rs | 2 +- iTriangle/tests/doc_tests.rs | 6 +++--- iTriangle/tests/float_tests.rs | 6 +++--- performance/rust_app/src/test/runner.rs | 4 ++-- 18 files changed, 24 insertions(+), 24 deletions(-) rename iTriangle/src/{float => generic}/builder.rs (96%) rename iTriangle/src/{float => generic}/centroid_net.rs (94%) rename iTriangle/src/{float => generic}/circumcenter.rs (96%) rename iTriangle/src/{float => generic}/convex.rs (93%) rename iTriangle/src/{float => generic}/custom.rs (99%) rename iTriangle/src/{float => generic}/delaunay.rs (96%) rename iTriangle/src/{float => generic}/locator.rs (96%) rename iTriangle/src/{float => generic}/mod.rs (100%) rename iTriangle/src/{float => generic}/triangulatable.rs (99%) rename iTriangle/src/{float => generic}/triangulation.rs (99%) rename iTriangle/src/{float => generic}/triangulator.rs (99%) rename iTriangle/src/{float => generic}/unchecked.rs (99%) diff --git a/editor/src/draw/path.rs b/editor/src/draw/path.rs index 964f3a4..544552d 100644 --- a/editor/src/draw/path.rs +++ b/editor/src/draw/path.rs @@ -1,7 +1,7 @@ use i_mesh::path::butt::ButtStrokeBuilder; use i_mesh::path::style::StrokeStyle; -use i_triangle::float::builder::TriangulationBuilder; -use i_triangle::float::triangulation::Triangulation; +use i_triangle::generic::builder::TriangulationBuilder; +use i_triangle::generic::triangulation::Triangulation; use i_triangle::i_overlay::i_float::float::point::FloatPoint; use i_triangle::i_overlay::i_float::int::point::IntPoint; use i_triangle::i_overlay::i_shape::int::path::{IntPath, IntPaths}; diff --git a/editor/src/mesh/path_builder.rs b/editor/src/mesh/path_builder.rs index bef8d9b..88f90bf 100644 --- a/editor/src/mesh/path_builder.rs +++ b/editor/src/mesh/path_builder.rs @@ -1,6 +1,6 @@ use i_mesh::path::butt::ButtStrokeBuilder; use i_mesh::path::style::StrokeStyle; -use i_triangle::float::builder::TriangulationBuilder; +use i_triangle::generic::builder::TriangulationBuilder; use i_triangle::i_overlay::i_float::float::point::FloatPoint; use i_triangle::i_overlay::i_float::int::point::IntPoint; use iced::{Color, Rectangle, Transformation}; diff --git a/iTriangle/src/float/builder.rs b/iTriangle/src/generic/builder.rs similarity index 96% rename from iTriangle/src/float/builder.rs rename to iTriangle/src/generic/builder.rs index 68814f3..54491a3 100644 --- a/iTriangle/src/float/builder.rs +++ b/iTriangle/src/generic/builder.rs @@ -1,4 +1,4 @@ -use crate::float::triangulation::Triangulation; +use crate::generic::triangulation::Triangulation; use crate::int::triangulation::IndexType; use alloc::vec::Vec; diff --git a/iTriangle/src/float/centroid_net.rs b/iTriangle/src/generic/centroid_net.rs similarity index 94% rename from iTriangle/src/float/centroid_net.rs rename to iTriangle/src/generic/centroid_net.rs index 92c3191..700a123 100644 --- a/iTriangle/src/float/centroid_net.rs +++ b/iTriangle/src/generic/centroid_net.rs @@ -1,4 +1,4 @@ -use crate::float::delaunay::Delaunay; +use crate::generic::delaunay::Delaunay; use alloc::vec::Vec; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::int::number::int::IntNumber; diff --git a/iTriangle/src/float/circumcenter.rs b/iTriangle/src/generic/circumcenter.rs similarity index 96% rename from iTriangle/src/float/circumcenter.rs rename to iTriangle/src/generic/circumcenter.rs index ea62256..9bbafd0 100644 --- a/iTriangle/src/float/circumcenter.rs +++ b/iTriangle/src/generic/circumcenter.rs @@ -1,4 +1,4 @@ -use crate::float::delaunay::Delaunay; +use crate::generic::delaunay::Delaunay; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::int::number::int::IntNumber; use i_overlay::i_float::int::number::wide_int::WideIntNumber; diff --git a/iTriangle/src/float/convex.rs b/iTriangle/src/generic/convex.rs similarity index 93% rename from iTriangle/src/float/convex.rs rename to iTriangle/src/generic/convex.rs index 4fd3ac1..38944d4 100644 --- a/iTriangle/src/float/convex.rs +++ b/iTriangle/src/generic/convex.rs @@ -1,4 +1,4 @@ -use crate::float::delaunay::Delaunay; +use crate::generic::delaunay::Delaunay; use alloc::vec::Vec; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::int::number::int::IntNumber; diff --git a/iTriangle/src/float/custom.rs b/iTriangle/src/generic/custom.rs similarity index 99% rename from iTriangle/src/float/custom.rs rename to iTriangle/src/generic/custom.rs index 3925327..01b15ec 100644 --- a/iTriangle/src/float/custom.rs +++ b/iTriangle/src/generic/custom.rs @@ -1,4 +1,4 @@ -use crate::float::triangulation::RawTriangulation; +use crate::generic::triangulation::RawTriangulation; use crate::int::custom::IntCustomTriangulatable; use crate::int::triangulation::RawIntTriangulation; use crate::int::validation::Validation; diff --git a/iTriangle/src/float/delaunay.rs b/iTriangle/src/generic/delaunay.rs similarity index 96% rename from iTriangle/src/float/delaunay.rs rename to iTriangle/src/generic/delaunay.rs index 6a31a62..daa5b66 100644 --- a/iTriangle/src/float/delaunay.rs +++ b/iTriangle/src/generic/delaunay.rs @@ -1,6 +1,6 @@ use crate::advanced::buffer::DelaunayBuffer; use crate::advanced::delaunay::IntDelaunay; -use crate::float::triangulation::{RawTriangulation, Triangulation}; +use crate::generic::triangulation::{RawTriangulation, Triangulation}; use crate::int::triangulation::IndexType; use alloc::vec::Vec; use i_overlay::i_float::adapter::FloatPointAdapter; diff --git a/iTriangle/src/float/locator.rs b/iTriangle/src/generic/locator.rs similarity index 96% rename from iTriangle/src/float/locator.rs rename to iTriangle/src/generic/locator.rs index dc3012f..084abde 100644 --- a/iTriangle/src/float/locator.rs +++ b/iTriangle/src/generic/locator.rs @@ -7,7 +7,7 @@ use i_overlay::{i_float::adapter::FloatPointAdapter, i_shape::float::adapter::Pa use crate::int::locator::IntPointInTriangulationLocator; use crate::{ - float::triangulation::Triangulation, int::triangulation::IndexType, + generic::triangulation::Triangulation, int::triangulation::IndexType, location::PointLocationInTriangulation, }; @@ -60,7 +60,7 @@ mod tests { use alloc::vec; use crate::{ - float::triangulation::Triangulation, + generic::triangulation::Triangulation, location::{PointLocationInTriangulation, TriangleIndex}, }; diff --git a/iTriangle/src/float/mod.rs b/iTriangle/src/generic/mod.rs similarity index 100% rename from iTriangle/src/float/mod.rs rename to iTriangle/src/generic/mod.rs diff --git a/iTriangle/src/float/triangulatable.rs b/iTriangle/src/generic/triangulatable.rs similarity index 99% rename from iTriangle/src/float/triangulatable.rs rename to iTriangle/src/generic/triangulatable.rs index 32c057f..a572dde 100644 --- a/iTriangle/src/float/triangulatable.rs +++ b/iTriangle/src/generic/triangulatable.rs @@ -1,4 +1,4 @@ -use crate::float::triangulation::RawTriangulation; +use crate::generic::triangulation::RawTriangulation; use crate::int::triangulatable::IntTriangulatable; use crate::int::triangulation::RawIntTriangulation; use i_key_sort::sort::key::SortKey; diff --git a/iTriangle/src/float/triangulation.rs b/iTriangle/src/generic/triangulation.rs similarity index 99% rename from iTriangle/src/float/triangulation.rs rename to iTriangle/src/generic/triangulation.rs index 822eba7..705cad1 100644 --- a/iTriangle/src/float/triangulation.rs +++ b/iTriangle/src/generic/triangulation.rs @@ -175,7 +175,7 @@ impl Triangulation { #[cfg(test)] mod tests { - use crate::float::triangulator::Triangulator; + use crate::generic::triangulator::Triangulator; #[test] fn test_0() { diff --git a/iTriangle/src/float/triangulator.rs b/iTriangle/src/generic/triangulator.rs similarity index 99% rename from iTriangle/src/float/triangulator.rs rename to iTriangle/src/generic/triangulator.rs index c6def4d..e00c131 100644 --- a/iTriangle/src/float/triangulator.rs +++ b/iTriangle/src/generic/triangulator.rs @@ -1,4 +1,4 @@ -use crate::float::triangulation::Triangulation; +use crate::generic::triangulation::Triangulation; use crate::int::triangulation::{IndexType, IntTriangulation}; use crate::int::triangulator::IntTriangulator; use crate::int::validation::Validation; diff --git a/iTriangle/src/float/unchecked.rs b/iTriangle/src/generic/unchecked.rs similarity index 99% rename from iTriangle/src/float/unchecked.rs rename to iTriangle/src/generic/unchecked.rs index 4356aaa..3c394c5 100644 --- a/iTriangle/src/float/unchecked.rs +++ b/iTriangle/src/generic/unchecked.rs @@ -1,4 +1,4 @@ -use crate::float::triangulation::RawTriangulation; +use crate::generic::triangulation::RawTriangulation; use crate::int::triangulation::RawIntTriangulation; use crate::int::unchecked::IntUncheckedTriangulatable; use i_key_sort::sort::key::SortKey; diff --git a/iTriangle/src/lib.rs b/iTriangle/src/lib.rs index 8bb0e90..e8f5af6 100644 --- a/iTriangle/src/lib.rs +++ b/iTriangle/src/lib.rs @@ -2,7 +2,7 @@ extern crate alloc; pub mod advanced; -pub mod float; +pub mod generic; pub mod geom; mod index; pub mod int; diff --git a/iTriangle/tests/doc_tests.rs b/iTriangle/tests/doc_tests.rs index 727c9f8..8ad432c 100644 --- a/iTriangle/tests/doc_tests.rs +++ b/iTriangle/tests/doc_tests.rs @@ -1,9 +1,9 @@ #[cfg(test)] mod tests { use i_overlay::i_shape::base::data::Contour; - use i_triangle::float::triangulatable::Triangulatable; - use i_triangle::float::triangulation::Triangulation; - use i_triangle::float::triangulator::Triangulator; + use i_triangle::generic::triangulatable::Triangulatable; + use i_triangle::generic::triangulation::Triangulation; + use i_triangle::generic::triangulator::Triangulator; use rand::RngExt; #[test] diff --git a/iTriangle/tests/float_tests.rs b/iTriangle/tests/float_tests.rs index 9d372e6..1ffe892 100644 --- a/iTriangle/tests/float_tests.rs +++ b/iTriangle/tests/float_tests.rs @@ -7,9 +7,9 @@ mod tests { use i_overlay::i_shape::base::data::Contour; use i_overlay::i_shape::float::area::Area; use i_tree::{Expiration, LayoutNumber}; - use i_triangle::float::triangulatable::Triangulatable; - use i_triangle::float::triangulation::Triangulation; - use i_triangle::float::triangulator::Triangulator; + use i_triangle::generic::triangulatable::Triangulatable; + use i_triangle::generic::triangulation::Triangulation; + use i_triangle::generic::triangulator::Triangulator; use rand::RngExt; trait TestInt: IntNumber + Expiration + LayoutNumber + SortKey {} diff --git a/performance/rust_app/src/test/runner.rs b/performance/rust_app/src/test/runner.rs index ed3e8be..965c02e 100644 --- a/performance/rust_app/src/test/runner.rs +++ b/performance/rust_app/src/test/runner.rs @@ -1,7 +1,7 @@ use std::hint::black_box; use std::time::Instant; -use i_triangle::float::triangulation::Triangulation; -use i_triangle::float::triangulator::Triangulator; +use i_triangle::generic::triangulation::Triangulation; +use i_triangle::generic::triangulator::Triangulator; use i_triangle::i_overlay::i_float::float::compatible::FloatPointCompatible; use i_triangle::i_overlay::i_float::float::number::FloatNumber; use i_triangle::i_overlay::i_shape::source::resource::ShapeResource; From 8488400d7bd889ad642bfd9fbad905e5074ee000 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 24 Jul 2026 19:24:42 +0200 Subject: [PATCH 2/6] Add identity-map adapter for integers to use same interface as floats --- iTriangle/src/generic/adapter.rs | 88 ++++++++++++++++++++++++++++++++ iTriangle/src/generic/mod.rs | 1 + 2 files changed, 89 insertions(+) create mode 100644 iTriangle/src/generic/adapter.rs diff --git a/iTriangle/src/generic/adapter.rs b/iTriangle/src/generic/adapter.rs new file mode 100644 index 0000000..4f7db5c --- /dev/null +++ b/iTriangle/src/generic/adapter.rs @@ -0,0 +1,88 @@ +use alloc::vec::Vec; +use core::marker::PhantomData; +use i_overlay::i_float::adapter::FloatPointAdapter; +use i_overlay::i_float::float::compatible::FloatPointCompatible; +use i_overlay::i_float::int::number::int::IntNumber; +use i_overlay::i_float::int::number::wide_int::WideIntNumber; +use i_overlay::i_float::int::point::IntPoint; + +pub trait PointAdapter: Clone { + type Point: Clone; + type Int: IntNumber; + type Measure: Copy; + + fn to_int_point(&self, point: &Self::Point) -> IntPoint; + fn from_int_point(&self, point: &IntPoint) -> Self::Point; + + fn measure_to_int_area(&self, measure: Self::Measure) -> ::WideUInt; + + #[inline] + fn points_to_int(&self, points: &[Self::Point]) -> Vec> { + points.iter().map(|p| self.to_int_point(p)).collect() + } + + #[inline] + fn points_from_int(&self, points: &[IntPoint]) -> Vec { + points.iter().map(|p| self.from_int_point(p)).collect() + } +} + +#[derive(Debug, Clone, Copy, Default)] +pub struct IntPointAdapter { + marker: PhantomData, +} + +impl IntPointAdapter { + #[inline] + pub const fn new() -> Self { + Self { + marker: PhantomData, + } + } +} + +impl PointAdapter for IntPointAdapter { + type Point = IntPoint; + type Int = I; + type Measure = I::WideUInt; + + #[inline] + fn to_int_point(&self, point: &Self::Point) -> IntPoint { + *point + } + + #[inline] + fn from_int_point(&self, point: &IntPoint) -> Self::Point { + *point + } + + #[inline] + fn measure_to_int_area(&self, measure: Self::Measure) -> I::WideUInt { + measure + } +} + +impl PointAdapter for FloatPointAdapter +where + P: FloatPointCompatible, + I: IntNumber, +{ + type Point = P; + type Int = I; + type Measure = P::Scalar; + + #[inline] + fn to_int_point(&self, point: &P) -> IntPoint { + self.float_to_int(point) + } + + #[inline] + fn from_int_point(&self, point: &IntPoint) -> P { + self.int_to_float(point) + } + + #[inline] + fn measure_to_int_area(&self, measure: P::Scalar) -> I::WideUInt { + self.round_sqr_len_to_int(measure).to_uint() + } +} diff --git a/iTriangle/src/generic/mod.rs b/iTriangle/src/generic/mod.rs index b601b5a..20483f4 100644 --- a/iTriangle/src/generic/mod.rs +++ b/iTriangle/src/generic/mod.rs @@ -1,3 +1,4 @@ +pub mod adapter; pub mod builder; pub mod centroid_net; pub mod circumcenter; From 413dbd0d2fa022945141f837c705cbd907cd4940 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 24 Jul 2026 20:16:42 +0200 Subject: [PATCH 3/6] Make `RawTriangulation` and `Delaunay` take only `A: PointAdapter` Instead of two generics. --- iTriangle/src/generic/centroid_net.rs | 3 ++- iTriangle/src/generic/circumcenter.rs | 3 ++- iTriangle/src/generic/convex.rs | 3 ++- iTriangle/src/generic/custom.rs | 20 +++++++-------- iTriangle/src/generic/delaunay.rs | 33 +++++++++++-------------- iTriangle/src/generic/triangulatable.rs | 20 +++++++-------- iTriangle/src/generic/triangulation.rs | 26 +++++++++---------- iTriangle/src/generic/unchecked.rs | 20 +++++++-------- 8 files changed, 64 insertions(+), 64 deletions(-) diff --git a/iTriangle/src/generic/centroid_net.rs b/iTriangle/src/generic/centroid_net.rs index 700a123..9c639cc 100644 --- a/iTriangle/src/generic/centroid_net.rs +++ b/iTriangle/src/generic/centroid_net.rs @@ -1,12 +1,13 @@ use crate::generic::delaunay::Delaunay; use alloc::vec::Vec; +use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::int::number::int::IntNumber; use i_overlay::i_float::int::number::wide_int::WideIntNumber; use i_overlay::i_shape::base::data::Contour; use i_overlay::i_shape::float::adapter::ShapeToFloat; -impl Delaunay { +impl Delaunay> { #[inline] pub fn to_centroid_net(&self, min_area: P::Scalar) -> Vec> { let int_area = self.adapter.round_sqr_len_to_int(min_area); diff --git a/iTriangle/src/generic/circumcenter.rs b/iTriangle/src/generic/circumcenter.rs index 9bbafd0..f8644c2 100644 --- a/iTriangle/src/generic/circumcenter.rs +++ b/iTriangle/src/generic/circumcenter.rs @@ -1,9 +1,10 @@ use crate::generic::delaunay::Delaunay; +use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::int::number::int::IntNumber; use i_overlay::i_float::int::number::wide_int::WideIntNumber; -impl Delaunay { +impl Delaunay> { #[inline] pub fn refine_with_circumcenters(mut self, min_area: P::Scalar) -> Self { self.refine_with_circumcenters_mut(min_area); diff --git a/iTriangle/src/generic/convex.rs b/iTriangle/src/generic/convex.rs index 38944d4..209943f 100644 --- a/iTriangle/src/generic/convex.rs +++ b/iTriangle/src/generic/convex.rs @@ -1,11 +1,12 @@ use crate::generic::delaunay::Delaunay; use alloc::vec::Vec; +use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::int::number::int::IntNumber; use i_overlay::i_shape::base::data::Contour; use i_overlay::i_shape::float::adapter::ShapeToFloat; -impl Delaunay { +impl Delaunay> { /// Groups triangles into non-overlapping convex polygons in counter-clockwise order. /// /// Returns a list of float-based [`Contour

`]s. diff --git a/iTriangle/src/generic/custom.rs b/iTriangle/src/generic/custom.rs index 01b15ec..41e0051 100644 --- a/iTriangle/src/generic/custom.rs +++ b/iTriangle/src/generic/custom.rs @@ -17,12 +17,12 @@ use i_tree::{Expiration, LayoutNumber}; /// Accepts a custom [`Validation`] object for tuning fill rule, min area, etc. pub trait CustomTriangulatable { /// Performs triangulation using the specified [`Validation`] settings. - fn custom_triangulate(&self, validation: Validation) -> RawTriangulation

{ + fn custom_triangulate(&self, validation: Validation) -> RawTriangulation> { self.custom_triangulate_as(validation) } /// Performs triangulation using the requested integer coordinate type. - fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation + fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey; @@ -31,7 +31,7 @@ pub trait CustomTriangulatable { &self, points: &[P], validation: Validation, - ) -> RawTriangulation

{ + ) -> RawTriangulation> { self.custom_triangulate_with_steiner_points_as(points, validation) } @@ -40,7 +40,7 @@ pub trait CustomTriangulatable { &self, points: &[P], validation: Validation, - ) -> RawTriangulation + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey; } @@ -49,7 +49,7 @@ impl

CustomTriangulatable

for Contour

where P: FloatPointCompatible, { - fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation + fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -69,7 +69,7 @@ where &self, points: &[P], validation: Validation, - ) -> RawTriangulation + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -93,7 +93,7 @@ impl

CustomTriangulatable

for [Contour

] where P: FloatPointCompatible, { - fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation + fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -113,7 +113,7 @@ where &self, points: &[P], validation: Validation, - ) -> RawTriangulation + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -137,7 +137,7 @@ impl

CustomTriangulatable

for [Shape

] where P: FloatPointCompatible, { - fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation + fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -157,7 +157,7 @@ where &self, points: &[P], validation: Validation, - ) -> RawTriangulation + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { diff --git a/iTriangle/src/generic/delaunay.rs b/iTriangle/src/generic/delaunay.rs index daa5b66..bb5a205 100644 --- a/iTriangle/src/generic/delaunay.rs +++ b/iTriangle/src/generic/delaunay.rs @@ -1,31 +1,28 @@ use crate::advanced::buffer::DelaunayBuffer; use crate::advanced::delaunay::IntDelaunay; +use crate::generic::adapter::PointAdapter; use crate::generic::triangulation::{RawTriangulation, Triangulation}; use crate::int::triangulation::IndexType; use alloc::vec::Vec; -use i_overlay::i_float::adapter::FloatPointAdapter; -use i_overlay::i_float::float::compatible::FloatPointCompatible; -use i_overlay::i_float::int::number::int::IntNumber; -use i_overlay::i_shape::float::adapter::PathToFloat; -/// A Delaunay-refined triangle mesh with float-mapped geometry. +/// A Delaunay-refined triangle mesh with adapter-mapped geometry. /// -/// Produced from [`Triangulation::into_delaunay`] by applying edge flips +/// Produced from [`RawTriangulation::into_delaunay`] by applying edge flips /// to satisfy the Delaunay condition. -pub struct Delaunay { - pub(super) delaunay: IntDelaunay, - pub(super) adapter: FloatPointAdapter, +pub struct Delaunay { + pub(super) delaunay: IntDelaunay, + pub(super) adapter: A, } -impl RawTriangulation { +impl RawTriangulation { #[inline] - pub fn into_delaunay(self) -> Delaunay { + pub fn into_delaunay(self) -> Delaunay { let mut buffer = DelaunayBuffer::new(); self.into_delaunay_with_buffer(&mut buffer) } #[inline] - pub fn into_delaunay_with_buffer(self, buffer: &mut DelaunayBuffer) -> Delaunay { + pub fn into_delaunay_with_buffer(self, buffer: &mut DelaunayBuffer) -> Delaunay { Delaunay { delaunay: self.raw.into_delaunay_with_buffer(buffer), adapter: self.adapter, @@ -33,11 +30,11 @@ impl RawTriangulation { } } -impl Delaunay { - /// Returns the float-mapped vertex positions in the triangulation. +impl Delaunay { + /// Returns the adapter-mapped vertex positions in the triangulation. #[inline] - pub fn points(&self) -> Vec

{ - self.delaunay.points.to_float(&self.adapter) + pub fn points(&self) -> Vec { + self.adapter.points_from_int(&self.delaunay.points) } /// Returns indices forming counter-clockwise triangles. @@ -52,9 +49,9 @@ impl Delaunay { self.delaunay.triangle_neighbors() } - /// Converts this refined mesh into a flat float [`Triangulation`]. + /// Converts this refined mesh into a flat [`Triangulation`]. #[inline] - pub fn to_triangulation(&self) -> Triangulation { + pub fn to_triangulation(&self) -> Triangulation { Triangulation { indices: self.triangle_indices(), points: self.points(), diff --git a/iTriangle/src/generic/triangulatable.rs b/iTriangle/src/generic/triangulatable.rs index a572dde..e94515b 100644 --- a/iTriangle/src/generic/triangulatable.rs +++ b/iTriangle/src/generic/triangulatable.rs @@ -24,24 +24,24 @@ pub trait Triangulatable { /// Triangulates the shape(s) using the default [`Triangulator`] configuration. /// /// Validation includes contour simplification, direction correction, and area filtering. - fn triangulate(&self) -> RawTriangulation

{ + fn triangulate(&self) -> RawTriangulation> { self.triangulate_as::() } /// Triangulates the shape(s) using the requested integer coordinate type. - fn triangulate_as(&self) -> RawTriangulation + fn triangulate_as(&self) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey; /// Triangulates the shape(s) and inserts the given Steiner points. /// /// Points must lie strictly within the interior of the geometry. - fn triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation

{ + fn triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation> { self.triangulate_with_steiner_points_as::(points) } /// Triangulates the shape(s) with Steiner points using the requested integer coordinate type. - fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation + fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey; } @@ -50,7 +50,7 @@ impl

Triangulatable

for [P] where P: FloatPointCompatible, { - fn triangulate_as(&self) -> RawTriangulation + fn triangulate_as(&self) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -66,7 +66,7 @@ where } } - fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation + fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -90,7 +90,7 @@ impl

Triangulatable

for [Contour

] where P: FloatPointCompatible, { - fn triangulate_as(&self) -> RawTriangulation + fn triangulate_as(&self) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -106,7 +106,7 @@ where } } - fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation + fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -130,7 +130,7 @@ impl

Triangulatable

for [Shape

] where P: FloatPointCompatible, { - fn triangulate_as(&self) -> RawTriangulation + fn triangulate_as(&self) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { @@ -146,7 +146,7 @@ where } } - fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation + fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { diff --git a/iTriangle/src/generic/triangulation.rs b/iTriangle/src/generic/triangulation.rs index 705cad1..4aec2b0 100644 --- a/iTriangle/src/generic/triangulation.rs +++ b/iTriangle/src/generic/triangulation.rs @@ -1,22 +1,22 @@ +use crate::generic::adapter::PointAdapter; use crate::int::triangulation::{IndexType, IntTriangulation, RawIntTriangulation}; use alloc::vec::Vec; use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::float::number::FloatNumber; use i_overlay::i_float::int::number::int::IntNumber; -use i_overlay::i_shape::float::adapter::PathToFloat; use i_overlay::i_shape::util::reserve::Reserve; -/// A triangulation result based on integer computation, with float mapping. +/// A triangulation result based on integer computation, with point mapping. /// -/// Internally uses an [`Triangulation`] for performance and robustness, -/// and maps results back to user-provided float types via a [`FloatPointAdapter`]. +/// Internally uses a [`RawIntTriangulation`] for performance and robustness, +/// and maps results back to user-provided point types via a [`PointAdapter`]. /// /// # Parameters -/// - `P`: Float point type (e.g., `Vec2`, `[f32; 2]`, etc.) -pub struct RawTriangulation { - pub raw: RawIntTriangulation, - pub adapter: FloatPointAdapter, +/// - `A`: Point adapter (e.g. [`FloatPointAdapter`] or [`crate::generic::adapter::IdentityAdapter`]) +pub struct RawTriangulation { + pub raw: RawIntTriangulation, + pub adapter: A, } /// A flat triangulation result consisting of float points and triangle indices. @@ -29,13 +29,13 @@ pub struct Triangulation { pub indices: Vec, } -impl RawTriangulation { - /// Returns the float-mapped points used in the triangulation. +impl RawTriangulation { + /// Returns the adapter-mapped points used in the triangulation. /// /// The points are guaranteed to match the input shape geometry within adapter precision. #[inline] - pub fn points(&self) -> Vec

{ - self.raw.points.to_float(&self.adapter) + pub fn points(&self) -> Vec { + self.adapter.points_from_int(&self.raw.points) } /// Returns the triangle indices for the mesh, ordered counter-clockwise. @@ -46,7 +46,7 @@ impl RawTriangulation { /// Converts this flat triangulation into a flat [`Triangulation`] (points + indices). #[inline] - pub fn to_triangulation(&self) -> Triangulation { + pub fn to_triangulation(&self) -> Triangulation { Triangulation { indices: self.triangle_indices(), points: self.points(), diff --git a/iTriangle/src/generic/unchecked.rs b/iTriangle/src/generic/unchecked.rs index 3c394c5..b4f5ffe 100644 --- a/iTriangle/src/generic/unchecked.rs +++ b/iTriangle/src/generic/unchecked.rs @@ -21,17 +21,17 @@ use i_tree::Expiration; /// - Steiner points must lie strictly within the shape pub trait UncheckedTriangulatable { /// Triangulates float geometry without validation or simplification. - fn unchecked_triangulate(&self) -> RawTriangulation

{ + fn unchecked_triangulate(&self) -> RawTriangulation> { self.unchecked_triangulate_as::() } /// Triangulates float geometry without validation using the requested integer coordinate type. - fn unchecked_triangulate_as(&self) -> RawTriangulation + fn unchecked_triangulate_as(&self) -> RawTriangulation> where I: IntNumber + Expiration + SortKey; /// Same as `unchecked_triangulate`, but inserts user-defined Steiner points. - fn unchecked_triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation

{ + fn unchecked_triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation> { self.unchecked_triangulate_with_steiner_points_as::(points) } @@ -39,7 +39,7 @@ pub trait UncheckedTriangulatable { fn unchecked_triangulate_with_steiner_points_as( &self, points: &[P], - ) -> RawTriangulation + ) -> RawTriangulation> where I: IntNumber + Expiration + SortKey; } @@ -48,7 +48,7 @@ impl

UncheckedTriangulatable

for [P] where P: FloatPointCompatible, { - fn unchecked_triangulate_as(&self) -> RawTriangulation + fn unchecked_triangulate_as(&self) -> RawTriangulation> where I: IntNumber + Expiration + SortKey, { @@ -67,7 +67,7 @@ where fn unchecked_triangulate_with_steiner_points_as( &self, points: &[P], - ) -> RawTriangulation + ) -> RawTriangulation> where I: IntNumber + Expiration + SortKey, { @@ -91,7 +91,7 @@ impl

UncheckedTriangulatable

for [Contour

] where P: FloatPointCompatible, { - fn unchecked_triangulate_as(&self) -> RawTriangulation + fn unchecked_triangulate_as(&self) -> RawTriangulation> where I: IntNumber + Expiration + SortKey, { @@ -110,7 +110,7 @@ where fn unchecked_triangulate_with_steiner_points_as( &self, points: &[P], - ) -> RawTriangulation + ) -> RawTriangulation> where I: IntNumber + Expiration + SortKey, { @@ -134,7 +134,7 @@ impl

UncheckedTriangulatable

for [Shape

] where P: FloatPointCompatible, { - fn unchecked_triangulate_as(&self) -> RawTriangulation + fn unchecked_triangulate_as(&self) -> RawTriangulation> where I: IntNumber + Expiration + SortKey, { @@ -153,7 +153,7 @@ where fn unchecked_triangulate_with_steiner_points_as( &self, points: &[P], - ) -> RawTriangulation + ) -> RawTriangulation> where I: IntNumber + Expiration + SortKey, { From 3b09b5c2b5fa6c342d88ad8f9fa128e7ec8e2709 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 24 Jul 2026 21:55:33 +0200 Subject: [PATCH 4/6] Now make conversions actually go through `PointAdapter` --- iTriangle/src/generic/centroid_net.rs | 18 +++---- iTriangle/src/generic/circumcenter.rs | 24 ++++----- iTriangle/src/generic/convex.rs | 17 ++++--- iTriangle/src/generic/custom.rs | 65 +++++++++++++++++-------- iTriangle/src/generic/locator.rs | 11 +++-- iTriangle/src/generic/triangulatable.rs | 65 +++++++++++++++++-------- iTriangle/src/generic/triangulation.rs | 30 +++++------- iTriangle/src/generic/triangulator.rs | 4 +- iTriangle/src/generic/unchecked.rs | 45 ++++++++++------- 9 files changed, 162 insertions(+), 117 deletions(-) diff --git a/iTriangle/src/generic/centroid_net.rs b/iTriangle/src/generic/centroid_net.rs index 9c639cc..d911bab 100644 --- a/iTriangle/src/generic/centroid_net.rs +++ b/iTriangle/src/generic/centroid_net.rs @@ -1,18 +1,16 @@ +use crate::generic::adapter::PointAdapter; use crate::generic::delaunay::Delaunay; use alloc::vec::Vec; -use i_overlay::i_float::adapter::FloatPointAdapter; -use i_overlay::i_float::float::compatible::FloatPointCompatible; -use i_overlay::i_float::int::number::int::IntNumber; -use i_overlay::i_float::int::number::wide_int::WideIntNumber; use i_overlay::i_shape::base::data::Contour; -use i_overlay::i_shape::float::adapter::ShapeToFloat; -impl Delaunay> { +impl Delaunay { #[inline] - pub fn to_centroid_net(&self, min_area: P::Scalar) -> Vec> { - let int_area = self.adapter.round_sqr_len_to_int(min_area); + pub fn to_centroid_net(&self, min_area: A::Measure) -> Vec> { + let int_area = self.adapter.measure_to_int_area(min_area); self.delaunay - .centroid_net(int_area.to_uint()) - .to_float(&self.adapter) + .centroid_net(int_area) + .into_iter() + .map(|contour| self.adapter.points_from_int(&contour)) + .collect() } } diff --git a/iTriangle/src/generic/circumcenter.rs b/iTriangle/src/generic/circumcenter.rs index f8644c2..966829d 100644 --- a/iTriangle/src/generic/circumcenter.rs +++ b/iTriangle/src/generic/circumcenter.rs @@ -1,33 +1,29 @@ +use crate::generic::adapter::PointAdapter; use crate::generic::delaunay::Delaunay; -use i_overlay::i_float::adapter::FloatPointAdapter; -use i_overlay::i_float::float::compatible::FloatPointCompatible; -use i_overlay::i_float::int::number::int::IntNumber; -use i_overlay::i_float::int::number::wide_int::WideIntNumber; -impl Delaunay> { +impl Delaunay { #[inline] - pub fn refine_with_circumcenters(mut self, min_area: P::Scalar) -> Self { + pub fn refine_with_circumcenters(mut self, min_area: A::Measure) -> Self { self.refine_with_circumcenters_mut(min_area); self } #[inline] - pub fn refine_with_circumcenters_by_obtuse_angle(mut self, min_area: P::Scalar) -> Self { + pub fn refine_with_circumcenters_by_obtuse_angle(mut self, min_area: A::Measure) -> Self { self.refine_with_circumcenters_by_obtuse_angle_mut(min_area); self } #[inline] - pub fn refine_with_circumcenters_mut(&mut self, min_area: P::Scalar) { - let int_area = self.adapter.round_sqr_len_to_int(min_area); - self.delaunay - .refine_with_circumcenters_mut(int_area.to_uint()); + pub fn refine_with_circumcenters_mut(&mut self, min_area: A::Measure) { + let int_area = self.adapter.measure_to_int_area(min_area); + self.delaunay.refine_with_circumcenters_mut(int_area); } #[inline] - pub fn refine_with_circumcenters_by_obtuse_angle_mut(&mut self, min_area: P::Scalar) { - let int_area = self.adapter.round_sqr_len_to_int(min_area); + pub fn refine_with_circumcenters_by_obtuse_angle_mut(&mut self, min_area: A::Measure) { + let int_area = self.adapter.measure_to_int_area(min_area); self.delaunay - .refine_with_circumcenters_by_obtuse_angle_mut(int_area.to_uint()); + .refine_with_circumcenters_by_obtuse_angle_mut(int_area); } } diff --git a/iTriangle/src/generic/convex.rs b/iTriangle/src/generic/convex.rs index 209943f..bc49a1d 100644 --- a/iTriangle/src/generic/convex.rs +++ b/iTriangle/src/generic/convex.rs @@ -1,17 +1,18 @@ +use crate::generic::adapter::PointAdapter; use crate::generic::delaunay::Delaunay; use alloc::vec::Vec; -use i_overlay::i_float::adapter::FloatPointAdapter; -use i_overlay::i_float::float::compatible::FloatPointCompatible; -use i_overlay::i_float::int::number::int::IntNumber; use i_overlay::i_shape::base::data::Contour; -use i_overlay::i_shape::float::adapter::ShapeToFloat; -impl Delaunay> { +impl Delaunay { /// Groups triangles into non-overlapping convex polygons in counter-clockwise order. /// - /// Returns a list of float-based [`Contour

`]s. + /// Returns a list of adapter-mapped [`Contour`]s. #[inline] - pub fn to_convex_polygons(&self) -> Vec> { - self.delaunay.to_convex_polygons().to_float(&self.adapter) + pub fn to_convex_polygons(&self) -> Vec> { + self.delaunay + .to_convex_polygons() + .into_iter() + .map(|contour| self.adapter.points_from_int(&contour)) + .collect() } } diff --git a/iTriangle/src/generic/custom.rs b/iTriangle/src/generic/custom.rs index 41e0051..233279f 100644 --- a/iTriangle/src/generic/custom.rs +++ b/iTriangle/src/generic/custom.rs @@ -1,15 +1,17 @@ +use crate::generic::adapter::PointAdapter; use crate::generic::triangulation::RawTriangulation; use crate::int::custom::IntCustomTriangulatable; use crate::int::triangulation::RawIntTriangulation; use crate::int::validation::Validation; +use alloc::vec::Vec; use i_key_sort::sort::key::SortKey; use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::float::rect::FloatRect; use i_overlay::i_float::int::number::int::IntNumber; use i_overlay::i_shape::base::data::{Contour, Shape}; -use i_overlay::i_shape::float::adapter::{PathToInt, ShapeToInt, ShapesToInt}; use i_overlay::i_shape::float::rect::RectInit; +use i_overlay::i_shape::int::shape::{IntContour, IntShape, IntShapes}; use i_tree::{Expiration, LayoutNumber}; /// A trait for triangulating float geometry with user-defined validation rules. @@ -17,12 +19,18 @@ use i_tree::{Expiration, LayoutNumber}; /// Accepts a custom [`Validation`] object for tuning fill rule, min area, etc. pub trait CustomTriangulatable { /// Performs triangulation using the specified [`Validation`] settings. - fn custom_triangulate(&self, validation: Validation) -> RawTriangulation> { + fn custom_triangulate( + &self, + validation: Validation, + ) -> RawTriangulation> { self.custom_triangulate_as(validation) } /// Performs triangulation using the requested integer coordinate type. - fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation> + fn custom_triangulate_as( + &self, + validation: Validation, + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey; @@ -49,13 +57,17 @@ impl

CustomTriangulatable

for Contour

where P: FloatPointCompatible, { - fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation> + fn custom_triangulate_as( + &self, + validation: Validation, + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { if let Some(rect) = FloatRect::with_path(self) { let adapter = FloatPointAdapter::::new(rect); - let raw = self.to_int(&adapter).custom_triangulate(validation); + let int_contour: IntContour = adapter.points_to_int(self); + let raw = int_contour.custom_triangulate(validation); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -75,10 +87,9 @@ where { if let Some(rect) = FloatRect::with_path(self) { let adapter = FloatPointAdapter::::new(rect); - let float_points = points.to_int(&adapter); - let raw = self - .to_int(&adapter) - .custom_triangulate_with_steiner_points(&float_points, validation); + let int_points = adapter.points_to_int(points); + let int_contour: IntContour = adapter.points_to_int(self); + let raw = int_contour.custom_triangulate_with_steiner_points(&int_points, validation); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -93,13 +104,17 @@ impl

CustomTriangulatable

for [Contour

] where P: FloatPointCompatible, { - fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation> + fn custom_triangulate_as( + &self, + validation: Validation, + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { if let Some(rect) = FloatRect::with_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let raw = self.to_int(&adapter).custom_triangulate(validation); + let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); + let raw = int_shape.custom_triangulate(validation); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -119,10 +134,9 @@ where { if let Some(rect) = FloatRect::with_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let float_points = points.to_int(&adapter); - let raw = self - .to_int(&adapter) - .custom_triangulate_with_steiner_points(&float_points, validation); + let int_points = adapter.points_to_int(points); + let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); + let raw = int_shape.custom_triangulate_with_steiner_points(&int_points, validation); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -137,13 +151,20 @@ impl

CustomTriangulatable

for [Shape

] where P: FloatPointCompatible, { - fn custom_triangulate_as(&self, validation: Validation) -> RawTriangulation> + fn custom_triangulate_as( + &self, + validation: Validation, + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { if let Some(rect) = FloatRect::with_list_of_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let raw = self.to_int(&adapter).custom_triangulate(validation); + let int_shapes: IntShapes = self + .iter() + .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) + .collect(); + let raw = int_shapes.custom_triangulate(validation); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -163,10 +184,12 @@ where { if let Some(rect) = FloatRect::with_list_of_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let float_points = points.to_int(&adapter); - let raw = self - .to_int(&adapter) - .custom_triangulate_with_steiner_points(&float_points, validation); + let int_points = adapter.points_to_int(points); + let int_shapes: IntShapes = self + .iter() + .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) + .collect(); + let raw = int_shapes.custom_triangulate_with_steiner_points(&int_points, validation); RawTriangulation { raw, adapter } } else { RawTriangulation { diff --git a/iTriangle/src/generic/locator.rs b/iTriangle/src/generic/locator.rs index 084abde..9f88588 100644 --- a/iTriangle/src/generic/locator.rs +++ b/iTriangle/src/generic/locator.rs @@ -3,8 +3,9 @@ use i_key_sort::sort::key::SortKey; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::float::number::FloatNumber; use i_overlay::i_float::int::number::int::IntNumber; -use i_overlay::{i_float::adapter::FloatPointAdapter, i_shape::float::adapter::PathToInt}; +use i_overlay::i_float::adapter::FloatPointAdapter; +use crate::generic::adapter::PointAdapter; use crate::int::locator::IntPointInTriangulationLocator; use crate::{ generic::triangulation::Triangulation, int::triangulation::IndexType, @@ -29,12 +30,12 @@ impl Triangulation { { let adapter = FloatPointAdapter::::with_iter(self.points.iter().chain(points.iter())); - let int_points = points.to_int(&adapter); + let int_points = adapter.points_to_int(points); let triangles = self.indices.chunks_exact(3).map(|triangle| { - let a = adapter.float_to_int(&self.points[triangle[0].into_usize()]); - let b = adapter.float_to_int(&self.points[triangle[1].into_usize()]); - let c = adapter.float_to_int(&self.points[triangle[2].into_usize()]); + let a = adapter.to_int_point(&self.points[triangle[0].into_usize()]); + let b = adapter.to_int_point(&self.points[triangle[1].into_usize()]); + let c = adapter.to_int_point(&self.points[triangle[2].into_usize()]); [a, b, c] }); diff --git a/iTriangle/src/generic/triangulatable.rs b/iTriangle/src/generic/triangulatable.rs index e94515b..ede8e9b 100644 --- a/iTriangle/src/generic/triangulatable.rs +++ b/iTriangle/src/generic/triangulatable.rs @@ -1,14 +1,16 @@ +use crate::generic::adapter::PointAdapter; use crate::generic::triangulation::RawTriangulation; use crate::int::triangulatable::IntTriangulatable; use crate::int::triangulation::RawIntTriangulation; +use alloc::vec::Vec; use i_key_sort::sort::key::SortKey; use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::float::rect::FloatRect; use i_overlay::i_float::int::number::int::IntNumber; use i_overlay::i_shape::base::data::{Contour, Shape}; -use i_overlay::i_shape::float::adapter::{PathToInt, ShapeToInt, ShapesToInt}; use i_overlay::i_shape::float::rect::RectInit; +use i_overlay::i_shape::int::shape::{IntContour, IntShape, IntShapes}; use i_tree::{Expiration, LayoutNumber}; /// A trait for triangulating float-based geometry with default validation. @@ -36,12 +38,18 @@ pub trait Triangulatable { /// Triangulates the shape(s) and inserts the given Steiner points. /// /// Points must lie strictly within the interior of the geometry. - fn triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation> { + fn triangulate_with_steiner_points( + &self, + points: &[P], + ) -> RawTriangulation> { self.triangulate_with_steiner_points_as::(points) } /// Triangulates the shape(s) with Steiner points using the requested integer coordinate type. - fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation> + fn triangulate_with_steiner_points_as( + &self, + points: &[P], + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey; } @@ -56,7 +64,8 @@ where { if let Some(rect) = FloatRect::with_path(self) { let adapter = FloatPointAdapter::::new(rect); - let raw = self.to_int(&adapter).triangulate(); + let int_contour: IntContour = adapter.points_to_int(self); + let raw = int_contour.triangulate(); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -66,16 +75,18 @@ where } } - fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation> + fn triangulate_with_steiner_points_as( + &self, + points: &[P], + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { if let Some(rect) = FloatRect::with_path(self) { let adapter = FloatPointAdapter::::new(rect); - let float_points = points.to_int(&adapter); - let raw = self - .to_int(&adapter) - .triangulate_with_steiner_points(&float_points); + let int_points = adapter.points_to_int(points); + let int_contour: IntContour = adapter.points_to_int(self); + let raw = int_contour.triangulate_with_steiner_points(&int_points); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -96,7 +107,8 @@ where { if let Some(rect) = FloatRect::with_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let raw = self.to_int(&adapter).triangulate(); + let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); + let raw = int_shape.triangulate(); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -106,16 +118,18 @@ where } } - fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation> + fn triangulate_with_steiner_points_as( + &self, + points: &[P], + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { if let Some(rect) = FloatRect::with_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let float_points = points.to_int(&adapter); - let raw = self - .to_int(&adapter) - .triangulate_with_steiner_points(&float_points); + let int_points = adapter.points_to_int(points); + let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); + let raw = int_shape.triangulate_with_steiner_points(&int_points); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -136,7 +150,11 @@ where { if let Some(rect) = FloatRect::with_list_of_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let raw = self.to_int(&adapter).triangulate(); + let int_shapes: IntShapes = self + .iter() + .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) + .collect(); + let raw = int_shapes.triangulate(); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -146,16 +164,21 @@ where } } - fn triangulate_with_steiner_points_as(&self, points: &[P]) -> RawTriangulation> + fn triangulate_with_steiner_points_as( + &self, + points: &[P], + ) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey, { if let Some(rect) = FloatRect::with_list_of_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let float_points = points.to_int(&adapter); - let raw = self - .to_int(&adapter) - .triangulate_with_steiner_points(&float_points); + let int_points = adapter.points_to_int(points); + let int_shapes: IntShapes = self + .iter() + .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) + .collect(); + let raw = int_shapes.triangulate_with_steiner_points(&int_points); RawTriangulation { raw, adapter } } else { RawTriangulation { diff --git a/iTriangle/src/generic/triangulation.rs b/iTriangle/src/generic/triangulation.rs index 4aec2b0..32ed38b 100644 --- a/iTriangle/src/generic/triangulation.rs +++ b/iTriangle/src/generic/triangulation.rs @@ -1,7 +1,6 @@ use crate::generic::adapter::PointAdapter; use crate::int::triangulation::{IndexType, IntTriangulation, RawIntTriangulation}; use alloc::vec::Vec; -use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::float::number::FloatNumber; use i_overlay::i_float::int::number::int::IntNumber; @@ -13,7 +12,8 @@ use i_overlay::i_shape::util::reserve::Reserve; /// and maps results back to user-provided point types via a [`PointAdapter`]. /// /// # Parameters -/// - `A`: Point adapter (e.g. [`FloatPointAdapter`] or [`crate::generic::adapter::IdentityAdapter`]) +/// - `A`: Point adapter (e.g. [`i_overlay::i_float::adapter::FloatPointAdapter`] +/// or [`crate::generic::adapter::IdentityAdapter`]) pub struct RawTriangulation { pub raw: RawIntTriangulation, pub adapter: A, @@ -64,18 +64,16 @@ impl Triangulation { } #[inline] - pub fn set_with_int( + pub fn set_with_int>( &mut self, - triangulation: &IntTriangulation, - adapter: &FloatPointAdapter, - ) where - P: FloatPointCompatible, - { + triangulation: &IntTriangulation, + adapter: &A, + ) { self.points.clear(); self.points .reserve_capacity(triangulation.points.capacity()); self.points - .extend(triangulation.points.iter().map(|p| adapter.int_to_float(p))); + .extend(triangulation.points.iter().map(|p| adapter.from_int_point(p))); self.indices.clear(); self.indices.extend_from_slice(&triangulation.indices); @@ -84,14 +82,11 @@ impl Triangulation { impl IntTriangulation { #[inline] - pub fn into_float( - self, - adapter: &FloatPointAdapter, - ) -> Triangulation { + pub fn into_adapted>(self, adapter: &A) -> Triangulation { let points = self .points .iter() - .map(|p| adapter.int_to_float(p)) + .map(|p| adapter.from_int_point(p)) .collect(); Triangulation { points, @@ -100,14 +95,11 @@ impl IntTriangulation { } #[inline] - pub fn to_float( - &self, - adapter: &FloatPointAdapter, - ) -> Triangulation { + pub fn to_adapted>(&self, adapter: &A) -> Triangulation { let points = self .points .iter() - .map(|p| adapter.int_to_float(p)) + .map(|p| adapter.from_int_point(p)) .collect(); Triangulation { points, diff --git a/iTriangle/src/generic/triangulator.rs b/iTriangle/src/generic/triangulator.rs index e00c131..365ddc4 100644 --- a/iTriangle/src/generic/triangulator.rs +++ b/iTriangle/src/generic/triangulator.rs @@ -110,7 +110,7 @@ where self.int_triangulator .triangulate_flat_into(&mut flat_buffer, &mut int_buffer); - let triangulation = int_buffer.to_float(&adapter); + let triangulation = int_buffer.to_adapted(&adapter); self.flat_buffer = Some(flat_buffer); self.int_buffer = Some(int_buffer); @@ -175,7 +175,7 @@ where self.int_triangulator .uncheck_triangulate_flat_into(&flat_buffer, &mut int_buffer); - let triangulation = int_buffer.to_float(&adapter); + let triangulation = int_buffer.to_adapted(&adapter); self.flat_buffer = Some(flat_buffer); self.int_buffer = Some(int_buffer); diff --git a/iTriangle/src/generic/unchecked.rs b/iTriangle/src/generic/unchecked.rs index b4f5ffe..33c0743 100644 --- a/iTriangle/src/generic/unchecked.rs +++ b/iTriangle/src/generic/unchecked.rs @@ -1,14 +1,16 @@ +use crate::generic::adapter::PointAdapter; use crate::generic::triangulation::RawTriangulation; use crate::int::triangulation::RawIntTriangulation; use crate::int::unchecked::IntUncheckedTriangulatable; +use alloc::vec::Vec; use i_key_sort::sort::key::SortKey; use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::float::rect::FloatRect; use i_overlay::i_float::int::number::int::IntNumber; use i_overlay::i_shape::base::data::{Contour, Shape}; -use i_overlay::i_shape::float::adapter::{PathToInt, ShapeToInt, ShapesToInt}; use i_overlay::i_shape::float::rect::RectInit; +use i_overlay::i_shape::int::shape::{IntContour, IntShape, IntShapes}; use i_tree::Expiration; /// A trait for triangulating already valid float-based geometry. @@ -31,7 +33,10 @@ pub trait UncheckedTriangulatable { I: IntNumber + Expiration + SortKey; /// Same as `unchecked_triangulate`, but inserts user-defined Steiner points. - fn unchecked_triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation> { + fn unchecked_triangulate_with_steiner_points( + &self, + points: &[P], + ) -> RawTriangulation> { self.unchecked_triangulate_with_steiner_points_as::(points) } @@ -54,7 +59,8 @@ where { if let Some(rect) = FloatRect::with_path(self) { let adapter = FloatPointAdapter::::new(rect); - let raw = self.to_int(&adapter).uncheck_triangulate(); + let int_contour: IntContour = adapter.points_to_int(self); + let raw = int_contour.uncheck_triangulate(); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -73,10 +79,9 @@ where { if let Some(rect) = FloatRect::with_path(self) { let adapter = FloatPointAdapter::::new(rect); - let float_points = points.to_int(&adapter); - let raw = self - .to_int(&adapter) - .uncheck_triangulate_with_steiner_points(&float_points); + let int_points = adapter.points_to_int(points); + let int_contour: IntContour = adapter.points_to_int(self); + let raw = int_contour.uncheck_triangulate_with_steiner_points(&int_points); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -97,7 +102,8 @@ where { if let Some(rect) = FloatRect::with_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let raw = self.to_int(&adapter).uncheck_triangulate(); + let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); + let raw = int_shape.uncheck_triangulate(); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -116,10 +122,9 @@ where { if let Some(rect) = FloatRect::with_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let float_points = points.to_int(&adapter); - let raw = self - .to_int(&adapter) - .uncheck_triangulate_with_steiner_points(&float_points); + let int_points = adapter.points_to_int(points); + let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); + let raw = int_shape.uncheck_triangulate_with_steiner_points(&int_points); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -140,7 +145,11 @@ where { if let Some(rect) = FloatRect::with_list_of_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let raw = self.to_int(&adapter).uncheck_triangulate(); + let int_shapes: IntShapes = self + .iter() + .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) + .collect(); + let raw = int_shapes.uncheck_triangulate(); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -159,10 +168,12 @@ where { if let Some(rect) = FloatRect::with_list_of_paths(self) { let adapter = FloatPointAdapter::::new(rect); - let float_points = points.to_int(&adapter); - let raw = self - .to_int(&adapter) - .uncheck_triangulate_with_steiner_points(&float_points); + let int_points = adapter.points_to_int(points); + let int_shapes: IntShapes = self + .iter() + .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) + .collect(); + let raw = int_shapes.uncheck_triangulate_with_steiner_points(&int_points); RawTriangulation { raw, adapter } } else { RawTriangulation { From 257478965f68131067af1068ae32a3cc4e112225 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 24 Jul 2026 22:28:34 +0200 Subject: [PATCH 5/6] Now make `Triangulatable`, `CustomTriangulatable`, `UncheckedTriangulatable` actually use `Adapter` Moved `*_as` methods to new `*TriangulatableAs` traits. Made some more changes. --- iTriangle/src/generic/custom.rs | 212 +++++++++++++++++++++--- iTriangle/src/generic/triangulatable.rs | 174 +++++++++++++++---- iTriangle/src/generic/triangulation.rs | 7 +- iTriangle/src/generic/triangulator.rs | 32 ++++ iTriangle/src/generic/unchecked.rs | 191 ++++++++++++++++++--- iTriangle/tests/float_tests.rs | 2 +- 6 files changed, 543 insertions(+), 75 deletions(-) diff --git a/iTriangle/src/generic/custom.rs b/iTriangle/src/generic/custom.rs index 233279f..d862c16 100644 --- a/iTriangle/src/generic/custom.rs +++ b/iTriangle/src/generic/custom.rs @@ -1,31 +1,42 @@ -use crate::generic::adapter::PointAdapter; +use crate::generic::adapter::{IntPointAdapter, PointAdapter}; use crate::generic::triangulation::RawTriangulation; use crate::int::custom::IntCustomTriangulatable; use crate::int::triangulation::RawIntTriangulation; use crate::int::validation::Validation; -use alloc::vec::Vec; use i_key_sort::sort::key::SortKey; use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::float::rect::FloatRect; use i_overlay::i_float::int::number::int::IntNumber; +use i_overlay::i_float::int::point::IntPoint; use i_overlay::i_shape::base::data::{Contour, Shape}; use i_overlay::i_shape::float::rect::RectInit; use i_overlay::i_shape::int::shape::{IntContour, IntShape, IntShapes}; use i_tree::{Expiration, LayoutNumber}; -/// A trait for triangulating float geometry with user-defined validation rules. +/// A trait for triangulating geometry with user-defined validation rules. /// /// Accepts a custom [`Validation`] object for tuning fill rule, min area, etc. -pub trait CustomTriangulatable { +pub trait CustomTriangulatable

{ + type Adapter: PointAdapter; + /// Performs triangulation using the specified [`Validation`] settings. fn custom_triangulate( &self, - validation: Validation, - ) -> RawTriangulation> { - self.custom_triangulate_as(validation) - } + validation: Validation<::Int>, + ) -> RawTriangulation; + + /// Performs triangulation with Steiner points and a custom [`Validation`] config. + fn custom_triangulate_with_steiner_points( + &self, + points: &[P], + validation: Validation<::Int>, + ) -> RawTriangulation; +} +/// Float-only. You can choose the integer coordinate type to be used internally +/// by the triangulator. +pub trait CustomTriangulatableAs: CustomTriangulatable

{ /// Performs triangulation using the requested integer coordinate type. fn custom_triangulate_as( &self, @@ -34,15 +45,6 @@ pub trait CustomTriangulatable { where I: IntNumber + Expiration + LayoutNumber + SortKey; - /// Performs triangulation with Steiner points and a custom [`Validation`] config. - fn custom_triangulate_with_steiner_points( - &self, - points: &[P], - validation: Validation, - ) -> RawTriangulation> { - self.custom_triangulate_with_steiner_points_as(points, validation) - } - /// Performs triangulation with Steiner points using the requested integer coordinate type. fn custom_triangulate_with_steiner_points_as( &self, @@ -53,7 +55,28 @@ pub trait CustomTriangulatable { I: IntNumber + Expiration + LayoutNumber + SortKey; } -impl

CustomTriangulatable

for Contour

+impl

CustomTriangulatable

for [P] +where + P: FloatPointCompatible, +{ + type Adapter = FloatPointAdapter; + + #[inline] + fn custom_triangulate(&self, validation: Validation) -> RawTriangulation { + self.custom_triangulate_as(validation) + } + + #[inline] + fn custom_triangulate_with_steiner_points( + &self, + points: &[P], + validation: Validation, + ) -> RawTriangulation { + self.custom_triangulate_with_steiner_points_as(points, validation) + } +} + +impl

CustomTriangulatableAs

for [P] where P: FloatPointCompatible, { @@ -67,7 +90,7 @@ where if let Some(rect) = FloatRect::with_path(self) { let adapter = FloatPointAdapter::::new(rect); let int_contour: IntContour = adapter.points_to_int(self); - let raw = int_contour.custom_triangulate(validation); + let raw = IntCustomTriangulatable::custom_triangulate(&int_contour, validation); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -89,7 +112,11 @@ where let adapter = FloatPointAdapter::::new(rect); let int_points = adapter.points_to_int(points); let int_contour: IntContour = adapter.points_to_int(self); - let raw = int_contour.custom_triangulate_with_steiner_points(&int_points, validation); + let raw = IntCustomTriangulatable::custom_triangulate_with_steiner_points( + &int_contour, + &int_points, + validation, + ); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -101,6 +128,27 @@ where } impl

CustomTriangulatable

for [Contour

] +where + P: FloatPointCompatible, +{ + type Adapter = FloatPointAdapter; + + #[inline] + fn custom_triangulate(&self, validation: Validation) -> RawTriangulation { + self.custom_triangulate_as(validation) + } + + #[inline] + fn custom_triangulate_with_steiner_points( + &self, + points: &[P], + validation: Validation, + ) -> RawTriangulation { + self.custom_triangulate_with_steiner_points_as(points, validation) + } +} + +impl

CustomTriangulatableAs

for [Contour

] where P: FloatPointCompatible, { @@ -114,7 +162,7 @@ where if let Some(rect) = FloatRect::with_paths(self) { let adapter = FloatPointAdapter::::new(rect); let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); - let raw = int_shape.custom_triangulate(validation); + let raw = IntCustomTriangulatable::custom_triangulate(&int_shape, validation); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -136,7 +184,11 @@ where let adapter = FloatPointAdapter::::new(rect); let int_points = adapter.points_to_int(points); let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); - let raw = int_shape.custom_triangulate_with_steiner_points(&int_points, validation); + let raw = IntCustomTriangulatable::custom_triangulate_with_steiner_points( + &int_shape, + &int_points, + validation, + ); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -148,6 +200,27 @@ where } impl

CustomTriangulatable

for [Shape

] +where + P: FloatPointCompatible, +{ + type Adapter = FloatPointAdapter; + + #[inline] + fn custom_triangulate(&self, validation: Validation) -> RawTriangulation { + self.custom_triangulate_as(validation) + } + + #[inline] + fn custom_triangulate_with_steiner_points( + &self, + points: &[P], + validation: Validation, + ) -> RawTriangulation { + self.custom_triangulate_with_steiner_points_as(points, validation) + } +} + +impl

CustomTriangulatableAs

for [Shape

] where P: FloatPointCompatible, { @@ -164,7 +237,7 @@ where .iter() .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) .collect(); - let raw = int_shapes.custom_triangulate(validation); + let raw = IntCustomTriangulatable::custom_triangulate(&int_shapes, validation); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -189,7 +262,11 @@ where .iter() .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) .collect(); - let raw = int_shapes.custom_triangulate_with_steiner_points(&int_points, validation); + let raw = IntCustomTriangulatable::custom_triangulate_with_steiner_points( + &int_shapes, + &int_points, + validation, + ); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -199,3 +276,90 @@ where } } } + +impl CustomTriangulatable> for IntContour +where + I: IntNumber + Expiration + LayoutNumber + SortKey, +{ + type Adapter = IntPointAdapter; + + #[inline] + fn custom_triangulate(&self, validation: Validation) -> RawTriangulation { + RawTriangulation::new( + IntCustomTriangulatable::custom_triangulate(self, validation), + IntPointAdapter::new(), + ) + } + + #[inline] + fn custom_triangulate_with_steiner_points( + &self, + points: &[IntPoint], + validation: Validation, + ) -> RawTriangulation { + RawTriangulation::new( + IntCustomTriangulatable::custom_triangulate_with_steiner_points( + self, points, validation, + ), + IntPointAdapter::new(), + ) + } +} + +impl CustomTriangulatable> for IntShape +where + I: IntNumber + Expiration + LayoutNumber + SortKey, +{ + type Adapter = IntPointAdapter; + + #[inline] + fn custom_triangulate(&self, validation: Validation) -> RawTriangulation { + RawTriangulation::new( + IntCustomTriangulatable::custom_triangulate(self, validation), + IntPointAdapter::new(), + ) + } + + #[inline] + fn custom_triangulate_with_steiner_points( + &self, + points: &[IntPoint], + validation: Validation, + ) -> RawTriangulation { + RawTriangulation::new( + IntCustomTriangulatable::custom_triangulate_with_steiner_points( + self, points, validation, + ), + IntPointAdapter::new(), + ) + } +} + +impl CustomTriangulatable> for IntShapes +where + I: IntNumber + Expiration + LayoutNumber + SortKey, +{ + type Adapter = IntPointAdapter; + + #[inline] + fn custom_triangulate(&self, validation: Validation) -> RawTriangulation { + RawTriangulation::new( + IntCustomTriangulatable::custom_triangulate(self, validation), + IntPointAdapter::new(), + ) + } + + #[inline] + fn custom_triangulate_with_steiner_points( + &self, + points: &[IntPoint], + validation: Validation, + ) -> RawTriangulation { + RawTriangulation::new( + IntCustomTriangulatable::custom_triangulate_with_steiner_points( + self, points, validation, + ), + IntPointAdapter::new(), + ) + } +} diff --git a/iTriangle/src/generic/triangulatable.rs b/iTriangle/src/generic/triangulatable.rs index ede8e9b..ac4b41c 100644 --- a/iTriangle/src/generic/triangulatable.rs +++ b/iTriangle/src/generic/triangulatable.rs @@ -1,50 +1,48 @@ -use crate::generic::adapter::PointAdapter; +use crate::generic::adapter::{IntPointAdapter, PointAdapter}; use crate::generic::triangulation::RawTriangulation; use crate::int::triangulatable::IntTriangulatable; use crate::int::triangulation::RawIntTriangulation; -use alloc::vec::Vec; use i_key_sort::sort::key::SortKey; use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::float::rect::FloatRect; use i_overlay::i_float::int::number::int::IntNumber; +use i_overlay::i_float::int::point::IntPoint; use i_overlay::i_shape::base::data::{Contour, Shape}; use i_overlay::i_shape::float::rect::RectInit; use i_overlay::i_shape::int::shape::{IntContour, IntShape, IntShapes}; use i_tree::{Expiration, LayoutNumber}; -/// A trait for triangulating float-based geometry with default validation. +/// A trait for triangulating geometry with default validation. /// -/// Automatically converts the input to integer space, applies validation, -/// and returns a float-mapped result. +/// Automatically converts the input to integer space when needed, applies validation, +/// and returns an adapter-mapped result. /// /// # Implemented For -/// - `Contour

` -/// - `[Contour

]` -/// - `[Shape

]` -pub trait Triangulatable { +/// - `[P]` / `[Contour

]` / `[Shape

]` (float) +/// - [`IntContour`] / [`IntShape`] / [`IntShapes`] (integer, identity adapter) +pub trait Triangulatable

{ + type Adapter: PointAdapter; + /// Triangulates the shape(s) using the default [`Triangulator`] configuration. /// /// Validation includes contour simplification, direction correction, and area filtering. - fn triangulate(&self) -> RawTriangulation> { - self.triangulate_as::() - } + fn triangulate(&self) -> RawTriangulation; + + /// Triangulates the shape(s) and inserts the given Steiner points. + /// + /// Points must lie strictly within the interior of the geometry. + fn triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation; +} +/// Float-only. You can choose the integer coordinate type to be used internally +/// by the triangulator. +pub trait TriangulatableAs: Triangulatable

{ /// Triangulates the shape(s) using the requested integer coordinate type. fn triangulate_as(&self) -> RawTriangulation> where I: IntNumber + Expiration + LayoutNumber + SortKey; - /// Triangulates the shape(s) and inserts the given Steiner points. - /// - /// Points must lie strictly within the interior of the geometry. - fn triangulate_with_steiner_points( - &self, - points: &[P], - ) -> RawTriangulation> { - self.triangulate_with_steiner_points_as::(points) - } - /// Triangulates the shape(s) with Steiner points using the requested integer coordinate type. fn triangulate_with_steiner_points_as( &self, @@ -55,6 +53,23 @@ pub trait Triangulatable { } impl

Triangulatable

for [P] +where + P: FloatPointCompatible, +{ + type Adapter = FloatPointAdapter; + + #[inline] + fn triangulate(&self) -> RawTriangulation { + self.triangulate_as::() + } + + #[inline] + fn triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation { + self.triangulate_with_steiner_points_as::(points) + } +} + +impl

TriangulatableAs

for [P] where P: FloatPointCompatible, { @@ -65,7 +80,7 @@ where if let Some(rect) = FloatRect::with_path(self) { let adapter = FloatPointAdapter::::new(rect); let int_contour: IntContour = adapter.points_to_int(self); - let raw = int_contour.triangulate(); + let raw = IntTriangulatable::triangulate(&int_contour); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -86,7 +101,7 @@ where let adapter = FloatPointAdapter::::new(rect); let int_points = adapter.points_to_int(points); let int_contour: IntContour = adapter.points_to_int(self); - let raw = int_contour.triangulate_with_steiner_points(&int_points); + let raw = IntTriangulatable::triangulate_with_steiner_points(&int_contour, &int_points); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -98,6 +113,23 @@ where } impl

Triangulatable

for [Contour

] +where + P: FloatPointCompatible, +{ + type Adapter = FloatPointAdapter; + + #[inline] + fn triangulate(&self) -> RawTriangulation { + self.triangulate_as::() + } + + #[inline] + fn triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation { + self.triangulate_with_steiner_points_as::(points) + } +} + +impl

TriangulatableAs

for [Contour

] where P: FloatPointCompatible, { @@ -108,7 +140,7 @@ where if let Some(rect) = FloatRect::with_paths(self) { let adapter = FloatPointAdapter::::new(rect); let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); - let raw = int_shape.triangulate(); + let raw = IntTriangulatable::triangulate(&int_shape); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -129,7 +161,7 @@ where let adapter = FloatPointAdapter::::new(rect); let int_points = adapter.points_to_int(points); let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); - let raw = int_shape.triangulate_with_steiner_points(&int_points); + let raw = IntTriangulatable::triangulate_with_steiner_points(&int_shape, &int_points); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -141,6 +173,23 @@ where } impl

Triangulatable

for [Shape

] +where + P: FloatPointCompatible, +{ + type Adapter = FloatPointAdapter; + + #[inline] + fn triangulate(&self) -> RawTriangulation { + self.triangulate_as::() + } + + #[inline] + fn triangulate_with_steiner_points(&self, points: &[P]) -> RawTriangulation { + self.triangulate_with_steiner_points_as::(points) + } +} + +impl

TriangulatableAs

for [Shape

] where P: FloatPointCompatible, { @@ -154,7 +203,7 @@ where .iter() .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) .collect(); - let raw = int_shapes.triangulate(); + let raw = IntTriangulatable::triangulate(&int_shapes); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -178,7 +227,7 @@ where .iter() .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) .collect(); - let raw = int_shapes.triangulate_with_steiner_points(&int_points); + let raw = IntTriangulatable::triangulate_with_steiner_points(&int_shapes, &int_points); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -188,3 +237,72 @@ where } } } + +impl Triangulatable> for IntContour +where + I: IntNumber + Expiration + LayoutNumber + SortKey, +{ + type Adapter = IntPointAdapter; + + #[inline] + fn triangulate(&self) -> RawTriangulation { + RawTriangulation::new(IntTriangulatable::triangulate(self), IntPointAdapter::new()) + } + + #[inline] + fn triangulate_with_steiner_points( + &self, + points: &[IntPoint], + ) -> RawTriangulation { + RawTriangulation::new( + IntTriangulatable::triangulate_with_steiner_points(self, points), + IntPointAdapter::new(), + ) + } +} + +impl Triangulatable> for IntShape +where + I: IntNumber + Expiration + LayoutNumber + SortKey, +{ + type Adapter = IntPointAdapter; + + #[inline] + fn triangulate(&self) -> RawTriangulation { + RawTriangulation::new(IntTriangulatable::triangulate(self), IntPointAdapter::new()) + } + + #[inline] + fn triangulate_with_steiner_points( + &self, + points: &[IntPoint], + ) -> RawTriangulation { + RawTriangulation::new( + IntTriangulatable::triangulate_with_steiner_points(self, points), + IntPointAdapter::new(), + ) + } +} + +impl Triangulatable> for IntShapes +where + I: IntNumber + Expiration + LayoutNumber + SortKey, +{ + type Adapter = IntPointAdapter; + + #[inline] + fn triangulate(&self) -> RawTriangulation { + RawTriangulation::new(IntTriangulatable::triangulate(self), IntPointAdapter::new()) + } + + #[inline] + fn triangulate_with_steiner_points( + &self, + points: &[IntPoint], + ) -> RawTriangulation { + RawTriangulation::new( + IntTriangulatable::triangulate_with_steiner_points(self, points), + IntPointAdapter::new(), + ) + } +} diff --git a/iTriangle/src/generic/triangulation.rs b/iTriangle/src/generic/triangulation.rs index 32ed38b..23a25a8 100644 --- a/iTriangle/src/generic/triangulation.rs +++ b/iTriangle/src/generic/triangulation.rs @@ -13,7 +13,7 @@ use i_overlay::i_shape::util::reserve::Reserve; /// /// # Parameters /// - `A`: Point adapter (e.g. [`i_overlay::i_float::adapter::FloatPointAdapter`] -/// or [`crate::generic::adapter::IdentityAdapter`]) +/// or [`crate::generic::adapter::IntPointAdapter`]) pub struct RawTriangulation { pub raw: RawIntTriangulation, pub adapter: A, @@ -30,6 +30,11 @@ pub struct Triangulation { } impl RawTriangulation { + #[inline] + pub fn new(raw: RawIntTriangulation, adapter: A) -> Self { + Self { raw, adapter } + } + /// Returns the adapter-mapped points used in the triangulation. /// /// The points are guaranteed to match the input shape geometry within adapter precision. diff --git a/iTriangle/src/generic/triangulator.rs b/iTriangle/src/generic/triangulator.rs index 365ddc4..a0c2f21 100644 --- a/iTriangle/src/generic/triangulator.rs +++ b/iTriangle/src/generic/triangulator.rs @@ -6,7 +6,9 @@ use i_key_sort::sort::key::SortKey; use i_overlay::core::solver::Solver; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::int::number::int::IntNumber; +use i_overlay::i_float::int::point::IntPoint; use i_overlay::i_shape::flat::buffer::FlatContoursBuffer; +use i_overlay::i_shape::int::shape::{IntContour, IntShape, IntShapes}; use i_overlay::i_shape::source::resource::ShapeResource; use i_tree::{Expiration, LayoutNumber}; @@ -219,4 +221,34 @@ where self.flat_buffer = Some(flat_buffer); self.int_buffer = Some(int_buffer); } + + /// Triangulates an integer contour and returns points as [`IntPoint`]s. + #[inline] + pub fn triangulate_contour(&mut self, contour: &IntContour) -> Triangulation, N> { + let t = self.int_triangulator.triangulate_contour(contour); + Triangulation { + points: t.points, + indices: t.indices, + } + } + + /// Triangulates an integer shape and returns points as [`IntPoint`]s. + #[inline] + pub fn triangulate_shape(&mut self, shape: &IntShape) -> Triangulation, N> { + let t = self.int_triangulator.triangulate_shape(shape); + Triangulation { + points: t.points, + indices: t.indices, + } + } + + /// Triangulates integer shapes and returns points as [`IntPoint`]s. + #[inline] + pub fn triangulate_shapes(&mut self, shapes: &IntShapes) -> Triangulation, N> { + let t = self.int_triangulator.triangulate_shapes(shapes); + Triangulation { + points: t.points, + indices: t.indices, + } + } } diff --git a/iTriangle/src/generic/unchecked.rs b/iTriangle/src/generic/unchecked.rs index 33c0743..9b359c4 100644 --- a/iTriangle/src/generic/unchecked.rs +++ b/iTriangle/src/generic/unchecked.rs @@ -1,19 +1,19 @@ -use crate::generic::adapter::PointAdapter; +use crate::generic::adapter::{IntPointAdapter, PointAdapter}; use crate::generic::triangulation::RawTriangulation; use crate::int::triangulation::RawIntTriangulation; use crate::int::unchecked::IntUncheckedTriangulatable; -use alloc::vec::Vec; use i_key_sort::sort::key::SortKey; use i_overlay::i_float::adapter::FloatPointAdapter; use i_overlay::i_float::float::compatible::FloatPointCompatible; use i_overlay::i_float::float::rect::FloatRect; use i_overlay::i_float::int::number::int::IntNumber; +use i_overlay::i_float::int::point::IntPoint; use i_overlay::i_shape::base::data::{Contour, Shape}; use i_overlay::i_shape::float::rect::RectInit; use i_overlay::i_shape::int::shape::{IntContour, IntShape, IntShapes}; use i_tree::Expiration; -/// A trait for triangulating already valid float-based geometry. +/// A trait for triangulating already valid geometry. /// /// Skips all validation for performance. Ideal when input is generated programmatically. /// @@ -21,24 +21,26 @@ use i_tree::Expiration; /// - Outer contours must be counter-clockwise /// - Holes must be clockwise /// - Steiner points must lie strictly within the shape -pub trait UncheckedTriangulatable { - /// Triangulates float geometry without validation or simplification. - fn unchecked_triangulate(&self) -> RawTriangulation> { - self.unchecked_triangulate_as::() - } +pub trait UncheckedTriangulatable

{ + type Adapter: PointAdapter; - /// Triangulates float geometry without validation using the requested integer coordinate type. - fn unchecked_triangulate_as(&self) -> RawTriangulation> - where - I: IntNumber + Expiration + SortKey; + /// Triangulates geometry without validation or simplification. + fn unchecked_triangulate(&self) -> RawTriangulation; /// Same as `unchecked_triangulate`, but inserts user-defined Steiner points. fn unchecked_triangulate_with_steiner_points( &self, points: &[P], - ) -> RawTriangulation> { - self.unchecked_triangulate_with_steiner_points_as::(points) - } + ) -> RawTriangulation; +} + +/// Float-only. You can choose the integer coordinate type to be used internally +/// by the triangulator. +pub trait UncheckedTriangulatableAs: UncheckedTriangulatable

{ + /// Triangulates without validation using the requested integer coordinate type. + fn unchecked_triangulate_as(&self) -> RawTriangulation> + where + I: IntNumber + Expiration + SortKey; /// Same as `unchecked_triangulate_as`, but inserts user-defined Steiner points. fn unchecked_triangulate_with_steiner_points_as( @@ -50,6 +52,26 @@ pub trait UncheckedTriangulatable { } impl

UncheckedTriangulatable

for [P] +where + P: FloatPointCompatible, +{ + type Adapter = FloatPointAdapter; + + #[inline] + fn unchecked_triangulate(&self) -> RawTriangulation { + self.unchecked_triangulate_as::() + } + + #[inline] + fn unchecked_triangulate_with_steiner_points( + &self, + points: &[P], + ) -> RawTriangulation { + self.unchecked_triangulate_with_steiner_points_as::(points) + } +} + +impl

UncheckedTriangulatableAs

for [P] where P: FloatPointCompatible, { @@ -60,7 +82,7 @@ where if let Some(rect) = FloatRect::with_path(self) { let adapter = FloatPointAdapter::::new(rect); let int_contour: IntContour = adapter.points_to_int(self); - let raw = int_contour.uncheck_triangulate(); + let raw = IntUncheckedTriangulatable::uncheck_triangulate(&int_contour); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -81,7 +103,10 @@ where let adapter = FloatPointAdapter::::new(rect); let int_points = adapter.points_to_int(points); let int_contour: IntContour = adapter.points_to_int(self); - let raw = int_contour.uncheck_triangulate_with_steiner_points(&int_points); + let raw = IntUncheckedTriangulatable::uncheck_triangulate_with_steiner_points( + &int_contour, + &int_points, + ); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -93,6 +118,26 @@ where } impl

UncheckedTriangulatable

for [Contour

] +where + P: FloatPointCompatible, +{ + type Adapter = FloatPointAdapter; + + #[inline] + fn unchecked_triangulate(&self) -> RawTriangulation { + self.unchecked_triangulate_as::() + } + + #[inline] + fn unchecked_triangulate_with_steiner_points( + &self, + points: &[P], + ) -> RawTriangulation { + self.unchecked_triangulate_with_steiner_points_as::(points) + } +} + +impl

UncheckedTriangulatableAs

for [Contour

] where P: FloatPointCompatible, { @@ -103,7 +148,7 @@ where if let Some(rect) = FloatRect::with_paths(self) { let adapter = FloatPointAdapter::::new(rect); let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); - let raw = int_shape.uncheck_triangulate(); + let raw = IntUncheckedTriangulatable::uncheck_triangulate(&int_shape); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -124,7 +169,10 @@ where let adapter = FloatPointAdapter::::new(rect); let int_points = adapter.points_to_int(points); let int_shape: IntShape = self.iter().map(|c| adapter.points_to_int(c)).collect(); - let raw = int_shape.uncheck_triangulate_with_steiner_points(&int_points); + let raw = IntUncheckedTriangulatable::uncheck_triangulate_with_steiner_points( + &int_shape, + &int_points, + ); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -136,6 +184,26 @@ where } impl

UncheckedTriangulatable

for [Shape

] +where + P: FloatPointCompatible, +{ + type Adapter = FloatPointAdapter; + + #[inline] + fn unchecked_triangulate(&self) -> RawTriangulation { + self.unchecked_triangulate_as::() + } + + #[inline] + fn unchecked_triangulate_with_steiner_points( + &self, + points: &[P], + ) -> RawTriangulation { + self.unchecked_triangulate_with_steiner_points_as::(points) + } +} + +impl

UncheckedTriangulatableAs

for [Shape

] where P: FloatPointCompatible, { @@ -149,7 +217,7 @@ where .iter() .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) .collect(); - let raw = int_shapes.uncheck_triangulate(); + let raw = IntUncheckedTriangulatable::uncheck_triangulate(&int_shapes); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -173,7 +241,10 @@ where .iter() .map(|shape| shape.iter().map(|c| adapter.points_to_int(c)).collect()) .collect(); - let raw = int_shapes.uncheck_triangulate_with_steiner_points(&int_points); + let raw = IntUncheckedTriangulatable::uncheck_triangulate_with_steiner_points( + &int_shapes, + &int_points, + ); RawTriangulation { raw, adapter } } else { RawTriangulation { @@ -183,3 +254,81 @@ where } } } + +impl UncheckedTriangulatable> for IntContour +where + I: IntNumber + SortKey, +{ + type Adapter = IntPointAdapter; + + #[inline] + fn unchecked_triangulate(&self) -> RawTriangulation { + RawTriangulation::new( + IntUncheckedTriangulatable::uncheck_triangulate(self), + IntPointAdapter::new(), + ) + } + + #[inline] + fn unchecked_triangulate_with_steiner_points( + &self, + points: &[IntPoint], + ) -> RawTriangulation { + RawTriangulation::new( + IntUncheckedTriangulatable::uncheck_triangulate_with_steiner_points(self, points), + IntPointAdapter::new(), + ) + } +} + +impl UncheckedTriangulatable> for IntShape +where + I: IntNumber + SortKey, +{ + type Adapter = IntPointAdapter; + + #[inline] + fn unchecked_triangulate(&self) -> RawTriangulation { + RawTriangulation::new( + IntUncheckedTriangulatable::uncheck_triangulate(self), + IntPointAdapter::new(), + ) + } + + #[inline] + fn unchecked_triangulate_with_steiner_points( + &self, + points: &[IntPoint], + ) -> RawTriangulation { + RawTriangulation::new( + IntUncheckedTriangulatable::uncheck_triangulate_with_steiner_points(self, points), + IntPointAdapter::new(), + ) + } +} + +impl UncheckedTriangulatable> for IntShapes +where + I: IntNumber + Expiration + SortKey, +{ + type Adapter = IntPointAdapter; + + #[inline] + fn unchecked_triangulate(&self) -> RawTriangulation { + RawTriangulation::new( + IntUncheckedTriangulatable::uncheck_triangulate(self), + IntPointAdapter::new(), + ) + } + + #[inline] + fn unchecked_triangulate_with_steiner_points( + &self, + points: &[IntPoint], + ) -> RawTriangulation { + RawTriangulation::new( + IntUncheckedTriangulatable::uncheck_triangulate_with_steiner_points(self, points), + IntPointAdapter::new(), + ) + } +} diff --git a/iTriangle/tests/float_tests.rs b/iTriangle/tests/float_tests.rs index 1ffe892..f1d7c74 100644 --- a/iTriangle/tests/float_tests.rs +++ b/iTriangle/tests/float_tests.rs @@ -7,7 +7,7 @@ mod tests { use i_overlay::i_shape::base::data::Contour; use i_overlay::i_shape::float::area::Area; use i_tree::{Expiration, LayoutNumber}; - use i_triangle::generic::triangulatable::Triangulatable; + use i_triangle::generic::triangulatable::TriangulatableAs; use i_triangle::generic::triangulation::Triangulation; use i_triangle::generic::triangulator::Triangulator; use rand::RngExt; From 6d33d041e42446979435511ff3e9627ea2f1c3c6 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 24 Jul 2026 22:37:32 +0200 Subject: [PATCH 6/6] Update readme and doc comments to match the new API Closes https://github.com/iShape-Rust/iTriangle/issues/11 --- iTriangle/README.md | 17 +++++++++-------- iTriangle/src/generic/triangulatable.rs | 2 +- iTriangle/src/generic/triangulation.rs | 4 ++-- iTriangle/src/generic/triangulator.rs | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/iTriangle/README.md b/iTriangle/README.md index cc14cb8..32797e5 100644 --- a/iTriangle/README.md +++ b/iTriangle/README.md @@ -50,7 +50,8 @@ iTriangle is a high-performance 2D polygon triangulation library for Rust. It tu iTriangle is designed around a deterministic integer core: -- Floating-point APIs accept `f32` and `f64` compatible point types, then map them into integer coordinates before triangulation. +- Generic API accepts `f32` and `f64` compatible point types, then maps them into integer coordinates before triangulation. +- You can also pass `i16`, `i32`, or `i64` coordinates to the generic API - it applies an identity map on them. - Integer APIs work directly with `i16`, `i32`, or `i64` coordinates when your geometry is already quantized. - `i32` is the default integer coordinate type for floating-point input. - `i64` is useful for larger coordinate ranges or finer fixed precision. @@ -72,7 +73,7 @@ i_triangle = "0.45" Minimal example: ```rust -use i_triangle::float::triangulatable::Triangulatable; +use i_triangle::generic::triangulatable::Triangulatable; let contour = vec![ [0.0, 0.0], @@ -90,8 +91,8 @@ coordinates. If your geometry needs a different integer precision, choose it explicitly: ```rust -use i_triangle::float::triangulatable::Triangulatable; -use i_triangle::float::triangulator::Triangulator; +use i_triangle::generic::triangulatable::TriangulatableAs; +use i_triangle::generic::triangulator::Triangulator; let shape = vec![vec![ [0.0, 0.0], @@ -121,8 +122,8 @@ let mesh = triangulator.triangulate(&shape); ```rust -use i_triangle::float::triangulatable::Triangulatable; -use i_triangle::float::triangulation::Triangulation; +use i_triangle::generic::triangulatable::Triangulatable; +use i_triangle::generic::triangulation::Triangulation; let shape = vec![ vec![ @@ -199,8 +200,8 @@ println!("centroids: {:?}", centroids); If you need to triangulate many shapes, it is more efficient to use `Triangulator`. ```rust -use i_triangle::float::triangulation::Triangulation; -use i_triangle::float::triangulator::Triangulator; +use i_triangle::generic::triangulation::Triangulation; +use i_triangle::generic::triangulator::Triangulator; let contours = vec![ vec![[0.0, 0.0], [4.0, 0.0], [4.0, 4.0], [0.0, 4.0]], diff --git a/iTriangle/src/generic/triangulatable.rs b/iTriangle/src/generic/triangulatable.rs index ac4b41c..5f7dcb5 100644 --- a/iTriangle/src/generic/triangulatable.rs +++ b/iTriangle/src/generic/triangulatable.rs @@ -20,7 +20,7 @@ use i_tree::{Expiration, LayoutNumber}; /// /// # Implemented For /// - `[P]` / `[Contour

]` / `[Shape

]` (float) -/// - [`IntContour`] / [`IntShape`] / [`IntShapes`] (integer, identity adapter) +/// - [`IntContour`] / [`IntShape`] / [`IntShapes`] (integer, [`IntPointAdapter`]) pub trait Triangulatable

{ type Adapter: PointAdapter; diff --git a/iTriangle/src/generic/triangulation.rs b/iTriangle/src/generic/triangulation.rs index 23a25a8..7f6ae93 100644 --- a/iTriangle/src/generic/triangulation.rs +++ b/iTriangle/src/generic/triangulation.rs @@ -19,9 +19,9 @@ pub struct RawTriangulation { pub adapter: A, } -/// A flat triangulation result consisting of float points and triangle indices. +/// A flat triangulation result consisting of points and triangle indices. /// -/// Useful for rendering, exporting, or post-processing the mesh in float space. +/// Useful for rendering, exporting, or post-processing the mesh. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone)] pub struct Triangulation { diff --git a/iTriangle/src/generic/triangulator.rs b/iTriangle/src/generic/triangulator.rs index a0c2f21..94b15f4 100644 --- a/iTriangle/src/generic/triangulator.rs +++ b/iTriangle/src/generic/triangulator.rs @@ -12,7 +12,7 @@ use i_overlay::i_shape::int::shape::{IntContour, IntShape, IntShapes}; use i_overlay::i_shape::source::resource::ShapeResource; use i_tree::{Expiration, LayoutNumber}; -/// A reusable triangulator that converts float-based shapes into triangle meshes. +/// A reusable triangulator that converts shapes into triangle meshes. pub struct Triangulator where I: IntNumber + Expiration + LayoutNumber + SortKey,