mirror of
https://github.com/hannobraun/Fornjot
synced 2025-06-21 10:48:58 +00:00
Merge pull request #1953 from hannobraun/approx
Make some cleanups in edge approximation code
This commit is contained in:
commit
40b364814a
@ -12,7 +12,7 @@ use fj_math::Point;
|
|||||||
use crate::{
|
use crate::{
|
||||||
geometry::{BoundaryOnCurve, GlobalPath, SurfacePath},
|
geometry::{BoundaryOnCurve, GlobalPath, SurfacePath},
|
||||||
objects::{GlobalEdge, HalfEdge, Surface, Vertex},
|
objects::{GlobalEdge, HalfEdge, Surface, Vertex},
|
||||||
storage::{Handle, ObjectId},
|
storage::{Handle, HandleWrapper},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{Approx, ApproxPoint, Tolerance};
|
use super::{Approx, ApproxPoint, Tolerance};
|
||||||
@ -54,8 +54,8 @@ impl Approx for (&HalfEdge, &Surface) {
|
|||||||
// approximations.
|
// approximations.
|
||||||
//
|
//
|
||||||
// Caching works like this: We check whether there already is a
|
// Caching works like this: We check whether there already is a
|
||||||
// cache entry for the `GlobalEdge`. If there isn't we create the 3D
|
// cache entry for the `GlobalEdge`. If there isn't, we create the
|
||||||
// approximation from the 2D `HalfEdge`. Next time we check for a
|
// 3D approximation from the 2D `HalfEdge`. Next time we check for a
|
||||||
// coincident `HalfEdge`, we'll find the cache and use that, getting
|
// coincident `HalfEdge`, we'll find the cache and use that, getting
|
||||||
// the exact same 3D approximation, instead of generating a slightly
|
// the exact same 3D approximation, instead of generating a slightly
|
||||||
// different one from the different 2D `HalfEdge`.
|
// different one from the different 2D `HalfEdge`.
|
||||||
@ -74,16 +74,10 @@ impl Approx for (&HalfEdge, &Surface) {
|
|||||||
// forward, as it is, well, too limiting. This means things here
|
// forward, as it is, well, too limiting. This means things here
|
||||||
// will need to change.
|
// will need to change.
|
||||||
//
|
//
|
||||||
// Basically, we're missing two things:
|
// What we need here, is more intelligent caching based on `Curve`
|
||||||
//
|
// and the edge boundaries, instead of `GlobalEdge`. The cache needs
|
||||||
// 1. A "global curve" object that is referenced by `HalfEdge`s and
|
// to be able to deliver partial results for a given boundary, then
|
||||||
// can be used as the cache key, in combination with the range.
|
// generating (and caching) the rest of it on the fly.
|
||||||
// 2. More intelligent caching, that can deliver partial results for
|
|
||||||
// the range given, while generating (and then caching) any
|
|
||||||
// unavailable parts of the range on the fly.
|
|
||||||
//
|
|
||||||
// Only item 2. is something we can do right here. Item 1. requires
|
|
||||||
// a change to the object graph.
|
|
||||||
let cached_approx = cache.get_edge(
|
let cached_approx = cache.get_edge(
|
||||||
half_edge.global_form().clone(),
|
half_edge.global_form().clone(),
|
||||||
half_edge.boundary(),
|
half_edge.boundary(),
|
||||||
@ -223,8 +217,11 @@ fn approx_edge(
|
|||||||
/// A cache for results of an approximation
|
/// A cache for results of an approximation
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct EdgeCache {
|
pub struct EdgeCache {
|
||||||
edge_approx: BTreeMap<(ObjectId, BoundaryOnCurve), GlobalEdgeApprox>,
|
edge_approx: BTreeMap<
|
||||||
vertex_approx: BTreeMap<ObjectId, Point<3>>,
|
(HandleWrapper<GlobalEdge>, BoundaryOnCurve),
|
||||||
|
GlobalEdgeApprox,
|
||||||
|
>,
|
||||||
|
vertex_approx: BTreeMap<HandleWrapper<Vertex>, Point<3>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EdgeCache {
|
impl EdgeCache {
|
||||||
@ -234,16 +231,18 @@ impl EdgeCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Access the approximation for the given [`GlobalEdge`], if available
|
/// Access the approximation for the given [`GlobalEdge`], if available
|
||||||
pub fn get_edge(
|
fn get_edge(
|
||||||
&self,
|
&self,
|
||||||
handle: Handle<GlobalEdge>,
|
handle: Handle<GlobalEdge>,
|
||||||
boundary: BoundaryOnCurve,
|
boundary: BoundaryOnCurve,
|
||||||
) -> Option<GlobalEdgeApprox> {
|
) -> Option<GlobalEdgeApprox> {
|
||||||
if let Some(approx) = self.edge_approx.get(&(handle.id(), boundary)) {
|
if let Some(approx) =
|
||||||
|
self.edge_approx.get(&(handle.clone().into(), boundary))
|
||||||
|
{
|
||||||
return Some(approx.clone());
|
return Some(approx.clone());
|
||||||
}
|
}
|
||||||
if let Some(approx) =
|
if let Some(approx) =
|
||||||
self.edge_approx.get(&(handle.id(), boundary.reverse()))
|
self.edge_approx.get(&(handle.into(), boundary.reverse()))
|
||||||
{
|
{
|
||||||
// If we have a cache entry for the reverse boundary, we need to use
|
// If we have a cache entry for the reverse boundary, we need to use
|
||||||
// that too!
|
// that too!
|
||||||
@ -254,19 +253,19 @@ impl EdgeCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Insert the approximation of a [`GlobalEdge`]
|
/// Insert the approximation of a [`GlobalEdge`]
|
||||||
pub fn insert_edge(
|
fn insert_edge(
|
||||||
&mut self,
|
&mut self,
|
||||||
handle: Handle<GlobalEdge>,
|
handle: Handle<GlobalEdge>,
|
||||||
boundary: BoundaryOnCurve,
|
boundary: BoundaryOnCurve,
|
||||||
approx: GlobalEdgeApprox,
|
approx: GlobalEdgeApprox,
|
||||||
) -> GlobalEdgeApprox {
|
) -> GlobalEdgeApprox {
|
||||||
self.edge_approx
|
self.edge_approx
|
||||||
.insert((handle.id(), boundary), approx.clone())
|
.insert((handle.into(), boundary), approx.clone())
|
||||||
.unwrap_or(approx)
|
.unwrap_or(approx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_position(&self, handle: &Handle<Vertex>) -> Option<Point<3>> {
|
fn get_position(&self, handle: &Handle<Vertex>) -> Option<Point<3>> {
|
||||||
self.vertex_approx.get(&handle.id()).cloned()
|
self.vertex_approx.get(&handle.clone().into()).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_position(
|
fn insert_position(
|
||||||
@ -275,21 +274,21 @@ impl EdgeCache {
|
|||||||
position: Point<3>,
|
position: Point<3>,
|
||||||
) -> Point<3> {
|
) -> Point<3> {
|
||||||
self.vertex_approx
|
self.vertex_approx
|
||||||
.insert(handle.id(), position)
|
.insert(handle.clone().into(), position)
|
||||||
.unwrap_or(position)
|
.unwrap_or(position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An approximation of a [`GlobalEdge`]
|
/// An approximation of a [`GlobalEdge`]
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||||
pub struct GlobalEdgeApprox {
|
struct GlobalEdgeApprox {
|
||||||
/// The points that approximate the edge
|
/// The points that approximate the edge
|
||||||
pub points: Vec<ApproxPoint<1>>,
|
points: Vec<ApproxPoint<1>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalEdgeApprox {
|
impl GlobalEdgeApprox {
|
||||||
/// Reverse the order of the approximation
|
/// Reverse the order of the approximation
|
||||||
pub fn reverse(mut self) -> Self {
|
fn reverse(mut self) -> Self {
|
||||||
self.points.reverse();
|
self.points.reverse();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user