-
Notifications
You must be signed in to change notification settings - Fork 182
Added renderer #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added renderer #97
Conversation
Right on, Nick! Seems like more and more people are working in Jupyter, and having a live render there in the notebook is a great thing. I've got a few questions before folding this in, but I'm fully in favor of it.
def get_jupyter_renderer(width=600, height=600, draw_grids=True, openscad_exe=None):
# Make sure we have all dependencies, or give instructions how to install them
try:
import jupyter_renderer
except ImportError as e:
print("Unable to import Jupyter dependencies. You can import needed dependencies with: \n"
"pip install pythreejs numpy <etc...>")
# If we can't guess location of openSCAD executable, warn that we need it
try:
openscad_exe = openscad_exe or jupyter_renderer.find_openscad_exe()
except ExecutableNotFoundError as enf_error:
print('No OpenSCAD executable found at %s'%openscad_exe)
# Return a usable renderer object.
renderer = jupyter_renderer.SolidRenderer(openscad_exe)
return renderer
This is great work. I'll get to all these bits in time if you don't, but you might get through it faster than I do. Cheers! |
Thanks, these are all really good suggestions, and I can get to work on it; I agree with all of them. -I wasn't aware of the tempfile module, and it certainly sounds like it is a good way to eliminate need to supply a temp directory. -I'll look into the .obj file stuff. Looking briefly, one thing that I see that certainly would be beneficial is that it looks like it has mechanisms to make different parts have different colors, which is lost in the .stl files. -Good point about guessing the openscad location. On a mac, it will almost certainly live in /Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD, and on linux, one could probably just guess that it is somewhere in the current $PATH. Windows I'm not too familiar with though. -I may be able to test on windows, because I think I have a windows virtual machine I can try it on. -One thing I'd be curious to hear your opinion on: the grids are a little clunky, mostly because I wanted to have something, but didn't want to spend too much time on it. It would also be possible to do something else, like draw axes like the openscad gui has, or to draw the grid lines with dashed lines, etc.. One thing I think I cannot do, however, is to have the grids automatically rescale as the user zooms in and out with the mouse. Anyway, any opinion on grids vs axes vs something else? |
I think the grids are just fine! They're useful and, while it would be nice to have them auto-scale, that's not possible without doing some deep magic. Maybe set alpha= 0.6 or so, so they're visible but translucent. The other thing (that I can't think quite how to do right now) would be to include some text that showed the extents of the grid. When you're just sketching in 3D, it can be good to know that one grid square is 1 unit vs 10 units vs 0.1 units. Anyway, those details are just sugar. I think the graphic you attached looks great! |
…for a temp directory to create files in
Ok, I've made a stab at most of these things, and pushed them to my SolidPython fork:
|
Thanks for getting all those bits in! I'll take a look and see about merging soon. |
BTW I added some installation details for pythreejs to my README.rst in my fork. Installation is not hard, but it's also not trivial. |
Awesome. I’m gonna try to get this merged and released this week— hassle me if I don’t. Thanks for adding this!
… On Nov 13, 2018, at 3:56 PM, nickc92 ***@***.***> wrote:
BTW I added some installation details for pythreejs to my README.rst in my fork. Installation is not hard, but it's also not trivial.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
For whatever reason, the little square I was drawing to indicate the scale wasn't working in jupyter lab; but rendering it as HTML instead of SVG seemed to work for me, so I pushed that change to my repo. Also, I should mention that I added a method to render directly to STL (rather than .scad), which for me eliminates one step in the design->3D print chain. |
OK, I just followed your instructions and got SP running in a Jupyter Notebook. It's awesome! I'm really impressed with what you've done. I wrote a shell script to install all the dependencies so that, on my system at least (famous last words) it's a one-line install: What occurs to me, though, is that you've managed to do something lots of people have wanted and not been able to find, AND, it would work for OpenSCAD code as easily as SolidPython. Do you have any interest in releasing this as its own PyPI module or Jupyter extension? |
And, since I haven't figured out how to make additions to a PR yet, here's #!/usr/bin/env bash
function testExists {
EXE=$1
if ! [ -x "$(command -v $EXE)" ]; then
echo "No $EXE executable found; please install before installng Jupyter Renderer."
exit 1;
fi
}
# Confirm that python, node, & npm are present, or fail with an error.
testExists python
testExists node
testExists npm
# Install required Python modules
pip install jupyterlab ipywidgets pythreejs
# Register/install Jupyter extensions
jupyter nbextension enable --py widgetsnbextension
jupyter labextension install @jupyter-widgets/jupyterlab-manager
jupyter nbextension install --py --symlink --sys-prefix pythreejs
jupyter nbextension enable --py --sys-prefix pythreejs
jupyter lab build
echo 'SolidPython Jupyter Renderer installed. Start it using `jupyter lab`'
|
Hey I realized I replied via email, and that I should probably reply here. Anyhow, thanks for the kind words. I'd be happy to turn this into a PyPI project, if that would be easier and would make more sense. I could basically provide a function, But if you prefer this thing to be part of SolidPython, I'm cool with that too; I think SolidPython is a very convenient way to make 3d print designs (my usual use case), and I'm hoping that adding a renderer makes it all the more usable. The folks who have built Jupyter have done such a great job and created something with such a high quality appearance that it's a pleasure to work within it. |
I suspect that this one particular feature that you've added may have more appeal than all of SolidPython itself. I poked around a bit for "Jupyter OpenSCAD" on the web and it seems like a lot of people have wanted it, but nobody until you has managed to make it work. So... with some trivial work, I think you could serve all SolidPython users and all OpenSCAD users. The other reason I suggested a separate package is that I think it might be simpler for people to install. With one So if you're game, I think releasing it as a PyPI package would make things easiest for users. I'd pop in a link to the package in the SolidPython Readme, so anybody using SolidPython would have quick access to the Jupyter renderer, and I think that way you'd get everybody who was searching for Jupyter & OpenSCAD together, too. I don't know enough about Jupyter kernels to know how you'd get native OpenSCAD code in a workbook, but if you were willing to put it in a Python triple-quoted string, it'd be trivial to get OpenSCAD code rendered as well as SolidPython. I think that's probably what most users are looking for (I've always been mystified by the fact that so many people were willing to use the clunky OpenSCAD language when SolidPython was available, but it's possible I'm a little biased ;-) ) So... that's my sales pitch. I know I've been leaning on you through this whole thing and making it a more involved project than you might have intended. (And I'm not done yet!) But you've done something pretty great, and I'd like to see a lot of people using it. The PyPI process is a little involved, but I think you'll be happy with the results once it's all packaged up. Let me know if you're going to go ahead with it or if you'd rather not jump all the way in. Cheers, Evan |
Thanks, all this feedback is very helpful. Not surprisingly, I'm completely on the same page as you about the openscad language, in that it seems unnecessary to create a new language when something like Python would do fine; and thanks to your efforts I can just use Python! I'm totally game for creating a PyPI package. That would be cool if it could test if node.js and npm are installed like your script does, and call those jupyter commands. Poking around a bit, it's possible that what I should be doing is creating a new Jupyter kernel, which looks like it's easier than it sounds. Looking at the output that SolidPython produces, I get the impression that internally, SolidPython essentially has to construct the CSG tree associated with your 3D object. Given this, I was even tempted to cut out the middle man and simply have SolidPython call the same CGAL routines that Openscad probably does to calculate the CSG (CGAL is a 3D object library that openscad relies on, and naturally there are Python bindings). But I figured that life might be more complicated than that, and that special cases might arise that openscad internally takes care of, so I put down that idea. |
OK, I totally spent too much time on this, but I put together a pip-installable package that gets the renderer working. It's at https://github.com/etjones/JupyterOpenSCAD . Still needs some work, since I haven't figured out how to reliably run the Jupyter extension install script. Anyway... go ahead and fork what's in that repo if you want, and I'll delete mine; it's just the setup.py file that I added. As for a pure Python => CGAL tree, that would be great to have. When I started writing SolidPython back in 2011, there were a couple people working on similar projects to do just that. But... I don't think those projects are still alive at all. SolidPython is a really chintzy text-substitution system, not even a real parser, but it works, so that's what I stuck with. As it is, I bet you'd be happy with any step you could lop off of the Python => OpenSCAD => STL => ThreeJs => SVG system that's going on now. |
Wow, that's terrific, thanks! I wonder if having that install script run automatically when someone types I'll play with this over the weekend, and hopefully get something functional. I might play with the naming of things a bit, and see what you think. Again, thanks for the efforts! |
Right on! Please do switch names around however you like; I just needed to pencil something in.
I know that arbitrary post-install code is possible, but there are some hiccups I don’t fully understand, and I didn’t figure it all out yesterday. One thing that’s not represented is that `pip install` can resolve to one of `install`, `develop`, or `egg_info`, so a true post-install hook might require three identical custom subclasses. There’s some info here: https://blog.niteo.co/setuptools-run-custom-code-in-setup-py/, and I found an example on Stack Overflow, but it’s all pretty involved. More fun!
One other thing I’d be happy to see is a method that let you render OpenSCAD code directly, even if it was just a string, like:
``` python
scad_code = ‘’’
difference(){
cube(),
sphere()
}
‘’’
r.render_scad(scad_code)
```
Seems like that might be a good stopgap until you feel like making an OpenSCAD kernel.
Good luck, and let me know when you publish something!
… On Nov 30, 2018, at 4:57 PM, nickc92 ***@***.***> wrote:
Wow, that's terrific, thanks!
I wonder if having that install script run automatically when someone types pip install JupyterOpenSCAD is even possible? The only reason I question whether it's possible is that installing pythreejs with pip install pythreejs does not automatically invoke the jupyter nbextension... business, and I would think that if it were possible, they would have done it; but perhaps they just made the decision that maybe the user hasn't yet installed jupyter or something.
I'll play with this over the weekend, and hopefully get something functional. I might play with the naming of things a bit, and see what you think. Again, thanks for the efforts!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Ha, we're thinking on the same wavelength. Last night I modified the render() method so that if you pass it a string, it assumes the string is OpenSCAD code, and renders it; but if you pass it an instance of Also, I learned something that may be of interest to you: if you make a method for an object called
and it worked. The point is, it would be kind of cool if OpenSCADObject had such a method. Perhaps you then would also need a method in the solidpython module, |
Whew! Ok, so I've got version 0.1 up and running, and pip installable. The package is now called
Unfortunately, I deactivated your install script until I can get a better handle on that, and left instructions on the github homepage for now. Anyway, I hope the package ends up being useful, and thanks for all your input! |
Excellent! Install went smoothly in a clean virtualenv and it all seems to be working great. I've deleted my repo so yours should be the only source of truth, and I'll add a writeup in the SolidPython README so anybody can find it there. Congrats! |
Hi Evan, just thought you may be interested to know I released a 0.2.0
version of ViewSCAD, which now lets you double-click on the rendered
objects and get info about the faces, edges, and vertices; this allowed
me to write some cool utility functions like "rotate_face_down()" and
"place_on()" (place one object on another).
-Nick
|
I created a renderer which allows you to have a SolidPython workflow completely within a Jupyter notebook. It is very easy to use; see the attached image. It requires pythreejs to be installed, but that is straightforward. The main caveat is that internally it calls openscad to render the object into an STL, which of course can be time-consuming for some models. But if that's not the case for your model, this could be a good way to use SolidPython. Let me know what you think!
