Manifold 1.0
Robust computational 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 <stdexcept>
18#include <vector>
19
20#include "manifold/linalg.h"
21
22namespace manifold {
28namespace la = linalg;
46
47constexpr double kPi = 3.14159265358979323846264338327950288;
48constexpr double kTwoPi = 6.28318530717958647692528676655900576;
49constexpr double kHalfPi = 1.57079632679489661923132169163975144;
50
51constexpr double radians(double a) { return a * kPi / 180; }
52constexpr double degrees(double a) { return a * 180 / kPi; }
53
54constexpr double smoothstep(double edge0, double edge1, double a) {
55 const double x = la::clamp((a - edge0) / (edge1 - edge0), 0, 1);
56 return x * x * (3 - 2 * x);
57}
58
59constexpr mat3x4 Identity3x4() { return mat3x4(mat3(la::identity), vec3(0.0)); }
60constexpr mat2x3 Identity2x3() { return mat2x3(mat2(la::identity), vec2(0.0)); }
61
67inline double sind(double x) {
68 if (!la::isfinite(x)) return sin(x);
69 if (x < 0.0) return -sind(-x);
70 int quo;
71 x = remquo(fabs(x), 90.0, &quo);
72 switch (quo % 4) {
73 case 0:
74 return sin(radians(x));
75 case 1:
76 return cos(radians(x));
77 case 2:
78 return -sin(radians(x));
79 case 3:
80 return -cos(radians(x));
81 }
82 return 0.0;
83}
84
90inline double cosd(double x) { return sind(x + 90.0); }
91
97using SimplePolygon = std::vector<vec2>;
98
105using Polygons = std::vector<SimplePolygon>;
106
113 size_t halfedge;
118};
119
124 double surfaceArea, volume;
125};
126
127struct Box {
128 vec3 min = vec3(std::numeric_limits<double>::infinity());
129 vec3 max = vec3(-std::numeric_limits<double>::infinity());
130
134 constexpr Box() {}
135
139 constexpr Box(const vec3 p1, const vec3 p2) {
140 min = la::min(p1, p2);
141 max = la::max(p1, p2);
142 }
143
147 constexpr vec3 Size() const { return max - min; }
148
152 constexpr vec3 Center() const { return 0.5 * (max + min); }
153
158 constexpr double Scale() const {
159 vec3 absMax = la::max(la::abs(min), la::abs(max));
160 return la::max(absMax.x, la::max(absMax.y, absMax.z));
161 }
162
166 constexpr bool Contains(const vec3& p) const {
167 return la::all(la::gequal(p, min)) && la::all(la::gequal(max, p));
168 }
169
173 constexpr bool Contains(const Box& box) const {
174 return la::all(la::gequal(box.min, min)) &&
175 la::all(la::gequal(max, box.max));
176 }
177
181 void Union(const vec3 p) {
182 min = la::min(min, p);
183 max = la::max(max, p);
184 }
185
189 constexpr Box Union(const Box& box) const {
190 Box out;
191 out.min = la::min(min, box.min);
192 out.max = la::max(max, box.max);
193 return out;
194 }
195
203 constexpr Box Transform(const mat3x4& transform) const {
204 Box out;
205 vec3 minT = transform * vec4(min, 1.0);
206 vec3 maxT = transform * vec4(max, 1.0);
207 out.min = la::min(minT, maxT);
208 out.max = la::max(minT, maxT);
209 return out;
210 }
211
215 constexpr Box operator+(vec3 shift) const {
216 Box out;
217 out.min = min + shift;
218 out.max = max + shift;
219 return out;
220 }
221
226 min += shift;
227 max += shift;
228 return *this;
229 }
230
234 constexpr Box operator*(vec3 scale) const {
235 Box out;
236 out.min = min * scale;
237 out.max = max * scale;
238 return out;
239 }
240
245 min *= scale;
246 max *= scale;
247 return *this;
248 }
249
253 constexpr bool DoesOverlap(const Box& box) const {
254 return min.x <= box.max.x && min.y <= box.max.y && min.z <= box.max.z &&
255 max.x >= box.min.x && max.y >= box.min.y && max.z >= box.min.z;
256 }
257
262 constexpr bool DoesOverlap(vec3 p) const { // projected in z
263 return p.x <= max.x && p.x >= min.x && p.y <= max.y && p.y >= min.y;
264 }
265
269 constexpr bool IsFinite() const {
270 return la::all(la::isfinite(min)) && la::all(la::isfinite(max));
271 }
272};
273
277struct Rect {
278 vec2 min = vec2(std::numeric_limits<double>::infinity());
279 vec2 max = vec2(-std::numeric_limits<double>::infinity());
280
284 constexpr Rect() {}
285
289 constexpr Rect(const vec2 a, const vec2 b) {
290 min = la::min(a, b);
291 max = la::max(a, b);
292 }
293
298
302 constexpr vec2 Size() const { return max - min; }
303
307 constexpr double Area() const {
308 auto sz = Size();
309 return sz.x * sz.y;
310 }
311
316 constexpr double Scale() const {
317 vec2 absMax = la::max(la::abs(min), la::abs(max));
318 return la::max(absMax.x, absMax.y);
319 }
320
324 constexpr vec2 Center() const { return 0.5 * (max + min); }
325
329 constexpr bool Contains(const vec2& p) const {
330 return la::all(la::gequal(p, min)) && la::all(la::gequal(max, p));
331 }
332
336 constexpr bool Contains(const Rect& rect) const {
337 return la::all(la::gequal(rect.min, min)) &&
338 la::all(la::gequal(max, rect.max));
339 }
340
344 constexpr bool DoesOverlap(const Rect& rect) const {
345 return min.x <= rect.max.x && min.y <= rect.max.y && max.x >= rect.min.x &&
346 max.y >= rect.min.y;
347 }
348
352 constexpr bool IsEmpty() const { return max.y <= min.y || max.x <= min.x; };
353
357 constexpr bool IsFinite() const {
358 return la::all(la::isfinite(min)) && la::all(la::isfinite(max));
359 }
360
362
366
370 void Union(const vec2 p) {
371 min = la::min(min, p);
372 max = la::max(max, p);
373 }
374
378 constexpr Rect Union(const Rect& rect) const {
379 Rect out;
380 out.min = la::min(min, rect.min);
381 out.max = la::max(max, rect.max);
382 return out;
383 }
384
388 constexpr Rect operator+(const vec2 shift) const {
389 Rect out;
390 out.min = min + shift;
391 out.max = max + shift;
392 return out;
393 }
394
398 Rect& operator+=(const vec2 shift) {
399 min += shift;
400 max += shift;
401 return *this;
402 }
403
407 constexpr Rect operator*(const vec2 scale) const {
408 Rect out;
409 out.min = min * scale;
410 out.max = max * scale;
411 return out;
412 }
413
417 Rect& operator*=(const vec2 scale) {
418 min *= scale;
419 max *= scale;
420 return *this;
421 }
422
430 constexpr Rect Transform(const mat2x3& m) const {
431 Rect rect;
432 rect.min = m * vec3(min, 1);
433 rect.max = m * vec3(max, 1);
434 return rect;
435 }
437};
447enum class OpType { Add, Subtract, Intersect };
448
449constexpr int DEFAULT_SEGMENTS = 0;
450constexpr double DEFAULT_ANGLE = 10.0;
451constexpr double DEFAULT_LENGTH = 1.0;
460class Quality {
461 private:
462 inline static int circularSegments_ = DEFAULT_SEGMENTS;
463 inline static double circularAngle_ = DEFAULT_ANGLE;
464 inline static double circularEdgeLength_ = DEFAULT_LENGTH;
465
466 public:
477 static void SetMinCircularAngle(double angle) {
478 if (angle <= 0) return;
479 circularAngle_ = angle;
480 }
481
491 static void SetMinCircularEdgeLength(double length) {
492 if (length <= 0) return;
493 circularEdgeLength_ = length;
494 }
495
505 static void SetCircularSegments(int number) {
506 if (number < 3 && number != 0) return;
507 circularSegments_ = number;
508 }
509
517 static int GetCircularSegments(double radius) {
518 if (circularSegments_ > 0) return circularSegments_;
519 int nSegA = 360.0 / circularAngle_;
520 int nSegL = 2.0 * radius * kPi / circularEdgeLength_;
521 int nSeg = fmin(nSegA, nSegL) + 3;
522 nSeg -= nSeg % 4;
523 return std::max(nSeg, 3);
524 }
525
531 static void ResetToDefaults() {
532 circularSegments_ = DEFAULT_SEGMENTS;
533 circularAngle_ = DEFAULT_ANGLE;
534 circularEdgeLength_ = DEFAULT_LENGTH;
535 }
536};
545struct userErr : public virtual std::runtime_error {
546 using std::runtime_error::runtime_error;
547};
548struct topologyErr : public virtual std::runtime_error {
549 using std::runtime_error::runtime_error;
550};
551struct geometryErr : public virtual std::runtime_error {
552 using std::runtime_error::runtime_error;
553};
554using logicErr = std::logic_error;
564 bool intermediateChecks = false;
567 bool verbose = false;
570 bool processOverlaps = true;
573 bool suppressErrors = false;
575 bool deterministic = false;
577 bool cleanupTriangles = true;
578};
579
580} // namespace manifold
Definition common.h:460
static void ResetToDefaults()
Definition common.h:531
static void SetCircularSegments(int number)
Definition common.h:505
static void SetMinCircularAngle(double angle)
Definition common.h:477
static int GetCircularSegments(double radius)
Definition common.h:517
static void SetMinCircularEdgeLength(double length)
Definition common.h:491
OpType
Definition common.h:447
Definition common.h:22
bool deterministic
Deterministic outputs. Will disable some parallel optimizations.
Definition common.h:575
bool suppressErrors
Definition common.h:573
std::vector< SimplePolygon > Polygons
Definition common.h:105
bool processOverlaps
Definition common.h:570
bool cleanupTriangles
Perform optional but recommended triangle cleanups in SimplifyTopology()
Definition common.h:577
size_t halfedge
The halfedge index = 3 * tri + i, referring to Mesh.triVerts[tri][i].
Definition common.h:113
bool verbose
Definition common.h:567
double cosd(double x)
Definition common.h:90
std::vector< vec2 > SimplePolygon
Definition common.h:97
double sind(double x)
Definition common.h:67
bool intermediateChecks
Definition common.h:564
double smoothness
Definition common.h:117
Definition common.h:561
Definition common.h:123
Definition common.h:111
Definition linalg.h:74
Definition common.h:127
constexpr Box Transform(const mat3x4 &transform) const
Definition common.h:203
constexpr Box operator+(vec3 shift) const
Definition common.h:215
constexpr bool Contains(const Box &box) const
Definition common.h:173
constexpr vec3 Center() const
Definition common.h:152
constexpr bool DoesOverlap(const Box &box) const
Definition common.h:253
constexpr double Scale() const
Definition common.h:158
constexpr Box Union(const Box &box) const
Definition common.h:189
constexpr bool DoesOverlap(vec3 p) const
Definition common.h:262
void Union(const vec3 p)
Definition common.h:181
Box & operator*=(vec3 scale)
Definition common.h:244
constexpr bool IsFinite() const
Definition common.h:269
constexpr vec3 Size() const
Definition common.h:147
constexpr Box operator*(vec3 scale) const
Definition common.h:234
Box & operator+=(vec3 shift)
Definition common.h:225
constexpr Box(const vec3 p1, const vec3 p2)
Definition common.h:139
constexpr Box()
Definition common.h:134
constexpr bool Contains(const vec3 &p) const
Definition common.h:166
Definition common.h:277
Rect & operator*=(const vec2 scale)
Definition common.h:417
constexpr bool Contains(const Rect &rect) const
Definition common.h:336
constexpr bool Contains(const vec2 &p) const
Definition common.h:329
constexpr bool IsEmpty() const
Definition common.h:352
constexpr Rect(const vec2 a, const vec2 b)
Definition common.h:289
constexpr vec2 Size() const
Definition common.h:302
constexpr double Area() const
Definition common.h:307
constexpr double Scale() const
Definition common.h:316
constexpr vec2 Center() const
Definition common.h:324
constexpr Rect operator*(const vec2 scale) const
Definition common.h:407
constexpr Rect operator+(const vec2 shift) const
Definition common.h:388
constexpr Rect Transform(const mat2x3 &m) const
Definition common.h:430
void Union(const vec2 p)
Definition common.h:370
constexpr Rect()
Definition common.h:284
constexpr bool IsFinite() const
Definition common.h:357
constexpr Rect Union(const Rect &rect) const
Definition common.h:378
constexpr bool DoesOverlap(const Rect &rect) const
Definition common.h:344
Rect & operator+=(const vec2 shift)
Definition common.h:398
Definition common.h:551
Definition common.h:548
Definition common.h:545