Closed jpanetta closed 5 years ago
Thanks for the report! I'm not currently able to reproduce this. Would you mind sharing the following general information:
This is just some information so that I can narrow it a bit before asking more specific questions. Normally, the widget/comm protocol and JS code should ensure that the object is fully created before a reference to the widget is passed to three.js. If you are able, can you go to the line producing the error and set a breakpoint to see what value the object is? I.e. the object that "is not an instance of THREE.Object3D".
I set a breakpoint, and apparently the object is undefined. The failing command is this.children.push(a)
within three.js
's add function, which called from assignChildren
in Object3D.js
, which is in turn called from syncToThreeObj
in Three.js
.
Thanks for the information. Since it happens only in notebook, and not in lab, could you try to update jupyter notebook and see if that changes anything?
Thanks for the suggestion--apparently updating Jupyter Notebook to 5.5.0 fixes the problem. It's unfortunate/disconcerting that the latest version in Ubuntu's packages (5.2.2) doesn't work. Do you think this is a bug that was recently fixed in Jupyter, or could it be just a coincidence that my example works now and this problem may reemerge in the future?
Did you install ipyvolume?
Yes, I had been playing around with ipyvolume, so it was installed/enabled.
I think you might have encountered a proper race-condition for pythreejs. I might have been making too strong assumptions about the order in which certain code paths were taken. I need to look around a little more to make sure.
Technical break down for posterity (all for JS side):
convertThreeTypeModelToThree()
, in which the obj
attribute of B
is attempted read.The problem is that the syncing code (convertThreeTypeModelToThree()
) is synchronous, and therefore doesn't check / use the initPromise
of B
. I think a lot of code depends on this currently (i.e. syncing being synchronous), so any refactoring will need to be very careful about promises being chained correctly.
Maybe the wrong threejs gets loaded, could you try uninstalling ipyvolume?
Technical: A possible solution could be to use a custom deserializer for other pythreejs widgets on the JS side, which would only resolve the widget model once the initPromise
resolves. This would need to be vetted against current assumptions.
It doesn't seem to have anything to do with ipyvolume. I can reproduce the bug with the following steps on a fresh Ubuntu 18.04 virtual machine:
sudo apt install jupyter-notebook
pip3 install pythreejs
sudo apt remove python3 ipywidgets # otherwise we get an error with the following command...
sudo jupyter nbextension install --py --symlink --sys-prefix pythreejs
sudo jupyter nbextension enable --py --sys-prefix pythreejs
jupyter notebook
I added some code in #196 to play around with. I'm most concerned about possible dead-lock scenarios because of circular dependencies.
Thanks for looking into this! Unfortunately, when I try that pull request in my VM, I get several javascript errors just trying to create an object:
Error: Could not create a model.
from utils.js: 119
Couldn't process kernel message
from kernel.js:1007
TypeError: e.initPromise is undefined
from Three.js:86
This entire block of errors is actually repeated twice even though I'm only running Object3D()
once.
Sorry, I'm a little busy atm, so I didn't have time to test the code properly (hence the WIP tag). I pushed some more fixes, but I still wouldn't call the code ready yet.
Sure, I understand. I wish I could be of more help, but unfortunately I'm inexperienced at javascript. It seems the latest code you pushed causes an infinite recursive call to unpack_models on widget.js:46.
The code below successfully displays a triangle. But if I comment out the "time.sleep" call, three.js prints
THREE.Object3D.add: object not an instance of THREE.Object3D
to the JavaScript console and renders an empty scene. Apparently some time is needed to initialize the Mesh object on the JavaScript side before it can be added to scene/group.Am I doing something wrong, or is this a bug? Is there a mechanism to notify my Python code when it is safe to add the Mesh object to the scene?