tpaviot / pythonocc-core

Python package for 3D geometry CAD/BIM/CAM
GNU Lesser General Public License v3.0
1.38k stars 380 forks source link

`OffscreenRenderer` doesn't propagate `size` correctly. #1180

Open gestj opened 1 year ago

gestj commented 1 year ago

The function init_display provides a size parameter which is meant for the screen size of the created and returned display/renderer (however you wanna call it).

BUT, in case of offscreen rendering (env.PYTHONOCC_OFFSCREEN_RENDERER = 1) the size isn't propagated correctly. Instead a default of 640x480 will be used ALWAYS. This is unexpected.

I use now my own implementation which is more or less c&p of your OffscreenRenderer including overwriting the Viewer3d and there the InitOffscreen (where I ignore its parameters and instead call its super method with the size I want to set) method because that was the most straight forward hack for me.

In Viewer3d.Create https://github.com/tpaviot/pythonocc-core/blob/master/src/Display/OCCViewer.py#L203 you can see that even if OffscreenRenderer would consider size correctly (in fact it does consider it a "little" bit; see its constructor) it wouldn't work as expected.

Overall the code is just wired incorrectly for this use case...

I might be able to provide a fix if you want, but, I am unsure how activly this entire repo is maintained anyway... So I won't spend time upfront on this since I am very very very busy with my own stuff.

The hack looks like this btw:

# Patched version of pyocc because it doesn't delegate screen size correctly.
class OffscreenRenderer(Viewer3d):
    _size: Tuple[int, int]

    # essentially same code as pyocc version, only I left out what I don't need anyway
    def __init__(self, size=(1920, 1080)):
        Viewer3d.__init__(self)
        self._size = size
        self.Create()
        self.SetModeShaded()
        self.capture_number = 0

    def InitOffscreen(self, size_x: "int", size_y: "int") -> "bool":
        # this is the reason why I patched it ...
        return Viewer3d.InitOffscreen(self, self._size[0], self._size[1])

# I needed to patch the pyocc version since it misses passing the size to the `OffscreenRenderer`
def init_display_patched(size=(1920, 1080)):
    if os.getenv("PYTHONOCC_OFFSCREEN_RENDERER") == "1":
        print(f"Using offscreen renderer with {size}")
        offscreen_renderer = OffscreenRenderer(size=size)

        def do_nothing(*kargs: Any, **kwargs: Any) -> None:
            """takes as many parameters as you want, and does nothing
            """
            return None

        def call_function(s, func: Callable) -> None:
            """A function that calls another function.
            Helpful to bypass add_function_to_menu. s should be a string
            """
            check_callable(func)
            print("Execute %s :: %s menu function" % (s, func.__name__))
            func()
            print("done")

        # returns empty classes and functions
        return offscreen_renderer, do_nothing, do_nothing, call_function
    return init_display(size=size, display_triedron=False)
tpaviot commented 1 year ago

feel free to open a PR. Since you already patched related file(s), this should not take too much of your precious precious precious time (15mn?). Anyway, this is two or three orders of magnitude lower than the overall time I spent providing this library for free. Honestly, no one here cares about your agenda.

Tanneguydv commented 1 year ago

In the readme section we can read : "Latest release: pythonocc-core 7.7.0 (December 2022)" one could guess that this "entire repo" is maintained ...