jupyter-widgets / pythreejs

A Jupyter - Three.js bridge
https://pythreejs.readthedocs.io
Other
936 stars 187 forks source link

Embedded widget's controls are broken #215

Closed jpanetta closed 5 years ago

jpanetta commented 5 years ago

When I export my renderer to a standalone HTML document using ipywidgets.embed, the OrbitControls and TrackballControls are broken. The scene renders properly, but the moment you interact with it, the camera parameters blow up.

Example code (see attached `tri_embed.html`) ``` from pythreejs import * from ipywidgets import embed scene = Scene(children=[AmbientLight(intensity=0.5)]) vertices = BufferAttribute(array=np.array( [[-1.0, -1.0, 0.0], [ 1.0, -1.0, 0.0], [ 1.0, 1.0, 0.0]], dtype=np.float32), normalized=False) index = BufferAttribute(array=np.array( [[0, 1, 2]], dtype=np.uint16).ravel(), normalized=False) geom = BufferGeometry(attributes={ 'position': vertices, 'index': index, }) surf=Mesh(geometry=geom, material=MeshLambertMaterial(color='red', side='DoubleSide')) scene.add(surf) c = PerspectiveCamera(position=[0, 0, 3], up=[0, 1, 0]) controls = OrbitControls(controlling=c) r = Renderer(camera=c, scene=scene, controls=[controls]) embed.embed_minimal_html('tri_embed.html', views=r) ```


Apparently, the main problem is the OrbitControls.maxDistance variable is changed from its initial value of Infinity (examples/controls/OrbitControls.js:32) to null, which breaks the eye vector calculation. This change to null happens in assignDirect, called from syncToThreeObj, so perhaps this is when the defaults specified in OrbitControls.autogen.js:20 are pushed to three.js--but I still don't have a clear picture of the steps taken to initialize/restore the three.js data structures.

When I manually change this maxDistance back to Infinity in the JS debugger, the controls mostly work (probably some other state is being overwritten, but I'll need to do some more debugging).

On a related note: is there a good way for me to point the standalone HTML file at my local development copy of the pythreejs code? It seems to always fall back to a CDN copy of juptyer-threejs, which prevents me from attempting to fix these issues.

Also, is it normal for it to take a couple minutes to run a Jupyter build after each change to the pythreejs source? I followed the current developer install instructions.

tri_embed.html.zip

vidartf commented 5 years ago

Thanks for the report. I'll answer the easy bit first:

On a related note: is there a good way for me to point the standalone HTML file at my local development copy of the pythreejs code?

Either modify the HTML after creating it, or use a template of your own. Then drop in e.g. a <script> tag with a relative path, or somehow else configure require.js to load it locally.

maartenbreddels commented 5 years ago

I usually link say jupyter-three.js, ipyvolume.js etc to my dev directory/files, so they are always using the latest version. e.g.

$ ln ~/src/ipyvolume/ipyvolume/static/index.js ipyvolume.js
vidartf commented 5 years ago

Actually, it already looks locally first, so just copy/link your compiled embeddable bundle from js/dist to be next to the HTML file.

maartenbreddels commented 5 years ago

Also, is it normal for it to take a couple minutes to run a Jupyter build after each change to the pythreejs source? I followed the current developer install instructions.

If you run jupyter lab like $ jupyter lab --watch, (after a first build) a rebuild is almost instant.

@vidartf I see there is no watch command in package.json, what do you do for incremental building for jupyter-threejs?

vidartf commented 5 years ago

@jpanetta Regarding the initial issue, I've identified it as the code missing out on the fact that JSON.stringify() converts +/-Infinity to null. I'll do a PR to fix it.

vidartf commented 5 years ago

@maartenbreddels There is no watch script, as there are so many different moving parts with the autogeneration and all. Getting it right while still getting the speedup was just too much of a hassle.

jpanetta commented 5 years ago

Ah, thanks, I was unsure what files to copy/link to since I couldn't find a jupyter-three.js anywhere. But now I understand that I should rename dist/index.js to juptyer-threejs.js. Sorry--I'm still quite new to the Javascript development tools. I'll test your PR now.

jpanetta commented 5 years ago

Ok, this PR fixes the blow-up issue on my end, and I should be better equipped now to debug the wonky behavior. Thank you!