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 "manifold/linalg.h"
24
25namespace manifold {
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>;
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); }
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
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
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 }
467};
468
473enum class OpType { 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 inline static int circularSegments_ = DEFAULT_SEGMENTS;
491 inline static double circularAngle_ = DEFAULT_ANGLE;
492 inline static double circularEdgeLength_ = DEFAULT_LENGTH;
493
494 public:
505 static void SetMinCircularAngle(double angle) {
506 if (angle <= 0) return;
507 circularAngle_ = angle;
508 }
509
519 static void SetMinCircularEdgeLength(double length) {
520 if (length <= 0) return;
521 circularEdgeLength_ = length;
522 }
523
533 static void SetCircularSegments(int number) {
534 if (number < 3 && number != 0) return;
535 circularSegments_ = number;
536 }
537
545 static int GetCircularSegments(double radius) {
546 if (circularSegments_ > 0) return circularSegments_;
547 int nSegA = 360.0 / circularAngle_;
548 int nSegL = 2.0 * radius * kPi / circularEdgeLength_;
549 int nSeg = fmin(nSegA, nSegL) + 3;
550 nSeg -= nSeg % 4;
551 return std::max(nSeg, 3);
552 }
553
559 static void ResetToDefaults() {
560 circularSegments_ = DEFAULT_SEGMENTS;
561 circularAngle_ = DEFAULT_ANGLE;
562 circularEdgeLength_ = DEFAULT_LENGTH;
563 }
564};
579 bool intermediateChecks = false;
582 bool verbose = false;
585 bool processOverlaps = true;
588 bool suppressErrors = false;
590 bool cleanupTriangles = true;
591};
594#ifdef MANIFOLD_DEBUG
595inline std::ostream& operator<<(std::ostream& stream, const Box& box) {
596 return stream << "min: " << box.min << ", "
597 << "max: " << box.max;
598}
599
600inline std::ostream& operator<<(std::ostream& stream, const Rect& box) {
601 return stream << "min: " << box.min << ", "
602 << "max: " << box.max;
603}
604
609template <typename T>
610void Dump(const std::vector<T>& vec) {
611 std::cout << "Vec = " << std::endl;
612 for (size_t i = 0; i < vec.size(); ++i) {
613 std::cout << i << ", " << vec[i] << ", " << std::endl;
614 }
615 std::cout << std::endl;
616}
617
618template <typename T>
619void Diff(const std::vector<T>& a, const std::vector<T>& b) {
620 std::cout << "Diff = " << std::endl;
621 if (a.size() != b.size()) {
622 std::cout << "a and b must have the same length, aborting Diff"
623 << std::endl;
624 return;
625 }
626 for (size_t i = 0; i < a.size(); ++i) {
627 if (a[i] != b[i])
628 std::cout << i << ": " << a[i] << ", " << b[i] << std::endl;
629 }
630 std::cout << std::endl;
631}
632
633struct Timer {
634 std::chrono::high_resolution_clock::time_point start, end;
635
636 void Start() { start = std::chrono::high_resolution_clock::now(); }
637
638 void Stop() { end = std::chrono::high_resolution_clock::now(); }
639
640 float Elapsed() {
641 return std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
642 .count();
643 }
644 void Print(std::string message) {
645 std::cout << "----------- " << std::round(Elapsed()) << " ms for "
646 << message << std::endl;
647 }
648};
649#endif
650} // namespace manifold
These static properties control how circular shapes are quantized by default on construction.
Definition common.h:488
static void ResetToDefaults()
Definition common.h:559
static void SetCircularSegments(int number)
Definition common.h:533
static void SetMinCircularAngle(double angle)
Definition common.h:505
static int GetCircularSegments(double radius)
Definition common.h:545
static void SetMinCircularEdgeLength(double length)
Definition common.h:519
bool suppressErrors
Definition common.h:588
bool processOverlaps
Definition common.h:585
bool cleanupTriangles
Perform optional but recommended triangle cleanups in SimplifyTopology()
Definition common.h:590
bool verbose
Definition common.h:582
bool intermediateChecks
Definition common.h:579
Global parameters that control debugging output. Only has an effect when compiled with the MANIFOLD_D...
Definition common.h:576
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
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
OpType
Boolean operation type: Add (Union), Subtract (Difference), and Intersect.
Definition common.h:473
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
constexpr apply_t< detail::clamp, X, L, H > clamp(const X &x, const L &l, const H &h)
Clamps the components of x between l and h, provided l[i] < h[i].
Definition linalg.h:1707
Definition linalg.h:68
Definition linalg.h:63
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
Axis-aligned 2D box, primarily for bounding.
Definition common.h:307
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:633