Skip to content

Commit dc4afa9

Browse files
authored
Refine To Length (#741)
* sketched out implementation * started PartitionQuad * added edge directions * compiles * first test passing * minor progress * simplify * refactor * fixed interior verts * getting manifold results * improved triangulation * finished algorithm * fixed fans * a few fixes * fixed 3-2-2 * handle reversed triangles * use Vec * fixed another bug * refine working * replaced old subdivide * fix allocation error * fixed sphere * fix cache * fixed undefined behavior * fix rounding error * updated test * cleanup * add lock * added properties support * tightened test * fixed edge colors * fixed corners * only duplicate props when necessary * fix boolean props * fixed manifoldness error * fixed some narrow triangles * fix compile * added bindings * fix formatting * addressing feedback * revert edge divisions change
1 parent c03a5ac commit dc4afa9

16 files changed

+644
-184
lines changed

.vscode/settings.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,12 @@
108108
"latch": "cpp",
109109
"semaphore": "cpp",
110110
"span": "cpp",
111-
"__sso_allocator": "cpp"
111+
"__sso_allocator": "cpp",
112+
"source_location": "cpp",
113+
"format": "cpp",
114+
"numbers": "cpp",
115+
"ranges": "cpp",
116+
"stop_token": "cpp"
112117
},
113118
"C_Cpp.clang_format_fallbackStyle": "google",
114119
"editor.formatOnSave": true,
@@ -117,7 +122,6 @@
117122
"-DMANIFOLD_CBIND=ON",
118123
"-DMANIFOLD_EXPORT=ON",
119124
"-DMANIFOLD_DEBUG=ON",
120-
"-DMANIFOLD_USE_CUDA=OFF",
121125
"-DMANIFOLD_PAR=TBB",
122126
"-DCODE_COVERAGE=OFF",
123127
"-DCMAKE_CXX_FLAGS=''" //'-fsanitize=address,undefined'"

bindings/c/include/manifoldc.h

+2
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ ManifoldManifold *manifold_mirror(void *mem, ManifoldManifold *m, float nx,
140140
ManifoldManifold *manifold_warp(void *mem, ManifoldManifold *m,
141141
ManifoldVec3 (*fun)(float, float, float));
142142
ManifoldManifold *manifold_refine(void *mem, ManifoldManifold *m, int refine);
143+
ManifoldManifold *manifold_refine_to_length(void *mem, ManifoldManifold *m,
144+
float length);
143145

144146
// Manifold Shapes / Constructors
145147

bindings/c/manifoldc.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,12 @@ ManifoldManifold *manifold_refine(void *mem, ManifoldManifold *m, int refine) {
305305
return to_c(new (mem) Manifold(refined));
306306
}
307307

308+
ManifoldManifold *manifold_refine_to_length(void *mem, ManifoldManifold *m,
309+
float length) {
310+
auto refined = from_c(m)->RefineToLength(length);
311+
return to_c(new (mem) Manifold(refined));
312+
}
313+
308314
ManifoldManifold *manifold_empty(void *mem) {
309315
return to_c(new (mem) Manifold());
310316
}

bindings/python/examples/all_apis.py

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def all_manifold():
9191
p = m.precision()
9292
c = m.project()
9393
m = m.refine(2)
94+
m = m.refine_to_length(0.1)
9495
i = Manifold.reserve_ids(1)
9596
m = m.scale((1, 2, 3))
9697
m = m.set_properties(3, lambda pos, prop: pos)

bindings/python/manifold3d.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ NB_MODULE(manifold3d, m) {
316316
nb::arg("gaussian_idx"), nb::arg("mean_idx"),
317317
manifold__calculate_curvature__gaussian_idx__mean_idx)
318318
.def("refine", &Manifold::Refine, nb::arg("n"), manifold__refine__n)
319+
.def("refine_to_length", &Manifold::RefineToLength, nb::arg("length"),
320+
manifold__refine_to_length__length)
319321
.def("to_mesh", &Manifold::GetMeshGL,
320322
nb::arg("normal_idx") = glm::ivec3(0),
321323
manifold__get_mesh_gl__normal_idx)

bindings/wasm/bindings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ EMSCRIPTEN_BINDINGS(whatever) {
143143
.function("hull", select_overload<Manifold() const>(&Manifold::Hull))
144144
.function("_GetMeshJS", &js::GetMeshJS)
145145
.function("refine", &Manifold::Refine)
146+
.function("refineToLength", &Manifold::RefineToLength)
146147
.function("_Warp", &man_js::Warp)
147148
.function("_SetProperties", &man_js::SetProperties)
148149
.function("transform", &man_js::Transform)

bindings/wasm/examples/worker.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ const manifoldStaticFunctions = [
5959
];
6060
// manifold member functions (that return a new manifold)
6161
const manifoldMemberFunctions = [
62-
'add', 'subtract', 'intersect', 'decompose', 'warp', 'transform', 'translate',
63-
'rotate', 'scale', 'mirror', 'refine', 'setProperties', 'asOriginal',
64-
'trimByPlane', 'split', 'splitByPlane', 'slice', 'project', 'hull'
62+
'add', 'subtract', 'intersect', 'decompose', 'warp',
63+
'transform', 'translate', 'rotate', 'scale', 'mirror',
64+
'refine', 'refineToLength', 'setProperties', 'asOriginal', 'trimByPlane',
65+
'split', 'splitByPlane', 'slice', 'project', 'hull'
6566
];
6667
// CrossSection static methods (that return a new cross-section)
6768
const crossSectionStaticFunctions = [

bindings/wasm/manifold-encapsulated-types.d.ts

+12
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,18 @@ export class Manifold {
571571
*/
572572
refine(n: number): Manifold;
573573

574+
/**
575+
* Increase the density of the mesh by splitting each edge into pieces of
576+
* roughly the input length. Interior verts are added to keep the rest of the
577+
* triangulation edges also of roughly the same length. If halfedgeTangents
578+
* are present (e.g. from the Smooth() constructor), the new vertices will be
579+
* moved to the interpolated surface according to their barycentric
580+
* coordinates.
581+
*
582+
* @param length The length that edges will be broken down to.
583+
*/
584+
refineToLength(length: number): Manifold;
585+
574586
/**
575587
* Create a new copy of this manifold with updated vertex properties by
576588
* supplying a function that takes the existing position and properties as

src/manifold/include/manifold.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ class Manifold {
220220
int, std::function<void(float*, glm::vec3, const float*)>) const;
221221
Manifold CalculateCurvature(int gaussianIdx, int meanIdx) const;
222222
Manifold Refine(int) const;
223-
// Manifold RefineToLength(float);
223+
Manifold RefineToLength(float) const;
224224
// Manifold RefineToPrecision(float);
225225
///@}
226226

src/manifold/src/constructors.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ Manifold Manifold::Sphere(float radius, int circularSegments) {
207207
int n = circularSegments > 0 ? (circularSegments + 3) / 4
208208
: Quality::GetCircularSegments(radius) / 4;
209209
auto pImpl_ = std::make_shared<Impl>(Impl::Shape::Octahedron);
210-
pImpl_->Subdivide(n);
210+
pImpl_->Subdivide([n](glm::vec3 edge) { return n - 1; });
211211
for_each_n(autoPolicy(pImpl_->NumVert()), pImpl_->vertPos_.begin(),
212212
pImpl_->NumVert(), ToSphere({radius}));
213213
pImpl_->Finish();

src/manifold/src/impl.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ struct Manifold::Impl {
138138

139139
// smoothing.cu
140140
void CreateTangents(const std::vector<Smoothness>&);
141-
Vec<Barycentric> Subdivide(int n);
142-
void Refine(int n);
141+
Vec<Barycentric> Subdivide(std::function<int(glm::vec3)>);
142+
void Refine(std::function<int(glm::vec3)>);
143143
};
144144
} // namespace manifold

src/manifold/src/manifold.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,26 @@ Manifold Manifold::CalculateCurvature(int gaussianIdx, int meanIdx) const {
667667
*/
668668
Manifold Manifold::Refine(int n) const {
669669
auto pImpl = std::make_shared<Impl>(*GetCsgLeafNode().GetImpl());
670-
pImpl->Refine(n);
670+
if (n > 1) {
671+
pImpl->Refine([n](glm::vec3 edge) { return n - 1; });
672+
}
673+
return Manifold(std::make_shared<CsgLeafNode>(pImpl));
674+
}
675+
676+
/**
677+
* Increase the density of the mesh by splitting each edge into pieces of
678+
* roughly the input length. Interior verts are added to keep the rest of the
679+
* triangulation edges also of roughly the same length. If halfedgeTangents are
680+
* present (e.g. from the Smooth() constructor), the new vertices will be moved
681+
* to the interpolated surface according to their barycentric coordinates.
682+
*
683+
* @param length The length that edges will be broken down to.
684+
*/
685+
Manifold Manifold::RefineToLength(float length) const {
686+
length = glm::abs(length);
687+
auto pImpl = std::make_shared<Impl>(*GetCsgLeafNode().GetImpl());
688+
pImpl->Refine(
689+
[length](glm::vec3 edge) { return glm::length(edge) / length; });
671690
return Manifold(std::make_shared<CsgLeafNode>(pImpl));
672691
}
673692

0 commit comments

Comments
 (0)