libigl-python-bindings icon indicating copy to clipboard operation
libigl-python-bindings copied to clipboard

`slim_precompute` fails when fixing only one vertex as a boundary condition

Open arvigj opened this issue 8 months ago • 8 comments

When trying to use igl::slim_precompute to get an isometric parametrization, I usually give one vertex (the first) as a boundary condition with a value of [0, 0]. This fails in the new bindings, with the following error message:

TypeError: slim_precompute(): incompatible function arguments. The following argument types are supported:
    1. slim_precompute(V: numpy.ndarray[dtype=float64, shape=(*, *), order='F'], F: numpy.ndarray[dtype=int32, shape=(*, *), order='F'], V_init: numpy.ndarray[dtype=float64, shape=(*, *), order='F'], slim_energy: igl.pyigl_core.MappingEnergyType, b: numpy.ndarray[dtype=int32, shape=(*), order='C'], bc: numpy.ndarray[dtype=float64, shape=(*, *), order='F'], soft_p: float = 100000.0) -> igl.pyigl_core.SLIMData

My current resolution is to pass in the boundary condition twice, duplicated, but this seems like it should be fixed. I'm not super familiar with the inner workings of nanobind, but is a one element numpy array being cast into an int?

arvigj avatar May 14 '25 22:05 arvigj

I think this is a pythonism. The normal expectation is that the indices are a list(vector) and the positions are a matrix. So if you just have one it needs to be a Singleton vector and a 1 row matrix.

On Wed, May 14, 2025, 6:02 PM Arvi Gjoka @.***> wrote:

arvigj created an issue (libigl/libigl-python-bindings#266) https://github.com/libigl/libigl-python-bindings/issues/266

When trying to use igl::slim_precompute to get an isometric parametrization, I usually give one vertex (the first) as a boundary condition with a value of [0, 0]. This fails in the new bindings, with the following error message:

TypeError: slim_precompute(): incompatible function arguments. The following argument types are supported: 1. slim_precompute(V: numpy.ndarray[dtype=float64, shape=(, ), order='F'], F: numpy.ndarray[dtype=int32, shape=(, ), order='F'], V_init: numpy.ndarray[dtype=float64, shape=(, ), order='F'], slim_energy: igl.pyigl_core.MappingEnergyType, b: numpy.ndarray[dtype=int32, shape=(), order='C'], bc: numpy.ndarray[dtype=float64, shape=(, *), order='F'], soft_p: float = 100000.0) -> igl.pyigl_core.SLIMData

My current resolution is to pass in the boundary condition twice, duplicated, but this seems like it should be fixed. I'm not super familiar with the inner workings of nanobind, but is a one element numpy array being cast into an int?

— Reply to this email directly, view it on GitHub https://github.com/libigl/libigl-python-bindings/issues/266, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARDJGP5CAXVQLUJW6THDF326O4PHAVCNFSM6AAAAAB5EQF2F6VHI2DSMVQWIX3LMV43ASLTON2WKOZTGA3DIMZWG44TONI . You are receiving this because you are subscribed to this thread.Message ID: @.***>

alecjacobson avatar May 14 '25 22:05 alecjacobson

So just to be clear. The following fails:

        b = np.array([0], dtype=f_.dtype)
        bc = np.array([[0., 0.]], dtype=v_uv.dtype)
        slim_data = igl.slim_precompute(v, f, v_init, igl.SYMMETRIC_DIRICHLET, b, bc, 1e5)

while the following works

        b = np.array([0, 0], dtype=f_.dtype)
        bc = np.array([[0., 0.], [0., 0.]], dtype=v_uv.dtype)
        slim_data = igl.slim_precompute(v, f, v_init, igl.SYMMETRIC_DIRICHLET, b, bc, 1e5)

arvigj avatar May 14 '25 23:05 arvigj

I see. I'm not sure why the first fails.

On Wed, May 14, 2025, 7:28 PM Arvi Gjoka @.***> wrote:

arvigj left a comment (libigl/libigl-python-bindings#266) https://github.com/libigl/libigl-python-bindings/issues/266#issuecomment-2881819910

So just to be clear. The following fails:

    b = np.array([0], dtype=f_.dtype)
    bc = np.array([[0., 0.]], dtype=v_uv.dtype)
    slim_data = igl.slim_precompute(v, f, v_init, igl.SYMMETRIC_DIRICHLET, b, bc, 1e5)

while the following works

    b = np.array([0, 0], dtype=f_.dtype)
    bc = np.array([[0., 0.], [0., 0.]], dtype=v_uv.dtype)
    slim_data = igl.slim_precompute(v, f, v_init, igl.SYMMETRIC_DIRICHLET, b, bc, 1e5)

— Reply to this email directly, view it on GitHub https://github.com/libigl/libigl-python-bindings/issues/266#issuecomment-2881819910, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARDJGKIFGRMTFOSXCKRQZL26PGQDAVCNFSM6AAAAAB5EQF2F6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQOBRHAYTSOJRGA . You are receiving this because you commented.Message ID: @.***>

alecjacobson avatar May 15 '25 00:05 alecjacobson

Are you on the dev branch?

On Wed, May 14, 2025, 8:41 PM Alec Jacobson @.***> wrote:

I see. I'm not sure why the first fails.

On Wed, May 14, 2025, 7:28 PM Arvi Gjoka @.***> wrote:

arvigj left a comment (libigl/libigl-python-bindings#266) https://github.com/libigl/libigl-python-bindings/issues/266#issuecomment-2881819910

So just to be clear. The following fails:

    b = np.array([0], dtype=f_.dtype)
    bc = np.array([[0., 0.]], dtype=v_uv.dtype)
    slim_data = igl.slim_precompute(v, f, v_init, igl.SYMMETRIC_DIRICHLET, b, bc, 1e5)

while the following works

    b = np.array([0, 0], dtype=f_.dtype)
    bc = np.array([[0., 0.], [0., 0.]], dtype=v_uv.dtype)
    slim_data = igl.slim_precompute(v, f, v_init, igl.SYMMETRIC_DIRICHLET, b, bc, 1e5)

— Reply to this email directly, view it on GitHub https://github.com/libigl/libigl-python-bindings/issues/266#issuecomment-2881819910, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARDJGKIFGRMTFOSXCKRQZL26PGQDAVCNFSM6AAAAAB5EQF2F6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQOBRHAYTSOJRGA . You are receiving this because you commented.Message ID: @.***>

alecjacobson avatar May 15 '25 00:05 alecjacobson

I'm compiling the bindings from this repo on the main branch. I have yet to test it, but if you reduce the boundary conditions to one node instead of two in the test file, I'm sure you'll get the same error. I will try this later, but I'm sure this will replicate the result.

arvigj avatar May 15 '25 01:05 arvigj

import igl
import numpy as np
v,f = igl.icosahedron()
v_init = v.copy()
bc = np.array([[0., 0.]], dtype=v.dtype)
b = np.array([0], dtype=f.dtype)
# also works fine
slim_data = igl.slim_precompute(v, f, v_init, igl.SYMMETRIC_DIRICHLET, b, bc, 1e5)
b = np.array([0, 0], dtype=f.dtype)
bc = np.array([[0., 0.], [0., 0.]], dtype=v.dtype)
# works fine
slim_data = igl.slim_precompute(v, f, v_init, igl.SYMMETRIC_DIRICHLET, b, bc, 1e5)

works fine for me on main on mac os.

alecjacobson avatar May 15 '25 01:05 alecjacobson

sorry, I was actually on https://github.com/libigl/libigl-python-bindings/tree/alecjacobson/bump-nanobind which has a newer version of nanobind. Maybe it was a nanobind issue? Anyway it seems to at least not crash on that branch (which I will merge as soon as the CI passes).

alecjacobson avatar May 15 '25 01:05 alecjacobson

Yea nanobind issue is what my thought was, because the failure seemed to come from type conversion and not the libigl C++ code. Thank you! PS Any chance you could trigger the CI for my PR adding bindings for some functions? I'll add the tests so it can be merged.

arvigj avatar May 15 '25 01:05 arvigj

Closing assuming this is fixed. Please reopen if it's a problem on the current version.

alecjacobson avatar Sep 14 '25 13:09 alecjacobson