Merge pull request #1596 from hannobraun/surface

Move reference to `Surface` from `Curve` to `HalfEdge`
This commit is contained in:
Hanno Braun 2023-02-17 12:29:49 +01:00 committed by GitHub
commit abef26ea52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 117 additions and 159 deletions

View File

@ -13,13 +13,13 @@ use std::collections::BTreeMap;
use crate::{
geometry::path::{GlobalPath, SurfacePath},
objects::{Curve, GlobalCurve},
objects::{Curve, GlobalCurve, Surface},
storage::{Handle, ObjectId},
};
use super::{path::RangeOnPath, Approx, ApproxPoint, Tolerance};
impl Approx for (&Handle<Curve>, RangeOnPath) {
impl Approx for (&Handle<Curve>, &Surface, RangeOnPath) {
type Approximation = CurveApprox;
type Cache = CurveCache;
@ -28,13 +28,14 @@ impl Approx for (&Handle<Curve>, RangeOnPath) {
tolerance: impl Into<Tolerance>,
cache: &mut Self::Cache,
) -> Self::Approximation {
let (curve, range) = self;
let (curve, surface, range) = self;
let global_curve = curve.global_form().clone();
let global_curve_approx = match cache.get(global_curve.clone(), range) {
Some(approx) => approx,
None => {
let approx = approx_global_curve(curve, range, tolerance);
let approx =
approx_global_curve(curve, surface, range, tolerance);
cache.insert(global_curve, range, approx)
}
};
@ -53,6 +54,7 @@ impl Approx for (&Handle<Curve>, RangeOnPath) {
fn approx_global_curve(
curve: &Curve,
surface: &Surface,
range: RangeOnPath,
tolerance: impl Into<Tolerance>,
) -> GlobalCurveApprox {
@ -62,7 +64,7 @@ fn approx_global_curve(
// This will probably all be unified eventually, as `SurfacePath` and
// `GlobalPath` grow APIs that are better suited to implementing this code
// 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(_)) => {
todo!(
"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
// later anyway, in the general case.
let point_global = curve
.surface()
let point_global = surface
.geometry()
.point_from_surface_coords(point_surface);
(point_curve, point_global)
@ -102,17 +103,15 @@ fn approx_global_curve(
[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 ());
let mut points = Vec::new();
for (u, _) in approx_u {
let t = (u.t - line.origin().u) / line.direction().u;
let point_surface = curve.path().point_from_path_coords([t]);
let point_global = curve
.surface()
.geometry()
.point_from_surface_coords(point_surface);
let point_global =
surface.geometry().point_from_surface_coords(point_surface);
points.push((u, point_global));
}
@ -211,7 +210,7 @@ impl GlobalCurveApprox {
#[cfg(test)]
mod tests {
use std::f64::consts::TAU;
use std::{f64::consts::TAU, ops::Deref};
use pretty_assertions::assert_eq;
@ -220,7 +219,7 @@ mod tests {
builder::{CurveBuilder, SurfaceBuilder},
geometry::path::GlobalPath,
insert::Insert,
partial::{Partial, PartialCurve, PartialObject, PartialSurface},
partial::{PartialCurve, PartialObject, PartialSurface},
services::Services,
};
@ -231,17 +230,14 @@ mod tests {
let mut services = Services::new();
let surface = services.objects.surfaces.xz_plane();
let mut curve = PartialCurve {
surface: Partial::from(surface),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[1., 1.], [2., 1.]]);
let curve = curve
.build(&mut services.objects)
.insert(&mut services.objects);
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());
}
@ -256,17 +252,14 @@ mod tests {
)
.build(&mut services.objects)
.insert(&mut services.objects);
let mut curve = PartialCurve {
surface: Partial::from(surface),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[1., 1.], [1., 2.]]);
let curve = curve
.build(&mut services.objects)
.insert(&mut services.objects);
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());
}
@ -279,10 +272,7 @@ mod tests {
let surface = PartialSurface::from_axes(path, [0., 0., 1.])
.build(&mut services.objects)
.insert(&mut services.objects);
let mut curve = PartialCurve {
surface: Partial::from(surface.clone()),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[0., 1.], [1., 1.]]);
let curve = curve
.build(&mut services.objects)
@ -291,7 +281,7 @@ mod tests {
let range = RangeOnPath::from([[0.], [TAU]]);
let tolerance = 1.;
let approx = (&curve, range).approx(tolerance);
let approx = (&curve, surface.deref(), range).approx(tolerance);
let expected_approx = (path, range)
.approx(tolerance)
@ -312,10 +302,7 @@ mod tests {
let mut services = Services::new();
let surface = services.objects.surfaces.xz_plane();
let mut curve = PartialCurve {
surface: Partial::from(surface),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_circle_from_radius(1.);
let curve = curve
.build(&mut services.objects)
@ -323,16 +310,14 @@ mod tests {
let range = RangeOnPath::from([[0.], [TAU]]);
let tolerance = 1.;
let approx = (&curve, range).approx(tolerance);
let approx = (&curve, surface.deref(), range).approx(tolerance);
let expected_approx = (curve.path(), range)
.approx(tolerance)
.into_iter()
.map(|(_, point_surface)| {
let point_global = curve
.surface()
.geometry()
.point_from_surface_coords(point_surface);
let point_global =
surface.geometry().point_from_surface_coords(point_surface);
ApproxPoint::new(point_surface, point_global)
})
.collect::<Vec<_>>();

View File

@ -5,6 +5,8 @@
//! approximations are usually used to build cycle approximations, and this way,
//! the caller doesn't have to call with duplicate vertices.
use std::ops::Deref;
use crate::{objects::HalfEdge, storage::Handle};
use super::{
@ -30,8 +32,8 @@ impl Approx for &Handle<HalfEdge> {
self.start_vertex().global_form().position(),
)
.with_source((self.clone(), self.boundary()[0]));
let curve_approx =
(self.curve(), range).approx_with_cache(tolerance, cache);
let curve_approx = (self.curve(), self.surface().deref(), range)
.approx_with_cache(tolerance, cache);
HalfEdgeApprox {
first,

View File

@ -87,10 +87,7 @@ mod tests {
let mut services = Services::new();
let surface = Partial::from(services.objects.surfaces.xy_plane());
let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_u_axis();
let curve = curve.build(&mut services.objects);
let half_edge = {
@ -118,10 +115,7 @@ mod tests {
let mut services = Services::new();
let surface = Partial::from(services.objects.surfaces.xy_plane());
let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_u_axis();
let curve = curve.build(&mut services.objects);
let half_edge = {
@ -149,10 +143,7 @@ mod tests {
let mut services = Services::new();
let surface = Partial::from(services.objects.surfaces.xy_plane());
let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_u_axis();
let curve = curve.build(&mut services.objects);
let half_edge = {
@ -175,10 +166,7 @@ mod tests {
let mut services = Services::new();
let surface = Partial::from(services.objects.surfaces.xy_plane());
let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_u_axis();
let curve = curve.build(&mut services.objects);
let half_edge = {

View File

@ -163,10 +163,7 @@ mod tests {
let surface = Partial::from(services.objects.surfaces.xy_plane());
let mut curve = PartialCurve {
surface: surface.clone(),
..Default::default()
};
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[-3., 0.], [-2., 0.]]);
let curve = curve.build(&mut services.objects);

View File

@ -132,11 +132,8 @@ mod tests {
let intersection =
FaceFaceIntersection::compute([&a, &b], &mut services.objects);
let expected_curves = surfaces.map(|surface| {
let mut curve = PartialCurve {
surface: Partial::from(surface),
..Default::default()
};
let expected_curves = surfaces.map(|_| {
let mut curve = PartialCurve::default();
curve.update_as_line_from_points([[0., 0.], [1., 0.]]);
curve
.build(&mut services.objects)

View File

@ -27,14 +27,10 @@ impl SurfaceSurfaceIntersection {
// Adaptations were made to get the intersection curves in local
// coordinates for each surface.
let surfaces_and_planes = surfaces.map(|surface| {
let plane = plane_from_surface(&surface);
(surface, plane)
});
let [a, b] = surfaces_and_planes.clone().map(|(_, plane)| plane);
let planes = surfaces.map(|surface| plane_from_surface(&surface));
let (a_distance, a_normal) = a.constant_normal_form();
let (b_distance, b_normal) = b.constant_normal_form();
let [(a_distance, a_normal), (b_distance, b_normal)] =
planes.map(|plane| plane.constant_normal_form());
let direction = a_normal.cross(&b_normal);
@ -57,11 +53,11 @@ impl SurfaceSurfaceIntersection {
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 global_form = GlobalCurve.insert(objects);
Curve::new(surface, path, global_form).insert(objects)
Curve::new(path, global_form).insert(objects)
});
Some(Self {
@ -92,7 +88,7 @@ mod tests {
algorithms::transform::TransformObject,
builder::CurveBuilder,
insert::Insert,
partial::{Partial, PartialCurve, PartialObject},
partial::{PartialCurve, PartialObject},
services::Services,
};
@ -120,18 +116,13 @@ mod tests {
None,
);
let mut expected_xy = PartialCurve {
surface: Partial::from(xy.clone()),
..Default::default()
};
let mut expected_xy = PartialCurve::default();
expected_xy.update_as_u_axis();
let expected_xy = expected_xy
.build(&mut services.objects)
.insert(&mut services.objects);
let mut expected_xz = PartialCurve {
surface: Partial::from(xz.clone()),
..Default::default()
};
let mut expected_xz = PartialCurve::default();
expected_xz.update_as_u_axis();
let expected_xz = expected_xz
.build(&mut services.objects)

View File

@ -19,6 +19,7 @@ impl Reverse for Handle<HalfEdge> {
};
HalfEdge::new(
self.surface().clone(),
self.curve().clone(),
vertices,
self.global_form().clone(),

View File

@ -12,7 +12,7 @@ use crate::{
use super::{Sweep, SweepCache};
impl Sweep for Handle<Curve> {
impl Sweep for (Handle<Curve>, &Surface) {
type Swept = Handle<Surface>;
fn sweep_with_cache(
@ -21,7 +21,9 @@ impl Sweep for Handle<Curve> {
_: &mut SweepCache,
objects: &mut Service<Objects>,
) -> Self::Swept {
match self.surface().geometry().u {
let (curve, surface) = self;
match surface.geometry().u {
GlobalPath::Circle(_) => {
// Sweeping a `Curve` creates a `Surface`. The u-axis of that
// `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) => {
let center = self
.surface()
let center = surface
.geometry()
.point_from_surface_coords(circle.center());
let a = self
.surface()
.geometry()
.vector_from_surface_coords(circle.a());
let b = self
.surface()
.geometry()
.vector_from_surface_coords(circle.b());
let a =
surface.geometry().vector_from_surface_coords(circle.a());
let b =
surface.geometry().vector_from_surface_coords(circle.b());
let circle = Circle::new(center, a, b);
GlobalPath::Circle(circle)
}
SurfacePath::Line(line) => {
let origin = self
.surface()
.geometry()
.point_from_surface_coords(line.origin());
let direction = self
.surface()
let origin =
surface.geometry().point_from_surface_coords(line.origin());
let direction = surface
.geometry()
.vector_from_surface_coords(line.direction());

View File

@ -1,3 +1,5 @@
use std::ops::Deref;
use fj_interop::{ext::ArrayExt, mesh::Color};
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
// we're sweeping.
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.
@ -194,7 +197,7 @@ mod tests {
};
let side_up = {
let mut side_up = PartialHalfEdge::default();
side_up.curve.write().surface = surface.clone();
side_up.replace_surface(surface.clone());
{
let [back, front] = side_up
@ -206,7 +209,6 @@ mod tests {
let mut front = front.write();
front.position = Some([1., 1.].into());
front.surface = surface.clone();
}
side_up.infer_global_form();
@ -216,7 +218,7 @@ mod tests {
};
let top = {
let mut top = PartialHalfEdge::default();
top.curve.write().surface = surface.clone();
top.replace_surface(surface.clone());
{
let [(back, back_surface), (front, front_surface)] =
@ -228,7 +230,6 @@ mod tests {
*front = Some(Point::from([0.]));
let mut front_surface = front_surface.write();
front_surface.position = Some([0., 1.].into());
front_surface.surface = surface.clone();
}
top.infer_global_form();
@ -243,7 +244,7 @@ mod tests {
};
let side_down = {
let mut side_down = PartialHalfEdge::default();
side_down.curve.write().surface = surface;
side_down.replace_surface(surface);
let [(back, back_surface), (front, front_surface)] =
side_down.vertices.each_mut_ext();

View File

@ -18,16 +18,12 @@ impl TransformObject for Curve {
// coordinates, and thus transforming `surface` takes care of it.
let path = self.path();
let surface = self
.surface()
.clone()
.transform_with_cache(transform, objects, cache);
let global_form = self
.global_form()
.clone()
.transform_with_cache(transform, objects, cache);
Self::new(surface, path, global_form)
Self::new(path, global_form)
}
}

View File

@ -15,6 +15,10 @@ impl TransformObject for HalfEdge {
objects: &mut Service<Objects>,
cache: &mut TransformCache,
) -> Self {
let surface = self
.surface()
.clone()
.transform_with_cache(transform, objects, cache);
let curve = self
.curve()
.clone()
@ -32,7 +36,7 @@ impl TransformObject for HalfEdge {
.clone()
.transform_with_cache(transform, objects, cache);
Self::new(curve, boundary, global_form)
Self::new(surface, curve, boundary, global_form)
}
}

View File

@ -64,7 +64,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
fn replace_surface(&mut self, surface: impl Into<Partial<Surface>>) {
let surface = surface.into();
self.curve.write().surface = surface.clone();
self.surface = surface.clone();
for vertex in &mut self.vertices {
vertex.1.write().surface = surface.clone();
@ -134,14 +134,11 @@ impl HalfEdgeBuilder for PartialHalfEdge {
surface: impl Into<Partial<Surface>>,
points: [impl Into<Point<2>>; 2],
) {
let surface = surface.into();
self.curve.write().surface = surface.clone();
self.replace_surface(surface.into());
for (vertex, point) in self.vertices.each_mut_ext().zip_ext(points) {
let mut surface_form = vertex.1.write();
surface_form.position = Some(point.into());
surface_form.surface = surface.clone();
}
self.update_as_line_segment()
@ -196,7 +193,7 @@ impl HalfEdgeBuilder for PartialHalfEdge {
self.curve.write().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) => {
// We have information about the other edge's surface
// available. We need to use that to interpret what the

View File

@ -1,6 +1,5 @@
use crate::{
geometry::path::SurfacePath,
objects::Surface,
storage::{Handle, HandleWrapper},
};
@ -8,19 +7,16 @@ use crate::{
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct Curve {
path: SurfacePath,
surface: Handle<Surface>,
global_form: HandleWrapper<GlobalCurve>,
}
impl Curve {
/// Construct a new instance of `Curve`
pub fn new(
surface: Handle<Surface>,
path: SurfacePath,
global_form: impl Into<HandleWrapper<GlobalCurve>>,
) -> Self {
Self {
surface,
path,
global_form: global_form.into(),
}
@ -31,11 +27,6 @@ impl Curve {
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
pub fn global_form(&self) -> &Handle<GlobalCurve> {
&self.global_form

View File

@ -39,7 +39,7 @@ impl Cycle {
/// Access the surface that the cycle is in
pub fn surface(&self) -> &Handle<Surface> {
if let Some(half_edge) = self.half_edges.first() {
return half_edge.curve().surface();
return half_edge.surface();
}
unreachable!(

View File

@ -4,13 +4,14 @@ use fj_interop::ext::ArrayExt;
use fj_math::Point;
use crate::{
objects::{Curve, GlobalCurve, GlobalVertex, SurfaceVertex},
objects::{Curve, GlobalCurve, GlobalVertex, Surface, SurfaceVertex},
storage::{Handle, HandleWrapper},
};
/// A half-edge
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct HalfEdge {
surface: Handle<Surface>,
curve: Handle<Curve>,
boundary: [(Point<1>, Handle<SurfaceVertex>); 2],
global_form: Handle<GlobalEdge>,
@ -19,17 +20,24 @@ pub struct HalfEdge {
impl HalfEdge {
/// Create an instance of `HalfEdge`
pub fn new(
surface: Handle<Surface>,
curve: Handle<Curve>,
boundary: [(Point<1>, Handle<SurfaceVertex>); 2],
global_form: Handle<GlobalEdge>,
) -> Self {
Self {
surface,
curve,
boundary,
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
pub fn curve(&self) -> &Handle<Curve> {
&self.curve

View File

@ -2,7 +2,7 @@ use fj_math::Scalar;
use crate::{
geometry::path::SurfacePath,
objects::{Curve, GlobalCurve, Objects, Surface},
objects::{Curve, GlobalCurve, Objects},
partial::{FullToPartialCache, Partial, PartialObject},
services::Service,
};
@ -13,9 +13,6 @@ pub struct PartialCurve {
/// The path that defines the curve
pub path: Option<MaybeSurfacePath>,
/// The surface the curve is defined in
pub surface: Partial<Surface>,
/// The global form of the curve
pub global_form: Partial<GlobalCurve>,
}
@ -26,7 +23,6 @@ impl PartialObject for PartialCurve {
fn from_full(curve: &Self::Full, cache: &mut FullToPartialCache) -> Self {
Self {
path: Some(curve.path().into()),
surface: Partial::from_full(curve.surface().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);
Curve::new(surface, path, global_form)
Curve::new(path, global_form)
}
}

View File

@ -6,7 +6,7 @@ use fj_math::Point;
use crate::{
objects::{
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects,
SurfaceVertex,
Surface, SurfaceVertex,
},
partial::{
FullToPartialCache, Partial, PartialObject, PartialSurfaceVertex,
@ -17,6 +17,9 @@ use crate::{
/// A partial [`HalfEdge`]
#[derive(Clone, Debug)]
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
pub curve: Partial<Curve>,
@ -35,6 +38,7 @@ impl PartialObject for PartialHalfEdge {
cache: &mut FullToPartialCache,
) -> Self {
Self {
surface: Partial::from_full(half_edge.surface().clone(), cache),
curve: Partial::from_full(half_edge.curve().clone(), cache),
vertices: half_edge
.boundary()
@ -53,6 +57,7 @@ impl PartialObject for PartialHalfEdge {
}
fn build(self, objects: &mut Service<Objects>) -> Self::Full {
let surface = self.surface.build(objects);
let curve = self.curve.build(objects);
let vertices = self.vertices.map(|mut vertex| {
let position_surface = vertex.1.read().position;
@ -76,10 +81,9 @@ impl PartialObject for PartialHalfEdge {
// Infer global position, if not available.
let position_global = vertex.1.read().global_form.read().position;
if position_global.is_none() {
let surface = curve.surface().geometry();
let position_global =
surface.point_from_surface_coords(position_surface);
let position_global = surface
.geometry()
.point_from_surface_coords(position_surface);
vertex.1.write().global_form.write().position =
Some(position_global);
}
@ -92,18 +96,18 @@ impl PartialObject for PartialHalfEdge {
});
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 {
fn default() -> Self {
let surface = Partial::new();
let curve = Partial::<Curve>::new();
let vertices = array::from_fn(|_| {
let surface = Partial::new();
let surface_form = Partial::from_partial(PartialSurfaceVertex {
surface,
surface: surface.clone(),
..Default::default()
});
@ -125,6 +129,7 @@ impl Default for PartialHalfEdge {
});
Self {
surface,
curve,
vertices,
global_form,

View File

@ -165,13 +165,13 @@ impl HalfEdgeValidationError {
half_edge: &HalfEdge,
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();
if curve_surface.id() != surface_form_surface.id() {
if surface.id() != surface_form_surface.id() {
errors.push(
Box::new(Self::SurfaceMismatch {
curve_surface: curve_surface.clone(),
curve_surface: surface.clone(),
surface_form_surface: surface_form_surface.clone(),
})
.into(),
@ -240,7 +240,12 @@ mod tests {
.boundary()
.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()?;
@ -282,7 +287,12 @@ mod tests {
.boundary()
.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()?;
@ -318,6 +328,7 @@ mod tests {
});
HalfEdge::new(
valid.surface().clone(),
valid.curve().clone(),
vertices,
valid.global_form().clone(),
@ -349,6 +360,7 @@ mod tests {
});
HalfEdge::new(
valid.surface().clone(),
valid.curve().clone(),
vertices,
valid.global_form().clone(),

View File

@ -31,13 +31,7 @@ impl Shape for fj::Sketch {
let surface = Partial::from(surface);
let mut half_edge = PartialHalfEdge::default();
half_edge.curve.write().surface = surface.clone();
for vertex in &mut half_edge.vertices {
vertex.1.write().surface = surface.clone();
}
half_edge.replace_surface(surface);
half_edge.update_as_circle_from_radius(circle.radius());
Partial::from_partial(half_edge)