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

[WIP] Build for/with pyodide #827

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft

Conversation

ochafik
Copy link
Contributor

@ochafik ochafik commented Jun 2, 2024

These changes are a step towards unlocking an out-of-tree build of Manifold for Pyodide.

(Includes a workaround for oneapi-src/oneTBB#1391, which could be retired once that PR is merged.)

EXCEPT: the resulting bindings explode with a cryptic RuntimeError: null function or function signature mismatch errors seemingly happening inside CPython / Pyodide's WASM code, seemingly only for the Mesh ctor in the example below. I've tried following the Pyodide debugging guide, bit stuck at the step of compiling pyodide for scratch / trying to identify which function is faulty.

(and I know there's already great WASM / JS bindings for Manifold, but I somehow found myself using the Python bindings and wanted an easy way to run the results on the web)

conda create -n manifold python=3.11.2
conda activate manifold
pip install build pyodide-build

git clone https://github.com/emscripten-core/emsdk.git --recursive
cd emsdk
PYODIDE_EMSCRIPTEN_VERSION=$(pyodide config get emscripten_version)
./emsdk install ${PYODIDE_EMSCRIPTEN_VERSION}
./emsdk activate ${PYODIDE_EMSCRIPTEN_VERSION}
source emsdk_env.sh
cd ..

git clone https://github.com/ochafik/manifold --single-branch --branch pyodide-build --recursive manifold
cd manifold
pyodide build
cp dist/*.whl manifold3d-2.4.5-py3-none-emscripten_$(pyodide config get emscripten_version | tr . _)_wasm32.whl

Then serve this index.html using python -m http.server:

<script type="text/javascript" src="https://cdn.jsdelivr.net/pyodide/v0.26.0/full/pyodide.js"></script>
<script type="text/javascript">
  async function main() {
    let pyodide = await loadPyodide();
    window.pyodide = pyodide;
    await pyodide.loadPackage("micropip");
    const micropip = pyodide.pyimport("micropip");
    await micropip.install([
      "./manifold3d-2.4.5-py3-none-emscripten_3_1_58_wasm32.whl",
    ]);
    
    await pyodide.runPython(`
      from manifold3d import Manifold, Mesh
      import numpy as np

      # WORKS!
      print("MESH 1", Manifold.cube([1, 2, 3]).to_mesh())
    
      # CRASHES!
      mesh = Mesh(
        tri_verts=np.array([[1, 0, 5], [1, 5, 2], [2, 5, 6], [2, 6, 3], [3, 6, 7], [3, 7, 4], [5, 0, 8], [5, 8, 6], [6, 8, 9], [6, 9, 7], [7, 9, 10], [7, 10, 4], [8, 0, 11], [8, 11, 9], [9, 11, 12], [9, 12, 10], [10, 12, 13], [10, 13, 4], [11, 0, 14], [11, 14, 12], [12, 14, 15], [12, 15, 13], [13, 15, 16], [13, 16, 4], [14, 0, 1], [14, 1, 15], [15, 1, 2], [15, 2, 16], [16, 2, 3], [16, 3, 4]], np.int32),
        vert_properties=np.array([[0.0, 0.0, -0.8660254037844387], [0.49999999999999994, 0.0, -0.8660254037844387], [1.0, 0.0, -6.123233995736766e-17], [0.49999999999999994, 0.0, 0.8660254037844387], [0.0, 0.0, 0.8660254037844387], [0.1545084971874737, 0.4755282581475767, -0.8660254037844387], [0.30901699437494745, 0.9510565162951535, -6.123233995736766e-17], [0.1545084971874737, 0.4755282581475767, 0.8660254037844387], [-0.4045084971874736, 0.29389262614623657, -0.8660254037844387], [-0.8090169943749473, 0.5877852522924732, -6.123233995736766e-17], [-0.4045084971874736, 0.29389262614623657, 0.8660254037844387], [-0.40450849718747367, -0.29389262614623646, -0.8660254037844387], [-0.8090169943749475, -0.587785252292473, -6.123233995736766e-17], [-0.40450849718747367, -0.29389262614623646, 0.8660254037844387], [0.1545084971874736, -0.47552825814757677, -0.8660254037844387], [0.30901699437494723, -0.9510565162951536, -6.123233995736766e-17], [0.1545084971874736, -0.47552825814757677, 0.8660254037844387]], np.float32),
      )

      print("MESH 2", mesh)
    `);
  }
  window.addEventListener('load', main)
</script>

@elalish
Copy link
Owner

elalish commented Jun 3, 2024

That's certainly interesting, though I don't think I'll be much use. I'm definitely a light-weight when it comes to Python.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants