-
-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1428 from hannobraun/partial
Introduce new partial object API
- Loading branch information
Showing
15 changed files
with
1,022 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
//! Partially defined objects | ||
//! | ||
//! This module contains types that mirror the full object types from | ||
//! [`crate::objects`], only the types from this module can be defined only | ||
//! partially, with the non-defined parts being inferred when a full object is | ||
//! constructed. | ||
//! | ||
//! # Implementation Note | ||
//! | ||
//! This API was created as a replacement for the [original partial object | ||
//! API][crate::partial]. This is still a work in progress. | ||
|
||
mod objects; | ||
mod traits; | ||
mod wrapper; | ||
|
||
pub use self::{ | ||
objects::{ | ||
curve::{PartialCurve, PartialGlobalCurve}, | ||
cycle::PartialCycle, | ||
edge::{PartialGlobalEdge, PartialHalfEdge}, | ||
face::PartialFace, | ||
shell::PartialShell, | ||
sketch::PartialSketch, | ||
solid::PartialSolid, | ||
surface::PartialSurface, | ||
vertex::{PartialGlobalVertex, PartialSurfaceVertex, PartialVertex}, | ||
}, | ||
traits::{HasPartial, PartialObject}, | ||
wrapper::{FullToPartialCache, Partial}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
use crate::{ | ||
geometry::path::SurfacePath, | ||
objects::{Curve, GlobalCurve, Objects, Surface}, | ||
partial2::{FullToPartialCache, Partial, PartialObject}, | ||
services::Service, | ||
}; | ||
|
||
/// A partial [`Curve`] | ||
#[derive(Clone, Debug)] | ||
pub struct PartialCurve { | ||
/// The path that defines the curve | ||
pub path: Option<SurfacePath>, | ||
|
||
/// The surface the curve is defined in | ||
pub surface: Partial<Surface>, | ||
|
||
/// The global form of the curve | ||
pub global_form: Partial<GlobalCurve>, | ||
} | ||
|
||
impl PartialCurve { | ||
/// Construct an instance of `PartialCurve` | ||
pub fn new( | ||
path: Option<SurfacePath>, | ||
surface: Option<Partial<Surface>>, | ||
global_form: Option<Partial<GlobalCurve>>, | ||
) -> Self { | ||
let surface = surface.unwrap_or_default(); | ||
let global_form = global_form.unwrap_or_default(); | ||
|
||
Self { | ||
path, | ||
surface, | ||
global_form, | ||
} | ||
} | ||
} | ||
|
||
impl PartialObject for PartialCurve { | ||
type Full = Curve; | ||
|
||
fn from_full(curve: &Self::Full, cache: &mut FullToPartialCache) -> Self { | ||
Self::new( | ||
Some(curve.path()), | ||
Some(Partial::from_full(curve.surface().clone(), cache)), | ||
Some(Partial::from_full(curve.global_form().clone(), cache)), | ||
) | ||
} | ||
|
||
fn build(self, objects: &mut Service<Objects>) -> Self::Full { | ||
let path = self.path.expect("Need path to build curve"); | ||
let surface = self.surface.build(objects); | ||
let global_form = self.global_form.build(objects); | ||
|
||
Curve::new(surface, path, global_form) | ||
} | ||
} | ||
|
||
impl Default for PartialCurve { | ||
fn default() -> Self { | ||
Self::new(None, None, None) | ||
} | ||
} | ||
|
||
/// A partial [`GlobalCurve`] | ||
#[derive(Clone, Debug)] | ||
pub struct PartialGlobalCurve; | ||
|
||
impl PartialGlobalCurve { | ||
/// Construct an instance of `PartialGlobalCurve` | ||
pub fn new() -> Self { | ||
Self | ||
} | ||
} | ||
|
||
impl PartialObject for PartialGlobalCurve { | ||
type Full = GlobalCurve; | ||
|
||
fn from_full(_: &Self::Full, _: &mut FullToPartialCache) -> Self { | ||
Self::new() | ||
} | ||
|
||
fn build(self, _: &mut Service<Objects>) -> Self::Full { | ||
GlobalCurve | ||
} | ||
} | ||
|
||
impl Default for PartialGlobalCurve { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use crate::{ | ||
objects::{Cycle, HalfEdge, Objects}, | ||
partial2::{FullToPartialCache, Partial, PartialObject}, | ||
services::Service, | ||
}; | ||
|
||
/// A partial [`Cycle`] | ||
#[derive(Clone, Debug)] | ||
pub struct PartialCycle { | ||
/// The half-edges that make up the cycle | ||
pub half_edges: Vec<Partial<HalfEdge>>, | ||
} | ||
|
||
impl PartialCycle { | ||
/// Construct an instance of `PartialCycle` | ||
pub fn new(half_edges: Vec<Partial<HalfEdge>>) -> Self { | ||
Self { half_edges } | ||
} | ||
} | ||
|
||
impl PartialObject for PartialCycle { | ||
type Full = Cycle; | ||
|
||
fn from_full(cycle: &Self::Full, cache: &mut FullToPartialCache) -> Self { | ||
Self::new( | ||
cycle | ||
.half_edges() | ||
.cloned() | ||
.map(|half_edge| Partial::from_full(half_edge, cache)) | ||
.collect(), | ||
) | ||
} | ||
|
||
fn build(self, objects: &mut Service<Objects>) -> Self::Full { | ||
let half_edges = self | ||
.half_edges | ||
.into_iter() | ||
.map(|half_edge| half_edge.build(objects)); | ||
|
||
Cycle::new(half_edges) | ||
} | ||
} | ||
|
||
impl Default for PartialCycle { | ||
fn default() -> Self { | ||
Self::new(Vec::new()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
use fj_interop::ext::ArrayExt; | ||
|
||
use crate::{ | ||
objects::{ | ||
Curve, GlobalCurve, GlobalEdge, GlobalVertex, HalfEdge, Objects, Vertex, | ||
}, | ||
partial2::{FullToPartialCache, Partial, PartialObject, PartialVertex}, | ||
services::Service, | ||
}; | ||
|
||
/// A partial [`HalfEdge`] | ||
#[derive(Clone, Debug)] | ||
pub struct PartialHalfEdge { | ||
/// The vertices that bound the half-edge on the curve | ||
pub vertices: [Partial<Vertex>; 2], | ||
|
||
/// The global form of the half-edge | ||
pub global_form: Partial<GlobalEdge>, | ||
} | ||
|
||
impl PartialHalfEdge { | ||
/// Construct an instance of `PartialHalfEdge` | ||
pub fn new( | ||
vertices: [Option<Partial<Vertex>>; 2], | ||
global_form: Option<Partial<GlobalEdge>>, | ||
) -> Self { | ||
let curve = Partial::<Curve>::new(); | ||
|
||
let vertices = vertices.map(|vertex| { | ||
vertex.unwrap_or_else(|| { | ||
Partial::from_partial(PartialVertex::new( | ||
None, | ||
Some(curve.clone()), | ||
None, | ||
)) | ||
}) | ||
}); | ||
|
||
let global_curve = curve.read().global_form.clone(); | ||
let global_vertices = | ||
vertices.each_ref_ext().map(|vertex: &Partial<Vertex>| { | ||
let surface_vertex = vertex.read().surface_form.clone(); | ||
let global_vertex = surface_vertex.read().global_form.clone(); | ||
Some(global_vertex) | ||
}); | ||
|
||
let global_form = global_form.unwrap_or_else(|| { | ||
Partial::from_partial(PartialGlobalEdge::new( | ||
Some(global_curve), | ||
global_vertices, | ||
)) | ||
}); | ||
|
||
Self { | ||
vertices, | ||
global_form, | ||
} | ||
} | ||
} | ||
|
||
impl PartialObject for PartialHalfEdge { | ||
type Full = HalfEdge; | ||
|
||
fn from_full( | ||
half_edge: &Self::Full, | ||
cache: &mut FullToPartialCache, | ||
) -> Self { | ||
Self::new( | ||
half_edge | ||
.vertices() | ||
.clone() | ||
.map(|vertex| Some(Partial::from_full(vertex, cache))), | ||
Some(Partial::from_full(half_edge.global_form().clone(), cache)), | ||
) | ||
} | ||
|
||
fn build(self, objects: &mut Service<Objects>) -> Self::Full { | ||
let vertices = self.vertices.map(|vertex| vertex.build(objects)); | ||
let global_form = self.global_form.build(objects); | ||
|
||
HalfEdge::new(vertices, global_form) | ||
} | ||
} | ||
|
||
impl Default for PartialHalfEdge { | ||
fn default() -> Self { | ||
Self::new([None, None], None) | ||
} | ||
} | ||
|
||
/// A partial [`GlobalEdge`] | ||
#[derive(Clone, Debug)] | ||
pub struct PartialGlobalEdge { | ||
/// The curve that defines the edge's geometry | ||
pub curve: Partial<GlobalCurve>, | ||
|
||
/// The vertices that bound the edge on the curve | ||
pub vertices: [Partial<GlobalVertex>; 2], | ||
} | ||
|
||
impl PartialGlobalEdge { | ||
/// Construct an instance of `PartialGlobalEdge` | ||
pub fn new( | ||
curve: Option<Partial<GlobalCurve>>, | ||
vertices: [Option<Partial<GlobalVertex>>; 2], | ||
) -> Self { | ||
let curve = curve.unwrap_or_default(); | ||
let vertices = vertices.map(Option::unwrap_or_default); | ||
|
||
Self { curve, vertices } | ||
} | ||
} | ||
|
||
impl PartialObject for PartialGlobalEdge { | ||
type Full = GlobalEdge; | ||
|
||
fn from_full( | ||
global_edge: &Self::Full, | ||
cache: &mut FullToPartialCache, | ||
) -> Self { | ||
Self::new( | ||
Some(Partial::from_full(global_edge.curve().clone(), cache)), | ||
global_edge | ||
.vertices() | ||
.access_in_normalized_order() | ||
.map(|vertex| Some(Partial::from_full(vertex, cache))), | ||
) | ||
} | ||
|
||
fn build(self, objects: &mut Service<Objects>) -> Self::Full { | ||
let curve = self.curve.build(objects); | ||
let vertices = self.vertices.map(|vertex| vertex.build(objects)); | ||
|
||
GlobalEdge::new(curve, vertices) | ||
} | ||
} | ||
|
||
impl Default for PartialGlobalEdge { | ||
fn default() -> Self { | ||
Self::new(None, [None, None]) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
use fj_interop::mesh::Color; | ||
|
||
use crate::{ | ||
objects::{Cycle, Face, Objects}, | ||
partial2::{FullToPartialCache, Partial, PartialObject}, | ||
services::Service, | ||
}; | ||
|
||
/// A partial [`Face`] | ||
#[derive(Clone, Debug)] | ||
pub struct PartialFace { | ||
/// The cycle that bounds the face on the outside | ||
pub exterior: Partial<Cycle>, | ||
|
||
/// The cycles that bound the face on the inside | ||
/// | ||
/// Each of these cycles defines a hole in the face. | ||
pub interiors: Vec<Partial<Cycle>>, | ||
|
||
/// The color of the face | ||
pub color: Option<Color>, | ||
} | ||
|
||
impl PartialFace { | ||
/// Construct an instance of `PartialFace` | ||
pub fn new( | ||
exterior: Option<Partial<Cycle>>, | ||
interiors: Vec<Partial<Cycle>>, | ||
color: Option<Color>, | ||
) -> Self { | ||
let exterior = exterior.unwrap_or_default(); | ||
|
||
Self { | ||
exterior, | ||
interiors, | ||
color, | ||
} | ||
} | ||
} | ||
|
||
impl PartialObject for PartialFace { | ||
type Full = Face; | ||
|
||
fn from_full(face: &Self::Full, cache: &mut FullToPartialCache) -> Self { | ||
Self::new( | ||
Some(Partial::from_full(face.exterior().clone(), cache)), | ||
face.interiors() | ||
.map(|cycle| Partial::from_full(cycle.clone(), cache)) | ||
.collect(), | ||
Some(face.color()), | ||
) | ||
} | ||
|
||
fn build(self, objects: &mut Service<Objects>) -> Self::Full { | ||
let exterior = self.exterior.build(objects); | ||
let interiors = | ||
self.interiors.into_iter().map(|cycle| cycle.build(objects)); | ||
let color = self.color.unwrap_or_default(); | ||
|
||
Face::new(exterior, interiors, color) | ||
} | ||
} | ||
|
||
impl Default for PartialFace { | ||
fn default() -> Self { | ||
Self::new(None, Vec::new(), None) | ||
} | ||
} |
Oops, something went wrong.