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;
192
198 int OriginalID() const;
199 Manifold AsOriginal() const;
200 static uint32_t ReserveIDs(uint32_t);
202
206 Manifold Translate(vec3) const;
207 Manifold Scale(vec3) const;
208 Manifold Rotate(double xDegrees, double yDegrees = 0.0,
209 double zDegrees = 0.0) const;
210 Manifold Mirror(vec3) const;
211 Manifold Transform(const mat3x4&) const;
212 Manifold Warp(std::function<void(vec3&)>) const;
213 Manifold WarpBatch(std::function<void(VecView<vec3>)>) const;
214 Manifold SetTolerance(double) const;
215 Manifold Simplify(double tolerance = 0) const;
217
222 Manifold Boolean(const Manifold& second, OpType op) const;
223 static Manifold BatchBoolean(const std::vector<Manifold>& manifolds,
224 OpType op);
225 // Boolean operation shorthand
226 Manifold operator+(const Manifold&) const; // Add (Union)
228 Manifold operator-(const Manifold&) const; // Subtract (Difference)
230 Manifold operator^(const Manifold&) const; // Intersect
232 std::pair<Manifold, Manifold> Split(const Manifold&) const;
233 std::pair<Manifold, Manifold> SplitByPlane(vec3 normal,
234 double originOffset) const;
235 Manifold TrimByPlane(vec3 normal, double originOffset) const;
236 Manifold MinkowskiSum(const Manifold&) const;
239
245 int numProp,
246 std::function<void(double*, vec3, const double*)> propFunc) const;
247 Manifold CalculateCurvature(int gaussianIdx, int meanIdx) const;
248 Manifold CalculateNormals(int normalIdx = 0,
249 double minSharpAngle = 52.5) const;
251
257 Manifold Refine(int) const;
258 Manifold RefineToLength(double) const;
259 Manifold RefineToTolerance(double) const;
260 Manifold SmoothByNormals(int normalIdx = 0) const;
261 Manifold SmoothOut(double minSharpAngle = 52.5,
262 double minSmoothness = 0) const;
263 static Manifold Smooth(const MeshGL&,
264 const std::vector<Smoothness>& sharpenedEdges = {});
265 static Manifold Smooth(const MeshGL64&,
266 const std::vector<Smoothness>& sharpenedEdges = {});
268
272 Manifold Hull() const;
273 static Manifold Hull(const std::vector<Manifold>& manifolds);
274 static Manifold Hull(const std::vector<vec3>& pts);
276
312#ifndef MANIFOLD_NO_IOSTREAM
313 static Manifold ReadOBJ(std::istream& stream);
314 bool WriteOBJ(std::ostream& stream) const;
315#endif
316
321 bool MatchesTriNormals() const;
322 size_t NumDegenerateTris() const;
323 double GetEpsilon() const;
325
326 struct Impl;
327
328 private:
329 Manifold(std::shared_ptr<CsgNode> pNode_);
330 Manifold(std::shared_ptr<Impl> pImpl_);
331 static Manifold Invalid();
332 static Manifold PropagateStatus(Error status);
333 mutable std::shared_ptr<std::mutex> pNodeMutex_ =
334 std::make_shared<std::mutex>();
335 mutable std::shared_ptr<CsgNode> pNode_;
336 // Optional attached ExecutionContext. shared_ptr so the Impl outlives
337 // the user's ExecutionContext if a ctx-attached Manifold survives it.
338 // Propagates through copy ctor / op= (raw copy preserves the attachment).
339 // Manifold-returning ops do *not* propagate it: derived Manifolds get a
340 // null ctx_. Eager ops (Status, Refine family) snapshot ctx_ to observe
341 // their in-call work; the snapshot uses std::atomic_load, which pins the
342 // Impl across long-running evaluations even if a concurrent op= reseats
343 // ctx_ mid-eval.
344 //
345 // Accessed only via std::atomic_load / std::atomic_store: no const method
346 // mutates ctx_, but op= and the copy ctor write it on a Manifold that
347 // may be concurrently observed by const methods on other threads. The
348 // atomic-shared-ptr free functions give a torn-read-free snapshot
349 // without taking a lock. (pNode_ uses a mutex instead because lazy CSG
350 // eval mutates it through const methods, which atomic_load can't model.)
351 std::shared_ptr<ExecutionContext::Impl> ctx_;
352
353 std::shared_ptr<CsgNode> LoadPNode() const;
354 CsgLeafNode& GetCsgLeafNode(ExecutionContext::Impl* ctx = nullptr) const;
355};
356
357
366#ifdef MANIFOLD_DEBUG
367inline std::string ToString(const Manifold::Error& error) {
368 switch (error) {
369 case Manifold::Error::NoError:
370 return "No Error";
371 case Manifold::Error::NonFiniteVertex:
372 return "Non Finite Vertex";
373 case Manifold::Error::NotManifold:
374 return "Not Manifold";
375 case Manifold::Error::VertexOutOfBounds:
376 return "Vertex Out Of Bounds";
377 case Manifold::Error::PropertiesWrongLength:
378 return "Properties Wrong Length";
379 case Manifold::Error::MissingPositionProperties:
380 return "Missing Position Properties";
381 case Manifold::Error::MergeVectorsDifferentLengths:
382 return "Merge Vectors Different Lengths";
383 case Manifold::Error::MergeIndexOutOfBounds:
384 return "Merge Index Out Of Bounds";
385 case Manifold::Error::TransformWrongLength:
386 return "Transform Wrong Length";
387 case Manifold::Error::RunIndexWrongLength:
388 return "Run Index Wrong Length";
389 case Manifold::Error::FaceIDWrongLength:
390 return "Face ID Wrong Length";
391 case Manifold::Error::InvalidConstruction:
392 return "Invalid Construction";
393 case Manifold::Error::ResultTooLarge:
394 return "Result Too Large";
395 case Manifold::Error::InvalidTangents:
396 return "Invalid Tangents";
397 case Manifold::Error::Cancelled:
398 return "Cancelled";
399 default:
400 return "Unknown Error";
401 };
402}
403
404inline std::ostream& operator<<(std::ostream& stream,
405 const Manifold::Error& error) {
406 return stream << ToString(error);
407}
408#endif
410} // namespace manifold
Observe and control a long-running Manifold evaluation.
Definition common.h:233
Manifold WithContext(const ExecutionContext &ctx) const
Definition manifold.cpp:165
static Manifold LevelSet(std::function< double(vec3)> sdf, Box bounds, double edgeLength, double level=0, double tolerance=-1, bool canParallel=true)
Definition sdf.cpp:468
Manifold SmoothOut(double minSharpAngle=52.5, double minSmoothness=0) const
Definition manifold.cpp:760
std::vector< RayHit > RayCast(vec3 origin, vec3 endpoint) const
Definition manifold.cpp:1132
Manifold RefineToLength(double) const
Definition manifold.cpp:808
Manifold CalculateCurvature(int gaussianIdx, int meanIdx) const
Definition manifold.cpp:672
static Manifold BatchBoolean(const std::vector< Manifold > &manifolds, OpType op)
Definition manifold.cpp:889
double MinGap(const Manifold &other, double searchLength) const
Definition manifold.cpp:1116
static uint32_t ReserveIDs(uint32_t)
Definition manifold.cpp:460
size_t NumProp() const
Definition manifold.cpp:323
Polygons Project() const
Definition manifold.cpp:1050
size_t NumPropVert() const
Definition manifold.cpp:331
static Manifold Extrude(const Polygons &crossSection, double height, int nDivisions=0, double twistDegrees=0.0, vec2 scaleTop=vec2(1.0))
Definition constructors.cpp:247
Box BoundingBox() const
Definition manifold.cpp:338
std::pair< Manifold, Manifold > SplitByPlane(vec3 normal, double originOffset) const
Definition manifold.cpp:974
Error Status() const
Definition manifold.cpp:296
Manifold MinkowskiDifference(const Manifold &) const
Definition manifold.cpp:1025
int Genus() const
Definition manifold.cpp:410
Manifold & operator+=(const Manifold &)
Definition manifold.cpp:911
Manifold Warp(std::function< void(vec3 &)>) const
Definition manifold.cpp:571
Manifold Refine(int) const
Definition manifold.cpp:784
MeshGL64 GetMeshGL64(int normalIdx=-1) const
Definition manifold.cpp:280
static Manifold Sphere(double radius, int circularSegments=0)
Definition constructors.cpp:203
std::pair< Manifold, Manifold > Split(const Manifold &) const
Definition manifold.cpp:953
bool MatchesTriNormals() const
Definition manifold.cpp:469
size_t NumEdge() const
Definition manifold.cpp:313
int OriginalID() const
Definition manifold.cpp:434
double Volume() const
Definition manifold.cpp:425
Manifold Transform(const mat3x4 &) const
Definition manifold.cpp:533
MeshGL GetMeshGL(int normalIdx=-1) const
Definition manifold.cpp:255
Manifold RefineToTolerance(double) const
Definition manifold.cpp:837
Manifold WarpBatch(std::function< void(VecView< vec3 >)>) const
Definition manifold.cpp:590
Manifold Translate(vec3) const
Definition manifold.cpp:488
std::vector< Manifold > Decompose() const
Definition constructors.cpp:487
Manifold Rotate(double xDegrees, double yDegrees=0.0, double zDegrees=0.0) const
Definition manifold.cpp:521
Manifold SetTolerance(double) const
Definition manifold.cpp:363
static Manifold Cylinder(double height, double radiusLow, double radiusHigh=-1.0, int circularSegments=0, bool center=false)
Definition constructors.cpp:160
Manifold & operator^=(const Manifold &)
Definition manifold.cpp:941
static Manifold Revolve(const Polygons &crossSection, int circularSegments=0, double revolveDegrees=360.0f)
Definition constructors.cpp:336
bool IsEmpty() const
Definition manifold.cpp:289
static Manifold Compose(const std::vector< Manifold > &)
Definition constructors.cpp:478
Manifold Boolean(const Manifold &second, OpType op) const
Definition manifold.cpp:878
Manifold AsOriginal() const
Definition manifold.cpp:445
Manifold Hull() const
Definition manifold.cpp:1072
Manifold CalculateNormals(int normalIdx=0, double minSharpAngle=52.5) const
Definition manifold.cpp:700
Manifold Scale(vec3) const
Definition manifold.cpp:498
Manifold TrimByPlane(vec3 normal, double originOffset) const
Definition manifold.cpp:994
size_t NumTri() const
Definition manifold.cpp:319
Manifold SetProperties(int numProp, std::function< void(double *, vec3, const double *)> propFunc) const
Definition manifold.cpp:617
double SurfaceArea() const
Definition manifold.cpp:418
size_t NumVert() const
Definition manifold.cpp:307
Polygons Slice(double height=0) const
Definition manifold.cpp:1040
double GetTolerance() const
Definition manifold.cpp:355
Manifold operator^(const Manifold &) const
Definition manifold.cpp:934
double GetEpsilon() const
Definition manifold.cpp:346
static Manifold Cube(vec3 size=vec3(1.0), bool center=false)
Definition constructors.cpp:137
Manifold()
Definition manifold.cpp:121
Manifold Mirror(vec3) const
Definition manifold.cpp:545
Manifold operator-(const Manifold &) const
Definition manifold.cpp:919
Manifold MinkowskiSum(const Manifold &) const
Definition manifold.cpp:1007
Manifold & operator-=(const Manifold &)
Definition manifold.cpp:926
Manifold Simplify(double tolerance=0) const
Definition manifold.cpp:388
Manifold SmoothByNormals(int normalIdx=0) const
Definition manifold.cpp:731
size_t NumDegenerateTris() const
Definition manifold.cpp:478
Manifold operator+(const Manifold &) const
Definition manifold.cpp:904
static Manifold Tetrahedron()
Definition constructors.cpp:125
static Manifold Smooth(const MeshGL &, const std::vector< Smoothness > &sharpenedEdges={})
Definition constructors.cpp:83
Definition vec_view.h:32
ExecutionParams & ManifoldParams()
Definition manifold.cpp:1054
Global parameters that control debugging output. Only has an effect when compiled with the MANIFOLD_D...
Definition common.h:624
OpType
Boolean operation type: Add (Union), Subtract (Difference), and Intersect.
Definition common.h:590
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:144
Axis-aligned 3D box, primarily for bounding.
Definition common.h:262