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

IndexError out of range when converting to STL #176

Open
mdjong1 opened this issue Nov 21, 2023 · 3 comments · May be fixed by #177
Open

IndexError out of range when converting to STL #176

mdjong1 opened this issue Nov 21, 2023 · 3 comments · May be fixed by #177

Comments

@mdjong1
Copy link
Member

mdjong1 commented Nov 21, 2023

Describe the bug
When trying to convert a CityJSON to STL I get a list index out of range. I'm running the command on a CityJSON I created by downloading BAG3D tiles and merging them. I then also upgraded the merged file to CityJSON 2.0 using cjio delft.city.json upgrade save delft-upgraded.city.json.

cjio validate on the file indicates that everything is valid.

Stacktrace
➜ cjio delft-upgraded.city.json export stl delft.stl
Parsing delft-upgraded.city.json
Exporting CityJSON to STL (/home/maarten/Documents/3DDelft/CityJSON/delft.stl)
Traceback (most recent call last):
  File "/home/maarten/Repositories/cityjson-related/venv/bin/cjio", line 33, in <module>
    sys.exit(load_entry_point('cjio==0.9.0', 'console_scripts', 'cjio')())
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/click/core.py", line 1720, in invoke
    return _process_result(rv)
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/click/core.py", line 1657, in _process_result
    value = ctx.invoke(self._result_callback, value, **ctx.params)
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/cjio/cjio.py", line 94, in process_pipeline
    cm = processor(cm)
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/cjio/cjio.py", line 240, in processor
    exporter(cm, sloppy)
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/cjio/cjio.py", line 179, in exporter
    re = cm.export2stl(sloppy)
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/cjio/cityjson.py", line 1752, in export2stl
    n, bb = geom_help.get_normal_newell(face)
  File "/home/maarten/Repositories/cityjson-related/venv/lib/python3.10/site-packages/cjio/geom_help.py", line 42, in get_normal_newell
    n[0] += ( (poly[i][1] - poly[ne][1]) * (poly[i][2] + poly[ne][2]) )
IndexError: list index out of range

cjio version
I installed from the git repo, but used tag v0.9.0.

➜ cjio --version                        
cjio v0.9.0; supports CityJSON v2.0

To Reproduce
It's awkward, because if I convert a single CityJSON to STL it works fine, but converting the merged file results in the IndexError, so I'm not sure which file is introducing it at this point. The merged file is kind of large to attach; I guess it might help if I try to convert each file separately and see which one crashes it?

Expected behavior
No IndexError upon conversion to STL 😅

Desktop (please complete the following information):
Ubuntu 22.04
Python 3.10.12

cjio installed to a fresh venv (with latest main of cjvalpy from git)

pip freeze
certifi==2023.11.17
cjio==0.9.0
cjvalpy @ file:///home/maarten/Repositories/cityjson-related/cjvalpy/target/wheels/cjvalpy-0.4.1-cp310-cp310-manylinux_2_34_x86_64.whl
click==8.1.7
mapbox-earcut==1.0.1
numpy==1.26.2
pandas==2.1.3
pyproj==3.6.1
python-dateutil==2.8.2
pytz==2023.3.post1
six==1.16.0
triangle==20230923
tzdata==2023.3
@mdjong1
Copy link
Member Author

mdjong1 commented Nov 21, 2023

So it looks like it's trying to get the normal using Newell's method for a poly that is only 2 elements long ([[1099, 1098]]) and therefore fails.

Happy to create a quick PR for it if I understand what would need to be changed here; should len(poly) >= 3 for this, since otherwise calculating a normal is kind of pointless anyways? And does this have further consequences, such as needing to drop the polygon in it's entirety further down (i.e. maybe returning False from the function I guess)?

Relevant function

def get_normal_newell(poly):
    # find normal with Newell's method
    # print (poly)
    n = np.array([0.0, 0.0, 0.0], dtype=np.float64)
    # if len(poly) == 0:
    #     print ("NOPOINTS")
    for i,p in enumerate(poly):
        ne = i + 1
        if (ne == len(poly)):
            ne = 0
        n[0] += ( (poly[i][1] - poly[ne][1]) * (poly[i][2] + poly[ne][2]) )
        n[1] += ( (poly[i][2] - poly[ne][2]) * (poly[i][0] + poly[ne][0]) )
        n[2] += ( (poly[i][0] - poly[ne][0]) * (poly[i][1] + poly[ne][1]) )
    
    if (n==np.array([0.0, 0.0, 0.0])).all():
        # print("one wrong")
        return (n, False)
    n = n / math.sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2])    
    return (n, True)

@hugoledoux
Copy link
Member

PR welcome.

Yes just drop the invalid/collapsed face, nothing more you can do here I'm afraid.

@sugizo
Copy link

sugizo commented May 15, 2024

stil got the same error
env
google colab

steps

pip install -U cjio triangle cjvalpy meshio
!wget -c https://www.cityjson.org/tutorials/files/twobuildings.city.json
!cjio twobuildings.city.json export stl two_buildings.stl

result

Parsing twobuildings.city.json
Exporting CityJSON to STL (/content/two_buildings.stl)
Traceback (most recent call last):
  File "/usr/local/bin/cjio", line 8, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1720, in invoke
    return _process_result(rv)
  File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1657, in _process_result
    value = ctx.invoke(self._result_callback, value, **ctx.params)
  File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/cjio/cjio.py", line 94, in process_pipeline
    cm = processor(cm)
  File "/usr/local/lib/python3.10/dist-packages/cjio/cjio.py", line 240, in processor
    exporter(cm, sloppy)
  File "/usr/local/lib/python3.10/dist-packages/cjio/cjio.py", line 179, in exporter
    re = cm.export2stl(sloppy)
  File "/usr/local/lib/python3.10/dist-packages/cjio/cityjson.py", line 1740, in export2stl
    n, bb = geom_help.get_normal_newell(face)
  File "/usr/local/lib/python3.10/dist-packages/cjio/geom_help.py", line 42, in get_normal_newell
    n[0] += ( (poly[i][1] - poly[ne][1]) * (poly[i][2] + poly[ne][2]) )
IndexError: list index out of range

expected result
can produce *.stl file with cjio

known work
generate *.obj file using cjio
then use meshio to generate *.stl file
e.g.

!cjio twobuildings.city.json export obj two_buildings.obj
!meshio convert two_buildings.obj two_buildings.stl

best regards

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 a pull request may close this issue.

3 participants