PhysicsBasedAnimationToolkit 0.0.10
Cross-platform C++20 library of algorithms and data structures commonly used in computer graphics research on physically-based simulation.
Loading...
Searching...
No Matches
Forest.h
1#ifndef PBAT_GEOMETRY_SDF_FOREST_H
2#define PBAT_GEOMETRY_SDF_FOREST_H
3
4#include "Composite.h"
5#include "Transform.h"
7#include "pbat/io/Archive.h"
8
9#include <array>
10#include <fmt/format.h>
11#include <string_view>
12#include <utility>
13#include <vector>
14
15namespace pbat::geometry::sdf {
16
20template <common::CArithmetic TScalar>
21struct Forest
22{
23 using ScalarType = TScalar;
24 std::vector<Node<ScalarType>> nodes;
25 std::vector<Transform<ScalarType>>
27 std::vector<int> roots;
28 std::vector<std::pair<int, int>> children;
30
34 void Serialize(io::Archive& archive) const;
39 void Deserialize(io::Archive& archive);
40};
41
42namespace detail::forest {
43
44template <class TMatrix>
45void SerializeMiniMatrix(std::string_view key, TMatrix const& A, io::Archive& archive)
46{
47 using ScalarType = typename TMatrix::ScalarType;
48 std::vector<ScalarType> data(TMatrix::kRows * TMatrix::kCols);
49 std::memcpy(data.data(), A.Data(), sizeof(ScalarType) * data.size());
50 archive.WriteData(std::string{key}, data);
51}
52
53template <class TMatrix>
54void DeserializeMiniMatrix(std::string_view key, TMatrix& A, io::Archive const& archive)
55{
56 using ScalarType = typename TMatrix::ScalarType;
57 std::vector<ScalarType> data = archive.ReadData<std::vector<ScalarType>>(std::string{key});
58 std::memcpy(A.Data(), data.data(), sizeof(ScalarType) * data.size());
59}
60
61} // namespace detail::forest
62
63template <common::CArithmetic TScalar>
65{
66 io::Archive group = archive["pbat.geometry.sdf.Forest"];
67 io::Archive nodesGroup = group["nodes"];
68 struct Visitor
69 {
70 Visitor(io::Archive const& _group, std::size_t _i) : group(_group), i(_i) {}
71 io::Archive group;
72 std::size_t i;
76 void operator()(Sphere<TScalar> const& prim)
77 {
78 io::Archive sphereGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Sphere");
79 sphereGroup.WriteMetaData("R", prim.R);
80 }
81 void operator()(Box<TScalar> const& prim)
82 {
83 io::Archive boxGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Box");
84 detail::forest::SerializeMiniMatrix("he", prim.he, boxGroup);
85 }
86 void operator()(BoxFrame<TScalar> const& prim)
87 {
88 io::Archive boxFrameGroup = group.GetOrCreateGroup("pbat.geometry.sdf.BoxFrame");
89 detail::forest::SerializeMiniMatrix("he", prim.he, boxFrameGroup);
90 boxFrameGroup.WriteMetaData("t", prim.t);
91 }
92 void operator()(Torus<TScalar> const& prim)
93 {
94 io::Archive torusGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Torus");
95 detail::forest::SerializeMiniMatrix("t", prim.t, torusGroup);
96 }
97 void operator()(CappedTorus<TScalar> const& prim)
98 {
99 io::Archive cappedTorusGroup = group.GetOrCreateGroup("pbat.geometry.sdf.CappedTorus");
100 detail::forest::SerializeMiniMatrix("sc", prim.sc, cappedTorusGroup);
101 cappedTorusGroup.WriteMetaData("ra", prim.ra);
102 cappedTorusGroup.WriteMetaData("rb", prim.rb);
103 }
104 void operator()(Link<TScalar> const& prim)
105 {
106 io::Archive linkGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Link");
107 detail::forest::SerializeMiniMatrix("t", prim.t, linkGroup);
108 linkGroup.WriteMetaData("le", prim.le);
109 }
110 void operator()(InfiniteCylinder<TScalar> const& prim)
111 {
112 io::Archive infiniteCylinderGroup =
113 group.GetOrCreateGroup("pbat.geometry.sdf.InfiniteCylinder");
114 detail::forest::SerializeMiniMatrix("c", prim.c, infiniteCylinderGroup);
115 }
116 void operator()(Cone<TScalar> const& prim)
117 {
118 io::Archive coneGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Cone");
119 detail::forest::SerializeMiniMatrix("sc", prim.sc, coneGroup);
120 coneGroup.WriteMetaData("h", prim.h);
121 }
122 void operator()(InfiniteCone<TScalar> const& prim)
123 {
124 io::Archive infiniteConeGroup =
125 group.GetOrCreateGroup("pbat.geometry.sdf.InfiniteCone");
126 detail::forest::SerializeMiniMatrix("sc", prim.sc, infiniteConeGroup);
127 }
128 void operator()([[maybe_unused]] Plane<TScalar> const& prim)
129 {
130 [[maybe_unused]] io::Archive planeGroup =
131 group.GetOrCreateGroup("pbat.geometry.sdf.Plane");
132 }
133 void operator()(HexagonalPrism<TScalar> const& prim)
134 {
135 io::Archive hexagonalPrismGroup =
136 group.GetOrCreateGroup("pbat.geometry.sdf.HexagonalPrism");
137 detail::forest::SerializeMiniMatrix("h", prim.h, hexagonalPrismGroup);
138 }
139 void operator()(Capsule<TScalar> const& prim)
140 {
141 io::Archive capsuleGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Capsule");
142 detail::forest::SerializeMiniMatrix("a", prim.a, capsuleGroup);
143 detail::forest::SerializeMiniMatrix("b", prim.b, capsuleGroup);
144 capsuleGroup.WriteMetaData("r", prim.r);
145 }
146 void operator()(VerticalCapsule<TScalar> const& prim)
147 {
148 io::Archive verticalCapsuleGroup =
149 group.GetOrCreateGroup("pbat.geometry.sdf.VerticalCapsule");
150 verticalCapsuleGroup.WriteMetaData("h", prim.h);
151 verticalCapsuleGroup.WriteMetaData("r", prim.r);
152 }
153 void operator()(CappedCylinder<TScalar> const& prim)
154 {
155 io::Archive cappedCylinderGroup =
156 group.GetOrCreateGroup("pbat.geometry.sdf.CappedCylinder");
157 detail::forest::SerializeMiniMatrix("a", prim.a, cappedCylinderGroup);
158 detail::forest::SerializeMiniMatrix("b", prim.b, cappedCylinderGroup);
159 cappedCylinderGroup.WriteMetaData("r", prim.r);
160 }
161 void operator()(VerticalCappedCylinder<TScalar> const& prim)
162 {
163 io::Archive verticalCappedCylinderGroup =
164 group.GetOrCreateGroup("pbat.geometry.sdf.VerticalCappedCylinder");
165 verticalCappedCylinderGroup.WriteMetaData("h", prim.h);
166 verticalCappedCylinderGroup.WriteMetaData("r", prim.r);
167 }
168 void operator()(RoundedCylinder<TScalar> const& prim)
169 {
170 io::Archive roundedCylinderGroup =
171 group.GetOrCreateGroup("pbat.geometry.sdf.RoundedCylinder");
172 roundedCylinderGroup.WriteMetaData("h", prim.h);
173 roundedCylinderGroup.WriteMetaData("ra", prim.ra);
174 roundedCylinderGroup.WriteMetaData("rb", prim.rb);
175 }
176 void operator()(VerticalCappedCone<TScalar> const& prim)
177 {
178 io::Archive verticalCappedConeGroup =
179 group.GetOrCreateGroup("pbat.geometry.sdf.VerticalCappedCone");
180 verticalCappedConeGroup.WriteMetaData("h", prim.h);
181 verticalCappedConeGroup.WriteMetaData("r1", prim.r1);
182 verticalCappedConeGroup.WriteMetaData("r2", prim.r2);
183 }
184 void operator()(CutHollowSphere<TScalar> const& prim)
185 {
186 io::Archive cutHollowSphereGroup =
187 group.GetOrCreateGroup("pbat.geometry.sdf.CutHollowSphere");
188 cutHollowSphereGroup.WriteMetaData("r", prim.r);
189 cutHollowSphereGroup.WriteMetaData("h", prim.h);
190 cutHollowSphereGroup.WriteMetaData("t", prim.t);
191 }
192 void operator()(VerticalRoundCone<TScalar> const& prim)
193 {
194 io::Archive verticalRoundConeGroup =
195 group.GetOrCreateGroup("pbat.geometry.sdf.VerticalRoundCone");
196 verticalRoundConeGroup.WriteMetaData("h", prim.h);
197 verticalRoundConeGroup.WriteMetaData("r1", prim.r1);
198 verticalRoundConeGroup.WriteMetaData("r2", prim.r2);
199 }
200 void operator()(Octahedron<TScalar> const& prim)
201 {
202 io::Archive octahedronGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Octahedron");
203 octahedronGroup.WriteMetaData("s", prim.s);
204 }
205 void operator()(Pyramid<TScalar> const& prim)
206 {
207 io::Archive pyramidGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Pyramid");
208 pyramidGroup.WriteMetaData("h", prim.h);
209 }
210 void operator()(Triangle<TScalar> const& prim)
211 {
212 io::Archive triangleGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Triangle");
213 detail::forest::SerializeMiniMatrix("a", prim.a, triangleGroup);
214 detail::forest::SerializeMiniMatrix("b", prim.b, triangleGroup);
215 detail::forest::SerializeMiniMatrix("c", prim.c, triangleGroup);
216 }
217 void operator()(Quadrilateral<TScalar> const& prim)
218 {
219 io::Archive quadrilateralGroup =
220 group.GetOrCreateGroup("pbat.geometry.sdf.Quadrilateral");
221 detail::forest::SerializeMiniMatrix("a", prim.a, quadrilateralGroup);
222 detail::forest::SerializeMiniMatrix("b", prim.b, quadrilateralGroup);
223 detail::forest::SerializeMiniMatrix("c", prim.c, quadrilateralGroup);
224 detail::forest::SerializeMiniMatrix("d", prim.d, quadrilateralGroup);
225 }
226
230 void operator()(Scale<TScalar> const& un)
231 {
232 io::Archive scaleGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Scale");
233 scaleGroup.WriteMetaData("s", un.s);
234 }
235 void operator()(Elongate<TScalar> const& un)
236 {
237 io::Archive elongateGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Elongate");
238 detail::forest::SerializeMiniMatrix("h", un.h, elongateGroup);
239 }
240 void operator()(Round<TScalar> const& un)
241 {
242 io::Archive roundGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Round");
243 roundGroup.WriteMetaData("r", un.r);
244 }
245 void operator()(Onion<TScalar> const& un)
246 {
247 io::Archive onionGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Onion");
248 onionGroup.WriteMetaData("t", un.t);
249 }
250 void operator()([[maybe_unused]] Symmetrize<TScalar> const& un)
251 {
252 [[maybe_unused]] io::Archive symmetrizeGroup =
253 group.GetOrCreateGroup("pbat.geometry.sdf.Symmetrize");
254 }
255 void operator()(Repeat<TScalar> const& un)
256 {
257 io::Archive repeatGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Repeat");
258 repeatGroup.WriteMetaData("s", un.s);
259 detail::forest::SerializeMiniMatrix("l", un.l, repeatGroup);
260 }
261 void operator()(RotationalRepeat<TScalar> const& un)
262 {
263 io::Archive rotationalRepeatGroup =
264 group.GetOrCreateGroup("pbat.geometry.sdf.RotationalRepeat");
265 rotationalRepeatGroup.WriteMetaData("n", un.n);
266 }
267 void operator()(Bump<TScalar> const& un)
268 {
269 io::Archive bumpGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Bump");
270 detail::forest::SerializeMiniMatrix("f", un.f, bumpGroup);
271 detail::forest::SerializeMiniMatrix("g", un.g, bumpGroup);
272 }
273 void operator()(Twist<TScalar> const& un)
274 {
275 io::Archive twistGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Twist");
276 twistGroup.WriteMetaData("k", un.k);
277 }
278 void operator()(Bend<TScalar> const& un)
279 {
280 io::Archive bendGroup = group.GetOrCreateGroup("pbat.geometry.sdf.Bend");
281 bendGroup.WriteMetaData("k", un.k);
282 }
283
287 void operator()([[maybe_unused]] Union<TScalar> const& bn)
288 {
289 [[maybe_unused]] io::Archive unionGroup =
290 group.GetOrCreateGroup("pbat.geometry.sdf.Union");
291 }
292 void operator()([[maybe_unused]] Difference<TScalar> const& bn)
293 {
294 [[maybe_unused]] io::Archive differenceGroup =
295 group.GetOrCreateGroup("pbat.geometry.sdf.Difference");
296 }
297 void operator()([[maybe_unused]] Intersection<TScalar> const& bn)
298 {
299 [[maybe_unused]] io::Archive intersectionGroup =
300 group.GetOrCreateGroup("pbat.geometry.sdf.Intersection");
301 }
302 void operator()([[maybe_unused]] ExclusiveOr<TScalar> const& bn)
303 {
304 [[maybe_unused]] io::Archive exclusiveOrGroup =
305 group.GetOrCreateGroup("pbat.geometry.sdf.ExclusiveOr");
306 }
307 void operator()(SmoothUnion<TScalar> const& bn)
308 {
309 io::Archive smoothUnionGroup = group.GetOrCreateGroup("pbat.geometry.sdf.SmoothUnion");
310 smoothUnionGroup.WriteMetaData("k", bn.k);
311 }
312 void operator()(SmoothDifference<TScalar> const& bn)
313 {
314 io::Archive smoothDifferenceGroup =
315 group.GetOrCreateGroup("pbat.geometry.sdf.SmoothDifference");
316 smoothDifferenceGroup.WriteMetaData("k", bn.k);
317 }
318 void operator()(SmoothIntersection<TScalar> const& bn)
319 {
320 io::Archive smoothIntersectionGroup =
321 group.GetOrCreateGroup("pbat.geometry.sdf.SmoothIntersection");
322 smoothIntersectionGroup.WriteMetaData("k", bn.k);
323 }
324 };
325 group.WriteMetaData("nNodes", static_cast<int>(nodes.size()));
326 for (std::size_t i = 0; i < nodes.size(); ++i)
327 {
328 io::Archive nodeGroup = nodesGroup[fmt::format("{}", i)];
329 std::visit(Visitor{nodeGroup, i}, nodes[i]);
330 }
331 io::Archive transformsGroup = group["transforms"];
332 for (std::size_t i = 0; i < transforms.size(); ++i)
333 {
334 Transform<TScalar> const& tr = transforms[i];
335 detail::forest::SerializeMiniMatrix(fmt::format("R{}", i), tr.R, transformsGroup);
336 detail::forest::SerializeMiniMatrix(fmt::format("t{}", i), tr.t, transformsGroup);
337 }
338 group.WriteData("roots", roots);
339 std::vector<int> lc(children.size()), rc(children.size());
340 for (std::size_t i = 0; i < children.size(); ++i)
341 {
342 lc[i] = children[i].first;
343 rc[i] = children[i].second;
344 }
345 group.WriteData("lc", lc);
346 group.WriteData("rc", rc);
347}
348
349template <common::CArithmetic TScalar>
351{
352 io::Archive group = archive["pbat.geometry.sdf.Forest"];
353 std::size_t nNodes = group.ReadMetaData<std::size_t>("nNodes");
354 nodes.resize(nNodes);
355 io::Archive nodesGroup = group["nodes"];
356 struct Visitor
357 {
358 Visitor(io::Archive const& _group, std::size_t _i) : group(_group), i(_i) {}
359 io::Archive group;
360 std::size_t i;
361
365 void operator()(Sphere<TScalar>& prim) const
366 {
367 io::Archive sphereGroup = group["pbat.geometry.sdf.Sphere"];
368 prim.R = sphereGroup.ReadMetaData<TScalar>("R");
369 }
370 void operator()(Box<TScalar>& prim) const
371 {
372 io::Archive boxGroup = group["pbat.geometry.sdf.Box"];
373 detail::forest::DeserializeMiniMatrix("he", prim.he, boxGroup);
374 }
375 void operator()(BoxFrame<TScalar>& prim) const
376 {
377 io::Archive boxFrameGroup = group["pbat.geometry.sdf.BoxFrame"];
378 detail::forest::DeserializeMiniMatrix("he", prim.he, boxFrameGroup);
379 prim.t = boxFrameGroup.ReadMetaData<TScalar>("t");
380 }
381 void operator()(Torus<TScalar>& prim) const
382 {
383 io::Archive torusGroup = group["pbat.geometry.sdf.Torus"];
384 detail::forest::DeserializeMiniMatrix("t", prim.t, torusGroup);
385 }
386 void operator()(CappedTorus<TScalar>& prim) const
387 {
388 io::Archive cappedTorusGroup = group["pbat.geometry.sdf.CappedTorus"];
389 detail::forest::DeserializeMiniMatrix("sc", prim.sc, cappedTorusGroup);
390 prim.ra = cappedTorusGroup.ReadMetaData<TScalar>("ra");
391 prim.rb = cappedTorusGroup.ReadMetaData<TScalar>("rb");
392 }
393 void operator()(Link<TScalar>& prim) const
394 {
395 io::Archive linkGroup = group["pbat.geometry.sdf.Link"];
396 detail::forest::DeserializeMiniMatrix("t", prim.t, linkGroup);
397 prim.le = linkGroup.ReadMetaData<TScalar>("le");
398 }
399 void operator()(InfiniteCylinder<TScalar>& prim) const
400 {
401 io::Archive infiniteCylinderGroup = group["pbat.geometry.sdf.InfiniteCylinder"];
402 detail::forest::DeserializeMiniMatrix("c", prim.c, infiniteCylinderGroup);
403 }
404 void operator()(Cone<TScalar>& prim) const
405 {
406 io::Archive coneGroup = group["pbat.geometry.sdf.Cone"];
407 detail::forest::DeserializeMiniMatrix("sc", prim.sc, coneGroup);
408 prim.h = coneGroup.ReadMetaData<TScalar>("h");
409 }
410 void operator()(InfiniteCone<TScalar>& prim) const
411 {
412 io::Archive infiniteConeGroup = group["pbat.geometry.sdf.InfiniteCone"];
413 detail::forest::DeserializeMiniMatrix("sc", prim.sc, infiniteConeGroup);
414 }
415 void operator()([[maybe_unused]] Plane<TScalar>& prim) const
416 {
417 [[maybe_unused]] io::Archive planeGroup = group["pbat.geometry.sdf.Plane"];
418 }
419 void operator()(HexagonalPrism<TScalar>& prim) const
420 {
421 io::Archive hexagonalPrismGroup = group["pbat.geometry.sdf.HexagonalPrism"];
422 detail::forest::DeserializeMiniMatrix("h", prim.h, hexagonalPrismGroup);
423 }
424 void operator()(Capsule<TScalar>& prim) const
425 {
426 io::Archive capsuleGroup = group["pbat.geometry.sdf.Capsule"];
427 detail::forest::DeserializeMiniMatrix("a", prim.a, capsuleGroup);
428 detail::forest::DeserializeMiniMatrix("b", prim.b, capsuleGroup);
429 prim.r = capsuleGroup.ReadMetaData<TScalar>("r");
430 }
431 void operator()(VerticalCapsule<TScalar>& prim) const
432 {
433 io::Archive verticalCapsuleGroup = group["pbat.geometry.sdf.VerticalCapsule"];
434 prim.h = verticalCapsuleGroup.ReadMetaData<TScalar>("h");
435 prim.r = verticalCapsuleGroup.ReadMetaData<TScalar>("r");
436 }
437 void operator()(CappedCylinder<TScalar>& prim) const
438 {
439 io::Archive cappedCylinderGroup = group["pbat.geometry.sdf.CappedCylinder"];
440 detail::forest::DeserializeMiniMatrix("a", prim.a, cappedCylinderGroup);
441 detail::forest::DeserializeMiniMatrix("b", prim.b, cappedCylinderGroup);
442 prim.r = cappedCylinderGroup.ReadMetaData<TScalar>("r");
443 }
444 void operator()(VerticalCappedCylinder<TScalar>& prim) const
445 {
446 io::Archive verticalCappedCylinderGroup =
447 group["pbat.geometry.sdf.VerticalCappedCylinder"];
448 prim.h = verticalCappedCylinderGroup.ReadMetaData<TScalar>("h");
449 prim.r = verticalCappedCylinderGroup.ReadMetaData<TScalar>("r");
450 }
451 void operator()(RoundedCylinder<TScalar>& prim) const
452 {
453 io::Archive roundedCylinderGroup = group["pbat.geometry.sdf.RoundedCylinder"];
454 prim.h = roundedCylinderGroup.ReadMetaData<TScalar>("h");
455 prim.ra = roundedCylinderGroup.ReadMetaData<TScalar>("ra");
456 prim.rb = roundedCylinderGroup.ReadMetaData<TScalar>("rb");
457 }
458 void operator()(VerticalCappedCone<TScalar>& prim) const
459 {
460 io::Archive verticalCappedConeGroup = group["pbat.geometry.sdf.VerticalCappedCone"];
461 prim.h = verticalCappedConeGroup.ReadMetaData<TScalar>("h");
462 prim.r1 = verticalCappedConeGroup.ReadMetaData<TScalar>("r1");
463 prim.r2 = verticalCappedConeGroup.ReadMetaData<TScalar>("r2");
464 }
465 void operator()(CutHollowSphere<TScalar>& prim) const
466 {
467 io::Archive cutHollowSphereGroup = group["pbat.geometry.sdf.CutHollowSphere"];
468 prim.r = cutHollowSphereGroup.ReadMetaData<TScalar>("r");
469 prim.h = cutHollowSphereGroup.ReadMetaData<TScalar>("h");
470 prim.t = cutHollowSphereGroup.ReadMetaData<TScalar>("t");
471 }
472 void operator()(VerticalRoundCone<TScalar>& prim) const
473 {
474 io::Archive verticalRoundConeGroup = group["pbat.geometry.sdf.VerticalRoundCone"];
475 prim.h = verticalRoundConeGroup.ReadMetaData<TScalar>("h");
476 prim.r1 = verticalRoundConeGroup.ReadMetaData<TScalar>("r1");
477 prim.r2 = verticalRoundConeGroup.ReadMetaData<TScalar>("r2");
478 }
479 void operator()(Octahedron<TScalar>& prim) const
480 {
481 io::Archive octahedronGroup = group["pbat.geometry.sdf.Octahedron"];
482 prim.s = octahedronGroup.ReadMetaData<TScalar>("s");
483 }
484 void operator()(Pyramid<TScalar>& prim) const
485 {
486 io::Archive pyramidGroup = group["pbat.geometry.sdf.Pyramid"];
487 prim.h = pyramidGroup.ReadMetaData<TScalar>("h");
488 }
489 void operator()(Triangle<TScalar>& prim) const
490 {
491 io::Archive triangleGroup = group["pbat.geometry.sdf.Triangle"];
492 detail::forest::DeserializeMiniMatrix("a", prim.a, triangleGroup);
493 detail::forest::DeserializeMiniMatrix("b", prim.b, triangleGroup);
494 detail::forest::DeserializeMiniMatrix("c", prim.c, triangleGroup);
495 }
496 void operator()(Quadrilateral<TScalar>& prim) const
497 {
498 io::Archive quadrilateralGroup = group["pbat.geometry.sdf.Quadrilateral"];
499 detail::forest::DeserializeMiniMatrix("a", prim.a, quadrilateralGroup);
500 detail::forest::DeserializeMiniMatrix("b", prim.b, quadrilateralGroup);
501 detail::forest::DeserializeMiniMatrix("c", prim.c, quadrilateralGroup);
502 detail::forest::DeserializeMiniMatrix("d", prim.d, quadrilateralGroup);
503 }
504
508 void operator()(Scale<TScalar>& un) const
509 {
510 io::Archive scaleGroup = group["pbat.geometry.sdf.Scale"];
511 un.s = scaleGroup.ReadMetaData<TScalar>("s");
512 }
513 void operator()(Elongate<TScalar>& un) const
514 {
515 io::Archive elongateGroup = group["pbat.geometry.sdf.Elongate"];
516 detail::forest::DeserializeMiniMatrix("h", un.h, elongateGroup);
517 }
518 void operator()(Round<TScalar>& un) const
519 {
520 io::Archive roundGroup = group["pbat.geometry.sdf.Round"];
521 un.r = roundGroup.ReadMetaData<TScalar>("r");
522 }
523 void operator()(Onion<TScalar>& un) const
524 {
525 io::Archive onionGroup = group["pbat.geometry.sdf.Onion"];
526 un.t = onionGroup.ReadMetaData<TScalar>("t");
527 }
528 void operator()([[maybe_unused]] Symmetrize<TScalar>& un) const
529 {
530 [[maybe_unused]] io::Archive symmetrizeGroup = group["pbat.geometry.sdf.Symmetrize"];
531 }
532 void operator()(Repeat<TScalar>& un) const
533 {
534 io::Archive repeatGroup = group["pbat.geometry.sdf.Repeat"];
535 un.s = repeatGroup.ReadMetaData<TScalar>("s");
536 detail::forest::DeserializeMiniMatrix("l", un.l, repeatGroup);
537 }
538 void operator()(RotationalRepeat<TScalar>& un) const
539 {
540 io::Archive rotationalRepeatGroup = group["pbat.geometry.sdf.RotationalRepeat"];
541 un.n = rotationalRepeatGroup.ReadMetaData<TScalar>("n");
542 }
543 void operator()(Bump<TScalar>& un) const
544 {
545 io::Archive bumpGroup = group["pbat.geometry.sdf.Bump"];
546 detail::forest::DeserializeMiniMatrix("f", un.f, bumpGroup);
547 detail::forest::DeserializeMiniMatrix("g", un.g, bumpGroup);
548 }
549 void operator()(Twist<TScalar>& un) const
550 {
551 io::Archive twistGroup = group["pbat.geometry.sdf.Twist"];
552 un.k = twistGroup.ReadMetaData<TScalar>("k");
553 }
554 void operator()(Bend<TScalar>& un) const
555 {
556 io::Archive bendGroup = group["pbat.geometry.sdf.Bend"];
557 un.k = bendGroup.ReadMetaData<TScalar>("k");
558 }
559
563 void operator()([[maybe_unused]] Union<TScalar>& bn) const
564 {
565 [[maybe_unused]] io::Archive unionGroup = group["pbat.geometry.sdf.Union"];
566 }
567 void operator()([[maybe_unused]] Difference<TScalar>& bn) const
568 {
569 [[maybe_unused]] io::Archive differenceGroup = group["pbat.geometry.sdf.Difference"];
570 }
571 void operator()([[maybe_unused]] Intersection<TScalar>& bn) const
572 {
573 [[maybe_unused]] io::Archive intersectionGroup =
574 group["pbat.geometry.sdf.Intersection"];
575 }
576 void operator()([[maybe_unused]] ExclusiveOr<TScalar>& bn) const
577 {
578 [[maybe_unused]] io::Archive exclusiveOrGroup = group["pbat.geometry.sdf.ExclusiveOr"];
579 }
580 void operator()(SmoothUnion<TScalar>& bn) const
581 {
582 io::Archive smoothUnionGroup = group["pbat.geometry.sdf.SmoothUnion"];
583 bn.k = smoothUnionGroup.ReadMetaData<TScalar>("k");
584 }
585 void operator()(SmoothDifference<TScalar>& bn) const
586 {
587 io::Archive smoothDifferenceGroup = group["pbat.geometry.sdf.SmoothDifference"];
588 bn.k = smoothDifferenceGroup.ReadMetaData<TScalar>("k");
589 }
590 void operator()(SmoothIntersection<TScalar>& bn) const
591 {
592 io::Archive smoothIntersectionGroup = group["pbat.geometry.sdf.SmoothIntersection"];
593 bn.k = smoothIntersectionGroup.ReadMetaData<TScalar>("k");
594 }
595 };
596 for (std::size_t i = 0; i < nNodes; ++i)
597 {
598 io::Archive nodeGroup = nodesGroup[fmt::format("{}", i)];
599 if (nodeGroup.HasGroup("pbat.geometry.sdf.Sphere"))
600 nodes[i] = Sphere<TScalar>{};
601 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Box"))
602 nodes[i] = Box<TScalar>{};
603 else if (nodeGroup.HasGroup("pbat.geometry.sdf.BoxFrame"))
605 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Torus"))
606 nodes[i] = Torus<TScalar>{};
607 else if (nodeGroup.HasGroup("pbat.geometry.sdf.CappedTorus"))
609 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Link"))
610 nodes[i] = Link<TScalar>{};
611 else if (nodeGroup.HasGroup("pbat.geometry.sdf.InfiniteCylinder"))
613 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Cone"))
614 nodes[i] = Cone<TScalar>{};
615 else if (nodeGroup.HasGroup("pbat.geometry.sdf.InfiniteCone"))
617 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Plane"))
618 nodes[i] = Plane<TScalar>{};
619 else if (nodeGroup.HasGroup("pbat.geometry.sdf.HexagonalPrism"))
621 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Capsule"))
622 nodes[i] = Capsule<TScalar>{};
623 else if (nodeGroup.HasGroup("pbat.geometry.sdf.VerticalCapsule"))
625 else if (nodeGroup.HasGroup("pbat.geometry.sdf.CappedCylinder"))
627 else if (nodeGroup.HasGroup("pbat.geometry.sdf.VerticalCappedCylinder"))
629 else if (nodeGroup.HasGroup("pbat.geometry.sdf.RoundedCylinder"))
631 else if (nodeGroup.HasGroup("pbat.geometry.sdf.VerticalCappedCone"))
633 else if (nodeGroup.HasGroup("pbat.geometry.sdf.CutHollowSphere"))
635 else if (nodeGroup.HasGroup("pbat.geometry.sdf.VerticalRoundCone"))
637 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Octahedron"))
639 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Pyramid"))
640 nodes[i] = Pyramid<TScalar>{};
641 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Triangle"))
643 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Quadrilateral"))
645 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Scale"))
646 nodes[i] = Scale<TScalar>{};
647 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Elongate"))
649 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Round"))
650 nodes[i] = Round<TScalar>{};
651 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Onion"))
652 nodes[i] = Onion<TScalar>{};
653 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Symmetrize"))
655 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Repeat"))
656 nodes[i] = Repeat<TScalar>{};
657 else if (nodeGroup.HasGroup("pbat.geometry.sdf.RotationalRepeat"))
659 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Bump"))
660 nodes[i] = Bump<TScalar>{};
661 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Twist"))
662 nodes[i] = Twist<TScalar>{};
663 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Bend"))
664 nodes[i] = Bend<TScalar>{};
665 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Union"))
666 nodes[i] = Union<TScalar>{};
667 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Difference"))
669 else if (nodeGroup.HasGroup("pbat.geometry.sdf.Intersection"))
671 else if (nodeGroup.HasGroup("pbat.geometry.sdf.ExclusiveOr"))
673 else if (nodeGroup.HasGroup("pbat.geometry.sdf.SmoothUnion"))
675 else if (nodeGroup.HasGroup("pbat.geometry.sdf.SmoothDifference"))
677 else if (nodeGroup.HasGroup("pbat.geometry.sdf.SmoothIntersection"))
679 else
680 throw std::runtime_error(
681 fmt::format("Forest::Deserialize: Unknown node type for node {}", i));
682 std::visit(Visitor{nodeGroup, i}, nodes[i]);
683 }
684 transforms.resize(nNodes);
685 io::Archive transformsGroup = group["transforms"];
686 for (std::size_t i = 0; i < nNodes; ++i)
687 {
688 detail::forest::DeserializeMiniMatrix(
689 fmt::format("R{}", i),
690 transforms[i].R,
691 transformsGroup);
692 detail::forest::DeserializeMiniMatrix(
693 fmt::format("t{}", i),
694 transforms[i].t,
695 transformsGroup);
696 }
697 roots = group.ReadData<std::vector<int>>("roots");
698 auto lc = group.ReadData<std::vector<int>>("lc");
699 auto rc = group.ReadData<std::vector<int>>("rc");
700 children.resize(nNodes);
701 for (std::size_t i = 0; i < nNodes; ++i)
702 children[i] = {lc[i], rc[i]};
703}
704
705} // namespace pbat::geometry::sdf
706
707#endif // PBAT_GEOMETRY_SDF_FOREST_H
(De)serializer
This file defines an SDF composition.
This file defines transforms useful for moving SDFs around.
Archive class for reading and writing data to HDF5 files.
Definition Archive.h:29
PBAT_API bool HasGroup(std::string const &path) const
Check if a group exists at the given path.
Definition Archive.cpp:86
PBAT_API Archive GetOrCreateGroup(std::string const &path)
Get or create a group at the given path.
Definition Archive.cpp:29
T ReadData(std::string const &path) const
Read data from the archive.
Definition Archive.h:179
void WriteMetaData(std::string const &key, T const &value)
Write metadata to the archive.
Definition Archive.h:158
void WriteData(std::string const &path, T const &data)
Write data to the archive.
Definition Archive.h:137
T ReadMetaData(std::string const &key) const
Read metadata from the archive.
Definition Archive.h:195
Concepts for common types.
Namespace for signed distance functions (SDFs) and related operations.
Definition BinaryNode.cpp:3
Bend operation around the z axis.
Definition UnaryNode.h:361
ScalarType k
Bend factor.
Definition UnaryNode.h:363
Box frame with half extents and thickness .
Definition Primitive.h:120
Vec3< ScalarType > he
Half extents of the box frame along each axis.
Definition Primitive.h:122
ScalarType t
Thickness of the box frame.
Definition Primitive.h:126
Axis-aligned box centered in with half extents .
Definition Primitive.h:81
Vec3< ScalarType > he
Half extents of the box along each axis.
Definition Primitive.h:83
Wave-like bumpiness operation along the axes.
Definition UnaryNode.h:284
Vec3< ScalarType > f
Frequency along each axis.
Definition UnaryNode.h:286
Vec3< ScalarType > g
Amplitude of the wave displacement.
Definition UnaryNode.h:287
Capped cylinder shape with endpoints and radius .
Definition Primitive.h:563
Vec3< ScalarType > a
Endpoint a of the capped cylinder.
Definition Primitive.h:565
ScalarType r
Radius of the capped cylinder.
Definition Primitive.h:567
Vec3< ScalarType > b
Endpoint b of the capped cylinder.
Definition Primitive.h:566
Capped torus centered in with parameters sc, ra, rb.
Definition Primitive.h:207
Vec2< ScalarType > sc
Sin/Cos.
Definition Primitive.h:209
ScalarType rb
Radius 2.
Definition Primitive.h:211
ScalarType ra
Radius 1.
Definition Primitive.h:210
Capsule shape with endpoints and radius .
Definition Primitive.h:482
ScalarType r
Radius of the capsule.
Definition Primitive.h:486
Vec3< ScalarType > a
Endpoint a of the capsule.
Definition Primitive.h:484
Vec3< ScalarType > b
Endpoint b of the capsule.
Definition Primitive.h:485
Cone shape.
Definition Primitive.h:331
Vec2< ScalarType > sc
sin/cos of the angle
Definition Primitive.h:333
ScalarType h
Height of the cone.
Definition Primitive.h:334
Cut hollow sphere shape with radius , cut height and thickness .
Definition Primitive.h:753
ScalarType r
Radius of the hollow sphere.
Definition Primitive.h:755
ScalarType t
Thickness of the hollow sphere.
Definition Primitive.h:757
ScalarType h
Cut height.
Definition Primitive.h:756
Difference operation.
Definition BinaryNode.h:58
Elongation operation along the axes.
Definition UnaryNode.h:72
Vec3< ScalarType > h
Elongation vector.
Definition UnaryNode.h:74
Exclusive or operation.
Definition BinaryNode.h:100
CPU storage for a forest (of SDFs).
Definition Forest.h:22
std::vector< int > roots
Definition Forest.h:27
std::vector< std::pair< int, int > > children
Definition Forest.h:28
void Deserialize(io::Archive &archive)
Deserialize the forest from an archive.
Definition Forest.h:350
std::vector< Transform< ScalarType > > transforms
Definition Forest.h:26
TScalar ScalarType
Scalar type.
Definition Forest.h:23
void Serialize(io::Archive &archive) const
Serialize the forest to an archive.
Definition Forest.h:64
std::vector< Node< ScalarType > > nodes
Definition Forest.h:24
Hexagonal prism shape.
Definition Primitive.h:436
Vec2< ScalarType > h
h[0]: radius of the hexagon, h[1]: half height of the prism
Definition Primitive.h:438
Infinite cone shape.
Definition Primitive.h:377
Vec2< ScalarType > sc
sin/cos of the angle
Definition Primitive.h:379
Infinite cylinder.
Definition Primitive.h:294
Vec3< ScalarType > c
Center of the cylinder (on the axis) in c(0), c(1) and radius in c(2)
Definition Primitive.h:296
Intersection operation.
Definition BinaryNode.h:79
Octahedron shape.
Definition Primitive.h:848
ScalarType s
Size of the octahedron.
Definition Primitive.h:850
Onion operation (i.e. carving interior)
Definition UnaryNode.h:139
ScalarType t
Onion thickness.
Definition UnaryNode.h:141
Plane shape with normal and point on the plane .
Definition Primitive.h:416
Pyramid shape.
Definition Primitive.h:896
ScalarType h
Height of the pyramid.
Definition Primitive.h:898
Quadrilateral shape with vertices .
Definition Primitive.h:1019
Vec3< ScalarType > c
Vertex c of the quadrilateral.
Definition Primitive.h:1023
Vec3< ScalarType > b
Vertex b of the quadrilateral.
Definition Primitive.h:1022
Vec3< ScalarType > d
Vertex d of the quadrilateral.
Definition Primitive.h:1024
Vec3< ScalarType > a
Vertex a of the quadrilateral.
Definition Primitive.h:1021
Grid-like repetition operation along the axes.
Definition UnaryNode.h:197
ScalarType s
Uniform repetition spacing.
Definition UnaryNode.h:199
Vec3< ScalarType > l
Half number of repetitions along each axis.
Definition UnaryNode.h:200
Circular repetition operation around axe.
Definition UnaryNode.h:240
ScalarType n
Number of repetitions.
Definition UnaryNode.h:242
Rounding operation (i.e. positive offset surface)
Definition UnaryNode.h:107
ScalarType r
Rounding radius.
Definition UnaryNode.h:109
Rounded cylinder shape with height , radius and rounding radius .
Definition Primitive.h:656
ScalarType h
Height of the rounded cylinder.
Definition Primitive.h:658
ScalarType ra
Radius of the rounded cylinder.
Definition Primitive.h:659
ScalarType rb
Rounding radius at edges.
Definition Primitive.h:660
Uniform scaling operation.
Definition UnaryNode.h:40
ScalarType s
Scaling factor.
Definition UnaryNode.h:42
Smooth difference operation.
Definition BinaryNode.h:154
ScalarType k
Smoothness factor.
Definition BinaryNode.h:156
Smooth intersection operation.
Definition BinaryNode.h:186
ScalarType k
Smoothness factor.
Definition BinaryNode.h:188
Smooth union operation.
Definition BinaryNode.h:121
ScalarType k
Smoothness factor.
Definition BinaryNode.h:123
Sphere centered in with radius .
Definition Primitive.h:50
ScalarType R
Sphere radius.
Definition Primitive.h:52
Symmetrization operation along the x axis.
Definition UnaryNode.h:172
Torus centered in with minor+major radius .
Definition Primitive.h:172
Vec2< ScalarType > t
t[0]: minor radius, t[1]: major radius
Definition Primitive.h:174
A 3D rigid transform.
Definition Transform.h:31
Mat3< ScalarType > R
Rotation matrix.
Definition Transform.h:33
Vec3< ScalarType > t
Translation vector.
Definition Transform.h:34
Triangle shape.
Definition Primitive.h:955
Vec3< ScalarType > a
Vertex a of the triangle.
Definition Primitive.h:957
Vec3< ScalarType > b
Vertex b of the triangle.
Definition Primitive.h:958
Vec3< ScalarType > c
Vertex c of the triangle.
Definition Primitive.h:959
Twist operation around the y axis.
Definition UnaryNode.h:325
ScalarType k
Twist factor.
Definition UnaryNode.h:327
Union operation.
Definition BinaryNode.h:35
Capped cone shape with height and minor+major radius .
Definition Primitive.h:700
ScalarType r2
Major radius of the capped cone.
Definition Primitive.h:704
ScalarType r1
Minor radius of the capped cone.
Definition Primitive.h:703
ScalarType h
Height of the capped cone.
Definition Primitive.h:702
Vertical capped cylinder shape with height and radius .
Definition Primitive.h:615
ScalarType h
Height of the capped cylinder.
Definition Primitive.h:617
ScalarType r
Radius of the capped cylinder.
Definition Primitive.h:618
Capsule shape with height and radius .
Definition Primitive.h:525
ScalarType r
Radius of the capsule.
Definition Primitive.h:528
ScalarType h
Height of the capsule.
Definition Primitive.h:527
Vertical round cone shape with height , radii at endpoints.
Definition Primitive.h:798
ScalarType h
Height of the round cone.
Definition Primitive.h:800
ScalarType r1
Radius at the bottom of the round cone.
Definition Primitive.h:801
ScalarType r2
Radius at the top of the round cone.
Definition Primitive.h:802