Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WASM warp #221

Merged
merged 3 commits into from
Sep 27, 2022
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
5 changes: 3 additions & 2 deletions bindings/wasm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
project(wasm)

add_executable(manifoldjs bindings.cpp)

# make sure that we recompile the wasm when bindings.js is being modified
set_source_files_properties(bindings.cpp OBJECT_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/bindings.js)
${CMAKE_CURRENT_SOURCE_DIR}/bindings.js)
target_link_libraries(manifoldjs manifold)
target_compile_options(manifoldjs PRIVATE ${MANIFOLD_FLAGS} -fexceptions)
target_link_options(manifoldjs PUBLIC --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/bindings.js --bind)
target_link_options(manifoldjs PUBLIC --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/bindings.js --bind -s ALLOW_TABLE_GROWTH=1)

target_compile_features(manifoldjs PUBLIC cxx_std_14)
set_target_properties(manifoldjs PROPERTIES OUTPUT_NAME "manifold")
Expand Down
6 changes: 6 additions & 0 deletions bindings/wasm/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ Manifold Transform(Manifold& manifold, std::vector<float>& mat) {
return manifold.Transform(matrix);
}

Manifold Warp(Manifold& manifold, uintptr_t funcPtr) {
void (*f)(glm::vec3&) = reinterpret_cast<void (*)(glm::vec3&)>(funcPtr);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part feels the most wrong to me. I'm slightly hazy on the distinction between a reference and a pointer, but I feel like the JS wants a pointer and the C++ is giving a reference to the glm::vec3 and I'm not really sure how to resolve that. And I'm not even sure that's the error I'm running into.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it's working now, so apparently that distinction is pretty moot. I'm honestly amazed this works.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, references are basically implemented as pointers under the hood, but with a bit more restrictions (cannot be null, cannot have T&&&&&& while you can have T********, for example).

return manifold.Warp(f);
}

EMSCRIPTEN_BINDINGS(whatever) {
value_object<glm::vec2>("vec2")
.field("x", &glm::vec2::x)
Expand Down Expand Up @@ -116,6 +121,7 @@ EMSCRIPTEN_BINDINGS(whatever) {
.function("intersect", &Intersection)
.function("getMesh", &Manifold::GetMesh)
.function("refine", &Manifold::Refine)
.function("_Warp", &Warp, allow_raw_pointers())
.function("_Transform", &Transform)
.function("_Translate", &Manifold::Translate)
.function("_Rotate", &Manifold::Rotate)
Expand Down
11 changes: 11 additions & 0 deletions bindings/wasm/bindings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ declare class Manifold {
* @param n The number of pieces to split every edge into. Must be > 1.
*/
refine(n: number): Manifold;

/**
* This function does not change the topology, but allows the vertices to be
* moved according to any arbitrary input function. It is easy to create a
* function that warps a geometrically valid object into one which overlaps, but
* that is not checked here, so it is up to the user to choose their function
* with discretion.
*
* @param warpFunc A function that modifies a given vertex position.
*/
warp(warpFunc: (vert: Vec3) => void): Manifold;
}

/**
Expand Down
22 changes: 19 additions & 3 deletions bindings/wasm/bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ Module.setup = function () {
return vec[0];
}

Module.Manifold.prototype.warp = function (func) {
const wasmFuncPtr = addFunction(function (vec3Ptr) {
const x = getValue(vec3Ptr, 'float');
const y = getValue(vec3Ptr + 1, 'float');
const z = getValue(vec3Ptr + 2, 'float');
const vert = [x, y, z];
func(vert);
setValue(vec3Ptr, vert[0], 'float');
setValue(vec3Ptr + 1, vert[1], 'float');
setValue(vec3Ptr + 2, vert[2], 'float');
}, 'vi');
const out = this._Warp(wasmFuncPtr);
removeFunction(wasmFuncPtr);
return out;
};

// note that the matrix is using column major (same as glm)
Module.Manifold.prototype.transform = function (mat) {
console.assert(mat.length == 4, 'expects a 3x4 matrix');
Expand All @@ -45,7 +61,7 @@ Module.setup = function () {
return this._Translate(vararg2vec(vec));
};

Module.Manifold.prototype.rotate = function(vec) {
Module.Manifold.prototype.rotate = function (vec) {
return this._Rotate(...vec);
};

Expand Down Expand Up @@ -97,15 +113,15 @@ Module.setup = function () {
};

function batchbool(name) {
return function(...args) {
return function (...args) {
if (args.length == 1)
args = args[0];
let v = new Module.Vector_manifold();
for (const m of args)
v.push_back(m);
const result = Module['_' + name + 'N'](v);
v.delete();
return result;
return result;
}
}

Expand Down