Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/manifold/include/manifold.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ class Manifold {
Manifold Transform(const glm::mat4x3&) const;
Manifold Mirror(glm::vec3) const;
Manifold Warp(std::function<void(glm::vec3&)>) const;
Manifold SetProperties(
int, std::function<void(glm::vec3, const float*, float*)>) const;
Manifold Refine(int) const;
// Manifold RefineToLength(float);
// Manifold RefineToPrecision(float);
Expand Down
72 changes: 72 additions & 0 deletions src/manifold/src/manifold.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ struct MakeTri {
}
};

struct UpdateProperties {
float* properties;
const int numProp;
const float* oldProperties;
const int numOldProp;
const glm::vec3* vertPos;
const glm::ivec3* triProperties;
const Halfedge* halfedges;
std::function<void(glm::vec3, const float* const, float* const)> propFunc;

__host__ __device__ void operator()(int tri) {
for (int i : {0, 1, 2}) {
const int vert = halfedges[3 * tri + i].startVert;
const int propVert = triProperties[tri][i];
propFunc(vertPos[vert], oldProperties + numOldProp * propVert,
properties + numProp * propVert);
}
}
};

Manifold Halfspace(Box bBox, glm::vec3 normal, float originOffset) {
normal = glm::normalize(normal);
Manifold cutter =
Expand Down Expand Up @@ -555,6 +575,58 @@ Manifold Manifold::Warp(std::function<void(glm::vec3&)> warpFunc) const {
return Manifold(std::make_shared<CsgLeafNode>(pImpl));
}

/**
* Create a new copy of this manifold with updated vertex properties by
* supplying a function that takes the existing position and properties as
* input. You may specify any number of output properties, allowing creation and
* removal of channels. Note: undefined behavior will result if you read past
* the number of input properties or write past the number of output properties.
*
* @param numProp The new number of properties per vertex.
* @param propFunc A function that modifies the properties of a given vertex.
*/
Manifold Manifold::SetProperties(
int numProp, std::function<void(glm::vec3 position, const float* oldProp,
float* newProp)>
propFunc) const {
auto pImpl = std::make_shared<Impl>(*GetCsgLeafNode().GetImpl());
const int oldNumProp = NumProp();
const VecDH<float> oldProperties = pImpl->meshRelation_.properties;

auto& triProperties = pImpl->meshRelation_.triProperties;
if (numProp == 0) {
triProperties.resize(0);
pImpl->meshRelation_.properties.resize(0);
} else {
if (triProperties.size() == 0) {
const int numTri = NumTri();
triProperties.resize(numTri);
int idx = 0;
for (int i = 0; i < numTri; ++i) {
for (const int j : {0, 1, 2}) {
triProperties[i][j] = idx++;
}
}
pImpl->meshRelation_.properties = VecDH<float>(numProp * idx, 0);
} else {
pImpl->meshRelation_.properties =
VecDH<float>(numProp * NumPropVert(), 0);
}
thrust::for_each_n(
thrust::host, countAt(0), NumTri(),
UpdateProperties({pImpl->meshRelation_.properties.ptrH(), numProp,
oldProperties.ptrH(), oldNumProp,
pImpl->vertPos_.ptrH(), triProperties.ptrH(),
pImpl->halfedge_.ptrH(), propFunc}));
}

pImpl->meshRelation_.numProp = numProp;
pImpl->CreateFaces();
pImpl->SimplifyTopology();
pImpl->Finish();
return Manifold(std::make_shared<CsgLeafNode>(pImpl));
}

/**
* Increase the density of the mesh by splitting every edge into n pieces. For
* instance, with n = 2, each triangle will be split into 4 triangles. These
Expand Down
33 changes: 15 additions & 18 deletions test/test_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,26 +211,23 @@ MeshGL WithIndexColors(const Mesh& in) {
}

MeshGL WithPositionColors(const Manifold& in) {
MeshGL inGL = in.GetMeshGL();
inGL.runIndex.clear();
inGL.runOriginalID.clear();
inGL.runTransform.clear();
inGL.faceID.clear();
inGL.runOriginalID = {Manifold::ReserveIDs(1)};
const int numVert = in.NumVert();
const Box bbox = in.BoundingBox();
const glm::vec3 size = bbox.Size();
const std::vector<float> oldProp = inGL.vertProperties;
inGL.numProp = 6;
inGL.vertProperties.resize(6 * numVert);
for (int i = 0; i < numVert; ++i) {
for (int j : {0, 1, 2}) inGL.vertProperties[6 * i + j] = oldProp[3 * i + j];
// vertex colors
inGL.vertProperties[6 * i + 3] = (oldProp[3 * i] - bbox.min.x) / size.x;
inGL.vertProperties[6 * i + 4] = (oldProp[3 * i + 1] - bbox.min.y) / size.y;
inGL.vertProperties[6 * i + 5] = (oldProp[3 * i + 2] - bbox.min.z) / size.z;
}
return inGL;

Manifold out = in.SetProperties(
3, [bbox, size](glm::vec3 pos, const float* oldProp, float* prop) {
for (int i : {0, 1, 2}) {
prop[i] = (pos[i] - bbox.min[i]) / size[i];
}
});

MeshGL outGL = out.GetMeshGL();
outGL.runIndex.clear();
outGL.runOriginalID.clear();
outGL.runTransform.clear();
outGL.faceID.clear();
outGL.runOriginalID = {Manifold::ReserveIDs(1)};
return outGL;
}

MeshGL WithNormals(const Manifold& in) {
Expand Down