fj_kernel/algorithms/transform/
mod.rs1mod cycle;
4mod edge;
5mod face;
6mod shell;
7mod sketch;
8mod solid;
9mod surface;
10mod vertex;
11
12use std::collections::BTreeMap;
13
14use fj_math::{Transform, Vector};
15use type_map::TypeMap;
16
17use crate::{
18 operations::Insert,
19 services::Services,
20 storage::{Handle, ObjectId},
21};
22
23pub trait TransformObject: Sized {
33 fn transform(self, transform: &Transform, services: &mut Services) -> Self {
35 let mut cache = TransformCache::default();
36 self.transform_with_cache(transform, services, &mut cache)
37 }
38
39 fn transform_with_cache(
41 self,
42 transform: &Transform,
43 services: &mut Services,
44 cache: &mut TransformCache,
45 ) -> Self;
46
47 fn translate(
51 self,
52 offset: impl Into<Vector<3>>,
53 services: &mut Services,
54 ) -> Self {
55 self.transform(&Transform::translation(offset), services)
56 }
57
58 fn rotate(
62 self,
63 axis_angle: impl Into<Vector<3>>,
64 services: &mut Services,
65 ) -> Self {
66 self.transform(&Transform::rotation(axis_angle), services)
67 }
68}
69
70impl<T> TransformObject for Handle<T>
71where
72 T: Clone + Insert<Inserted = Handle<T>> + TransformObject + 'static,
73{
74 fn transform_with_cache(
75 self,
76 transform: &Transform,
77 services: &mut Services,
78 cache: &mut TransformCache,
79 ) -> Self {
80 if let Some(object) = cache.get(&self) {
81 return object.clone();
82 }
83
84 let transformed = self
85 .clone_object()
86 .transform_with_cache(transform, services, cache)
87 .insert(services);
88
89 cache.insert(self.clone(), transformed.clone());
90
91 transformed
92 }
93}
94
95#[derive(Default)]
99pub struct TransformCache(TypeMap);
100
101impl TransformCache {
102 fn get<T: 'static>(&mut self, key: &Handle<T>) -> Option<&Handle<T>> {
103 let map = self
104 .0
105 .entry::<BTreeMap<ObjectId, Handle<T>>>()
106 .or_insert_with(BTreeMap::new);
107
108 map.get(&key.id())
109 }
110
111 fn insert<T: 'static>(&mut self, key: Handle<T>, value: Handle<T>) {
112 let map = self
113 .0
114 .entry::<BTreeMap<ObjectId, Handle<T>>>()
115 .or_insert_with(BTreeMap::new);
116
117 map.insert(key.id(), value);
118 }
119}