Skip to content

Commit

Permalink
adding python set_properties (#504)
Browse files Browse the repository at this point in the history
* adding test of properties

* python set_properties

* fixed sponge example

---------

Co-authored-by: pca006132 <[email protected]>
  • Loading branch information
elalish and pca006132 authored Jul 30, 2023
1 parent 7facd0e commit ffdd97d
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 3 deletions.
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,8 @@
"Verts"
],
"javascript.format.semicolons": "insert",
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
},
"python.formatting.provider": "none",
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ node test/manifold_test.js
### Python

The CMake script will build the python binding `manifold3d` automatically. To
use the extension, please add `$BUILD_DIR/tools` to your `PYTHONPATH`, where
use the extension, please add `$BUILD_DIR/bindings/python` to your `PYTHONPATH`, where
`$BUILD_DIR` is the build directory for CMake. Examples using the python binding
can be found in `bindings/python/examples`. To see exported samples, run:
```
Expand Down
7 changes: 5 additions & 2 deletions bindings/python/examples/run_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@
mesh = model.to_mesh()
if export_models:
if mesh.vert_properties.shape[1] > 3:
vertices = np.hsplit(mesh.vert_properties, 3)[0]
vertices = mesh.vert_properties[:, :3]
colors = (mesh.vert_properties[:, 3:] * 255).astype(np.uint8)
else:
vertices = mesh.vert_properties
meshOut = trimesh.Trimesh(vertices=vertices, faces=mesh.tri_verts)
colors = None
meshOut = trimesh.Trimesh(vertices=vertices, faces=mesh.tri_verts,
vertex_colors=colors)
trimesh.exchange.export.export_mesh(meshOut, f'{f}.glb', 'glb')
print(f'Exported model to {f}.glb')
t1 = time()
Expand Down
40 changes: 40 additions & 0 deletions bindings/python/examples/sponge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from manifold3d import Manifold
import numpy as np


def fractal(holes, hole, w, position, depth, maxDepth):
w /= 3
holes.append(hole.scale([w, w, 1.0]).translate(
[position[0], position[1], 0.0]))
if depth == maxDepth:
return
offsets = np.array([
[-w, -w],
[-w, 0.0],
[-w, w],
[0.0, w],
[w, w],
[w, 0.0],
[w, -w],
[0.0, -w],
])
for offset in offsets:
fractal(holes, hole, w, position + offset, depth + 1, maxDepth)


def posColors(pos, _):
return [1 - p / 2 for p in pos] + [1.0]


def run(n=1):
result = Manifold.cube([1, 1, 1], True)
holes = []
fractal(holes, result, 1.0, np.array([0.0, 0.0]), 1, n)

hole = Manifold.compose(holes)

result -= hole
result -= hole.rotate([90, 0, 0])
result -= hole.rotate([0, 90, 0])

return result.trim_by_plane([1, 1, 1], 0).set_properties(4, posColors).scale(100)
37 changes: 37 additions & 0 deletions bindings/python/manifold3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,36 @@ PYBIND11_MODULE(manifold3d, m) {
"the user to choose their function with discretion."
"\n\n"
":param warpFunc: A function that modifies a given vertex position.")
.def(
"set_properties",
[](Manifold &self, int newNumProp,
const std::function<py::array_t<float>(
Float3, const py::array_t<float> &)> &f) {
const int oldNumProp = self.NumProp();
return self.SetProperties(newNumProp, [newNumProp, oldNumProp, &f](
float *newProps,
glm::vec3 v,
const float *oldProps) {
auto array = f(std::make_tuple(v.x, v.y, v.z),
py::array(oldNumProp, oldProps));
if (array.ndim() != 1 || array.shape(0) != newNumProp)
throw std::runtime_error("Invalid vector shape, expected (" +
std::to_string(newNumProp) + ")");
auto array_view = array.unchecked<1>();
for (int i = 0; i < newNumProp; i++) newProps[i] = array_view(i);
});
},
py::arg("new_num_prop"), py::arg("f"),
"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."
"\n\n"
":param numProp: The new number of properties per vertex."
":param propFunc: A function that modifies the properties of a given "
"vertex.")
.def(
"refine", [](Manifold &self, int n) { return self.Refine(n); },
py::arg("n"),
Expand Down Expand Up @@ -428,6 +458,13 @@ PYBIND11_MODULE(manifold3d, m) {
.def_static(
"from_mesh", [](const MeshGL &mesh) { return Manifold(mesh); },
py::arg("mesh"))
.def_static(
"compose",
[](const std::vector<Manifold> &list) {
return Manifold::Compose(list);
},
"combine several manifolds into one without checking for "
"intersections.")
.def_static(
"tetrahedron", []() { return Manifold::Tetrahedron(); },
"Constructs a tetrahedron centered at the origin with one vertex at "
Expand Down

0 comments on commit ffdd97d

Please sign in to comment.