cq.vis.show improvements (#1726)
* Handle vtkActors * Mypy fix * Update Showables * Add specular lighting * Make show non-blocking and add title * Return only qwin * Revert * Test fix * Better coverage * Adding vis docs * Add references * Primer tweaks * Cleanup * Correct file names * Tweaks * Try with -q * Try with always_yes * Remove -q * Try with mamba * Use mamba run * Set MAMBA_ROOT_PREFIX * Fix prefix * Apply suggestions from code review Co-authored-by: Jeremy Wright <wrightjmf@gmail.com> * Do not use full screen * State correct version --------- Co-authored-by: Jeremy Wright <wrightjmf@gmail.com>
This commit is contained in:
		
							
								
								
									
										14
									
								
								appveyor.yml
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								appveyor.yml
									
									
									
									
									
								
							@ -20,25 +20,27 @@ init:
 | 
				
			|||||||
    - cmd: Miniforge.exe /InstallationType=JustMe /RegisterPython=0 /S /D=%MINICONDA_DIRNAME%
 | 
					    - cmd: Miniforge.exe /InstallationType=JustMe /RegisterPython=0 /S /D=%MINICONDA_DIRNAME%
 | 
				
			||||||
    - cmd: set "PATH=%MINICONDA_DIRNAME%;%MINICONDA_DIRNAME%\\Scripts;%PATH%"
 | 
					    - cmd: set "PATH=%MINICONDA_DIRNAME%;%MINICONDA_DIRNAME%\\Scripts;%PATH%"
 | 
				
			||||||
    - cmd: activate
 | 
					    - cmd: activate
 | 
				
			||||||
 | 
					    - cmd: set MAMBA_ROOT_PREFIX=C:/Miniforge/Library
 | 
				
			||||||
    - sh: curl -sL https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$OS-x86_64.sh > miniconda.sh
 | 
					    - sh: curl -sL https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$OS-x86_64.sh > miniconda.sh
 | 
				
			||||||
    - sh: bash miniconda.sh -b -p $HOME/miniconda;
 | 
					    - sh: bash miniconda.sh -b -p $HOME/miniconda;
 | 
				
			||||||
    - sh: export PATH="$HOME/miniconda/bin:$HOME/miniconda/lib:$PATH";
 | 
					    - sh: export PATH="$HOME/miniconda/bin:$HOME/miniconda/lib:$PATH";
 | 
				
			||||||
    - sh: source $HOME/miniconda/bin/activate
 | 
					    - sh: source $HOME/miniconda/bin/activate
 | 
				
			||||||
 | 
					    - sh: export MAMBA_ROOT_PREFIX=$HOME/miniconda
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install:
 | 
					install:
 | 
				
			||||||
 | 
					    - conda config --set always_yes yes
 | 
				
			||||||
    - mamba env create -f environment.yml
 | 
					    - mamba env create -f environment.yml
 | 
				
			||||||
    - conda activate cadquery
 | 
					    - mamba list -n cadquery
 | 
				
			||||||
    - conda list
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
build: false
 | 
					build: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test_script:
 | 
					test_script:
 | 
				
			||||||
    - black . --diff --check
 | 
					    - mamba run -n cadquery black . --diff --check
 | 
				
			||||||
    - mypy cadquery
 | 
					    - mamba run -n cadquery mypy cadquery
 | 
				
			||||||
    - pytest -v --cov
 | 
					    - mamba run -n cadquery pytest -v --cov
 | 
				
			||||||
 | 
					
 | 
				
			||||||
on_success:
 | 
					on_success:
 | 
				
			||||||
    - codecov
 | 
					    - mamba run -n cadquery codecov
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#on_finish:
 | 
					#on_finish:
 | 
				
			||||||
#    - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
 | 
					#    - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
from . import Shape, Workplane, Assembly, Sketch, Compound, Color, Vector, Location
 | 
					from . import Shape, Workplane, Assembly, Sketch, Compound, Color, Vector, Location
 | 
				
			||||||
from .occ_impl.exporters.assembly import _vtkRenderWindow
 | 
					from .occ_impl.assembly import _loc2vtk, toVTK
 | 
				
			||||||
from .occ_impl.assembly import _loc2vtk
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from typing import Union, Any, List, Tuple
 | 
					from typing import Union, Any, List, Tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -15,8 +14,10 @@ from vtkmodules.vtkRenderingCore import (
 | 
				
			|||||||
    vtkMapper,
 | 
					    vtkMapper,
 | 
				
			||||||
    vtkRenderWindowInteractor,
 | 
					    vtkRenderWindowInteractor,
 | 
				
			||||||
    vtkActor,
 | 
					    vtkActor,
 | 
				
			||||||
 | 
					    vtkProp,
 | 
				
			||||||
    vtkPolyDataMapper,
 | 
					    vtkPolyDataMapper,
 | 
				
			||||||
    vtkAssembly,
 | 
					    vtkAssembly,
 | 
				
			||||||
 | 
					    vtkRenderWindow,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from vtkmodules.vtkCommonCore import vtkPoints
 | 
					from vtkmodules.vtkCommonCore import vtkPoints
 | 
				
			||||||
from vtkmodules.vtkCommonDataModel import vtkCellArray, vtkPolyData
 | 
					from vtkmodules.vtkCommonDataModel import vtkCellArray, vtkPolyData
 | 
				
			||||||
@ -27,8 +28,14 @@ DEFAULT_COLOR = [1, 0.8, 0, 1]
 | 
				
			|||||||
DEFAULT_PT_SIZE = 7.5
 | 
					DEFAULT_PT_SIZE = 7.5
 | 
				
			||||||
DEFAULT_PT_COLOR = "darkviolet"
 | 
					DEFAULT_PT_COLOR = "darkviolet"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SPECULAR = 0.3
 | 
				
			||||||
 | 
					SPECULAR_POWER = 100
 | 
				
			||||||
 | 
					SPECULAR_COLOR = vtkNamedColors().GetColor3d("White")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ShapeLike = Union[Shape, Workplane, Assembly, Sketch, TopoDS_Shape]
 | 
					ShapeLike = Union[Shape, Workplane, Assembly, Sketch, TopoDS_Shape]
 | 
				
			||||||
Showable = Union[ShapeLike, List[ShapeLike], Vector, List[Vector]]
 | 
					Showable = Union[
 | 
				
			||||||
 | 
					    ShapeLike, List[ShapeLike], Vector, List[Vector], vtkProp, List[vtkProp]
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _to_assy(*objs: ShapeLike, alpha: float = 1) -> Assembly:
 | 
					def _to_assy(*objs: ShapeLike, alpha: float = 1) -> Assembly:
 | 
				
			||||||
@ -50,7 +57,9 @@ def _to_assy(*objs: ShapeLike, alpha: float = 1) -> Assembly:
 | 
				
			|||||||
    return assy
 | 
					    return assy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _split_showables(objs) -> Tuple[List[ShapeLike], List[Vector], List[Location]]:
 | 
					def _split_showables(
 | 
				
			||||||
 | 
					    objs,
 | 
				
			||||||
 | 
					) -> Tuple[List[ShapeLike], List[Vector], List[Location], List[vtkProp]]:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Split into showables and others.
 | 
					    Split into showables and others.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
@ -58,6 +67,7 @@ def _split_showables(objs) -> Tuple[List[ShapeLike], List[Vector], List[Location
 | 
				
			|||||||
    rv_s: List[ShapeLike] = []
 | 
					    rv_s: List[ShapeLike] = []
 | 
				
			||||||
    rv_v: List[Vector] = []
 | 
					    rv_v: List[Vector] = []
 | 
				
			||||||
    rv_l: List[Location] = []
 | 
					    rv_l: List[Location] = []
 | 
				
			||||||
 | 
					    rv_a: List[vtkProp] = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for el in objs:
 | 
					    for el in objs:
 | 
				
			||||||
        if instance_of(el, ShapeLike):
 | 
					        if instance_of(el, ShapeLike):
 | 
				
			||||||
@ -66,21 +76,24 @@ def _split_showables(objs) -> Tuple[List[ShapeLike], List[Vector], List[Location
 | 
				
			|||||||
            rv_v.append(el)
 | 
					            rv_v.append(el)
 | 
				
			||||||
        elif isinstance(el, Location):
 | 
					        elif isinstance(el, Location):
 | 
				
			||||||
            rv_l.append(el)
 | 
					            rv_l.append(el)
 | 
				
			||||||
 | 
					        elif isinstance(el, vtkProp):
 | 
				
			||||||
 | 
					            rv_a.append(el)
 | 
				
			||||||
        elif isinstance(el, list):
 | 
					        elif isinstance(el, list):
 | 
				
			||||||
            tmp1, tmp2, tmp3 = _split_showables(el)  # split recursively
 | 
					            tmp1, tmp2, tmp3, tmp4 = _split_showables(el)  # split recursively
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            rv_s.extend(tmp1)
 | 
					            rv_s.extend(tmp1)
 | 
				
			||||||
            rv_v.extend(tmp2)
 | 
					            rv_v.extend(tmp2)
 | 
				
			||||||
            rv_l.extend(tmp3)
 | 
					            rv_l.extend(tmp3)
 | 
				
			||||||
 | 
					            rv_a.extend(tmp4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return rv_s, rv_v, rv_l
 | 
					    return rv_s, rv_v, rv_l, rv_a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _to_vtk_pts(
 | 
					def _to_vtk_pts(
 | 
				
			||||||
    vecs: List[Vector], size: float = DEFAULT_PT_SIZE, color: str = DEFAULT_PT_COLOR
 | 
					    vecs: List[Vector], size: float = DEFAULT_PT_SIZE, color: str = DEFAULT_PT_COLOR
 | 
				
			||||||
) -> vtkActor:
 | 
					) -> vtkActor:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Convert vectors to vtkActor.
 | 
					    Convert Vectors to vtkActor.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rv = vtkActor()
 | 
					    rv = vtkActor()
 | 
				
			||||||
@ -110,7 +123,7 @@ def _to_vtk_pts(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def _to_vtk_axs(locs: List[Location], scale: float = 0.1) -> vtkActor:
 | 
					def _to_vtk_axs(locs: List[Location], scale: float = 0.1) -> vtkActor:
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Convert vectors to vtkActor.
 | 
					    Convert Locations to vtkActor.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rv = vtkAssembly()
 | 
					    rv = vtkAssembly()
 | 
				
			||||||
@ -135,6 +148,8 @@ def show(
 | 
				
			|||||||
    alpha: float = 1,
 | 
					    alpha: float = 1,
 | 
				
			||||||
    tolerance: float = 1e-3,
 | 
					    tolerance: float = 1e-3,
 | 
				
			||||||
    edges: bool = False,
 | 
					    edges: bool = False,
 | 
				
			||||||
 | 
					    specular: bool = True,
 | 
				
			||||||
 | 
					    title: str = "CQ viewer",
 | 
				
			||||||
    **kwrags: Any,
 | 
					    **kwrags: Any,
 | 
				
			||||||
):
 | 
					):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
@ -142,7 +157,7 @@ def show(
 | 
				
			|||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # split objects
 | 
					    # split objects
 | 
				
			||||||
    shapes, vecs, locs = _split_showables(objs)
 | 
					    shapes, vecs, locs, props = _split_showables(objs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # construct the assy
 | 
					    # construct the assy
 | 
				
			||||||
    assy = _to_assy(*shapes, alpha=alpha)
 | 
					    assy = _to_assy(*shapes, alpha=alpha)
 | 
				
			||||||
@ -151,19 +166,28 @@ def show(
 | 
				
			|||||||
    pts = _to_vtk_pts(vecs)
 | 
					    pts = _to_vtk_pts(vecs)
 | 
				
			||||||
    axs = _to_vtk_axs(locs, scale=scale)
 | 
					    axs = _to_vtk_axs(locs, scale=scale)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # create a VTK window
 | 
					    # assy+renderer
 | 
				
			||||||
    win = _vtkRenderWindow(assy, tolerance=tolerance)
 | 
					    renderer = toVTK(assy, tolerance=tolerance)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    win.SetWindowName("CQ viewer")
 | 
					    # VTK window boilerplate
 | 
				
			||||||
 | 
					    win = vtkRenderWindow()
 | 
				
			||||||
 | 
					    win.SetWindowName(title)
 | 
				
			||||||
 | 
					    win.AddRenderer(renderer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # get renderer and actor
 | 
					    # get renderer and actor
 | 
				
			||||||
    if edges:
 | 
					    for act in renderer.GetActors():
 | 
				
			||||||
        ren = win.GetRenderers().GetFirstRenderer()
 | 
					
 | 
				
			||||||
        for act in ren.GetActors():
 | 
					        propt = act.GetProperty()
 | 
				
			||||||
            act.GetProperty().EdgeVisibilityOn()
 | 
					
 | 
				
			||||||
 | 
					        if edges:
 | 
				
			||||||
 | 
					            propt.EdgeVisibilityOn()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if specular:
 | 
				
			||||||
 | 
					            propt.SetSpecular(SPECULAR)
 | 
				
			||||||
 | 
					            propt.SetSpecularPower(SPECULAR_POWER)
 | 
				
			||||||
 | 
					            propt.SetSpecularColor(SPECULAR_COLOR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # rendering related settings
 | 
					    # rendering related settings
 | 
				
			||||||
    win.SetMultiSamples(16)
 | 
					 | 
				
			||||||
    vtkMapper.SetResolveCoincidentTopologyToPolygonOffset()
 | 
					    vtkMapper.SetResolveCoincidentTopologyToPolygonOffset()
 | 
				
			||||||
    vtkMapper.SetResolveCoincidentTopologyPolygonOffsetParameters(1, 0)
 | 
					    vtkMapper.SetResolveCoincidentTopologyPolygonOffsetParameters(1, 0)
 | 
				
			||||||
    vtkMapper.SetResolveCoincidentTopologyLineOffsetParameters(-1, 0)
 | 
					    vtkMapper.SetResolveCoincidentTopologyLineOffsetParameters(-1, 0)
 | 
				
			||||||
@ -193,7 +217,7 @@ def show(
 | 
				
			|||||||
    orient_widget.InteractiveOff()
 | 
					    orient_widget.InteractiveOff()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # use gradient background
 | 
					    # use gradient background
 | 
				
			||||||
    renderer = win.GetRenderers().GetFirstRenderer()
 | 
					    renderer.SetBackground(1, 1, 1)
 | 
				
			||||||
    renderer.GradientBackgroundOn()
 | 
					    renderer.GradientBackgroundOn()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # use FXXAA
 | 
					    # use FXXAA
 | 
				
			||||||
@ -209,9 +233,15 @@ def show(
 | 
				
			|||||||
    renderer.AddActor(pts)
 | 
					    renderer.AddActor(pts)
 | 
				
			||||||
    renderer.AddActor(axs)
 | 
					    renderer.AddActor(axs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # add other vtk actors
 | 
				
			||||||
 | 
					    for p in props:
 | 
				
			||||||
 | 
					        renderer.AddActor(p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # initialize and set size
 | 
					    # initialize and set size
 | 
				
			||||||
    inter.Initialize()
 | 
					    inter.Initialize()
 | 
				
			||||||
    win.SetSize(*win.GetScreenSize())
 | 
					
 | 
				
			||||||
 | 
					    w, h = win.GetScreenSize()
 | 
				
			||||||
 | 
					    win.SetSize((w // 2, h // 2))
 | 
				
			||||||
    win.SetPosition(-10, 0)
 | 
					    win.SetPosition(-10, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # show and return
 | 
					    # show and return
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								doc/_static/show.PNG
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doc/_static/show.PNG
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 314 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								doc/_static/show_demo.PNG
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doc/_static/show_demo.PNG
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 290 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								doc/_static/show_jupyter.PNG
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doc/_static/show_jupyter.PNG
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 152 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								doc/_static/show_vtk.PNG
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doc/_static/show_vtk.PNG
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 107 KiB  | 
@ -41,6 +41,7 @@ Table Of Contents
 | 
				
			|||||||
    sketch.rst
 | 
					    sketch.rst
 | 
				
			||||||
    assy.rst
 | 
					    assy.rst
 | 
				
			||||||
    free-func.rst
 | 
					    free-func.rst
 | 
				
			||||||
 | 
					    vis.rst
 | 
				
			||||||
    fileformat.rst
 | 
					    fileformat.rst
 | 
				
			||||||
    examples.rst
 | 
					    examples.rst
 | 
				
			||||||
    apireference.rst
 | 
					    apireference.rst
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										293
									
								
								doc/primer.rst
									
									
									
									
									
								
							
							
						
						
									
										293
									
								
								doc/primer.rst
									
									
									
									
									
								
							@ -27,157 +27,24 @@ kernel, there is another set of Geometrical constructs involved as well. For exa
 | 
				
			|||||||
hold a reference to an underlying curve that is a full circle, and each linear edge holds underneath it the equation
 | 
					hold a reference to an underlying curve that is a full circle, and each linear edge holds underneath it the equation
 | 
				
			||||||
for a line.  CadQuery shields you from these constructs.
 | 
					for a line.  CadQuery shields you from these constructs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
Workplane class
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The Workplane class contains the currently selected objects (a list of Shapes, Vectors or Locations
 | 
					 | 
				
			||||||
in the :attr:`~cadquery.Workplane.objects` attribute), the modelling context (in the
 | 
					 | 
				
			||||||
:attr:`~cadquery.Workplane.ctx` attribute), and CadQuery's fluent api methods. It is the main class
 | 
					 | 
				
			||||||
that users will instantiate.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See :ref:`apireference` to learn more.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Workplanes
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Most CAD programs use the concept of Workplanes. If you have experience with other CAD programs you will probably
 | 
					 | 
				
			||||||
feel comfortable with CadQuery's Workplanes, but if you don't have experience then they are an essential concept to
 | 
					 | 
				
			||||||
understand.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Workplanes represent a plane in space, from which other features can be located. They have a center point and a local
 | 
					 | 
				
			||||||
coordinate system. Most methods that create an object do so relative to the current workplane.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Usually the first workplane created is the "XY" plane, also known as the "front" plane. Once a solid is defined the most
 | 
					 | 
				
			||||||
common way to create a workplane is to select a face on the solid that you intend to modify and create a new workplane
 | 
					 | 
				
			||||||
relative to it. You can also create new workplanes in anywhere in world coordinate system, or relative to other planes
 | 
					 | 
				
			||||||
using offsets or rotations.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The most powerful feature of workplanes is that they allow you to work in 2D space in the coordinate system of the
 | 
					 | 
				
			||||||
workplane, and then CadQuery will transform these points from the workplane coordinate system to the world coordinate
 | 
					 | 
				
			||||||
system so your 3D features are located where you intended. This makes scripts much easier to create and maintain.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See :py:class:`cadquery.Workplane` to learn more.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2D Construction
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Once you create a workplane, you can work in 2D, and then later use the features you create to make 3D objects.
 | 
					 | 
				
			||||||
You'll find all of the 2D constructs you expect -- circles, lines, arcs, mirroring, points, etc.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See :ref:`2dOperations` to learn more.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
3D Construction
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You can construct 3D primitives such as boxes, wedges, cylinders and spheres directly. You can also sweep, extrude,
 | 
					 | 
				
			||||||
and loft 2D geometry to form 3D features.  Of course the basic primitive operations are also available.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See :ref:`3doperations` to learn more.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Selectors
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Selectors allow you to select one or more features, in order to define new features.  As an example, you might
 | 
					 | 
				
			||||||
extrude a box, and then select the top face as the location for a new feature.  Or, you might extrude a box, and
 | 
					 | 
				
			||||||
then select all of the vertical edges so that you can apply a fillet to them.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You can select Vertices, Edges, Faces, Solids, and Wires using selectors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Think of selectors as the equivalent of your hand and mouse, if you were to build an object using a conventional CAD system.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
See :ref:`selectors` to learn more.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Construction Geometry
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
Construction geometry are features that are not part of the object, but are only defined to aid in building the object.
 | 
					 | 
				
			||||||
A common example might be to define a rectangle, and then use the corners to define the location of a set of holes.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Most CadQuery construction methods provide a ``forConstruction`` keyword, which creates a feature that will only be used
 | 
					 | 
				
			||||||
to locate other features.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The Stack
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
As you work in CadQuery, each operation returns a new Workplane object with the result of that
 | 
					 | 
				
			||||||
operations. Each Workplane object has a list of objects, and a reference to its parent.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You can always go backwards to older operations by removing the current object from the stack.  For example::
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Workplane(someObject).faces(">Z").first().vertices()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
returns a CadQuery object that contains all of the vertices on the highest face of someObject. But you can always move
 | 
					 | 
				
			||||||
backwards in the stack to get the face as well::
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Workplane(someObject).faces(">Z").first().vertices().end()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
You can browse stack access methods here: :ref:`stackMethods`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. _chaining:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Chaining
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
All Workplane methods return another Workplane object, so that you can chain the methods together
 | 
					 | 
				
			||||||
fluently. Use the core Workplane methods to get at the objects that were created.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Each time a new Workplane object is produced during these chained calls, it has a
 | 
					 | 
				
			||||||
:attr:`~cadquery.Workplane.parent` attribute that points to the Workplane object that created it.
 | 
					 | 
				
			||||||
Several CadQuery methods search this parent chain, for example when searching for the context solid.
 | 
					 | 
				
			||||||
You can also give a Workplane object a tag, and further down your chain of calls you can refer back
 | 
					 | 
				
			||||||
to this particular object using its tag.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The Context Solid
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Most of the time, you are building a single object, and adding features to that single object.  CadQuery watches
 | 
					 | 
				
			||||||
your operations, and defines the first solid object created as the 'context solid'.  After that, any features
 | 
					 | 
				
			||||||
you create are automatically combined (unless you specify otherwise) with that solid.  This happens even if the
 | 
					 | 
				
			||||||
solid was created  a long way up in the stack.  For example::
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Workplane("XY").box(1, 2, 3).faces(">Z").circle(0.25).extrude(1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Will create a 1x2x3 box, with a cylindrical boss extending from the top face.  It was not necessary to manually
 | 
					 | 
				
			||||||
combine the cylinder created by extruding the circle with the box, because the default behavior for extrude is
 | 
					 | 
				
			||||||
to combine the result with the context solid. The hole() method works similarly -- CadQuery presumes that you want
 | 
					 | 
				
			||||||
to subtract the hole from the context solid.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If you want to avoid this, you can specify ``combine=False``, and CadQuery will create the solid separately.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Iteration
 | 
					 | 
				
			||||||
---------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CAD models often have repeated geometry, and its really annoying to resort to for loops to construct features.
 | 
					 | 
				
			||||||
Many CadQuery methods operate automatically on each element on the stack, so that you don't have to write loops.
 | 
					 | 
				
			||||||
For example, this::
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Workplane("XY").box(1, 2, 3).faces(">Z").vertices().circle(0.5)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Will actually create 4 circles, because ``vertices()`` selects 4 vertices of a rectangular face, and the ``circle()`` method
 | 
					 | 
				
			||||||
iterates on each member of the stack.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is really useful to remember  when you author your own plugins. :py:meth:`cadquery.Workplane.each` is useful for this purpose.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CadQuery API layers
 | 
					CadQuery API layers
 | 
				
			||||||
---------------------------
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Once you start to dive a bit more into CadQuery, you may find yourself a bit confused juggling between different types of objects the CadQuery APIs can return.
 | 
					Once you start to dive a bit more into CadQuery, you may find yourself a bit confused juggling between different types of objects the CadQuery APIs can return.
 | 
				
			||||||
This chapter aims to give an explanation on this topic and to provide background on the underlying implementation and kernel layers so you can leverage more of CadQuery functionality.
 | 
					This chapter aims to give an explanation on this topic and to provide background on the underlying implementation and kernel layers so you can leverage more of CadQuery functionality.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CadQuery is composed of 3 different API, which are implemented on top of each other.
 | 
					CadQuery is composed of 4 different API, which are implemented on top of each other.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1. The Fluent API
 | 
					1. The Fluent API
 | 
				
			||||||
 | 
					    #. :class:`~cadquery.Workplane` 
 | 
				
			||||||
 | 
					    #. :class:`~cadquery.Sketch` 
 | 
				
			||||||
 | 
					    #. :class:`~cadquery.Assembly`
 | 
				
			||||||
2. The Direct API
 | 
					2. The Direct API
 | 
				
			||||||
 | 
					    #. :class:`~cadquery.Shape` 
 | 
				
			||||||
 | 
					2. The Geometry API
 | 
				
			||||||
 | 
					    #. :class:`~cadquery.Vector`
 | 
				
			||||||
 | 
					    #. :class:`~cadquery.Plane`
 | 
				
			||||||
 | 
					    #. :class:`~cadquery.Location`
 | 
				
			||||||
3. The OCCT API
 | 
					3. The OCCT API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The Fluent API
 | 
					The Fluent API
 | 
				
			||||||
@ -799,6 +666,148 @@ that is shown in the 3D view above.
 | 
				
			|||||||
  rather than the object from the previous step.
 | 
					  rather than the object from the previous step.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Workplane class
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The Workplane class contains the currently selected objects (a list of Shapes, Vectors or Locations
 | 
				
			||||||
 | 
					in the :attr:`~cadquery.Workplane.objects` attribute), the modelling context (in the
 | 
				
			||||||
 | 
					:attr:`~cadquery.Workplane.ctx` attribute), and CadQuery's fluent api methods. It is the main class
 | 
				
			||||||
 | 
					that users will instantiate.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See :ref:`apireference` to learn more.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Workplanes
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Most CAD programs use the concept of Workplanes. If you have experience with other CAD programs you will probably
 | 
				
			||||||
 | 
					feel comfortable with CadQuery's Workplanes, but if you don't have experience then they are an essential concept to
 | 
				
			||||||
 | 
					understand.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Workplanes represent a plane in space, from which other features can be located. They have a center point and a local
 | 
				
			||||||
 | 
					coordinate system. Most methods that create an object do so relative to the current workplane.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Usually the first workplane created is the "XY" plane, also known as the "front" plane. Once a solid is defined the most
 | 
				
			||||||
 | 
					common way to create a workplane is to select a face on the solid that you intend to modify and create a new workplane
 | 
				
			||||||
 | 
					relative to it. You can also create new workplanes anywhere in the world coordinate system, or relative to other planes
 | 
				
			||||||
 | 
					using offsets or rotations.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The most powerful feature of workplanes is that they allow you to work in 2D space in the coordinate system of the
 | 
				
			||||||
 | 
					workplane, and then CadQuery will transform these points from the workplane coordinate system to the world coordinate
 | 
				
			||||||
 | 
					system so your 3D features are located where you intended. This makes scripts much easier to create and maintain.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See :py:class:`cadquery.Workplane` to learn more.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2D Construction
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Once you create a workplane, you can work in 2D, and then later use the features you create to make 3D objects.
 | 
				
			||||||
 | 
					You'll find all of the 2D constructs you expect -- circles, lines, arcs, mirroring, points, etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See :ref:`2dOperations` to learn more.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3D Construction
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can construct 3D primitives such as boxes, wedges, cylinders and spheres directly. You can also sweep, extrude,
 | 
				
			||||||
 | 
					and loft 2D geometry to form 3D features.  Of course the basic primitive operations are also available.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See :ref:`3doperations` to learn more.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Selectors
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Selectors allow you to select one or more features, in order to define new features.  As an example, you might
 | 
				
			||||||
 | 
					extrude a box, and then select the top face as the location for a new feature.  Or, you might extrude a box, and
 | 
				
			||||||
 | 
					then select all of the vertical edges so that you can apply a fillet to them.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can select Vertices, Edges, Faces, Solids, and Wires using selectors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Think of selectors as the equivalent of your hand and mouse, if you were to build an object using a conventional CAD system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See :ref:`selectors` to learn more.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Construction Geometry
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					Construction geometry are features that are not part of the object, but are only defined to aid in building the object.
 | 
				
			||||||
 | 
					A common example might be to define a rectangle, and then use the corners to define the location of a set of holes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Most CadQuery construction methods provide a ``forConstruction`` keyword, which creates a feature that will only be used
 | 
				
			||||||
 | 
					to locate other features.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The Stack
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					As you work in CadQuery, each operation returns a new Workplane object with the result of that
 | 
				
			||||||
 | 
					operations. Each Workplane object has a list of objects, and a reference to its parent.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can always go backwards to older operations by removing the current object from the stack.  For example::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Workplane(someObject).faces(">Z").first().vertices()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					returns a CadQuery object that contains all of the vertices on the highest face of someObject. But you can always move
 | 
				
			||||||
 | 
					backwards in the stack to get the face as well::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Workplane(someObject).faces(">Z").first().vertices().end()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can browse stack access methods here: :ref:`stackMethods`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _chaining:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Chaining
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All Workplane methods return another Workplane object, so that you can chain the methods together
 | 
				
			||||||
 | 
					fluently. Use the core Workplane methods to get at the objects that were created.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Each time a new Workplane object is produced during these chained calls, it has a
 | 
				
			||||||
 | 
					:attr:`~cadquery.Workplane.parent` attribute that points to the Workplane object that created it.
 | 
				
			||||||
 | 
					Several CadQuery methods search this parent chain, for example when searching for the context solid.
 | 
				
			||||||
 | 
					You can also give a Workplane object a tag, and further down your chain of calls you can refer back
 | 
				
			||||||
 | 
					to this particular object using its tag.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The Context Solid
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Most of the time, you are building a single object, and adding features to that single object.  CadQuery watches
 | 
				
			||||||
 | 
					your operations, and defines the first solid object created as the 'context solid'.  After that, any features
 | 
				
			||||||
 | 
					you create are automatically combined (unless you specify otherwise) with that solid.  This happens even if the
 | 
				
			||||||
 | 
					solid was created a long way up in the stack.  For example::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Workplane("XY").box(1, 2, 3).faces(">Z").circle(0.25).extrude(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Will create a 1x2x3 box, with a cylindrical boss extending from the top face.  It was not necessary to manually
 | 
				
			||||||
 | 
					combine the cylinder created by extruding the circle with the box, because the default behavior for extrude is
 | 
				
			||||||
 | 
					to combine the result with the context solid. The hole() method works similarly -- CadQuery presumes that you want
 | 
				
			||||||
 | 
					to subtract the hole from the context solid.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want to avoid this, you can specify ``combine=False``, and CadQuery will create the solid separately.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Iteration
 | 
				
			||||||
 | 
					---------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CAD models often have repeated geometry, and its really annoying to resort to for loops to construct features.
 | 
				
			||||||
 | 
					Many CadQuery methods operate automatically on each element on the stack, so that you don't have to write loops.
 | 
				
			||||||
 | 
					For example, this::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Workplane("XY").box(1, 2, 3).faces(">Z").vertices().circle(0.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Will actually create 4 circles, because ``vertices()`` selects 4 vertices of a rectangular face, and the ``circle()`` method
 | 
				
			||||||
 | 
					iterates on each member of the stack.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is really useful to remember when you author your own plugins. :py:meth:`cadquery.Workplane.each` is useful for this purpose.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Assemblies
 | 
					Assemblies
 | 
				
			||||||
----------
 | 
					----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										94
									
								
								doc/vis.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								doc/vis.rst
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					.. _vis:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					===========================
 | 
				
			||||||
 | 
					Visualization
 | 
				
			||||||
 | 
					===========================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pure Python
 | 
				
			||||||
 | 
					===========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Since version 2.4 CadQuery supports visualization without any external tools. Those facilities are based on the VTK library
 | 
				
			||||||
 | 
					and are not tied to any external tool.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from cadquery import *
 | 
				
			||||||
 | 
					    from cadquery.vis import show
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    w = Workplane().sphere(1).split(keepBottom=True) - Workplane().sphere(0.5)
 | 
				
			||||||
 | 
					    r = w.faces('>Z').fillet(0.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Show the result
 | 
				
			||||||
 | 
					    show(r, alpha=0.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..  image:: _static/show.PNG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					One can visualize objects of type :class:`~cadquery.Workplane`, :class:`~cadquery.Sketch`, :class:`~cadquery.Assembly`, :class:`~cadquery.Shape`,
 | 
				
			||||||
 | 
					:class:`~cadquery.Vector`, :class:`~cadquery.Location` and lists thereof.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   from cadquery import *
 | 
				
			||||||
 | 
					   from cadquery.occ_impl.shapes import *
 | 
				
			||||||
 | 
					   from cadquery.vis import show
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   w = Workplane().sphere(0.5).split(keepTop=True)
 | 
				
			||||||
 | 
					   sk = Sketch().rect(1.5, 1.5)
 | 
				
			||||||
 | 
					   sh = torus(5, 0.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   r = rect(2, 2)
 | 
				
			||||||
 | 
					   c = circle(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   N = 50
 | 
				
			||||||
 | 
					   params = [i/N for i in range(N)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   vecs = r.positions(params)
 | 
				
			||||||
 | 
					   locs = c.locations(params)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   # Render the solid
 | 
				
			||||||
 | 
					   show(w, sk, sh, vecs, locs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..  image:: _static/show_demo.PNG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Additionally it is possible to integrate with other libraries using VTK and display any `vtkProp` object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from cadquery.vis import show
 | 
				
			||||||
 | 
					    from cadquery.occ_impl.shapes import torus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from vtkmodules.vtkRenderingAnnotation import vtkAnnotatedCubeActor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a = vtkAnnotatedCubeActor()
 | 
				
			||||||
 | 
					    t = torus(5,1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    show(t, a)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..  image:: _static/show_vtk.PNG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that currently the show function is blocking.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Jupyter/JupterLab
 | 
				
			||||||
 | 
					=================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There is also more limited support for displaying :class:`~cadquery.Workplane`, :class:`~cadquery.Sketch`, :class:`~cadquery.Assembly`,
 | 
				
			||||||
 | 
					:class:`~cadquery.Shape` in Jupyter and JupyterLab. This functionality is implemented using VTK.js.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from cadquery import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Workplane().sphere(1).split(keepTop=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..  image:: _static/show_jupyter.PNG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,12 +1,12 @@
 | 
				
			|||||||
from cadquery import Workplane, Assembly, Sketch, Location, Vector, Location
 | 
					from cadquery import Workplane, Assembly, Sketch, Location, Vector
 | 
				
			||||||
from cadquery.vis import show, show_object
 | 
					from cadquery.vis import show, show_object, vtkAxesActor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cadquery.occ_impl.exporters.assembly as assembly
 | 
					 | 
				
			||||||
import cadquery.vis as vis
 | 
					import cadquery.vis as vis
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from vtkmodules.vtkRenderingCore import vtkRenderWindow, vtkRenderWindowInteractor
 | 
					from vtkmodules.vtkRenderingCore import vtkRenderWindow, vtkRenderWindowInteractor
 | 
				
			||||||
 | 
					from vtkmodules.vtkRenderingAnnotation import vtkAnnotatedCubeActor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pytest import fixture, raises
 | 
					from pytest import fixture
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@fixture
 | 
					@fixture
 | 
				
			||||||
@ -59,7 +59,7 @@ def test_show(wp, assy, sk, monkeypatch):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # use some dummy vtk objects
 | 
					    # use some dummy vtk objects
 | 
				
			||||||
    monkeypatch.setattr(vis, "vtkRenderWindowInteractor", FakeInteractor)
 | 
					    monkeypatch.setattr(vis, "vtkRenderWindowInteractor", FakeInteractor)
 | 
				
			||||||
    monkeypatch.setattr(assembly, "vtkRenderWindow", FakeWindow)
 | 
					    monkeypatch.setattr(vis, "vtkRenderWindow", FakeWindow)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # simple smoke test
 | 
					    # simple smoke test
 | 
				
			||||||
    show(wp)
 | 
					    show(wp)
 | 
				
			||||||
@ -89,3 +89,6 @@ def test_show(wp, assy, sk, monkeypatch):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    # for now a workaround to be compatible with more complicated CQ-editor invocations
 | 
					    # for now a workaround to be compatible with more complicated CQ-editor invocations
 | 
				
			||||||
    show(1)
 | 
					    show(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # show a raw vtkProp
 | 
				
			||||||
 | 
					    show(vtkAxesActor(), [vtkAnnotatedCubeActor()])
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user