f3d-app / f3d

Fast and minimalist 3D viewer.
https://f3d.app
BSD 3-Clause "New" or "Revised" License
2.88k stars 207 forks source link

Concave polygon rendering artifact #473

Open thwd opened 2 years ago

thwd commented 2 years ago

Version

$ f3d --version
f3d 1.2.1

F3D - A fast and minimalist 3D viewer
Version: 1.2.1
Build date: 2022-02-20 15:49:12
System: Linux x86_64
Compiler: GNU 11.2.0
RayTracing module: OFF
Exodus module: ON
OpenCASCADE module: OFF
Assimp module: OFF
VTK version: 9.1.0 (build 0)

Minimal repro .obj file

v -0.5000 1.0000 0.0000
v -0.3333 1.0000 0.0000
v 0.0000 1.2500 0.0000
v 0.3333 1.0000 0.0000
v 0.5000 1.0000 0.0000
v 0.5000 1.1667 0.0000
v 0.2500 1.5000 0.0000
v 0.5000 1.8333 0.0000
v 0.5000 2.0000 0.0000
v 0.3333 2.0000 0.0000
v 0.0000 1.7500 0.0000
v -0.3333 2.0000 0.0000
v -0.5000 2.0000 0.0000
v -0.5000 1.8333 0.0000
v -0.2500 1.5000 0.0000
v -0.5000 1.1667 0.0000
f 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1

The bug

If you change the f (face) command on the last line to l (line), you get the correct shape outline. But if you render with a f, you get something boxy.

line.png

line

face.png

face

Meakk commented 2 years ago

Concave polygons aren't well supported in VTK.
I'm not sure if it can be improved easily. Any input @mwestphal ?

mwestphal commented 2 years ago

Thats correct, such polygons are usually triangulated before rendering when working directly with VTK. I should not be that hard to fix, it's just that polygon are a wild beast compared to other cell types, I'm not sure it's worth spending time on this tbh.

mwestphal commented 2 years ago

for reference: https://discourse.vtk.org/t/complex-concave-polygons/2857

thwd commented 2 years ago

Thanks for the quick feedback. is there any way to detect this case and error? Or, even better, to triangulate the concave face on-the-fly? I'm not familiar with VTK.

other cell types

I'm wondering whether alternatives exist in obj format? Or a similarly simple format?

My use-case: I'm writing a toy CAD program and need to quickly dump some polygons & polyhedrons onto the screen from time to time. So far f3d has been amazing for this.

Meakk commented 2 years ago

You can triangulate the polygon yourself and store the triangles instead of the polygon in the obj file.
There are many resources on internet.
You can also cut the polygon in a convex polygon set.
One idea: find a vertex with angles > 180 degrees and cut the polygon at this vertex until you have only convex polygons (all angles < 180 degrees).

snoyer commented 1 year ago

You can triangulate the polygon yourself and store the triangles instead of the polygon in the obj file.

@thwd, I'm late to the party but I would suggest that solution too; especially given that the next step after "concave polygon" is "complex polygons" (with holes) and you'll want to have proper triangulation when you eventually find yourself with some of these. I'd recommend checking for bindings/wrappers/ports for https://www.cs.cmu.edu/~quake/triangle.html for your language of choice before you go down the rabbit hole of reinventing triangulation.

Meakk commented 1 year ago

Note that @snoyer's recommendation is a library for "quality mesh" (with almost equilateral triangles), where points are added inside the polygon area.
I came across earcut recently for "visual mesh" (minimal number of triangles).
I works very well and is very easy to use.

mwestphal commented 9 months ago

This is a wontfix imo. If VTK fixes it, we will take it, but we do not plan to add a triangulation step in our pipeline.

Wdyt @Meakk ?

Meakk commented 9 months ago

If I'm correct, the triangulation (at the mapper level) is done in https://github.com/Kitware/VTK/blob/6a8928918ade34498f54559d379ca4e6527ebd4f/Rendering/OpenGL2/vtkOpenGLIndexBufferObject.cxx#L35
Maybe we could use a VTK factory to instantiate our own vtkOpenGLIndexBufferObject and call earcut to triangulate it?
I don't think it's critical to support that for now, but let's keep it opened.

mwestphal commented 9 months ago

I'm not closing it, just labeling as wontfix :)