Manifold 3.0
Robust geometry
Loading...
Searching...
No Matches
manifold.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 <cstdint> // uint32_t, uint64_t
17#include <functional>
18#include <memory> // needed for shared_ptr
19#include <mutex>
20
21#include "manifold/common.h"
22#include "manifold/mesh.h"
23#include "manifold/vec_view.h"
24
25namespace manifold {
26
35
36class CsgNode;
37class CsgLeafNode;
38
43
67class Manifold {
68 public:
73 Manifold();
74 ~Manifold();
75 Manifold(const Manifold& other);
76 Manifold& operator=(const Manifold& other);
77 Manifold(Manifold&&) noexcept;
78 Manifold& operator=(Manifold&&) noexcept;
80
85 Manifold(const MeshGL&);
86 Manifold(const MeshGL64&);
87 MeshGL GetMeshGL(int normalIdx = -1) const;
88 MeshGL64 GetMeshGL64(int normalIdx = -1) const;
90
95 std::vector<Manifold> Decompose() const;
96 [[deprecated(
97 "Compose is deprecated, use BatchBoolean with OpType::Add instead.")]]
98 static Manifold Compose(const std::vector<Manifold>&);
99 static Manifold Tetrahedron();
100 static Manifold Cube(vec3 size = vec3(1.0), bool center = false);
101 static Manifold Cylinder(double height, double radiusLow,
102 double radiusHigh = -1.0, int circularSegments = 0,
103 bool center = false);
104 static Manifold Sphere(double radius, int circularSegments = 0);
105 static Manifold LevelSet(std::function<double(vec3)> sdf, Box bounds,
106 double edgeLength, double level = 0,
107 double tolerance = -1, bool canParallel = true);
109
114 Polygons Slice(double height = 0) const;
115 Polygons Project() const;
116 static Manifold Extrude(const Polygons& crossSection, double height,
117 int nDivisions = 0, double twistDegrees = 0.0,
118 vec2 scaleTop = vec2(1.0));
119 static Manifold Revolve(const Polygons& crossSection,
120 int circularSegments = 0,
121 double revolveDegrees = 360.0f);
123
124 enum class Error {
125 NoError,
126 NonFiniteVertex,
127 NotManifold,
128 VertexOutOfBounds,
129 PropertiesWrongLength,
130 MissingPositionProperties,
131 MergeVectorsDifferentLengths,
132 MergeIndexOutOfBounds,
133 TransformWrongLength,
134 RunIndexWrongLength,
135 FaceIDWrongLength,
136 InvalidConstruction,
137 ResultTooLarge,
138 InvalidTangents,
139 Cancelled,
140 };
141
146 Error Status() const;
147
171 Manifold WithContext(const ExecutionContext& ctx) const;
172
173 bool IsEmpty() const;
174 size_t NumVert() const;
175 size_t NumEdge() const;
176 size_t NumTri() const;
177 size_t NumProp() const;
178 size_t NumPropVert() const;
179 Box BoundingBox() const;
180 int Genus() const;
181 double GetTolerance() const;
183
187 double SurfaceArea() const;
188 double Volume() const;
189 double MinGap(const Manifold& other, double searchLength) const;
190 std::vector<RayHit> RayCast(vec3 origin, vec3 endpoint) const;
191 std::vector<int> WindingNumber(const std::vector<vec3>& points) const;
193
199 int OriginalID() const;
200 Manifold AsOriginal() const;
201 static uint32_t ReserveIDs(uint32_t);
203
207 Manifold Translate(vec3) const;
208 Manifold Scale(vec3) const;
209 Manifold Rotate(double xDegrees, double yDegrees = 0.0,
210 double zDegrees = 0.0) const;
211 Manifold Mirror(vec3) const;
212 Manifold Transform(const mat3x4&) const;
213 Manifold Warp(std::function<void(vec3&)>) const;
214 Manifold WarpBatch(std::function<void(VecView<vec3>)>) const;
215 Manifold SetTolerance(double) const;
216 Manifold Simplify(double tolerance = 0) const;
218
223 Manifold Boolean(const Manifold& second, OpType op) const;
224 static Manifold BatchBoolean(const std::vector<Manifold>& manifolds,
225 OpType op);
226 // Boolean operation shorthand
227 Manifold operator+(const Manifold&) const; // Add (Union)
229 Manifold operator-(const Manifold&) const; // Subtract (Difference)
231 Manifold operator^(const Manifold&) const; // Intersect
233 std::pair<Manifold, Manifold> Split(const Manifold&) const;
234 std::pair<Manifold, Manifold> SplitByPlane(vec3 normal,
235 double originOffset) const;
236 Manifold TrimByPlane(vec3 normal, double originOffset) const;
237 Manifold MinkowskiSum(const Manifold&) const;
240
246 int numProp,
247 std::function<void(double*, vec3, const double*)> propFunc) const;
248 Manifold CalculateCurvature(int gaussianIdx, int meanIdx) const;
249 Manifold CalculateNormals(int normalIdx = 0,
250 double minSharpAngle = 52.5) const;
252
258 Manifold Refine(int) const;
259 Manifold RefineToLength(double) const;
260 Manifold RefineToTolerance(double) const;
261 Manifold SmoothByNormals(int normalIdx = 0) const;
262 Manifold SmoothOut(double minSharpAngle = 52.5,
263 double minSmoothness = 0) const;
264 static Manifold Smooth(const MeshGL&,
265 const std::vector<Smoothness>& sharpenedEdges = {});
266 static Manifold Smooth(const MeshGL64&,
267 const std::vector<Smoothness>& sharpenedEdges = {});
269
273 Manifold Hull() const;
274 static Manifold Hull(const std::vector<Manifold>& manifolds);
275 static Manifold Hull(const std::vector<vec3>& pts);
277
313#ifndef MANIFOLD_NO_IOSTREAM
314 static Manifold ReadOBJ(std::istream& stream);
315 bool WriteOBJ(std::ostream& stream) const;
316#endif
317
322 bool MatchesTriNormals() const;
323 size_t NumDegenerateTris() const;
324 double GetEpsilon() const;
326
327 struct Impl;
328
333 static Manifold FromImpl(std::shared_ptr<Impl> pImpl);
334
335 private:
336 Manifold(std::shared_ptr<CsgNode> pNode_);
337 Manifold(std::shared_ptr<Impl> pImpl_);
338 static Manifold Invalid();
339 static Manifold PropagateStatus(Error status);
340 mutable std::shared_ptr<std::mutex> pNodeMutex_ =
341 std::make_shared<std::mutex>();
342 mutable std::shared_ptr<CsgNode> pNode_;
343 // Optional attached ExecutionContext. shared_ptr so the Impl outlives
344 // the user's ExecutionContext if a ctx-attached Manifold survives it.
345 // Propagates through copy ctor / op= (raw copy preserves the attachment).
346 // Manifold-returning ops do *not* propagate it: derived Manifolds get a
347 // null ctx_. Eager ops (Status, Refine family) snapshot ctx_ to observe
348 // their in-call work; the snapshot uses std::atomic_load, which pins the
349 // Impl across long-running evaluations even if a concurrent op= reseats
350 // ctx_ mid-eval.
351 //
352 // Accessed only via std::atomic_load / std::atomic_store: no const method
353 // mutates ctx_, but op= and the copy ctor write it on a Manifold that
354 // may be concurrently observed by const methods on other threads. The
355 // atomic-shared-ptr free functions give a torn-read-free snapshot
356 // without taking a lock. (pNode_ uses a mutex instead because lazy CSG
357 // eval mutates it through const methods, which atomic_load can't model.)
358 std::shared_ptr<ExecutionContext::Impl> ctx_;
359
360 std::shared_ptr<CsgNode> LoadPNode() const;
361 CsgLeafNode& GetCsgLeafNode(ExecutionContext::Impl* ctx = nullptr) const;
362};
363
364
373#ifdef MANIFOLD_DEBUG
374inline std::string ToString(const Manifold::Error& error) {
375 switch (error) {
376 case Manifold::Error::NoError:
377 return "No Error";
378 case Manifold::Error::NonFiniteVertex:
379 return "Non Finite Vertex";
380 case Manifold::Error::NotManifold:
381 return "Not Manifold";
382 case Manifold::Error::VertexOutOfBounds:
383 return "Vertex Out Of Bounds";
384 case Manifold::Error::PropertiesWrongLength:
385 return "Properties Wrong Length";
386 case Manifold::Error::MissingPositionProperties:
387 return "Missing Position Properties";
388 case Manifold::Error::MergeVectorsDifferentLengths:
389 return "Merge Vectors Different Lengths";
390 case Manifold::Error::MergeIndexOutOfBounds:
391 return "Merge Index Out Of Bounds";
392 case Manifold::Error::TransformWrongLength:
393 return "Transform Wrong Length";
394 case Manifold::Error::RunIndexWrongLength:
395 return "Run Index Wrong Length";
396 case Manifold::Error::FaceIDWrongLength:
397 return "Face ID Wrong Length";
398 case Manifold::Error::InvalidConstruction:
399 return "Invalid Construction";
400 case Manifold::Error::ResultTooLarge:
401 return "Result Too Large";
402 case Manifold::Error::InvalidTangents:
403 return "Invalid Tangents";
404 case Manifold::Error::Cancelled:
405 return "Cancelled";
406 default:
407 return "Unknown Error";
408 };
409}
410
411inline std::ostream& operator<<(std::ostream& stream,
412 const Manifold::Error& error) {
413 return stream << ToString(error);
414}
415#endif
417} // namespace manifold
Observe and control a long-running Manifold evaluation.
Definition common.h:244
Manifold WithContext(const ExecutionContext &ctx) const
Definition manifold.cpp:171
static Manifold LevelSet(std::function< double(vec3)> sdf, Box bounds, double edgeLength, double level=0, double tolerance=-1, bool canParallel=true)
Definition sdf.cpp:469
Manifold SmoothOut(double minSharpAngle=52.5, double minSmoothness=0) const
Definition manifold.cpp:766
std::vector< RayHit > RayCast(vec3 origin, vec3 endpoint) const
Definition manifold.cpp:1138
Manifold RefineToLength(double) const
Definition manifold.cpp:814
Manifold CalculateCurvature(int gaussianIdx, int meanIdx) const
Definition manifold.cpp:678
static Manifold BatchBoolean(const std::vector< Manifold > &manifolds, OpType op)
Definition manifold.cpp:895
double MinGap(const Manifold &other, double searchLength) const
Definition manifold.cpp:1122
static uint32_t ReserveIDs(uint32_t)
Definition manifold.cpp:466
size_t NumProp() const
Definition manifold.cpp:329
Polygons Project() const
Definition manifold.cpp:1056
size_t NumPropVert() const
Definition manifold.cpp:337
static Manifold Extrude(const Polygons &crossSection, double height, int nDivisions=0, double twistDegrees=0.0, vec2 scaleTop=vec2(1.0))
Definition constructors.cpp:215
Box BoundingBox() const
Definition manifold.cpp:344
std::pair< Manifold, Manifold > SplitByPlane(vec3 normal, double originOffset) const
Definition manifold.cpp:980
Error Status() const
Definition manifold.cpp:302
Manifold MinkowskiDifference(const Manifold &) const
Definition manifold.cpp:1031
int Genus() const
Definition manifold.cpp:416
Manifold & operator+=(const Manifold &)
Definition manifold.cpp:917
Manifold Warp(std::function< void(vec3 &)>) const
Definition manifold.cpp:577
Manifold Refine(int) const
Definition manifold.cpp:790
MeshGL64 GetMeshGL64(int normalIdx=-1) const
Definition manifold.cpp:286
static Manifold Sphere(double radius, int circularSegments=0)
Definition constructors.cpp:171
std::pair< Manifold, Manifold > Split(const Manifold &) const
Definition manifold.cpp:959
bool MatchesTriNormals() const
Definition manifold.cpp:475
size_t NumEdge() const
Definition manifold.cpp:319
int OriginalID() const
Definition manifold.cpp:440
double Volume() const
Definition manifold.cpp:431
Manifold Transform(const mat3x4 &) const
Definition manifold.cpp:539
MeshGL GetMeshGL(int normalIdx=-1) const
Definition manifold.cpp:261
Manifold RefineToTolerance(double) const
Definition manifold.cpp:843
Manifold WarpBatch(std::function< void(VecView< vec3 >)>) const
Definition manifold.cpp:596
Manifold Translate(vec3) const
Definition manifold.cpp:494
std::vector< Manifold > Decompose() const
Definition constructors.cpp:455
Manifold Rotate(double xDegrees, double yDegrees=0.0, double zDegrees=0.0) const
Definition manifold.cpp:527
Manifold SetTolerance(double) const
Definition manifold.cpp:369
static Manifold Cylinder(double height, double radiusLow, double radiusHigh=-1.0, int circularSegments=0, bool center=false)
Definition constructors.cpp:128
Manifold & operator^=(const Manifold &)
Definition manifold.cpp:947
static Manifold Revolve(const Polygons &crossSection, int circularSegments=0, double revolveDegrees=360.0f)
Definition constructors.cpp:304
bool IsEmpty() const
Definition manifold.cpp:295
static Manifold Compose(const std::vector< Manifold > &)
Definition constructors.cpp:446
Manifold Boolean(const Manifold &second, OpType op) const
Definition manifold.cpp:884
Manifold AsOriginal() const
Definition manifold.cpp:451
Manifold Hull() const
Definition manifold.cpp:1078
Manifold CalculateNormals(int normalIdx=0, double minSharpAngle=52.5) const
Definition manifold.cpp:706
Manifold Scale(vec3) const
Definition manifold.cpp:504
Manifold TrimByPlane(vec3 normal, double originOffset) const
Definition manifold.cpp:1000
size_t NumTri() const
Definition manifold.cpp:325
Manifold SetProperties(int numProp, std::function< void(double *, vec3, const double *)> propFunc) const
Definition manifold.cpp:623
std::vector< int > WindingNumber(const std::vector< vec3 > &points) const
Definition manifold.cpp:1150
double SurfaceArea() const
Definition manifold.cpp:424
size_t NumVert() const
Definition manifold.cpp:313
Polygons Slice(double height=0) const
Definition manifold.cpp:1046
double GetTolerance() const
Definition manifold.cpp:361
Manifold operator^(const Manifold &) const
Definition manifold.cpp:940
double GetEpsilon() const
Definition manifold.cpp:352
static Manifold Cube(vec3 size=vec3(1.0), bool center=false)
Definition constructors.cpp:105
Manifold()
Definition manifold.cpp:123
Manifold Mirror(vec3) const
Definition manifold.cpp:551
Manifold operator-(const Manifold &) const
Definition manifold.cpp:925
Manifold MinkowskiSum(const Manifold &) const
Definition manifold.cpp:1013
Manifold & operator-=(const Manifold &)
Definition manifold.cpp:932
Manifold Simplify(double tolerance=0) const
Definition manifold.cpp:394
Manifold SmoothByNormals(int normalIdx=0) const
Definition manifold.cpp:737
size_t NumDegenerateTris() const
Definition manifold.cpp:484
Manifold operator+(const Manifold &) const
Definition manifold.cpp:910
static Manifold Tetrahedron()
Definition constructors.cpp:93
static Manifold Smooth(const MeshGL &, const std::vector< Smoothness > &sharpenedEdges={})
Definition constructors.cpp:51
Definition vec_view.h:32
ExecutionParams & ManifoldParams()
Definition manifold.cpp:1060
Global parameters that control debugging output. Only has an effect when compiled with the MANIFOLD_D...
Definition common.h:693
OpType
Boolean operation type: Add (Union), Subtract (Difference), and Intersect.
Definition common.h:626
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:155
Axis-aligned 3D box, primarily for bounding.
Definition common.h:298