mirror of
https://github.com/hannobraun/Fornjot
synced 2025-02-12 18:26:00 +00:00
Merge pull request #1596 from hannobraun/surface
Move reference to `Surface` from `Curve` to `HalfEdge`
This commit is contained in:
commit
abef26ea52
@ -13,13 +13,13 @@ use std::collections::BTreeMap;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::path::{GlobalPath, SurfacePath},
|
geometry::path::{GlobalPath, SurfacePath},
|
||||||
objects::{Curve, GlobalCurve},
|
objects::{Curve, GlobalCurve, Surface},
|
||||||
storage::{Handle, ObjectId},
|
storage::{Handle, ObjectId},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{path::RangeOnPath, Approx, ApproxPoint, Tolerance};
|
use super::{path::RangeOnPath, Approx, ApproxPoint, Tolerance};
|
||||||
|
|
||||||
impl Approx for (&Handle<Curve>, RangeOnPath) {
|
impl Approx for (&Handle<Curve>, &Surface, RangeOnPath) {
|
||||||
type Approximation = CurveApprox;
|
type Approximation = CurveApprox;
|
||||||
type Cache = CurveCache;
|
type Cache = CurveCache;
|
||||||
|
|
||||||
@ -28,13 +28,14 @@ impl Approx for (&Handle<Curve>, RangeOnPath) {
|
|||||||
tolerance: impl Into<Tolerance>,
|
tolerance: impl Into<Tolerance>,
|
||||||
cache: &mut Self::Cache,
|
cache: &mut Self::Cache,
|
||||||
) -> Self::Approximation {
|
) -> Self::Approximation {
|
||||||
let (curve, range) = self;
|
let (curve, surface, range) = self;
|
||||||
|
|
||||||
let global_curve = curve.global_form().clone();
|
let global_curve = curve.global_form().clone();
|
||||||
let global_curve_approx = match cache.get(global_curve.clone(), range) {
|
let global_curve_approx = match cache.get(global_curve.clone(), range) {
|
||||||
Some(approx) => approx,
|
Some(approx) => approx,
|
||||||
None => {
|
None => {
|
||||||
let approx = approx_global_curve(curve, range, tolerance);
|
let approx =
|
||||||
|
approx_global_curve(curve, surface, range, tolerance);
|
||||||
cache.insert(global_curve, range, approx)
|
cache.insert(global_curve, range, approx)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -53,6 +54,7 @@ impl Approx for (&Handle<Curve>, RangeOnPath) {
|
|||||||
|
|
||||||
fn approx_global_curve(
|
fn approx_global_curve(
|
||||||
curve: &Curve,
|
curve: &Curve,
|
||||||
|
surface: &Surface,
|
||||||
range: RangeOnPath,
|
range: RangeOnPath,
|
||||||
tolerance: impl Into<Tolerance>,
|
tolerance: impl Into<Tolerance>,
|
||||||
) -> GlobalCurveApprox {
|
) -> GlobalCurveApprox {
|
||||||
@ -62,7 +64,7 @@ fn approx_global_curve(
|
|||||||
// This will probably all be unified eventually, as `SurfacePath` and
|
// This will probably all be unified eventually, as `SurfacePath` and
|
||||||
// `GlobalPath` grow APIs that are better suited to implementing this code
|
// `GlobalPath` grow APIs that are better suited to implementing this code
|
||||||
// in a more abstract way.
|
// in a more abstract way.
|
||||||
let points = match (curve.path(), curve.surface().geometry().u) {
|
let points = match (curve.path(), surface.geometry().u) {
|
||||||
(SurfacePath::Circle(_), GlobalPath::Circle(_)) => {
|
(SurfacePath::Circle(_), GlobalPath::Circle(_)) => {
|
||||||
todo!(
|
todo!(
|
||||||
"Approximating a circle on a curved surface not supported yet."
|
"Approximating a circle on a curved surface not supported yet."
|
||||||
@ -88,8 +90,7 @@ fn approx_global_curve(
|
|||||||
// surface point available, so it needs to be computed
|
// surface point available, so it needs to be computed
|
||||||
// later anyway, in the general case.
|
// later anyway, in the general case.
|
||||||
|
|
||||||
let point_global = curve
|
let point_global = surface
|
||||||
.surface()
|
|
||||||
.geometry()
|
.geometry()
|
||||||
.point_from_surface_coords(point_surface);
|
.point_from_surface_coords(point_surface);
|
||||||
(point_curve, point_global)
|
(point_curve, point_global)
|
||||||
@ -102,17 +103,15 @@ fn approx_global_curve(
|
|||||||
[curve.path().point_from_path_coords(point_curve).u]
|
[curve.path().point_from_path_coords(point_curve).u]
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let approx_u = (curve.surface().geometry().u, range_u)
|
let approx_u = (surface.geometry().u, range_u)
|
||||||
.approx_with_cache(tolerance, &mut ());
|
.approx_with_cache(tolerance, &mut ());
|
||||||
|
|
||||||
let mut points = Vec::new();
|
let mut points = Vec::new();
|
||||||
for (u, _) in approx_u {
|
for (u, _) in approx_u {
|
||||||
let t = (u.t - line.origin().u) / line.direction().u;
|
let t = (u.t - line.origin().u) / line.direction().u;
|
||||||
let point_surface = curve.path().point_from_path_coords([t]);
|
let point_surface = curve.path().point_from_path_coords([t]);
|
||||||
let point_global = curve
|
let point_global =
|
||||||
.surface()
|
surface.geometry().point_from_surface_coords(point_surface);
|
||||||
.geometry()
|
|
||||||
.point_from_surface_coords(point_surface);
|
|
||||||
points.push((u, point_global));
|
points.push((u, point_global));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +210,7 @@ impl GlobalCurveApprox {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::f64::consts::TAU;
|
use std::{f64::consts::TAU, ops::Deref};
|
||||||
|
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
@ -220,7 +219,7 @@ mod tests {
|
|||||||
builder::{CurveBuilder, SurfaceBuilder},
|
builder::{CurveBuilder, SurfaceBuilder},
|
||||||
geometry::path::GlobalPath,
|
geometry::path::GlobalPath,
|
||||||
insert::Insert,
|
insert::Insert,
|
||||||
partial::{Partial, PartialCurve, PartialObject, PartialSurface},
|
partial::{PartialCurve, PartialObject, PartialSurface},
|
||||||
services::Services,
|
services::Services,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -231,17 +230,14 @@ mod tests {
|
|||||||
let mut services = Services::new();
|
let mut services = Services::new();
|
||||||
|
|
||||||
let surface = services.objects.surfaces.xz_plane();
|
let surface = services.objects.surfaces.xz_plane();
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: Partial::from(surface),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_line_from_points([[1., 1.], [2., 1.]]);
|
curve.update_as_line_from_points([[1., 1.], [2., 1.]]);
|
||||||
let curve = curve
|
let curve = curve
|
||||||
.build(&mut services.objects)
|
.build(&mut services.objects)
|
||||||
.insert(&mut services.objects);
|
.insert(&mut services.objects);
|
||||||
let range = RangeOnPath::from([[0.], [1.]]);
|
let range = RangeOnPath::from([[0.], [1.]]);
|
||||||
|
|
||||||
let approx = (&curve, range).approx(1.);
|
let approx = (&curve, surface.deref(), range).approx(1.);
|
||||||
|
|
||||||
assert_eq!(approx, CurveApprox::empty());
|
assert_eq!(approx, CurveApprox::empty());
|
||||||
}
|
}
|
||||||
@ -256,17 +252,14 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.build(&mut services.objects)
|
.build(&mut services.objects)
|
||||||
.insert(&mut services.objects);
|
.insert(&mut services.objects);
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: Partial::from(surface),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_line_from_points([[1., 1.], [1., 2.]]);
|
curve.update_as_line_from_points([[1., 1.], [1., 2.]]);
|
||||||
let curve = curve
|
let curve = curve
|
||||||
.build(&mut services.objects)
|
.build(&mut services.objects)
|
||||||
.insert(&mut services.objects);
|
.insert(&mut services.objects);
|
||||||
let range = RangeOnPath::from([[0.], [1.]]);
|
let range = RangeOnPath::from([[0.], [1.]]);
|
||||||
|
|
||||||
let approx = (&curve, range).approx(1.);
|
let approx = (&curve, surface.deref(), range).approx(1.);
|
||||||
|
|
||||||
assert_eq!(approx, CurveApprox::empty());
|
assert_eq!(approx, CurveApprox::empty());
|
||||||
}
|
}
|
||||||
@ -279,10 +272,7 @@ mod tests {
|
|||||||
let surface = PartialSurface::from_axes(path, [0., 0., 1.])
|
let surface = PartialSurface::from_axes(path, [0., 0., 1.])
|
||||||
.build(&mut services.objects)
|
.build(&mut services.objects)
|
||||||
.insert(&mut services.objects);
|
.insert(&mut services.objects);
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: Partial::from(surface.clone()),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_line_from_points([[0., 1.], [1., 1.]]);
|
curve.update_as_line_from_points([[0., 1.], [1., 1.]]);
|
||||||
let curve = curve
|
let curve = curve
|
||||||
.build(&mut services.objects)
|
.build(&mut services.objects)
|
||||||
@ -291,7 +281,7 @@ mod tests {
|
|||||||
let range = RangeOnPath::from([[0.], [TAU]]);
|
let range = RangeOnPath::from([[0.], [TAU]]);
|
||||||
let tolerance = 1.;
|
let tolerance = 1.;
|
||||||
|
|
||||||
let approx = (&curve, range).approx(tolerance);
|
let approx = (&curve, surface.deref(), range).approx(tolerance);
|
||||||
|
|
||||||
let expected_approx = (path, range)
|
let expected_approx = (path, range)
|
||||||
.approx(tolerance)
|
.approx(tolerance)
|
||||||
@ -312,10 +302,7 @@ mod tests {
|
|||||||
let mut services = Services::new();
|
let mut services = Services::new();
|
||||||
|
|
||||||
let surface = services.objects.surfaces.xz_plane();
|
let surface = services.objects.surfaces.xz_plane();
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: Partial::from(surface),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_circle_from_radius(1.);
|
curve.update_as_circle_from_radius(1.);
|
||||||
let curve = curve
|
let curve = curve
|
||||||
.build(&mut services.objects)
|
.build(&mut services.objects)
|
||||||
@ -323,16 +310,14 @@ mod tests {
|
|||||||
|
|
||||||
let range = RangeOnPath::from([[0.], [TAU]]);
|
let range = RangeOnPath::from([[0.], [TAU]]);
|
||||||
let tolerance = 1.;
|
let tolerance = 1.;
|
||||||
let approx = (&curve, range).approx(tolerance);
|
let approx = (&curve, surface.deref(), range).approx(tolerance);
|
||||||
|
|
||||||
let expected_approx = (curve.path(), range)
|
let expected_approx = (curve.path(), range)
|
||||||
.approx(tolerance)
|
.approx(tolerance)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, point_surface)| {
|
.map(|(_, point_surface)| {
|
||||||
let point_global = curve
|
let point_global =
|
||||||
.surface()
|
surface.geometry().point_from_surface_coords(point_surface);
|
||||||
.geometry()
|
|
||||||
.point_from_surface_coords(point_surface);
|
|
||||||
ApproxPoint::new(point_surface, point_global)
|
ApproxPoint::new(point_surface, point_global)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
//! approximations are usually used to build cycle approximations, and this way,
|
//! approximations are usually used to build cycle approximations, and this way,
|
||||||
//! the caller doesn't have to call with duplicate vertices.
|
//! the caller doesn't have to call with duplicate vertices.
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use crate::{objects::HalfEdge, storage::Handle};
|
use crate::{objects::HalfEdge, storage::Handle};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -30,8 +32,8 @@ impl Approx for &Handle<HalfEdge> {
|
|||||||
self.start_vertex().global_form().position(),
|
self.start_vertex().global_form().position(),
|
||||||
)
|
)
|
||||||
.with_source((self.clone(), self.boundary()[0]));
|
.with_source((self.clone(), self.boundary()[0]));
|
||||||
let curve_approx =
|
let curve_approx = (self.curve(), self.surface().deref(), range)
|
||||||
(self.curve(), range).approx_with_cache(tolerance, cache);
|
.approx_with_cache(tolerance, cache);
|
||||||
|
|
||||||
HalfEdgeApprox {
|
HalfEdgeApprox {
|
||||||
first,
|
first,
|
||||||
|
@ -87,10 +87,7 @@ mod tests {
|
|||||||
let mut services = Services::new();
|
let mut services = Services::new();
|
||||||
|
|
||||||
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: surface.clone(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_u_axis();
|
curve.update_as_u_axis();
|
||||||
let curve = curve.build(&mut services.objects);
|
let curve = curve.build(&mut services.objects);
|
||||||
let half_edge = {
|
let half_edge = {
|
||||||
@ -118,10 +115,7 @@ mod tests {
|
|||||||
let mut services = Services::new();
|
let mut services = Services::new();
|
||||||
|
|
||||||
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: surface.clone(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_u_axis();
|
curve.update_as_u_axis();
|
||||||
let curve = curve.build(&mut services.objects);
|
let curve = curve.build(&mut services.objects);
|
||||||
let half_edge = {
|
let half_edge = {
|
||||||
@ -149,10 +143,7 @@ mod tests {
|
|||||||
let mut services = Services::new();
|
let mut services = Services::new();
|
||||||
|
|
||||||
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: surface.clone(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_u_axis();
|
curve.update_as_u_axis();
|
||||||
let curve = curve.build(&mut services.objects);
|
let curve = curve.build(&mut services.objects);
|
||||||
let half_edge = {
|
let half_edge = {
|
||||||
@ -175,10 +166,7 @@ mod tests {
|
|||||||
let mut services = Services::new();
|
let mut services = Services::new();
|
||||||
|
|
||||||
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: surface.clone(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_u_axis();
|
curve.update_as_u_axis();
|
||||||
let curve = curve.build(&mut services.objects);
|
let curve = curve.build(&mut services.objects);
|
||||||
let half_edge = {
|
let half_edge = {
|
||||||
|
@ -163,10 +163,7 @@ mod tests {
|
|||||||
|
|
||||||
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
let surface = Partial::from(services.objects.surfaces.xy_plane());
|
||||||
|
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: surface.clone(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_line_from_points([[-3., 0.], [-2., 0.]]);
|
curve.update_as_line_from_points([[-3., 0.], [-2., 0.]]);
|
||||||
let curve = curve.build(&mut services.objects);
|
let curve = curve.build(&mut services.objects);
|
||||||
|
|
||||||
|
@ -132,11 +132,8 @@ mod tests {
|
|||||||
let intersection =
|
let intersection =
|
||||||
FaceFaceIntersection::compute([&a, &b], &mut services.objects);
|
FaceFaceIntersection::compute([&a, &b], &mut services.objects);
|
||||||
|
|
||||||
let expected_curves = surfaces.map(|surface| {
|
let expected_curves = surfaces.map(|_| {
|
||||||
let mut curve = PartialCurve {
|
let mut curve = PartialCurve::default();
|
||||||
surface: Partial::from(surface),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
curve.update_as_line_from_points([[0., 0.], [1., 0.]]);
|
curve.update_as_line_from_points([[0., 0.], [1., 0.]]);
|
||||||
curve
|
curve
|
||||||
.build(&mut services.objects)
|
.build(&mut services.objects)
|
||||||
|
@ -27,14 +27,10 @@ impl SurfaceSurfaceIntersection {
|
|||||||
// Adaptations were made to get the intersection curves in local
|
// Adaptations were made to get the intersection curves in local
|
||||||
// coordinates for each surface.
|
// coordinates for each surface.
|
||||||
|
|
||||||
let surfaces_and_planes = surfaces.map(|surface| {
|
let planes = surfaces.map(|surface| plane_from_surface(&surface));
|
||||||
let plane = plane_from_surface(&surface);
|
|
||||||
(surface, plane)
|
|
||||||
});
|
|
||||||
let [a, b] = surfaces_and_planes.clone().map(|(_, plane)| plane);
|
|
||||||
|
|
||||||
let (a_distance, a_normal) = a.constant_normal_form();
|
let [(a_distance, a_normal), (b_distance, b_normal)] =
|
||||||
let (b_distance, b_normal) = b.constant_normal_form();
|
planes.map(|plane| plane.constant_normal_form());
|
||||||
|
|
||||||
let direction = a_normal.cross(&b_normal);
|
let direction = a_normal.cross(&b_normal);
|
||||||
|
|
||||||
@ -57,11 +53,11 @@ impl SurfaceSurfaceIntersection {
|
|||||||
|
|
||||||
let line = Line::from_origin_and_direction(origin, direction);
|
let line = Line::from_origin_and_direction(origin, direction);
|
||||||
|
|
||||||
let curves = surfaces_and_planes.map(|(surface, plane)| {
|
let curves = planes.map(|plane| {
|
||||||
let path = SurfacePath::Line(plane.project_line(&line));
|
let path = SurfacePath::Line(plane.project_line(&line));
|
||||||
let global_form = GlobalCurve.insert(objects);
|
let global_form = GlobalCurve.insert(objects);
|
||||||
|
|
||||||
Curve::new(surface, path, global_form).insert(objects)
|
Curve::new(path, global_form).insert(objects)
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(Self {
|
Some(Self {
|
||||||
@ -92,7 +88,7 @@ mod tests {
|
|||||||
algorithms::transform::TransformObject,
|
algorithms::transform::TransformObject,
|
||||||
builder::CurveBuilder,
|
builder::CurveBuilder,
|
||||||
insert::Insert,
|
insert::Insert,
|
||||||
partial::{Partial, PartialCurve, PartialObject},
|
partial::{PartialCurve, PartialObject},
|
||||||
services::Services,
|
services::Services,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,18 +116,13 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut expected_xy = PartialCurve {
|
let mut expected_xy = PartialCurve::default();
|
||||||
surface: Partial::from(xy.clone()),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
expected_xy.update_as_u_axis();
|
expected_xy.update_as_u_axis();
|
||||||
let expected_xy = expected_xy
|
let expected_xy = expected_xy
|
||||||
.build(&mut services.objects)
|
.build(&mut services.objects)
|
||||||
.insert(&mut services.objects);
|
.insert(&mut services.objects);
|
||||||
let mut expected_xz = PartialCurve {
|
|
||||||
surface: Partial::from(xz.clone()),
|
let mut expected_xz = PartialCurve::default();
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
expected_xz.update_as_u_axis();
|
expected_xz.update_as_u_axis();
|
||||||
let expected_xz = expected_xz
|
let expected_xz = expected_xz
|
||||||
.build(&mut services.objects)
|
.build(&mut services.objects)
|
||||||
|
@ -19,6 +19,7 @@ impl Reverse for Handle<HalfEdge> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
HalfEdge::new(
|
HalfEdge::new(
|
||||||
|
self.surface().clone(),
|
||||||
self.curve().clone(),
|
self.curve().clone(),
|
||||||
vertices,
|
vertices,
|
||||||
self.global_form().clone(),
|
self.global_form().clone(),
|
||||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{Sweep, SweepCache};
|
use super::{Sweep, SweepCache};
|
||||||
|
|
||||||
impl Sweep for Handle<Curve> {
|
impl Sweep for (Handle<Curve>, &Surface) {
|
||||||
type Swept = Handle<Surface>;
|
type Swept = Handle<Surface>;
|
||||||
|
|
||||||
fn sweep_with_cache(
|
fn sweep_with_cache(
|
||||||
@ -21,7 +21,9 @@ impl Sweep for Handle<Curve> {
|
|||||||
_: &mut SweepCache,
|
_: &mut SweepCache,
|
||||||
objects: &mut Service<Objects>,
|
objects: &mut Service<Objects>,
|
||||||
) -> Self::Swept {
|
) -> Self::Swept {
|
||||||
match self.surface().geometry().u {
|
let (curve, surface) = self;
|
||||||
|
|
||||||
|
match surface.geometry().u {
|
||||||
GlobalPath::Circle(_) => {
|
GlobalPath::Circle(_) => {
|
||||||
// Sweeping a `Curve` creates a `Surface`. The u-axis of that
|
// Sweeping a `Curve` creates a `Surface`. The u-axis of that
|
||||||
// `Surface` is a `GlobalPath`, which we are computing below.
|
// `Surface` is a `GlobalPath`, which we are computing below.
|
||||||
@ -45,32 +47,24 @@ impl Sweep for Handle<Curve> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let u = match self.path() {
|
let u = match curve.path() {
|
||||||
SurfacePath::Circle(circle) => {
|
SurfacePath::Circle(circle) => {
|
||||||
let center = self
|
let center = surface
|
||||||
.surface()
|
|
||||||
.geometry()
|
.geometry()
|
||||||
.point_from_surface_coords(circle.center());
|
.point_from_surface_coords(circle.center());
|
||||||
let a = self
|
let a =
|
||||||
.surface()
|
surface.geometry().vector_from_surface_coords(circle.a());
|
||||||
.geometry()
|
let b =
|
||||||
.vector_from_surface_coords(circle.a());
|
surface.geometry().vector_from_surface_coords(circle.b());
|
||||||
let b = self
|
|
||||||
.surface()
|
|
||||||
.geometry()
|
|
||||||
.vector_from_surface_coords(circle.b());
|
|
||||||
|
|
||||||
let circle = Circle::new(center, a, b);
|
let circle = Circle::new(center, a, b);
|
||||||
|
|
||||||
GlobalPath::Circle(circle)
|
GlobalPath::Circle(circle)
|
||||||
}
|
}
|
||||||
SurfacePath::Line(line) => {
|
SurfacePath::Line(line) => {
|
||||||
let origin = self
|
let origin =
|
||||||
.surface()
|
surface.geometry().point_from_surface_coords(line.origin());
|
||||||
.geometry()
|
let direction = surface
|
||||||
.point_from_surface_coords(line.origin());
|
|
||||||
let direction = self
|
|
||||||
.surface()
|
|
||||||
.geometry()
|
.geometry()
|
||||||
.vector_from_surface_coords(line.direction());
|
.vector_from_surface_coords(line.direction());
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use fj_interop::{ext::ArrayExt, mesh::Color};
|
use fj_interop::{ext::ArrayExt, mesh::Color};
|
||||||
use fj_math::{Point, Scalar, Vector};
|
use fj_math::{Point, Scalar, Vector};
|
||||||
|
|
||||||
@ -34,7 +36,8 @@ impl Sweep for (Handle<HalfEdge>, Color) {
|
|||||||
// be created by sweeping a curve, so let's sweep the curve of the edge
|
// be created by sweeping a curve, so let's sweep the curve of the edge
|
||||||
// we're sweeping.
|
// we're sweeping.
|
||||||
face.exterior.write().surface = Partial::from(
|
face.exterior.write().surface = Partial::from(
|
||||||
edge.curve().clone().sweep_with_cache(path, cache, objects),
|
(edge.curve().clone(), edge.surface().deref())
|
||||||
|
.sweep_with_cache(path, cache, objects),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Now we're ready to create the edges.
|
// Now we're ready to create the edges.
|
||||||
@ -194,7 +197,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let side_up = {
|
let side_up = {
|
||||||
let mut side_up = PartialHalfEdge::default();
|
let mut side_up = PartialHalfEdge::default();
|
||||||
side_up.curve.write().surface = surface.clone();
|
side_up.replace_surface(surface.clone());
|
||||||
|
|
||||||
{
|
{
|
||||||
let [back, front] = side_up
|
let [back, front] = side_up
|
||||||
@ -206,7 +209,6 @@ mod tests {
|
|||||||
|
|
||||||
let mut front = front.write();
|
let mut front = front.write();
|
||||||
front.position = Some([1., 1.].into());
|
front.position = Some([1., 1.].into());
|
||||||
front.surface = surface.clone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
side_up.infer_global_form();
|
side_up.infer_global_form();
|
||||||
@ -216,7 +218,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let top = {
|
let top = {
|
||||||
let mut top = PartialHalfEdge::default();
|
let mut top = PartialHalfEdge::default();
|
||||||
top.curve.write().surface = surface.clone();
|
top.replace_surface(surface.clone());
|
||||||
|
|
||||||
{
|
{
|
||||||
let [(back, back_surface), (front, front_surface)] =
|
let [(back, back_surface), (front, front_surface)] =
|
||||||
@ -228,7 +230,6 @@ mod tests {
|
|||||||
*front = Some(Point::from([0.]));
|
*front = Some(Point::from([0.]));
|
||||||
let mut front_surface = front_surface.write();
|
let mut front_surface = front_surface.write();
|
||||||
front_surface.position = Some([0., 1.].into());
|
front_surface.position = Some([0., 1.].into());
|
||||||
front_surface.surface = surface.clone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
top.infer_global_form();
|
top.infer_global_form();
|
||||||
@ -243,7 +244,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let side_down = {
|
let side_down = {
|
||||||
let mut side_down = PartialHalfEdge::default();
|
let mut side_down = PartialHalfEdge::default();
|
||||||
side_down.curve.write().surface = surface;
|
side_down.replace_surface(surface);
|
||||||
|
|
||||||
let [(back, back_surface), (front, front_surface)] =
|
let [(back, back_surface), (front, front_surface)] =
|
||||||
side_down.vertices.each_mut_ext();
|
side_down.vertices.each_mut_ext();
|
||||||
|
@ -18,16 +18,12 @@ impl TransformObject for Curve {
|
|||||||
// coordinates, and thus transforming `surface` takes care of it.
|
// coordinates, and thus transforming `surface` takes care of it.
|
||||||
let path = self.path();
|
let path = self.path();
|
||||||
|
|
||||||
let surface = self
|
|
||||||
.surface()
|
|
||||||
.clone()
|
|
||||||
.transform_with_cache(transform, objects, cache);
|
|
||||||
let global_form = self
|
let global_form = self
|
||||||
.global_form()
|
.global_form()
|
||||||
.clone()
|
.clone()
|
||||||
.transform_with_cache(transform, objects, cache);
|
.transform_with_cache(transform, objects, cache);
|
||||||
|
|
||||||
Self::new(surface, path, global_form)
|
Self::new(path, global_form)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,10 @@ impl TransformObject for HalfEdge {
|
|||||||
objects: &mut Service<Objects>,
|
objects: &mut Service<Objects>,
|
||||||
cache: &mut TransformCache,
|
cache: &mut TransformCache,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let surface = self
|
||||||
|
.surface()
|
||||||
|
.clone()
|
||||||
|
.transform_with_cache(transform, objects, cache);
|
||||||
let curve = self
|
let curve = self
|
||||||
.curve()
|
.curve()
|
||||||
.clone()
|
.clone()
|
||||||
@ -32,7 +36,7 @@ impl TransformObject for HalfEdge {
|
|||||||
.clone()
|
.clone()
|
||||||
.transform_with_cache(transform, objects, cache);
|
.transform_with_cache(transform, objects, cache);
|
||||||
|
|
||||||
Self::new(curve, boundary, global_form)
|
Self::new(surface, curve, boundary, global_form)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
|||||||
fn replace_surface(&mut self, surface: impl Into<Partial<Surface>>) {
|
fn replace_surface(&mut self, surface: impl Into<Partial<Surface>>) {
|
||||||
let surface = surface.into();
|
let surface = surface.into();
|
||||||
|
|
||||||
self.curve.write().surface = surface.clone();
|
self.surface = surface.clone();
|
||||||
|
|
||||||
for vertex in &mut self.vertices {
|
for vertex in &mut self.vertices {
|
||||||
vertex.1.write().surface = surface.clone();
|
vertex.1.write().surface = surface.clone();
|
||||||
@ -134,14 +134,11 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
|||||||
surface: impl Into<Partial<Surface>>,
|
surface: impl Into<Partial<Surface>>,
|
||||||
points: [impl Into<Point<2>>; 2],
|
points: [impl Into<Point<2>>; 2],
|
||||||
) {
|
) {
|
||||||
let surface = surface.into();
|
self.replace_surface(surface.into());
|
||||||
|
|
||||||
self.curve.write().surface = surface.clone();
|
|
||||||
|
|
||||||
for (vertex, point) in self.vertices.each_mut_ext().zip_ext(points) {
|
for (vertex, point) in self.vertices.each_mut_ext().zip_ext(points) {
|
||||||
let mut surface_form = vertex.1.write();
|
let mut surface_form = vertex.1.write();
|
||||||
surface_form.position = Some(point.into());
|
surface_form.position = Some(point.into());
|
||||||
surface_form.surface = surface.clone();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_as_line_segment()
|
self.update_as_line_segment()
|
||||||
@ -196,7 +193,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
|
|||||||
|
|
||||||
self.curve.write().path =
|
self.curve.write().path =
|
||||||
other.read().curve.read().path.as_ref().and_then(|path| {
|
other.read().curve.read().path.as_ref().and_then(|path| {
|
||||||
match other.read().curve.read().surface.read().geometry {
|
match other.read().surface.read().geometry {
|
||||||
Some(surface) => {
|
Some(surface) => {
|
||||||
// We have information about the other edge's surface
|
// We have information about the other edge's surface
|
||||||
// available. We need to use that to interpret what the
|
// available. We need to use that to interpret what the
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
geometry::path::SurfacePath,
|
geometry::path::SurfacePath,
|
||||||
objects::Surface,
|
|
||||||
storage::{Handle, HandleWrapper},
|
storage::{Handle, HandleWrapper},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -8,19 +7,16 @@ use crate::{
|
|||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||||
pub struct Curve {
|
pub struct Curve {
|
||||||
path: SurfacePath,
|
path: SurfacePath,
|
||||||
surface: Handle<Surface>,
|
|
||||||
global_form: HandleWrapper<GlobalCurve>,
|
global_form: HandleWrapper<GlobalCurve>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Curve {
|
impl Curve {
|
||||||
/// Construct a new instance of `Curve`
|
/// Construct a new instance of `Curve`
|
||||||
pub fn new(
|
pub fn new(
|
||||||
surface: Handle<Surface>,
|
|
||||||
path: SurfacePath,
|
path: SurfacePath,
|
||||||
global_form: impl Into<HandleWrapper<GlobalCurve>>,
|
global_form: impl Into<HandleWrapper<GlobalCurve>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
surface,
|
|
||||||
path,
|
path,
|
||||||
global_form: global_form.into(),
|
global_form: global_form.into(),
|
||||||
}
|
}
|
||||||
@ -31,11 +27,6 @@ impl Curve {
|
|||||||
self.path
|
self.path
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access the surface that the curve is defined in
|
|
||||||
pub fn surface(&self) -> &Handle<Surface> {
|
|
||||||
&self.surface
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Access the global form of the curve
|
/// Access the global form of the curve
|
||||||
pub fn global_form(&self) -> &Handle<GlobalCurve> {
|
pub fn global_form(&self) -> &Handle<GlobalCurve> {
|
||||||
&self.global_form
|
&self.global_form
|
||||||
|
@ -39,7 +39,7 @@ impl Cycle {
|
|||||||
/// Access the surface that the cycle is in
|
/// Access the surface that the cycle is in
|
||||||
pub fn surface(&self) -> &Handle<Surface> {
|
pub fn surface(&self) -> &Handle<Surface> {
|
||||||
if let Some(half_edge) = self.half_edges.first() {
|
if let Some(half_edge) = self.half_edges.first() {
|
||||||
return half_edge.curve().surface();
|
return half_edge.surface();
|
||||||
}
|
}
|
||||||
|
|
||||||
unreachable!(
|
unreachable!(
|
||||||
|
@ -4,13 +4,14 @@ use fj_interop::ext::ArrayExt;
|
|||||||
use fj_math::Point;
|
use fj_math::Point;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
objects::{Curve, GlobalCurve, GlobalVertex, SurfaceVertex},
|
objects::{Curve, GlobalCurve, GlobalVertex, Surface, SurfaceVertex},
|
||||||
storage::{Handle, HandleWrapper},
|
storage::{Handle, HandleWrapper},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A half-edge
|
/// A half-edge
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||||
pub struct HalfEdge {
|
pub struct HalfEdge {
|
||||||
|
surface: Handle<Surface>,
|
||||||
curve: Handle<Curve>,
|
curve: Handle<Curve>,
|
||||||
boundary: [(Point<1>, Handle<SurfaceVertex>); 2],
|
boundary: [(Point<1>, Handle<SurfaceVertex>); 2],
|
||||||
global_form: Handle<GlobalEdge>,
|
global_form: Handle<GlobalEdge>,
|
||||||
@ -19,17 +20,24 @@ pub struct HalfEdge {
|
|||||||
impl HalfEdge {
|
impl HalfEdge {
|
||||||
/// Create an instance of `HalfEdge`
|
/// Create an instance of `HalfEdge`
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
surface: Handle<Surface>,
|
||||||
curve: Handle<Curve>,
|
curve: Handle<Curve>,
|
||||||
boundary: [(Point<1>, Handle<SurfaceVertex>); 2],
|
boundary: [(Point<1>, Handle<SurfaceVertex>); 2],
|
||||||
global_form: Handle<GlobalEdge>,
|
global_form: Handle<GlobalEdge>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
surface,
|
||||||
curve,
|
curve,
|
||||||
boundary,
|
boundary,
|
||||||
global_form,
|
global_form,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Access the surface that the half-edge is defined in
|
||||||
|
pub fn surface(&self) -> &Handle<Surface> {
|
||||||
|
&self.surface
|
||||||
|
}
|
||||||
|
|
||||||
/// Access the curve that defines the half-edge's geometry
|
/// Access the curve that defines the half-edge's geometry
|
||||||
pub fn curve(&self) -> &Handle<Curve> {
|
pub fn curve(&self) -> &Handle<Curve> {
|
||||||
&self.curve
|
&self.curve
|
||||||
|
@ -2,7 +2,7 @@ use fj_math::Scalar;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::path::SurfacePath,
|
geometry::path::SurfacePath,
|
||||||
objects::{Curve, GlobalCurve, Objects, Surface},
|
objects::{Curve, GlobalCurve, Objects},
|
||||||
partial::{FullToPartialCache, Partial, PartialObject},
|
partial::{FullToPartialCache, Partial, PartialObject},
|
||||||
services::Service,
|
services::Service,
|
||||||
};
|
};
|
||||||
@ -13,9 +13,6 @@ pub struct PartialCurve {
|
|||||||
/// The path that defines the curve
|
/// The path that defines the curve
|
||||||
pub path: Option<MaybeSurfacePath>,
|
pub path: Option<MaybeSurfacePath>,
|
||||||
|
|
||||||
/// The surface the curve is defined in
|
|
||||||
pub surface: Partial<Surface>,
|
|
||||||
|
|
||||||
/// The global form of the curve
|
/// The global form of the curve
|
||||||
pub global_form: Partial<GlobalCurve>,
|
pub global_form: Partial<GlobalCurve>,
|
||||||
}
|
}
|
||||||
@ -26,7 +23,6 @@ impl PartialObject for PartialCurve {
|
|||||||
fn from_full(curve: &Self::Full, cache: &mut FullToPartialCache) -> Self {
|
fn from_full(curve: &Self::Full, cache: &mut FullToPartialCache) -> Self {
|
||||||
Self {
|
Self {
|
||||||
path: Some(curve.path().into()),
|
path: Some(curve.path().into()),
|
||||||
surface: Partial::from_full(curve.surface().clone(), cache),
|
|
||||||
global_form: Partial::from_full(curve.global_form().clone(), cache),
|
global_form: Partial::from_full(curve.global_form().clone(), cache),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,10 +36,9 @@ impl PartialObject for PartialCurve {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let surface = self.surface.build(objects);
|
|
||||||
let global_form = self.global_form.build(objects);
|
let global_form = self.global_form.build(objects);
|
||||||
|
|
||||||
Curve::new(surface, path, global_form)
|
Curve::new(path, global_form)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ use fj_math::Point;
|
|||||||
use crate::{
|
use crate::{
|
||||||
objects::{
|
objects::{
|
||||||
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
|
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
|
||||||
SurfaceVertex,
|
Surface, SurfaceVertex,
|
||||||
},
|
},
|
||||||
partial::{
|
partial::{
|
||||||
FullToPartialCache, Partial, PartialObject, PartialSurfaceVertex,
|
FullToPartialCache, Partial, PartialObject, PartialSurfaceVertex,
|
||||||
@ -17,6 +17,9 @@ use crate::{
|
|||||||
/// A partial [`HalfEdge`]
|
/// A partial [`HalfEdge`]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PartialHalfEdge {
|
pub struct PartialHalfEdge {
|
||||||
|
/// The surface that the half-edge is defined in
|
||||||
|
pub surface: Partial<Surface>,
|
||||||
|
|
||||||
/// The curve that the half-edge is defined in
|
/// The curve that the half-edge is defined in
|
||||||
pub curve: Partial<Curve>,
|
pub curve: Partial<Curve>,
|
||||||
|
|
||||||
@ -35,6 +38,7 @@ impl PartialObject for PartialHalfEdge {
|
|||||||
cache: &mut FullToPartialCache,
|
cache: &mut FullToPartialCache,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
surface: Partial::from_full(half_edge.surface().clone(), cache),
|
||||||
curve: Partial::from_full(half_edge.curve().clone(), cache),
|
curve: Partial::from_full(half_edge.curve().clone(), cache),
|
||||||
vertices: half_edge
|
vertices: half_edge
|
||||||
.boundary()
|
.boundary()
|
||||||
@ -53,6 +57,7 @@ impl PartialObject for PartialHalfEdge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build(self, objects: &mut Service<Objects>) -> Self::Full {
|
fn build(self, objects: &mut Service<Objects>) -> Self::Full {
|
||||||
|
let surface = self.surface.build(objects);
|
||||||
let curve = self.curve.build(objects);
|
let curve = self.curve.build(objects);
|
||||||
let vertices = self.vertices.map(|mut vertex| {
|
let vertices = self.vertices.map(|mut vertex| {
|
||||||
let position_surface = vertex.1.read().position;
|
let position_surface = vertex.1.read().position;
|
||||||
@ -76,10 +81,9 @@ impl PartialObject for PartialHalfEdge {
|
|||||||
// Infer global position, if not available.
|
// Infer global position, if not available.
|
||||||
let position_global = vertex.1.read().global_form.read().position;
|
let position_global = vertex.1.read().global_form.read().position;
|
||||||
if position_global.is_none() {
|
if position_global.is_none() {
|
||||||
let surface = curve.surface().geometry();
|
let position_global = surface
|
||||||
|
.geometry()
|
||||||
let position_global =
|
.point_from_surface_coords(position_surface);
|
||||||
surface.point_from_surface_coords(position_surface);
|
|
||||||
vertex.1.write().global_form.write().position =
|
vertex.1.write().global_form.write().position =
|
||||||
Some(position_global);
|
Some(position_global);
|
||||||
}
|
}
|
||||||
@ -92,18 +96,18 @@ impl PartialObject for PartialHalfEdge {
|
|||||||
});
|
});
|
||||||
let global_form = self.global_form.build(objects);
|
let global_form = self.global_form.build(objects);
|
||||||
|
|
||||||
HalfEdge::new(curve, vertices, global_form)
|
HalfEdge::new(surface, curve, vertices, global_form)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PartialHalfEdge {
|
impl Default for PartialHalfEdge {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let surface = Partial::new();
|
||||||
|
|
||||||
let curve = Partial::<Curve>::new();
|
let curve = Partial::<Curve>::new();
|
||||||
let vertices = array::from_fn(|_| {
|
let vertices = array::from_fn(|_| {
|
||||||
let surface = Partial::new();
|
|
||||||
|
|
||||||
let surface_form = Partial::from_partial(PartialSurfaceVertex {
|
let surface_form = Partial::from_partial(PartialSurfaceVertex {
|
||||||
surface,
|
surface: surface.clone(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -125,6 +129,7 @@ impl Default for PartialHalfEdge {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
surface,
|
||||||
curve,
|
curve,
|
||||||
vertices,
|
vertices,
|
||||||
global_form,
|
global_form,
|
||||||
|
@ -165,13 +165,13 @@ impl HalfEdgeValidationError {
|
|||||||
half_edge: &HalfEdge,
|
half_edge: &HalfEdge,
|
||||||
errors: &mut Vec<ValidationError>,
|
errors: &mut Vec<ValidationError>,
|
||||||
) {
|
) {
|
||||||
let curve_surface = half_edge.curve().surface();
|
let surface = half_edge.surface();
|
||||||
let surface_form_surface = half_edge.start_vertex().surface();
|
let surface_form_surface = half_edge.start_vertex().surface();
|
||||||
|
|
||||||
if curve_surface.id() != surface_form_surface.id() {
|
if surface.id() != surface_form_surface.id() {
|
||||||
errors.push(
|
errors.push(
|
||||||
Box::new(Self::SurfaceMismatch {
|
Box::new(Self::SurfaceMismatch {
|
||||||
curve_surface: curve_surface.clone(),
|
curve_surface: surface.clone(),
|
||||||
surface_form_surface: surface_form_surface.clone(),
|
surface_form_surface: surface_form_surface.clone(),
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
@ -240,7 +240,12 @@ mod tests {
|
|||||||
.boundary()
|
.boundary()
|
||||||
.zip_ext(valid.surface_vertices().map(Clone::clone));
|
.zip_ext(valid.surface_vertices().map(Clone::clone));
|
||||||
|
|
||||||
HalfEdge::new(valid.curve().clone(), vertices, global_form)
|
HalfEdge::new(
|
||||||
|
valid.surface().clone(),
|
||||||
|
valid.curve().clone(),
|
||||||
|
vertices,
|
||||||
|
global_form,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
valid.validate_and_return_first_error()?;
|
valid.validate_and_return_first_error()?;
|
||||||
@ -282,7 +287,12 @@ mod tests {
|
|||||||
.boundary()
|
.boundary()
|
||||||
.zip_ext(valid.surface_vertices().map(Clone::clone));
|
.zip_ext(valid.surface_vertices().map(Clone::clone));
|
||||||
|
|
||||||
HalfEdge::new(valid.curve().clone(), vertices, global_form)
|
HalfEdge::new(
|
||||||
|
valid.surface().clone(),
|
||||||
|
valid.curve().clone(),
|
||||||
|
vertices,
|
||||||
|
global_form,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
valid.validate_and_return_first_error()?;
|
valid.validate_and_return_first_error()?;
|
||||||
@ -318,6 +328,7 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
HalfEdge::new(
|
HalfEdge::new(
|
||||||
|
valid.surface().clone(),
|
||||||
valid.curve().clone(),
|
valid.curve().clone(),
|
||||||
vertices,
|
vertices,
|
||||||
valid.global_form().clone(),
|
valid.global_form().clone(),
|
||||||
@ -349,6 +360,7 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
HalfEdge::new(
|
HalfEdge::new(
|
||||||
|
valid.surface().clone(),
|
||||||
valid.curve().clone(),
|
valid.curve().clone(),
|
||||||
vertices,
|
vertices,
|
||||||
valid.global_form().clone(),
|
valid.global_form().clone(),
|
||||||
|
@ -31,13 +31,7 @@ impl Shape for fj::Sketch {
|
|||||||
let surface = Partial::from(surface);
|
let surface = Partial::from(surface);
|
||||||
|
|
||||||
let mut half_edge = PartialHalfEdge::default();
|
let mut half_edge = PartialHalfEdge::default();
|
||||||
|
half_edge.replace_surface(surface);
|
||||||
half_edge.curve.write().surface = surface.clone();
|
|
||||||
|
|
||||||
for vertex in &mut half_edge.vertices {
|
|
||||||
vertex.1.write().surface = surface.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
half_edge.update_as_circle_from_radius(circle.radius());
|
half_edge.update_as_circle_from_radius(circle.radius());
|
||||||
|
|
||||||
Partial::from_partial(half_edge)
|
Partial::from_partial(half_edge)
|
||||||
|
Loading…
Reference in New Issue
Block a user