2424#include " ../ifcgeom/IteratorSettings.h"
2525#include " ../ifcgeom/taxonomy.h"
2626
27+ #include < memory>
2728#include < vector>
2829
2930namespace IfcGeom {
@@ -32,26 +33,203 @@ namespace IfcGeom {
3233 class IFC_GEOM_API Triangulation;
3334 }
3435
35- class IFC_GEOM_API ConversionResultShape {
36+ template <typename T>
37+ constexpr T add_ (T a, T b) {
38+ return a + b;
39+ }
40+
41+ template <typename T>
42+ constexpr T subtract_ (T a, T b) {
43+ return a - b;
44+ }
45+
46+ template <typename T>
47+ constexpr T multiply_ (T a, T b) {
48+ return a * b;
49+ }
50+
51+ template <typename T>
52+ constexpr T divide_ (T a, T b) {
53+ return a / b;
54+ }
55+
56+ template <typename T>
57+ constexpr bool equals_ (T a, T b) {
58+ return a == b;
59+ }
60+
61+ template <typename T>
62+ constexpr bool less_than_ (T a, T b) {
63+ return a < b;
64+ }
65+
66+ template <typename T>
67+ constexpr T negate_ (T a) {
68+ return -a;
69+ }
70+
71+ class IFC_GEOM_API OpaqueNumber {
3672 public:
37- virtual void Triangulate (const IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int surface_style_id) const = 0;
73+ virtual double to_double () const = 0;
74+ virtual ~OpaqueNumber () {}
75+
76+ virtual OpaqueNumber* operator +(OpaqueNumber* other) const = 0 ;
77+ virtual OpaqueNumber* operator -(OpaqueNumber* other) const = 0 ;
78+ virtual OpaqueNumber* operator *(OpaqueNumber* other) const = 0 ;
79+ virtual OpaqueNumber* operator /(OpaqueNumber* other) const = 0 ;
80+ virtual bool operator ==(OpaqueNumber* other) const = 0 ;
81+ virtual bool operator <(OpaqueNumber* other) const = 0 ;
82+ virtual OpaqueNumber* operator -() const = 0 ;
83+ };
84+
85+ // @todo this can simply be a template class, to remove the need for the NumberEpeck in CGAL kernel.
86+ class IFC_GEOM_API NumberNativeDouble : public OpaqueNumber {
87+ private:
88+ double value_;
89+
90+ template <double (*Fn)(double , double )>
91+ OpaqueNumber* binary_op (OpaqueNumber* other) const {
92+ auto nnd = dynamic_cast <NumberNativeDouble*>(other);
93+ if (nnd) {
94+ return new NumberNativeDouble (Fn (value_, nnd->value_ ));
95+ } else {
96+ return nullptr ;
97+ }
98+ }
99+
100+ template <bool (*Fn)(double , double )>
101+ bool binary_op_bool (OpaqueNumber* other) const {
102+ auto nnd = dynamic_cast <NumberNativeDouble*>(other);
103+ if (nnd) {
104+ return new NumberNativeDouble (Fn (value_, nnd->value_ ));
105+ } else {
106+ return nullptr ;
107+ }
108+ }
109+
110+ template <double (*Fn)(double )>
111+ OpaqueNumber* unary_op () const {
112+ return new NumberNativeDouble (Fn (value_));
113+ }
114+ public:
115+ NumberNativeDouble (double v)
116+ : value_(v) {}
117+
118+ virtual double to_double () const {
119+ return value_;
120+ }
121+
122+ virtual OpaqueNumber* operator +(OpaqueNumber* other) const {
123+ return binary_op<add_<double >>(other);
124+ }
38125
126+ virtual OpaqueNumber* operator -(OpaqueNumber* other) const {
127+ return binary_op<subtract_<double >>(other);
128+ }
129+ virtual OpaqueNumber* operator *(OpaqueNumber* other) const {
130+ return binary_op<multiply_<double >>(other);
131+ }
132+ virtual OpaqueNumber* operator /(OpaqueNumber* other) const {
133+ return binary_op<divide_<double >>(other);
134+ }
135+ virtual bool operator ==(OpaqueNumber* other) const {
136+ return binary_op_bool<equals_<double >>(other);
137+ }
138+ virtual bool operator <(OpaqueNumber* other) const {
139+ return binary_op_bool<less_than_<double >>(other);
140+ }
141+ virtual OpaqueNumber* operator -() const {
142+ return unary_op<negate_<double >>();
143+ }
144+ };
145+
146+ template <size_t N>
147+ struct IFC_GEOM_API OpaqueCoordinate {
148+ std::array<std::shared_ptr<OpaqueNumber>, N> values;
149+
150+ template <typename ... Args>
151+ OpaqueCoordinate (Args... args) {
152+ static_assert (sizeof ...(args) == N, " Incorrect number of arguments provided" );
153+ init_<0 >(args...);
154+ }
155+
156+ OpaqueCoordinate () {
157+ for (auto it = values.begin (); it != values.end (); ++it) {
158+ *it = nullptr ;
159+ }
160+ }
161+
162+ std::shared_ptr<OpaqueNumber> get (size_t i) {
163+ if (i >= N) {
164+ return nullptr ;
165+ }
166+ return values[i];
167+ }
168+
169+ void set (size_t i, std::shared_ptr<OpaqueNumber> n) {
170+ if (i < N) {
171+ values[i] = n;
172+ }
173+ }
174+ private:
175+ template <size_t Index, typename ... Args>
176+ void init_ (std::shared_ptr<OpaqueNumber> value, Args... args) {
177+ values[Index] = value;
178+ if constexpr (Index + 1 < N) {
179+ init_<Index + 1 >(args...);
180+ }
181+ }
182+ };
183+
184+ class IFC_GEOM_API ConversionResultShape {
185+ public:
186+ virtual void Triangulate (const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int surface_style_id) const = 0;
187+ IfcGeom::Representation::Triangulation* Triangulate (const IfcGeom::IteratorSettings& settings) const ;
39188 virtual void Serialize (const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const = 0;
40- virtual ConversionResultShape* clone () const = 0;
189+
41190 virtual int surface_genus () const = 0;
42191 virtual bool is_manifold () const = 0;
43- // @todo this must be something with a virtual dtor so that we can delete it.
44- virtual double bounding_box (void *& b) const = 0;
192+
45193 virtual int num_vertices () const = 0;
194+ virtual int num_edges () const = 0;
195+ virtual int num_faces () const = 0;
196+
197+ // @todo choose one prototype
198+ virtual double bounding_box (void *&) const = 0;
199+ // @todo this must be something with a virtual dtor so that we can delete it.
200+ virtual std::pair<OpaqueCoordinate<3 >, OpaqueCoordinate<3 >> bounding_box () const = 0;
46201 virtual void set_box (void * b) = 0;
202+
203+ virtual std::shared_ptr<OpaqueNumber> length () = 0;
204+ virtual std::shared_ptr<OpaqueNumber> area () = 0;
205+ virtual std::shared_ptr<OpaqueNumber> volume () = 0;
206+
207+ virtual OpaqueCoordinate<3 > position () = 0;
208+ virtual OpaqueCoordinate<3 > axis () = 0;
209+ virtual OpaqueCoordinate<4 > plane_equation () = 0;
210+
211+ virtual std::vector<ConversionResultShape*> convex_decomposition () = 0;
212+ virtual ConversionResultShape* halfspaces () = 0;
213+ virtual ConversionResultShape* box () = 0;
214+ virtual ConversionResultShape* solid () = 0;
215+ virtual std::vector<ConversionResultShape*> edges () = 0;
216+ virtual std::vector<ConversionResultShape*> facets () = 0;
217+
218+ virtual ConversionResultShape* add (ConversionResultShape*) = 0;
219+ virtual ConversionResultShape* subtract (ConversionResultShape*) = 0;
220+ virtual ConversionResultShape* intersect (ConversionResultShape*) = 0;
221+
222+ virtual void map (OpaqueCoordinate<4 >& from, OpaqueCoordinate<4 >& to) = 0;
223+ virtual ConversionResultShape* moved (ifcopenshell::geometry::taxonomy::matrix4::ptr) const = 0;
224+
47225 virtual ~ConversionResultShape () {}
48226 };
49227
50228 class IFC_GEOM_API ConversionResult {
51229 private:
52230 int id;
53231 ifcopenshell::geometry::taxonomy::matrix4::ptr placement_;
54- ConversionResultShape* shape_;
232+ std::shared_ptr< ConversionResultShape> shape_;
55233 ifcopenshell::geometry::taxonomy::style::ptr style_;
56234 public:
57235 ConversionResult (int id, ifcopenshell::geometry::taxonomy::matrix4::ptr placement, ConversionResultShape* shape, ifcopenshell::geometry::taxonomy::style::ptr style)
@@ -74,7 +252,7 @@ namespace IfcGeom {
74252 // @todo verify order
75253 placement_->components () = trsf->ccomponents () * placement_->ccomponents ();
76254 }
77- ConversionResultShape* Shape () const { return shape_; }
255+ std::shared_ptr< ConversionResultShape> Shape () const { return shape_; }
78256 ifcopenshell::geometry::taxonomy::matrix4::ptr Placement () const { return placement_; }
79257 bool hasStyle () const { return !!style_; }
80258 const ifcopenshell::geometry::taxonomy::style& Style () const { return *style_; }
0 commit comments