Skip to content

Commit afac65b

Browse files
authored
Add SetProperties() (elalish#433)
* SetProperties working * cleanup
1 parent c237923 commit afac65b

File tree

3 files changed

+89
-18
lines changed

3 files changed

+89
-18
lines changed

src/manifold/include/manifold.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ class Manifold {
206206
Manifold Transform(const glm::mat4x3&) const;
207207
Manifold Mirror(glm::vec3) const;
208208
Manifold Warp(std::function<void(glm::vec3&)>) const;
209+
Manifold SetProperties(
210+
int, std::function<void(glm::vec3, const float*, float*)>) const;
209211
Manifold Refine(int) const;
210212
// Manifold RefineToLength(float);
211213
// Manifold RefineToPrecision(float);

src/manifold/src/manifold.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ struct MakeTri {
4040
}
4141
};
4242

43+
struct UpdateProperties {
44+
float* properties;
45+
const int numProp;
46+
const float* oldProperties;
47+
const int numOldProp;
48+
const glm::vec3* vertPos;
49+
const glm::ivec3* triProperties;
50+
const Halfedge* halfedges;
51+
std::function<void(glm::vec3, const float* const, float* const)> propFunc;
52+
53+
__host__ __device__ void operator()(int tri) {
54+
for (int i : {0, 1, 2}) {
55+
const int vert = halfedges[3 * tri + i].startVert;
56+
const int propVert = triProperties[tri][i];
57+
propFunc(vertPos[vert], oldProperties + numOldProp * propVert,
58+
properties + numProp * propVert);
59+
}
60+
}
61+
};
62+
4363
Manifold Halfspace(Box bBox, glm::vec3 normal, float originOffset) {
4464
normal = glm::normalize(normal);
4565
Manifold cutter =
@@ -555,6 +575,58 @@ Manifold Manifold::Warp(std::function<void(glm::vec3&)> warpFunc) const {
555575
return Manifold(std::make_shared<CsgLeafNode>(pImpl));
556576
}
557577

578+
/**
579+
* Create a new copy of this manifold with updated vertex properties by
580+
* supplying a function that takes the existing position and properties as
581+
* input. You may specify any number of output properties, allowing creation and
582+
* removal of channels. Note: undefined behavior will result if you read past
583+
* the number of input properties or write past the number of output properties.
584+
*
585+
* @param numProp The new number of properties per vertex.
586+
* @param propFunc A function that modifies the properties of a given vertex.
587+
*/
588+
Manifold Manifold::SetProperties(
589+
int numProp, std::function<void(glm::vec3 position, const float* oldProp,
590+
float* newProp)>
591+
propFunc) const {
592+
auto pImpl = std::make_shared<Impl>(*GetCsgLeafNode().GetImpl());
593+
const int oldNumProp = NumProp();
594+
const VecDH<float> oldProperties = pImpl->meshRelation_.properties;
595+
596+
auto& triProperties = pImpl->meshRelation_.triProperties;
597+
if (numProp == 0) {
598+
triProperties.resize(0);
599+
pImpl->meshRelation_.properties.resize(0);
600+
} else {
601+
if (triProperties.size() == 0) {
602+
const int numTri = NumTri();
603+
triProperties.resize(numTri);
604+
int idx = 0;
605+
for (int i = 0; i < numTri; ++i) {
606+
for (const int j : {0, 1, 2}) {
607+
triProperties[i][j] = idx++;
608+
}
609+
}
610+
pImpl->meshRelation_.properties = VecDH<float>(numProp * idx, 0);
611+
} else {
612+
pImpl->meshRelation_.properties =
613+
VecDH<float>(numProp * NumPropVert(), 0);
614+
}
615+
thrust::for_each_n(
616+
thrust::host, countAt(0), NumTri(),
617+
UpdateProperties({pImpl->meshRelation_.properties.ptrH(), numProp,
618+
oldProperties.ptrH(), oldNumProp,
619+
pImpl->vertPos_.ptrH(), triProperties.ptrH(),
620+
pImpl->halfedge_.ptrH(), propFunc}));
621+
}
622+
623+
pImpl->meshRelation_.numProp = numProp;
624+
pImpl->CreateFaces();
625+
pImpl->SimplifyTopology();
626+
pImpl->Finish();
627+
return Manifold(std::make_shared<CsgLeafNode>(pImpl));
628+
}
629+
558630
/**
559631
* Increase the density of the mesh by splitting every edge into n pieces. For
560632
* instance, with n = 2, each triangle will be split into 4 triangles. These

test/test_main.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -211,26 +211,23 @@ MeshGL WithIndexColors(const Mesh& in) {
211211
}
212212

213213
MeshGL WithPositionColors(const Manifold& in) {
214-
MeshGL inGL = in.GetMeshGL();
215-
inGL.runIndex.clear();
216-
inGL.runOriginalID.clear();
217-
inGL.runTransform.clear();
218-
inGL.faceID.clear();
219-
inGL.runOriginalID = {Manifold::ReserveIDs(1)};
220-
const int numVert = in.NumVert();
221214
const Box bbox = in.BoundingBox();
222215
const glm::vec3 size = bbox.Size();
223-
const std::vector<float> oldProp = inGL.vertProperties;
224-
inGL.numProp = 6;
225-
inGL.vertProperties.resize(6 * numVert);
226-
for (int i = 0; i < numVert; ++i) {
227-
for (int j : {0, 1, 2}) inGL.vertProperties[6 * i + j] = oldProp[3 * i + j];
228-
// vertex colors
229-
inGL.vertProperties[6 * i + 3] = (oldProp[3 * i] - bbox.min.x) / size.x;
230-
inGL.vertProperties[6 * i + 4] = (oldProp[3 * i + 1] - bbox.min.y) / size.y;
231-
inGL.vertProperties[6 * i + 5] = (oldProp[3 * i + 2] - bbox.min.z) / size.z;
232-
}
233-
return inGL;
216+
217+
Manifold out = in.SetProperties(
218+
3, [bbox, size](glm::vec3 pos, const float* oldProp, float* prop) {
219+
for (int i : {0, 1, 2}) {
220+
prop[i] = (pos[i] - bbox.min[i]) / size[i];
221+
}
222+
});
223+
224+
MeshGL outGL = out.GetMeshGL();
225+
outGL.runIndex.clear();
226+
outGL.runOriginalID.clear();
227+
outGL.runTransform.clear();
228+
outGL.faceID.clear();
229+
outGL.runOriginalID = {Manifold::ReserveIDs(1)};
230+
return outGL;
234231
}
235232

236233
MeshGL WithNormals(const Manifold& in) {

0 commit comments

Comments
 (0)