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
20#include "manifold/common.h"
21#include "manifold/vec_view.h"
22
23namespace manifold {
24
33
34class CsgNode;
35class CsgLeafNode;
36
41
112template <typename Precision, typename I = uint32_t>
113struct MeshGLP {
115 I NumVert() const { return vertProperties.size() / numProp; };
117 I NumTri() const { return triVerts.size() / 3; };
119 I NumRun() const { return runOriginalID.size(); };
121 I numProp = 3;
125 std::vector<Precision> vertProperties;
128 std::vector<I> triVerts;
131 std::vector<I> mergeFromVert;
135 std::vector<I> mergeToVert;
143 std::vector<I> runIndex;
149 std::vector<uint32_t> runOriginalID;
154 std::vector<Precision> runTransform;
158 std::vector<uint8_t> runFlags;
164 std::vector<I> faceID;
169 std::vector<Precision> halfedgeTangent;
174 Precision tolerance = 0;
175
176 MeshGLP() = default;
177
187 void UpdateNormals(int normalIdx);
188
204 bool Merge();
205
211 la::vec<Precision, 3> GetVertPos(size_t v) const {
212 size_t offset = v * numProp;
213 return la::vec<Precision, 3>(vertProperties[offset],
214 vertProperties[offset + 1],
215 vertProperties[offset + 2]);
216 }
217
223 la::vec<I, 3> GetTriVerts(size_t t) const {
224 size_t offset = 3 * t;
225 return la::vec<I, 3>(triVerts[offset], triVerts[offset + 1],
226 triVerts[offset + 2]);
227 }
228
234 la::vec<Precision, 4> GetTangent(size_t h) const {
235 size_t offset = 4 * h;
236 return la::vec<Precision, 4>(
237 halfedgeTangent[offset], halfedgeTangent[offset + 1],
238 halfedgeTangent[offset + 2], halfedgeTangent[offset + 3]);
239 }
240
246 mat3x4 GetRunTransform(size_t run) const {
247 size_t offset = 12 * run;
248 if (offset + 12 > runTransform.size()) {
249 return la::identity;
250 }
251 return mat3x4(la::mat<Precision, 3, 4>(&runTransform[offset]));
252 }
253
261 bool Backside(size_t run) const {
262 return run < runFlags.size() && runFlags[run] == 1;
263 }
264};
265
274
275MeshGL64 ReadOBJ(std::istream& stream);
276bool WriteOBJ(std::ostream& stream, const MeshGL64& mesh);
277
301class Manifold {
302 public:
307 Manifold();
308 ~Manifold();
309 Manifold(const Manifold& other);
310 Manifold& operator=(const Manifold& other);
311 Manifold(Manifold&&) noexcept;
312 Manifold& operator=(Manifold&&) noexcept;
314
319 Manifold(const MeshGL&);
320 Manifold(const MeshGL64&);
321 MeshGL GetMeshGL(int normalIdx = -1) const;
322 MeshGL64 GetMeshGL64(int normalIdx = -1) const;
324
329 std::vector<Manifold> Decompose() const;
330 [[deprecated(
331 "Compose is deprecated, use BatchBoolean with OpType::Add instead.")]]
332 static Manifold Compose(const std::vector<Manifold>&);
333 static Manifold Tetrahedron();
334 static Manifold Cube(vec3 size = vec3(1.0), bool center = false);
335 static Manifold Cylinder(double height, double radiusLow,
336 double radiusHigh = -1.0, int circularSegments = 0,
337 bool center = false);
338 static Manifold Sphere(double radius, int circularSegments = 0);
339 static Manifold LevelSet(std::function<double(vec3)> sdf, Box bounds,
340 double edgeLength, double level = 0,
341 double tolerance = -1, bool canParallel = true);
343
348 Polygons Slice(double height = 0) const;
349 Polygons Project() const;
350 static Manifold Extrude(const Polygons& crossSection, double height,
351 int nDivisions = 0, double twistDegrees = 0.0,
352 vec2 scaleTop = vec2(1.0));
353 static Manifold Revolve(const Polygons& crossSection,
354 int circularSegments = 0,
355 double revolveDegrees = 360.0f);
357
358 enum class Error {
359 NoError,
360 NonFiniteVertex,
361 NotManifold,
362 VertexOutOfBounds,
363 PropertiesWrongLength,
364 MissingPositionProperties,
365 MergeVectorsDifferentLengths,
366 MergeIndexOutOfBounds,
367 TransformWrongLength,
368 RunIndexWrongLength,
369 FaceIDWrongLength,
370 InvalidConstruction,
371 ResultTooLarge,
372 };
373
378 Error Status() const;
379 bool IsEmpty() const;
380 size_t NumVert() const;
381 size_t NumEdge() const;
382 size_t NumTri() const;
383 size_t NumProp() const;
384 size_t NumPropVert() const;
385 Box BoundingBox() const;
386 int Genus() const;
387 double GetTolerance() const;
389
393 double SurfaceArea() const;
394 double Volume() const;
395 double MinGap(const Manifold& other, double searchLength) const;
397
403 int OriginalID() const;
404 Manifold AsOriginal() const;
405 static uint32_t ReserveIDs(uint32_t);
407
411 Manifold Translate(vec3) const;
412 Manifold Scale(vec3) const;
413 Manifold Rotate(double xDegrees, double yDegrees = 0.0,
414 double zDegrees = 0.0) const;
415 Manifold Mirror(vec3) const;
416 Manifold Transform(const mat3x4&) const;
417 Manifold Warp(std::function<void(vec3&)>) const;
418 Manifold WarpBatch(std::function<void(VecView<vec3>)>) const;
419 Manifold SetTolerance(double) const;
420 Manifold Simplify(double tolerance = 0) const;
422
427 Manifold Boolean(const Manifold& second, OpType op) const;
428 static Manifold BatchBoolean(const std::vector<Manifold>& manifolds,
429 OpType op);
430 // Boolean operation shorthand
431 Manifold operator+(const Manifold&) const; // Add (Union)
433 Manifold operator-(const Manifold&) const; // Subtract (Difference)
435 Manifold operator^(const Manifold&) const; // Intersect
437 std::pair<Manifold, Manifold> Split(const Manifold&) const;
438 std::pair<Manifold, Manifold> SplitByPlane(vec3 normal,
439 double originOffset) const;
440 Manifold TrimByPlane(vec3 normal, double originOffset) const;
441 Manifold MinkowskiSum(const Manifold&) const;
444
450 int numProp,
451 std::function<void(double*, vec3, const double*)> propFunc) const;
452 Manifold CalculateCurvature(int gaussianIdx, int meanIdx) const;
453 Manifold CalculateNormals(int normalIdx, double minSharpAngle = 60) const;
455
461 Manifold Refine(int) const;
462 Manifold RefineToLength(double) const;
463 Manifold RefineToTolerance(double) const;
464 Manifold SmoothByNormals(int normalIdx) const;
465 Manifold SmoothOut(double minSharpAngle = 60, double minSmoothness = 0) const;
466 static Manifold Smooth(const MeshGL&,
467 const std::vector<Smoothness>& sharpenedEdges = {});
468 static Manifold Smooth(const MeshGL64&,
469 const std::vector<Smoothness>& sharpenedEdges = {});
471
475 Manifold Hull() const;
476 static Manifold Hull(const std::vector<Manifold>& manifolds);
477 static Manifold Hull(const std::vector<vec3>& pts);
479
515 static Manifold ReadOBJ(std::istream& stream);
516 bool WriteOBJ(std::ostream& stream) const;
517
522 bool MatchesTriNormals() const;
523 size_t NumDegenerateTris() const;
524 double GetEpsilon() const;
526
527 struct Impl;
528
529 private:
530 Manifold(std::shared_ptr<CsgNode> pNode_);
531 Manifold(std::shared_ptr<Impl> pImpl_);
532 static Manifold Invalid();
533 mutable std::shared_ptr<CsgNode> pNode_;
534
535 CsgLeafNode& GetCsgLeafNode() const;
536};
537
538
547#ifdef MANIFOLD_DEBUG
548inline std::string ToString(const Manifold::Error& error) {
549 switch (error) {
550 case Manifold::Error::NoError:
551 return "No Error";
552 case Manifold::Error::NonFiniteVertex:
553 return "Non Finite Vertex";
554 case Manifold::Error::NotManifold:
555 return "Not Manifold";
556 case Manifold::Error::VertexOutOfBounds:
557 return "Vertex Out Of Bounds";
558 case Manifold::Error::PropertiesWrongLength:
559 return "Properties Wrong Length";
560 case Manifold::Error::MissingPositionProperties:
561 return "Missing Position Properties";
562 case Manifold::Error::MergeVectorsDifferentLengths:
563 return "Merge Vectors Different Lengths";
564 case Manifold::Error::MergeIndexOutOfBounds:
565 return "Merge Index Out Of Bounds";
566 case Manifold::Error::TransformWrongLength:
567 return "Transform Wrong Length";
568 case Manifold::Error::RunIndexWrongLength:
569 return "Run Index Wrong Length";
570 case Manifold::Error::FaceIDWrongLength:
571 return "Face ID Wrong Length";
572 case Manifold::Error::InvalidConstruction:
573 return "Invalid Construction";
574 case Manifold::Error::ResultTooLarge:
575 return "Result Too Large";
576 default:
577 return "Unknown Error";
578 };
579}
580
581inline std::ostream& operator<<(std::ostream& stream,
582 const Manifold::Error& error) {
583 return stream << ToString(error);
584}
585#endif
587} // namespace manifold
static Manifold LevelSet(std::function< double(vec3)> sdf, Box bounds, double edgeLength, double level=0, double tolerance=-1, bool canParallel=true)
Definition sdf.cpp:456
Manifold SmoothOut(double minSharpAngle=60, double minSmoothness=0) const
Definition manifold.cpp:652
Manifold RefineToLength(double) const
Definition manifold.cpp:701
Manifold CalculateCurvature(int gaussianIdx, int meanIdx) const
Definition manifold.cpp:588
static Manifold BatchBoolean(const std::vector< Manifold > &manifolds, OpType op)
Definition manifold.cpp:767
double MinGap(const Manifold &other, double searchLength) const
Definition manifold.cpp:972
static uint32_t ReserveIDs(uint32_t)
Definition manifold.cpp:391
size_t NumProp() const
Definition manifold.cpp:257
Polygons Project() const
Definition manifold.cpp:917
size_t NumPropVert() const
Definition manifold.cpp:265
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:272
std::pair< Manifold, Manifold > SplitByPlane(vec3 normal, double originOffset) const
Definition manifold.cpp:852
Error Status() const
Definition manifold.cpp:235
Manifold MinkowskiDifference(const Manifold &) const
Definition manifold.cpp:895
int Genus() const
Definition manifold.cpp:338
Manifold & operator+=(const Manifold &)
Definition manifold.cpp:789
Manifold Warp(std::function< void(vec3 &)>) const
Definition manifold.cpp:492
Manifold Refine(int) const
Definition manifold.cpp:683
MeshGL64 GetMeshGL64(int normalIdx=-1) const
Definition manifold.cpp:220
static Manifold Sphere(double radius, int circularSegments=0)
Definition constructors.cpp:203
std::pair< Manifold, Manifold > Split(const Manifold &) const
Definition manifold.cpp:831
bool MatchesTriNormals() const
Definition manifold.cpp:400
size_t NumEdge() const
Definition manifold.cpp:247
int OriginalID() const
Definition manifold.cpp:362
double Volume() const
Definition manifold.cpp:353
Manifold Transform(const mat3x4 &) const
Definition manifold.cpp:462
MeshGL GetMeshGL(int normalIdx=-1) const
Definition manifold.cpp:199
Manifold RefineToTolerance(double) const
Definition manifold.cpp:722
Manifold WarpBatch(std::function< void(VecView< vec3 >)>) const
Definition manifold.cpp:511
Manifold Translate(vec3) const
Definition manifold.cpp:419
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:450
Manifold SetTolerance(double) const
Definition manifold.cpp:297
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:819
static Manifold Revolve(const Polygons &crossSection, int circularSegments=0, double revolveDegrees=360.0f)
Definition constructors.cpp:336
bool IsEmpty() const
Definition manifold.cpp:228
static Manifold Compose(const std::vector< Manifold > &)
Definition constructors.cpp:478
Manifold Boolean(const Manifold &second, OpType op) const
Definition manifold.cpp:759
Manifold AsOriginal() const
Definition manifold.cpp:373
Manifold Hull() const
Definition manifold.cpp:939
Manifold SmoothByNormals(int normalIdx) const
Definition manifold.cpp:626
Manifold Scale(vec3) const
Definition manifold.cpp:429
Manifold TrimByPlane(vec3 normal, double originOffset) const
Definition manifold.cpp:867
size_t NumTri() const
Definition manifold.cpp:253
Manifold SetProperties(int numProp, std::function< void(double *, vec3, const double *)> propFunc) const
Definition manifold.cpp:536
Manifold CalculateNormals(int normalIdx, double minSharpAngle=60) const
Definition manifold.cpp:609
double SurfaceArea() const
Definition manifold.cpp:346
size_t NumVert() const
Definition manifold.cpp:241
Polygons Slice(double height=0) const
Definition manifold.cpp:907
double GetTolerance() const
Definition manifold.cpp:289
Manifold operator^(const Manifold &) const
Definition manifold.cpp:812
double GetEpsilon() const
Definition manifold.cpp:280
static Manifold Cube(vec3 size=vec3(1.0), bool center=false)
Definition constructors.cpp:137
Manifold()
Definition manifold.cpp:120
Manifold Mirror(vec3) const
Definition manifold.cpp:474
Manifold operator-(const Manifold &) const
Definition manifold.cpp:797
Manifold MinkowskiSum(const Manifold &) const
Definition manifold.cpp:880
Manifold & operator-=(const Manifold &)
Definition manifold.cpp:804
Manifold Simplify(double tolerance=0) const
Definition manifold.cpp:319
size_t NumDegenerateTris() const
Definition manifold.cpp:409
Manifold operator+(const Manifold &) const
Definition manifold.cpp:782
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
MeshGLP< double, uint64_t > MeshGL64
Double-precision, 64-bit indices - best for huge meshes.
Definition manifold.h:273
MeshGLP< float > MeshGL
Single-precision - ideal for most uses, especially graphics.
Definition manifold.h:269
ExecutionParams & ManifoldParams()
Definition manifold.cpp:921
Global parameters that control debugging output. Only has an effect when compiled with the MANIFOLD_D...
Definition common.h:510
OpType
Boolean operation type: Add (Union), Subtract (Difference), and Intersect.
Definition common.h:476
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:142
Axis-aligned 3D box, primarily for bounding.
Definition common.h:160
Mesh input/output suitable for pushing directly into graphics libraries.
Definition manifold.h:113
la::vec< I, 3 > GetTriVerts(size_t t) const
Definition manifold.h:223
bool Backside(size_t run) const
Definition manifold.h:261
std::vector< uint32_t > mergeFromVert
Definition manifold.h:131
I NumRun() const
Number of triangle runs.
Definition manifold.h:119
void UpdateNormals(int normalIdx)
std::vector< uint32_t > runIndex
Definition manifold.h:143
std::vector< float > vertProperties
Definition manifold.h:125
std::vector< float > runTransform
Definition manifold.h:154
std::vector< uint8_t > runFlags
Definition manifold.h:158
std::vector< uint32_t > mergeToVert
Definition manifold.h:135
I NumTri() const
Number of triangles.
Definition manifold.h:117
mat3x4 GetRunTransform(size_t run) const
Definition manifold.h:246
std::vector< float > halfedgeTangent
Definition manifold.h:169
std::vector< uint32_t > runOriginalID
Definition manifold.h:149
std::vector< uint32_t > triVerts
Definition manifold.h:128
la::vec< Precision, 4 > GetTangent(size_t h) const
Definition manifold.h:234
float tolerance
Definition manifold.h:174
I NumVert() const
Number of property vertices.
Definition manifold.h:115
std::vector< uint32_t > faceID
Definition manifold.h:164
la::vec< Precision, 3 > GetVertPos(size_t v) const
Definition manifold.h:211
uint32_t numProp
Definition manifold.h:121