-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
GeometryEvaluator.h
107 lines (93 loc) · 4.99 KB
/
GeometryEvaluator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#pragma once
#include "NodeVisitor.h"
#include "enums.h"
#include "Geometry.h"
#include <memory>
#include <utility>
#include <list>
#include <vector>
#include <map>
class CGAL_Nef_polyhedron;
class Polygon2d;
class Tree;
// This evaluates a node tree into concrete geometry usign an underlying geometry engine
// FIXME: Ideally, each engine should implement its own subtype. Instead we currently have
// multiple embedded engines with varoius methods of selecting the right one.
class GeometryEvaluator : public NodeVisitor
{
public:
GeometryEvaluator(const Tree& tree);
std::shared_ptr<const Geometry> evaluateGeometry(const AbstractNode& node, bool allownef);
Response visit(State& state, const AbstractNode& node) override;
Response visit(State& state, const AbstractIntersectionNode& node) override;
Response visit(State& state, const AbstractPolyNode& node) override;
Response visit(State& state, const LinearExtrudeNode& node) override;
Response visit(State& state, const RotateExtrudeNode& node) override;
#if defined(ENABLE_EXPERIMENTAL) && defined(ENABLE_CGAL)
Response visit(State& state, const RoofNode& node) override;
#endif
Response visit(State& state, const ListNode& node) override;
Response visit(State& state, const GroupNode& node) override;
Response visit(State& state, const RootNode& node) override;
Response visit(State& state, const LeafNode& node) override;
Response visit(State& state, const TransformNode& node) override;
Response visit(State& state, const CsgOpNode& node) override;
Response visit(State& state, const CgalAdvNode& node) override;
Response visit(State& state, const ProjectionNode& node) override;
Response visit(State& state, const RenderNode& node) override;
Response visit(State& state, const TextNode& node) override;
Response visit(State& state, const OffsetNode& node) override;
[[nodiscard]] const Tree& getTree() const { return this->tree; }
private:
class ResultObject
{
public:
// This makes it explicit if we want a const vs. non-const result.
// This is important to avoid inadvertently tagging a geometry as const when
// the underlying geometry is actually mutable.
// The template trick, combined with private constructors, makes it possible
// to create a ResultObject containing a const, _only_ from const objects
// (i.e. no implicit conversion from non-const to const).
template<class T> static ResultObject constResult(std::shared_ptr<const T> geom) {return {geom};}
template<class T> static ResultObject mutableResult(std::shared_ptr<T> geom) {return {geom};}
// Default constructor with nullptr can be used to represent empty geometry,
// for example union() with no children, etc.
ResultObject() : is_const(true) {}
std::shared_ptr<Geometry> ptr() { assert(!is_const); return pointer; }
[[nodiscard]] std::shared_ptr<const Geometry> constptr() const {
return is_const ? const_pointer : std::static_pointer_cast<const Geometry>(pointer);
}
std::shared_ptr<Geometry> asMutableGeometry() {
if (is_const) return {constptr() ? constptr()->copy() : nullptr};
else return ptr();
}
private:
template<class T> ResultObject(std::shared_ptr<const T> g) : is_const(true), const_pointer(std::move(g)) {}
template<class T> ResultObject(std::shared_ptr<T> g) : is_const(false), pointer(std::move(g)) {}
bool is_const;
std::shared_ptr<Geometry> pointer;
std::shared_ptr<const Geometry> const_pointer;
};
void smartCacheInsert(const AbstractNode& node, const std::shared_ptr<const Geometry>& geom);
std::shared_ptr<const Geometry> smartCacheGet(const AbstractNode& node, bool preferNef);
bool isSmartCached(const AbstractNode& node);
bool isValidDim(const Geometry::GeometryItem& item, unsigned int& dim) const;
std::vector<std::shared_ptr<const Polygon2d>> collectChildren2D(const AbstractNode& node);
Geometry::Geometries collectChildren3D(const AbstractNode& node);
std::unique_ptr<Polygon2d> applyMinkowski2D(const AbstractNode& node);
std::unique_ptr<Polygon2d> applyHull2D(const AbstractNode& node);
std::unique_ptr<Polygon2d> applyFill2D(const AbstractNode& node);
std::unique_ptr<Geometry> applyHull3D(const AbstractNode& node);
void applyResize3D(CGAL_Nef_polyhedron& N, const Vector3d& newsize, const Eigen::Matrix<bool, 3, 1>& autosize);
std::unique_ptr<Polygon2d> applyToChildren2D(const AbstractNode& node, OpenSCADOperator op);
ResultObject applyToChildren3D(const AbstractNode& node, OpenSCADOperator op);
ResultObject applyToChildren(const AbstractNode& node, OpenSCADOperator op);
std::shared_ptr<const Geometry> projectionCut(const ProjectionNode& node);
std::shared_ptr<const Geometry> projectionNoCut(const ProjectionNode& node);
void addToParent(const State& state, const AbstractNode& node, const std::shared_ptr<const Geometry>& geom);
Response lazyEvaluateRootNode(State& state, const AbstractNode& node);
std::map<int, Geometry::Geometries> visitedchildren;
const Tree& tree;
std::shared_ptr<const Geometry> root;
public:
};