Manifold 3.0
Robust geometry
 
Loading...
Searching...
No Matches
common.h
1// Copyright 2021 The Manifold Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16#include <limits>
17#include <vector>
18
19#ifdef MANIFOLD_DEBUG
20#include <chrono>
21#endif
22
23#include "linalg.h"
24
25namespace manifold {
30
34namespace la = linalg;
35using vec2 = la::vec<double, 2>;
36using vec3 = la::vec<double, 3>;
37using vec4 = la::vec<double, 4>;
38using bvec4 = la::vec<bool, 4>;
39using mat2 = la::mat<double, 2, 2>;
40using mat3x2 = la::mat<double, 3, 2>;
41using mat4x2 = la::mat<double, 4, 2>;
42using mat2x3 = la::mat<double, 2, 3>;
43using mat3 = la::mat<double, 3, 3>;
44using mat4x3 = la::mat<double, 4, 3>;
45using mat3x4 = la::mat<double, 3, 4>;
46using mat4 = la::mat<double, 4, 4>;
47using ivec2 = la::vec<int, 2>;
48using ivec3 = la::vec<int, 3>;
49using ivec4 = la::vec<int, 4>;
50using quat = la::vec<double, 4>;
52
58
59constexpr double kPi = 3.14159265358979323846264338327950288;
60constexpr double kTwoPi = 6.28318530717958647692528676655900576;
61constexpr double kHalfPi = 1.57079632679489661923132169163975144;
62
68constexpr double radians(double a) { return a * kPi / 180; }
69
75constexpr double degrees(double a) { return a * 180 / kPi; }
76
84constexpr double smoothstep(double edge0, double edge1, double a) {
85 const double x = la::clamp((a - edge0) / (edge1 - edge0), 0, 1);
86 return x * x * (3 - 2 * x);
87}
88
94inline double sind(double x) {
95 if (!la::isfinite(x)) return sin(x);
96 if (x < 0.0) return -sind(-x);
97 int quo;
98 x = remquo(fabs(x), 90.0, &quo);
99 switch (quo % 4) {
100 case 0:
101 return sin(radians(x));
102 case 1:
103 return cos(radians(x));
104 case 2:
105 return -sin(radians(x));
106 case 3:
107 return -cos(radians(x));
108 }
109 return 0.0;
110}
111
117inline double cosd(double x) { return sind(x + 90.0); }
119
125
131using SimplePolygon = std::vector<vec2>;
132
139using Polygons = std::vector<SimplePolygon>;
140
147 size_t halfedge;
152};
153
157struct Box {
158 vec3 min = vec3(std::numeric_limits<double>::infinity());
159 vec3 max = vec3(-std::numeric_limits<double>::infinity());
160
164 constexpr Box() {}
165
169 constexpr Box(const vec3 p1, const vec3 p2) {
170 min = la::min(p1, p2);
171 max = la::max(p1, p2);
172 }
173
177 constexpr vec3 Size() const { return max - min; }
178
182 constexpr vec3 Center() const { return 0.5 * (max + min); }
183
188 constexpr double Scale() const {
189 vec3 absMax = la::max(la::abs(min), la::abs(max));
190 return la::max(absMax.x, la::max(absMax.y, absMax.z));
191 }
192
196 constexpr bool Contains(const vec3& p) const {
197 return la::all(la::gequal(p, min)) && la::all(la::gequal(max, p));
198 }
199
203 constexpr bool Contains(const Box& box) const {
204 return la::all(la::gequal(box.min, min)) &&
205 la::all(la::gequal(max, box.max));
206 }
207
211 void Union(const vec3 p) {
212 min = la::min(min, p);
213 max = la::max(max, p);
214 }
215
219 constexpr Box Union(const Box& box) const {
220 Box out;
221 out.min = la::min(min, box.min);
222 out.max = la::max(max, box.max);
223 return out;
224 }
225
233 constexpr Box Transform(const mat3x4& transform) const {
234 Box out;
235 vec3 minT = transform * vec4(min, 1.0);
236 vec3 maxT = transform * vec4(max, 1.0);
237 out.min = la::min(minT, maxT);
238 out.max = la::max(minT, maxT);
239 return out;
240 }
241
245 constexpr Box operator+(vec3 shift) const {
246 Box out;
247 out.min = min + shift;
248 out.max = max + shift;
249 return out;
250 }
251
255 Box& operator+=(vec3 shift) {
256 min += shift;
257 max += shift;
258 return *this;
259 }
260
264 constexpr Box operator*(vec3 scale) const {
265 Box out;
266 out.min = min * scale;
267 out.max = max * scale;
268 return out;
269 }
270
274 Box& operator*=(vec3 scale) {
275 min *= scale;
276 max *= scale;
277 return *this;
278 }
279
283 constexpr bool DoesOverlap(const Box& box) const {
284 return min.x <= box.max.x && min.y <= box.max.y && min.z <= box.max.z &&
285 max.x >= box.min.x && max.y >= box.min.y && max.z >= box.min.z;
286 }
287
292 constexpr bool DoesOverlap(vec3 p) const { // projected in z
293 return p.x <= max.x && p.x >= min.x && p.y <= max.y && p.y >= min.y;
294 }
295
299 constexpr bool IsFinite() const {
300 return la::all(la::isfinite(min)) && la::all(la::isfinite(max));
301 }
302};
303
307struct Rect {
308 vec2 min = vec2(std::numeric_limits<double>::infinity());
309 vec2 max = vec2(-std::numeric_limits<double>::infinity());
310
314 constexpr Rect() {}
315
319 constexpr Rect(const vec2 a, const vec2 b) {
320 min = la::min(a, b);
321 max = la::max(a, b);
322 }
323
328
332 constexpr vec2 Size() const { return max - min; }
333
337 constexpr double Area() const {
338 auto sz = Size();
339 return sz.x * sz.y;
340 }
341
346 constexpr double Scale() const {
347 vec2 absMax = la::max(la::abs(min), la::abs(max));
348 return la::max(absMax.x, absMax.y);
349 }
350
354 constexpr vec2 Center() const { return 0.5 * (max + min); }
355
359 constexpr bool Contains(const vec2& p) const {
360 return la::all(la::gequal(p, min)) && la::all(la::gequal(max, p));
361 }
362
366 constexpr bool Contains(const Rect& rect) const {
367 return la::all(la::gequal(rect.min, min)) &&
368 la::all(la::gequal(max, rect.max));
369 }
370
374 constexpr bool DoesOverlap(const Rect& rect) const {
375 return min.x <= rect.max.x && min.y <= rect.max.y && max.x >= rect.min.x &&
376 max.y >= rect.min.y;
377 }
378
382 constexpr bool IsEmpty() const { return max.y <= min.y || max.x <= min.x; };
383
387 constexpr bool IsFinite() const {
388 return la::all(la::isfinite(min)) && la::all(la::isfinite(max));
389 }
390
392
396
400 void Union(const vec2 p) {
401 min = la::min(min, p);
402 max = la::max(max, p);
403 }
404
408 constexpr Rect Union(const Rect& rect) const {
409 Rect out;
410 out.min = la::min(min, rect.min);
411 out.max = la::max(max, rect.max);
412 return out;
413 }
414
418 constexpr Rect operator+(const vec2 shift) const {
419 Rect out;
420 out.min = min + shift;
421 out.max = max + shift;
422 return out;
423 }
424
428 Rect& operator+=(const vec2 shift) {
429 min += shift;
430 max += shift;
431 return *this;
432 }
433
437 constexpr Rect operator*(const vec2 scale) const {
438 Rect out;
439 out.min = min * scale;
440 out.max = max * scale;
441 return out;
442 }
443
447 Rect& operator*=(const vec2 scale) {
448 min *= scale;
449 max *= scale;
450 return *this;
451 }
452
460 constexpr Rect Transform(const mat2x3& m) const {
461 Rect rect;
462 rect.min = m * vec3(min, 1);
463 rect.max = m * vec3(max, 1);
464 return rect;
465 }
466
467};
468
473enum class OpType : char { Add, Subtract, Intersect };
474
475constexpr int DEFAULT_SEGMENTS = 0;
476constexpr double DEFAULT_ANGLE = 10.0;
477constexpr double DEFAULT_LENGTH = 1.0;
488class Quality {
489 private:
490 public:
491 static void SetMinCircularAngle(double angle);
492 static void SetMinCircularEdgeLength(double length);
493 static void SetCircularSegments(int number);
494 static int GetCircularSegments(double radius);
495 static void ResetToDefaults();
496};
497
498
503
511 bool intermediateChecks = false;
517 bool processOverlaps = true;
520 bool suppressErrors = false;
523 bool cleanupTriangles = true;
529 int verbose = 0;
530};
531
532
533#ifdef MANIFOLD_DEBUG
534
535inline std::ostream& operator<<(std::ostream& stream, const Box& box) {
536 return stream << "min: " << box.min << ", "
537 << "max: " << box.max;
538}
539
540inline std::ostream& operator<<(std::ostream& stream, const Rect& box) {
541 return stream << "min: " << box.min << ", "
542 << "max: " << box.max;
543}
544
545inline std::ostream& operator<<(std::ostream& stream, const Smoothness& s) {
546 return stream << "halfedge: " << s.halfedge << ", "
547 << "smoothness: " << s.smoothness;
548}
549
554template <typename T>
555void Dump(const std::vector<T>& vec) {
556 std::cout << "Vec = " << std::endl;
557 for (size_t i = 0; i < vec.size(); ++i) {
558 std::cout << i << ", " << vec[i] << ", " << std::endl;
559 }
560 std::cout << std::endl;
561}
562
563template <typename T>
564void Diff(const std::vector<T>& a, const std::vector<T>& b) {
565 std::cout << "Diff = " << std::endl;
566 if (a.size() != b.size()) {
567 std::cout << "a and b must have the same length, aborting Diff"
568 << std::endl;
569 return;
570 }
571 for (size_t i = 0; i < a.size(); ++i) {
572 if (a[i] != b[i])
573 std::cout << i << ": " << a[i] << ", " << b[i] << std::endl;
574 }
575 std::cout << std::endl;
576}
577
578struct Timer {
579 std::chrono::high_resolution_clock::time_point start, end;
580
581 void Start() { start = std::chrono::high_resolution_clock::now(); }
582
583 void Stop() { end = std::chrono::high_resolution_clock::now(); }
584
585 float Elapsed() {
586 return std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
587 .count();
588 }
589 void Print(std::string message) {
590 std::cout << "----------- " << std::round(Elapsed()) << " ms for "
591 << message << std::endl;
592 }
593};
594#endif
595} // namespace manifold
These static properties control how circular shapes are quantized by default on construction.
Definition common.h:488
static void SetMinCircularAngle(double angle)
Definition manifold.cpp:217
static void ResetToDefaults()
Definition manifold.cpp:271
static void SetCircularSegments(int number)
Definition manifold.cpp:245
static int GetCircularSegments(double radius)
Definition manifold.cpp:257
static void SetMinCircularEdgeLength(double length)
Definition manifold.cpp:231
int verbose
Definition common.h:529
bool suppressErrors
Definition common.h:520
bool processOverlaps
Definition common.h:517
bool cleanupTriangles
Definition common.h:523
bool selfIntersectionChecks
Definition common.h:514
bool intermediateChecks
Definition common.h:511
Global parameters that control debugging output. Only has an effect when compiled with the MANIFOLD_D...
Definition common.h:508
constexpr double smoothstep(double edge0, double edge1, double a)
Definition common.h:84
constexpr double degrees(double a)
Definition common.h:75
double cosd(double x)
Definition common.h:117
double sind(double x)
Definition common.h:94
constexpr double radians(double a)
Definition common.h:68
size_t halfedge
The halfedge index = 3 * tri + i, referring to Mesh.triVerts[tri][i].
Definition common.h:147
double smoothness
Definition common.h:151
OpType
Boolean operation type: Add (Union), Subtract (Difference), and Intersect.
Definition common.h:473
std::vector< SimplePolygon > Polygons
Set of polygons with holes. Order of contours is arbitrary. Can contain any depth of nested holes and...
Definition common.h:139
std::vector< vec2 > SimplePolygon
Single polygon contour, wound CCW. First and last point are implicitly connected. Should ensure all i...
Definition common.h:131
Defines which edges to sharpen and how much for the Manifold.Smooth() constructor.
Definition common.h:145
Definition linalg.h:61
Definition linalg.h:56
Axis-aligned 3D box, primarily for bounding.
Definition common.h:157
constexpr Box Transform(const mat3x4 &transform) const
Definition common.h:233
constexpr Box operator+(vec3 shift) const
Definition common.h:245
constexpr bool Contains(const Box &box) const
Definition common.h:203
constexpr vec3 Center() const
Definition common.h:182
constexpr bool DoesOverlap(const Box &box) const
Definition common.h:283
constexpr double Scale() const
Definition common.h:188
constexpr Box Union(const Box &box) const
Definition common.h:219
constexpr bool DoesOverlap(vec3 p) const
Definition common.h:292
void Union(const vec3 p)
Definition common.h:211
Box & operator*=(vec3 scale)
Definition common.h:274
constexpr bool IsFinite() const
Definition common.h:299
constexpr vec3 Size() const
Definition common.h:177
constexpr Box operator*(vec3 scale) const
Definition common.h:264
Box & operator+=(vec3 shift)
Definition common.h:255
constexpr Box(const vec3 p1, const vec3 p2)
Definition common.h:169
constexpr Box()
Definition common.h:164
constexpr bool Contains(const vec3 &p) const
Definition common.h:196
Rect & operator*=(const vec2 scale)
Definition common.h:447
constexpr bool Contains(const Rect &rect) const
Definition common.h:366
constexpr bool Contains(const vec2 &p) const
Definition common.h:359
constexpr bool IsEmpty() const
Definition common.h:382
constexpr Rect(const vec2 a, const vec2 b)
Definition common.h:319
constexpr vec2 Size() const
Definition common.h:332
constexpr double Area() const
Definition common.h:337
constexpr double Scale() const
Definition common.h:346
constexpr vec2 Center() const
Definition common.h:354
constexpr Rect operator*(const vec2 scale) const
Definition common.h:437
constexpr Rect operator+(const vec2 shift) const
Definition common.h:418
constexpr Rect Transform(const mat2x3 &m) const
Definition common.h:460
void Union(const vec2 p)
Definition common.h:400
constexpr Rect()
Definition common.h:314
constexpr bool IsFinite() const
Definition common.h:387
constexpr Rect Union(const Rect &rect) const
Definition common.h:408
constexpr bool DoesOverlap(const Rect &rect) const
Definition common.h:374
Rect & operator+=(const vec2 shift)
Definition common.h:428
Definition common.h:578