cnr-isti-vclab / PyMeshLab

The open source mesh processing python library
GNU General Public License v3.0
778 stars 62 forks source link

BUG: generate_alpha_shape fails for high coords and leads to segmentation fault afterwards #384

Open MeshMatze opened 2 months ago

MeshMatze commented 2 months ago

I have a set of clouds (saved in path in ply format) for which i want to generate the alpha shape.

# test.py
from pathlib import Path

import pymeshlab
from loguru import logger

def gen_alpha_shapes(path):
    clouds = Path(path).rglob("*.ply")
    for idx, cloud in enumerate(clouds):
        ms = pymeshlab.MeshSet()
        logger.info("Load new mesh {}", idx)
        ms.load_new_mesh(str(cloud))
        logger.info("Mesh loades {}", idx)
        try:
            ms.generate_alpha_shape(
                alpha=pymeshlab.PercentageValue(0.01),
                filtering="Alpha Shape",
            )
        except pymeshlab.PyMeshLabException as e:
            # ms.clear()
            logger.error(e)
            # Alpha shape generation completely fails usually for clouds with to many points.
        logger.info("Done generate_alpha_shape for {}", idx)

if __name__ == "__main__":
    path = "/berta/common/test_data/okr/kysuce/3_label/2024-07-19_functional_testing_pipeline/ply/"
    gen_alpha_shapes(path)

Unfortunately running python3 -m test failed with

2024-07-24 12:46:41.539 | INFO     | __main__:<module>:40 - Load new mesh 0
2024-07-24 12:46:41.576 | INFO     | __main__:<module>:42 - Mesh loades 0
QH6229 qhull input error: 51 attempts to construct a convex hull with joggled input.  Increase joggle above 'QJ0.038' or modify qh_JOGGLE... parameters in user_r.h

While executing:  | qhull d QJ Tcv
Options selected for Qhull 2020.2.r 2020/08/31:
  run-id 1252999482  delaunay  Tcheck-frequently  Tverify  Qbbound-last-qj
  Pgood
  _run 51  QJoggle 0.038  _joggle-seed 1048648955  _max-width 3.7
  Error-roundoff 1.8e-12  Width-outside 3.6e-12  _wide-facet 1.1e-11
  _maxoutside 7.5e-10
Last point added to hull was p27270.
2024-07-24 12:47:15.659 | ERROR    | __main__:<module>:50 - Failed to apply filter: generate_alpha_shape
Details: Failed computing alpha complex shape.
2024-07-24 12:47:15.659 | INFO     | __main__:<module>:52 - Done generate_alpha_shape for 0
2024-07-24 12:47:15.659 | INFO     | __main__:<module>:40 - Load new mesh 1
Segmentation fault (core dumped)

The core dump was not expressiv, but i could create a readable core dump by running gdb --args python3.9 test.py, run and bt it says:

#0  0x00007fffa3ad5bcc in void doActivate<false>(QObject*, int, void**) () from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/lib/libQt5Core.so.5
#1  0x00007fffa5e8463e in GLLogStream::log(int, char const*) () from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/lib/libmeshlab-common.so
#2  0x00007fffa5ee0dbe in ?? () from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/pmeshlab.cpython-39-x86_64-linux-gnu.so
#3  0x00007fff9ca92de9 in BaseMeshIOPlugin::open(QString const&, QString const&, MeshModel&, int&, RichParameterList const&, bool (*)(int, char const*)) ()
   from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/lib/plugins/libio_base.so
#4  0x00007fffa5e56a67 in IOPlugin::open(QString const&, QString const&, std::__cxx11::list<MeshModel*, std::allocator<MeshModel*> > const&, std::__cxx11::list<int, std::allocator<int> >&, RichParameterList const&, bool (*)(int, char const*)) () from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/lib/libmeshlab-common.so
#5  0x00007fffa5e7d5f2 in meshlab::loadMesh(QString const&, IOPlugin*, RichParameterList const&, std::__cxx11::list<MeshModel*, std::allocator<MeshModel*> > const&, std::__cxx11::list<int, std::allocator<int> >&, bool (*)(int, char const*)) () from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/lib/libmeshlab-common.so
#6  0x00007fffa5e7f1a5 in meshlab::loadMeshWithStandardParameters[abi:cxx11](QString const&, MeshDocument&, bool (*)(int, char const*), RichParameterList) ()
   from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/lib/libmeshlab-common.so
#7  0x00007fffa5ee5c2f in ?? () from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/pmeshlab.cpython-39-x86_64-linux-gnu.so
#8  0x00007fffa5eece1d in ?? () from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/pmeshlab.cpython-39-x86_64-linux-gnu.so
#9  0x00007fffa5ef6378 in ?? () from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/pmeshlab.cpython-39-x86_64-linux-gnu.so
#10 0x00007fffa5f19435 in ?? () from /home/mbr/.cache/pypoetry/virtualenvs/aiii-ORyUtqmF-py3.9/lib/python3.9/site-packages/pymeshlab/pmeshlab.cpython-39-x86_64-linux-gnu.so
#11 0x00005555557633bb in cfunction_call (func=0x7fffa5f6c3b0, args=<optimized out>, kwargs=<optimized out>) at Objects/methodobject.c:543
#12 0x00005555555c502d in _PyObject_MakeTpCall (tstate=0x555555914ef0, callable=0x7fffa5f6c3b0, args=<optimized out>, nargs=<optimized out>, keywords=0x0) at Objects/call.c:191
#13 0x000055555574f2fa in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=2, args=0x55555596fe48, callable=0x7fffa5f6c3b0, tstate=0x555555914ef0) at ./Include/cpython/abstract.h:116
#14 _PyObject_VectorcallTstate (kwnames=0x0, nargsf=2, args=0x55555596fe48, callable=0x7fffa5f6c3b0, tstate=0x555555914ef0) at ./Include/cpython/abstract.h:103
#15 method_vectorcall (method=<optimized out>, args=0x55555596fe50, nargsf=<optimized out>, kwnames=0x0) at Objects/classobject.c:53
#16 0x00005555555b5be6 in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=<optimized out>, args=0x55555596fe50, callable=0x7fff503b8b40, tstate=0x555555914ef0) at ./Include/cpython/abstract.h:118
#17 PyObject_Vectorcall (kwnames=0x0, nargsf=<optimized out>, args=<optimized out>, callable=0x7fff503b8b40) at ./Include/cpython/abstract.h:127
#18 call_function (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=<optimized out>) at Python/ceval.c:5077
#19 _PyEval_EvalFrameDefault (tstate=<optimized out>, f=<optimized out>, throwflag=<optimized out>) at Python/ceval.c:3489
#20 0x000055555567277c in _PyEval_EvalFrame (throwflag=0, f=0x55555596fcd0, tstate=0x555555914ef0) at ./Include/internal/pycore_ceval.h:40
#21 _PyEval_EvalCode (tstate=0x555555914ef0, _co=_co@entry=0x7ffff7b44500, globals=globals@entry=0x7ffff7bb3400, locals=locals@entry=0x7ffff7bb3400, args=args@entry=0x0, argcount=argcount@entry=0, kwnames=0x0,
    kwargs=0x0, kwcount=0, kwstep=2, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name=0x0, qualname=0x0) at Python/ceval.c:4329
#22 0x0000555555672ad6 in _PyEval_EvalCodeWithName (qualname=0x0, name=0x0, closure=0x0, kwdefs=0x0, defcount=0, defs=0x0, kwstep=2, kwcount=0, kwargs=0x0, kwnames=0x0, argcount=0, args=0x0, locals=0x7ffff7bb3400,
    globals=0x7ffff7bb3400, _co=0x7ffff7b44500) at Python/ceval.c:4361
#23 PyEval_EvalCodeEx (closure=0x0, kwdefs=0x0, defcount=0, defs=0x0, kwcount=0, kws=0x0, argcount=0, args=0x0, locals=0x7ffff7bb3400, globals=globals@entry=0x7ffff7bb3400, _co=_co@entry=0x7ffff7b44500)
    at Python/ceval.c:4377
#24 PyEval_EvalCode (co=co@entry=0x7ffff7b44500, globals=globals@entry=0x7ffff7bb3400, locals=locals@entry=0x7ffff7bb3400) at Python/ceval.c:828
#25 0x00005555556b095c in run_eval_code_obj (locals=0x7ffff7bb3400, globals=0x7ffff7bb3400, co=0x7ffff7b44500, tstate=0x555555914ef0) at Python/pythonrun.c:1221
#26 run_mod (mod=<optimized out>, filename=filename@entry=0x7ffff7bb2bc0, globals=globals@entry=0x7ffff7bb3400, locals=locals@entry=0x7ffff7bb3400, flags=flags@entry=0x7fffffffdff8, arena=arena@entry=0x7ffff7b4dad0)
    at Python/pythonrun.c:1242
#27 0x00005555556b27cb in pyrun_file (flags=0x7fffffffdff8, closeit=1, locals=0x7ffff7bb3400, globals=0x7ffff7bb3400, start=257, filename=0x7ffff7bb2bc0, fp=0x555555910340) at Python/pythonrun.c:1140
#28 pyrun_simple_file (flags=0x7fffffffdff8, closeit=1, filename=0x7ffff7bb2bc0, fp=0x555555910340) at Python/pythonrun.c:450
#29 PyRun_SimpleFileExFlags (fp=fp@entry=0x555555910340, filename=<optimized out>, closeit=closeit@entry=1, flags=flags@entry=0x7fffffffdff8) at Python/pythonrun.c:483
#30 0x00005555556b2e13 in PyRun_AnyFileExFlags (fp=fp@entry=0x555555910340, filename=<optimized out>, closeit=closeit@entry=1, flags=flags@entry=0x7fffffffdff8) at Python/pythonrun.c:92
#31 0x00005555555b8c37 in pymain_run_file (cf=0x7fffffffdff8, config=0x5555559135f0) at Modules/main.c:373
#32 pymain_run_python (exitcode=exitcode@entry=0x7fffffffe110) at Modules/main.c:598
#33 0x00005555555b923a in Py_RunMain () at Modules/main.c:677
#34 pymain_main (args=0x7fffffffe0d0) at Modules/main.c:707
#35 Py_BytesMain (argc=<optimized out>, argv=<optimized out>) at Modules/main.c:731
#36 0x00007ffff7cff24a in __libc_start_call_main (main=main@entry=0x5555555ae680 <main>, argc=argc@entry=2, argv=argv@entry=0x7fffffffe248) at ../sysdeps/nptl/libc_start_call_main.h:58
#37 0x00007ffff7cff305 in __libc_start_main_impl (main=0x5555555ae680 <main>, argc=2, argv=0x7fffffffe248, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe238)
    at ../csu/libc-start.c:360
#38 0x00005555555b7ee1 in _start ()

I'm not really familiar with C++, that why i'm kinda stuck here.

I also tried reloading pymeshlab each iteration. Meaning i added:

from importlib import reload <---

    for idx, cloud in enumerate(clouds):
        reload(pymeshlab) <---
        ms = pymeshlab.MeshSet()

but that did not help either...

I would highly appreciate any help or a reasonable workaround for this. Thanks :-)

MeshMatze commented 2 months ago

After further testing it seems to result from to high coords. I created some pointclouds from the standford bunny and changed the coords of them: Centered coords: centered_coords_ply.zip High coords: high_coords_ply.zip