View CadQuery objects in JupyterLab or in a standalone viewer for any IDE
Click on the "launch binder" icon to start Jupyter-CadQuery on binder:
-
New features
- A new Viewer component based on
voilà
allows to use Jupyter-CadQuery as viewer for any IDE - Dark theme support
- Tessellation normals can be rendered now for inspection
- Jupyter-CadQuery now has a logo, which is show as 3D objects when CAD viewer starts in (both sidecar and new Viewer)
set_sidecar
can now immediatly start the viewer (parameterinit
)
- A new Viewer component based on
-
Changes
show
has new parametersambient_intensity
: set ambient light intensitydirect_intensity
: set direct light intensitydefault_edgecolor
: set default edge colorrender_normals
: render normals
- During tessellation, normals are normalized
- Defaults system now lives in
jupyter_cadquery.defaults
and is more consistent - Lean scrollbars are now default (
mac_scrollbar
parameter) - Rendering timer restructured with finer granular selection
-
Fixes
- Hidden edges are now visible in transparent view
- Fixed reset camera logic between different calls to
show
- Optimized bounding box calculation
- Double scrollbars removed
- Support for CadQuery 2.1 and OCP
- Viewing options:
- Directly in the JupyterLab output cell
- In a central Jupyterlab sidecar for any JupyterLab cell (see example 1 below)
- As a standalone viewer for use from any IDE (see example 2 below)
- Viewer features
- Toggle visibilty of shapes and edges
- Orthographic and perspective view
- Clipping with max 3 clipping planes (of free orientation)
- Transparency mode
- Double click on shapes shows bounding box info
- Assemblies
- Supports CadQuery Assemblies
- Support Manual Assemblies with animation of models
- Auto display of CadQuery shapes
- Visual debugging by
- displaying selected CadQuery faces and edges
- replaying steps of the rendered object (note, this is not supported in the standalone viewer for the time being)
-
Simple Example in JupyterLab using Sidecar (light theme)
To try this yourself, you can use the code here
-
Animation system in JupyterLab
-
Debugging in VC Code with Standalone Viewer (dark theme)
Note:
- the top half is the standalone viewer in a browser window
- the bottom half is the CadQuery code being debugged in VS Code
- The
show
command in the code will tessellate the objects and send them via zmq to the standalone viewer
-
Using conda
-
Create a conda environment with Jupyterlab:
-
If you don't have it already, create a new conda environment with CadQuery 2.1
conda create -n cq22 -c conda-forge -c cadquery python=3.8 cadquery conda activate cq22
-
Install Jupyter-CadQuery (note, matplotlib is only used for the examples)
pip install jupyter-cadquery==2.2.0rc1 matplotlib
Windows users should also install
pywin32
again withconda
to ensure it is configured correctlyconda install pywin32
-
-
Run Jupyter-CadQuery in JupyterLab
conda activate cq22 jupyter lab
If you use the dark theme of JuypterLab, add the following code in the first cell of your notebook:
[1]: from jupyter_cadquery import set_defaults, set_sidecar set_defaults(theme="dark") set_sidecar("CadQuery", init=True)
-
Run Jupyter-CadQuery as standalone viewer
conda activate cq22 jcv # light theme jcv -d # dark theme
In your code import the
show
orshow_object
function from the viewer:from jupyter_cadquery.viewer.client import show, show_object
show
works as in JupyterLab, whileshow_object
views objects incrementally as in CQ-Editor
-
-
Using a docker image
-
Run the docker container (jupyter in the container will start in
/home/cq
)WORKDIR=/tmp/jupyter mkdir -p "$WORKDIR" # this has to exist, otherwise an access error will be thrown docker run -it --rm -v $WORKDIR:/home/cq -p 8888:8888 bwalter42/jupyter_cadquery:2.2.0rc1
Notes:
- To start with examples, you can
- omit the volume mapping and just run
docker run -it --rm -p 8888:8888 bwalter42/jupyter_cadquery:2.2.0rc1
or - copy the example notebooks to your
$WORKDIR
. They will be available for JupyterLab in the container.
- omit the volume mapping and just run
- If you want to change the Dockerfile,
make docker
will create a new docker image
- To start with examples, you can
-
(animated gifs)
- Features demo
- Clipping demo
- Faces-Edges-Vertices demo
- Replay demo (note, this is not supported in the standalone viewer for the time being)
- OCC demo
-
show(cad_objs, **kwargs)
args:
cad_objs
: Comma separated list of cadquery objects; Note: For OCP objects only one object is supported
kwargs:
height
: Height of the CAD view (default=600)tree_width
: Width of navigation tree part of the view (default=250)cad_width
: Width of CAD view part of the view (default=800)bb_factor
: Scale bounding box to ensure compete rendering (default=1.5)default_color
: Default mesh color (default=(232, 176, 36))default_edgecolor
: Default mesh color (default=(128, 128, 128))render_edges
: Render edges (default=True)render_normals
: Render normals (default=False)render_mates
: Render mates (for MAssemblies)mate_scale
: Scale of rendered mates (for MAssemblies)quality
: Linear deflection for tessellation (default=None) If None, uses bounding box as in (xlen + ylen + zlen) / 300 * deviation)deviation
: Deviation from default for linear deflection value ((default=0.1)angular_tolerance
: Angular deflection in radians for tessellation (default=0.2)edge_accuracy
: Presicion of edge discretizaion (default=None) If None, uses: quality / 100optimal_bb
: Use optimal bounding box (default=False)axes
: Show axes (default=False)axes0
: Show axes at (0,0,0) (default=False)grid
: Show grid (default=False)ticks
: Hint for the number of ticks in both directions (default=10)ortho
: Use orthographic projections (default=True)transparent
: Show objects transparent (default=False)ambient_intensity
Intensity of ambient ligth (default=1.0)direct_intensity
Intensity of direct lights (default=0.12)position
: Relative camera position that will be scaled (default=(1, 1, 1))rotation
: z, y and y rotation angles to apply to position vector (default=(0, 0, 0))zoom
: Zoom factor of view (default=2.5)reset_camera
: Reset camera position, rotation and zoom to default (default=True)mac_scrollbar
: Prettify scrollbars (default=True)display
: Select display: "sidecar", "cell", "html"tools
: Show the viewer tools like the object treetimeit
: Show rendering times, levels = False, 0,1,2,3,4,5 (default=False)
For example isometric projection can be achieved in two ways:
position = (1, 1, 1)
position = (0, 0, 1)
androtation = (45, 35.264389682, 0)
-
set_defaults(**kwargs)
: allows to globally set the defaults value so they do not need to be provided with everyshow
callkwargs:
- see
show
- see
-
get_default(value)
: Get the global default for a singlevalue
-
get_defaults()
: Get all global defaults -
reset_defaults()
: Reset all defaults back to its initial value
Note, this is not supported in the standalone viewer for the time being.
-
replay(args)
args:
cad_obj
: cadquery objectindex
(default=0
): Element in the fluent API stack to showdebug
(default=False
): Trace building the replay stackcad_width
(default=600
): Width of the CAD viewheight
(default=600
): Height of the CAD view
-
OCC
from jupyter_cadquery import exportSTL exportSTL(a1, "a1.stl", linear_deflection=0.01, angular_deflection=0.1)
Smaller
linear_deflection
andangular_deflection
means more details.
A straight forward approach is to use
w = show(a1)
adapt the cad view as wanted (axis, viewpoint, transparency, ...) and then call
from ipywidgets.embed import embed_minimal_html
embed_minimal_html('export.html', views=[w.cq_view.renderer], title='Renderer')
Using w.cq_view.renderer
this will save the exact state of the visible pythreejs view.
Of course, you can also call w = show(a1, *params)
where params
is the dict of show parameters you'd like to be used and then call the embed_minimal_html
with views=w.cq_view.renderer
Notes:
-
If you use
sidecar
then you need to close it first:from jupyter_cadquery import cad_display cad_display.SIDECAR.close()
-
Buttons and treeview can be exported, however the interaction logic of the UI is implemented in Python. So the treeview and the buttons won't have any effect in an exported HTML page.
-
Part
: A CadQuery shape plus some attributes for it:shape
: CadQuery shapename
: Part name in the viewcolor
: Part color in the viewshow_faces
: show the faces of this particular partshow_edges
: show the edges of this particular part
-
Faces
: CadQuery faces plus some attributesfaces
: List of CadQuery faces (shape.faces(selector))
)name
: Part name in the viewcolor
: Part color in the viewshow_faces
: show the faces for these particular facesshow_edges
: show the edges for these particular faces
-
Edges
:edges
: List of CadQuery edges (shape.edges(selector))
)name
: Part name in the viewcolor
: Part color in the view
-
Vertices
:vertices
: List of CadQuery vertices (shape.vertices(selector))
)name
: Part name in the viewcolor
: Part color in the view
-
PartGroup
: Basically a list of parts and some attributes for the view:name
: PartGroup name in the viewobjects
: all parts and assemblies included in the assembly as a list
import cadquery as cq
from jupyter_cadquery.cadquery import (PartGroup, Part, Edges, Faces, Vertices, show)
from jupyter_cadquery import set_sidecar, set_defaults
set_defaults(axes=False, grid=True, axes0=True, ortho=True, transparent=True)
set_sidecar("CadQuery", init=True)
box1 = cq.Workplane('XY').box(10, 20, 30).edges(">X or <X").chamfer(2)
box2 = cq.Workplane('XY').box(8, 18, 28).edges(">X or <X").chamfer(2)
box3 = cq.Workplane('XY').transformed(offset=(0, 15, 7)).box(30, 20, 6).edges(">Z").fillet(3)
box4 = box3.mirror("XY").translate((0, -5, 0))
box1 = box1\
.cut(box2)\
.cut(box3)\
.cut(box4)
a1 = PartGroup(
[
Part(box1, "red box", "#d7191c", show_edges=False),
Part(box3, "green box", "#abdda4", show_edges=False),
Part(box4, "blue box", "#2b83ba", show_faces=False),
],
"example 1"
)
show(a1, grid=False) # overwrite grid default value
- Thomas Paviot for python-occ. Ideas are derived/taken from his
jupyter_renderer.py
- Dave Cowden for CadQuery
- Adam Urbańczyk for the OCP version of CadQuery
- z-fighting happens some times, especially when using multiple clip planes (cannot be solved in general)
- Using more than one clip plane will lead to cut surfaces not being shown as solid. (very hard to solve in general)
-
New features
- Complete new tessellator class. Significantly faster (for a 15MB STEP file it reduced the rendering time from 3 min to <10 sec)
- Mesh quality is calculated as in FreeCad (sum of bounding box x-, y-, z-widths divided by 300 times deviation paramter)
-
Changes
- Pan speed is adapted to object size sum of bounding box x-, y-, z-widths divided by 300)
- Replay warnings can be suppressed now (
replay(warning=False)
)
-
New features
- Jupyter-CadQuery supports the latest CadQuery 2.1 with OCP (note, it will not run with the FreeCAD version of CadQuery).
- Uses JupyterLab 3.0 which has a new extension deployment system which simplifies the installation of
Jupyter-CadQuery
drastically (see below) - It supports the new CadQuery Assemblies
- Splits UI and shape rendering and shows a progress bar during rendering, especially useful for large assembblies
- If you install
cadquery-massembly
(see below) then the classMAssembly
(meaning "Mate base Assembly") is available, which is derived fromcadquery.Assembly
but similar tocqparts
or FreeCad'sAssembly4
works with mates to manually connect instead of constraints and a numerical solver. - Comes with an animation system to simulate models built with
MAssembly
-
Changes
- Deprecates Jupyter-CadQuery's
Assembly
(too many assemblies in the meantime) and has renamed it toPartGroup
(no semantic change).Assembly
can still be used with warnings at the moment. - Does not test or change the
cqparts
support since the project doesn't seem to be active any more
- Deprecates Jupyter-CadQuery's