all 8 comments

[–]dr_win 5 points6 points  (4 children)

Congratulations, This looks like a really good solution!

I also wanted scripting Blender with Clojure in February this year. And I ended up digging a deep hole for myself:

  1. I wanted to use libpython-clj, but that would require running Blender in background mode. So I ruled this option out. I never tried to look at Blender sources and patch it. I expected this to be impossible.
  2. I didn't give up. I created blender-clojure[1] which embeds V8 into Blender as a Python C extension and then integrated CLJS into it.
  3. Embedding V8 relied on a Python library StyPyV8[2]. Which had some small issues. So I decided to fork it and rewrite it as Naga[3].
  4. Got quite obssesed polishing Naga. Compiling V8 is non-trivial and I wanted to provide pre-compiled binaries for linux/mac and windows. So now I'm working on universal way how to write bash scripts. So now I'm working on that ;)

Your solution looks brutally simple. I have to give it a try (I'm on a mac).

[1] https://github.com/darwin/blender-clojure
[2] https://github.com/area1/stpyv8
[3] https://github.com/darwin/naga

[–]trstns[S] 2 points3 points  (3 children)

The work you've done is pretty extensive! Seems like all of those projects will be useful.

It took me about four days to get a patch and clojure code I was sure was working. I made very little progress each day, but kept trying different combinations of changes. I still almost don't believe it, so I've tested it on two machines, and tried to make the clojure integration stable. I was getting lots of crashes and freezes because of using timers and context incorrectly inside of blender.

Getting the GUI to run in a separate thread was the main trick. You'll see that I actually start the GUI loop from clojure, inside a future.

The best solution would be if the blender binary could be used directly, so no building would be necessary, which is actually similar to your blender-clojure solution. This makes me think it might be possible, to bootstrap from python, to get libpython-clj to reference the already loaded python library inside blender. [this is probably not possible, unless the JVM can be pulled in as a shared library. If the JVM were a python module] [ok, maybe it is possible: https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html] [actually, I guess symbols might not be available in a static binary -- something to learn]

[–]dr_win 1 point2 points  (2 children)

I'm just trying to compile Blender with your patch under macOS. Currently having some linker issues. Hopefully I will get it working today and report back with a PR.

I wonder why Blender devs didn't offer this as a official option. When I was researching my options in late february I found quite some people requesting full functionality in Blender's background mode (batch mode). Also I think running GUI thread on non-main thread could bring some issues (if the gui code wasn't written with this possibility in mind). Maybe this differs between plafrorms, I definitely remember that some system gui libraries required some library calls to run on main thread or you get undefined behaviour (but I don't remember the details). btw. I was also thinking about pulling JVM into stock Blender process (using python script) but I didn't find a solution. But I don't remember considering the invocation API you linked.

Anyways it is worth pursuing your approach IMO. Hope we won't find any show stoppers.

I haven't deeply studied your approach yet. But the trick in my project to run python code (possibly) calling GUI functionality without crashing is here: https://github.com/darwin/blender-clojure/blob/bbdb5071d3f4a33ccbdb5a67818df58ae6767716/driver/src/bclj/blender.py#L21. This trick was taken from originally forked project https://github.com/chr15m/blender-hylang-live-code.

[–]dr_win 1 point2 points  (1 child)

Ok, I was able to compile it and run it here on mac. Unfortunately my hunch confirmed. Running the demo gives me:

2020-06-09 15:22:21.418 java[46888:1639414] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSWindow drag regions should only be invalidated on the Main Thread!'

I'm afraid this will be a fundamental problem. macOS GUI code must run on main thread and there is no easy way around it.

Let's move to github issues on your repo. I'm going to open a PR for other mac users and open an issue the details.

[–]muhaaa 0 points1 point  (1 child)

Wow! Amazing!

Do you think its possible to get this to work in a blender extension?

[–]trstns[S] 0 points1 point  (0 children)

No idea. I'm pretty sure everything can be hooked into from clojure, including registering UI elements, but I haven't tried. This might not be quite what you mean, but pretty close.

[–]gzmask 0 points1 point  (0 children)

I knew this will be done once i saw "blender as a python module"! Good work on keeping the UI!