diff --git a/.gitignore b/.gitignore index 3a1b007..6783eb7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ doc/_build/* dist/* .idea/* -cadquery.egg-info \ No newline at end of file +cadquery.egg-info +target/* diff --git a/build-docs.sh b/build-docs.sh new file mode 100755 index 0000000..bef2f78 --- /dev/null +++ b/build-docs.sh @@ -0,0 +1,2 @@ +#!/bin/sh +sphinx-build -b html doc target/docs \ No newline at end of file diff --git a/cadquery.egg-info/PKG-INFO b/cadquery.egg-info/PKG-INFO index ad87534..a12e07e 100644 --- a/cadquery.egg-info/PKG-INFO +++ b/cadquery.egg-info/PKG-INFO @@ -32,6 +32,14 @@ Description: What is a CadQuery? It has tons of awesome features like integration with FreeCAD so you can see your objects, code-autocompletion, an examples bundle, and script saving/loading. Its definitely the best way to kick the tires! + + Recently Added Features + ======================================== + + * 12/5/14 -- New FreeCAD/CadQuery Module! https://github.com/jmwright/cadquery-freecad-module + * 10/25/14 -- Added Revolution Feature ( thanks Jeremy ! ) + + Why CadQuery instead of OpenSCAD? ======================================== diff --git a/cadquery.egg-info/SOURCES.txt b/cadquery.egg-info/SOURCES.txt index 2507a90..06a2837 100644 --- a/cadquery.egg-info/SOURCES.txt +++ b/cadquery.egg-info/SOURCES.txt @@ -10,7 +10,6 @@ cadquery.egg-info/PKG-INFO cadquery.egg-info/SOURCES.txt cadquery.egg-info/dependency_links.txt cadquery.egg-info/not-zip-safe -cadquery.egg-info/pbr.json cadquery.egg-info/top_level.txt cadquery/contrib/__init__.py cadquery/freecad_impl/__init__.py diff --git a/cadquery/CQ.py b/cadquery/CQ.py index 2ba78a5..59a1180 100644 --- a/cadquery/CQ.py +++ b/cadquery/CQ.py @@ -1735,8 +1735,7 @@ class Workplane(CQ): """ Evaluates the provided function at each point on the stack (ie, eachpoint) and then cuts the result from the context solid. - :param fcn: a function suitable for use in the eachpoint method: ie, that accepts - a vector + :param fcn: a function suitable for use in the eachpoint method: ie, that accepts a vector :param useLocalCoords: same as for :py:meth:`eachpoint` :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape :return: a CQ object that contains the resulting solid diff --git a/cadquery/freecad_impl/geom.py b/cadquery/freecad_impl/geom.py index 2ae7525..6d54ad8 100644 --- a/cadquery/freecad_impl/geom.py +++ b/cadquery/freecad_impl/geom.py @@ -363,7 +363,8 @@ class Plane(object): self._calcTransforms() def setOrigin2d(self, x, y): - """Set a new origin in the plane itself + """ + Set a new origin in the plane itself Set a new origin in the plane itself. The plane's orientation and xDrection are unaffected. @@ -377,6 +378,7 @@ class Plane(object): p = Plane.XY() p.setOrigin2d(2, 2) p.setOrigin2d(2, 2) + results in a plane with its origin at (x, y) = (4, 4) in global coordinates. Both operations were relative to local coordinates of the plane. diff --git a/cadquery/freecad_impl/shapes.py b/cadquery/freecad_impl/shapes.py index d0d14bb..94658f6 100644 --- a/cadquery/freecad_impl/shapes.py +++ b/cadquery/freecad_impl/shapes.py @@ -349,6 +349,10 @@ class Shape(object): class Vertex(Shape): + """ + A Single Point in Space + """ + def __init__(self, obj, forConstruction=False): """ Create a vertex from a FreeCAD Vertex @@ -373,6 +377,10 @@ class Vertex(Shape): class Edge(Shape): + """ + A trimmed curve that represents the border of a face + """ + def __init__(self, obj): """ An Edge @@ -479,6 +487,10 @@ class Edge(Shape): class Wire(Shape): + """ + A series of connected, ordered Edges, that typically bounds a Face + """ + def __init__(self, obj): """ A Wire @@ -545,10 +557,11 @@ class Wire(Shape): return self class Face(Shape): + """ + a bounded surface that represents part of the boundary of a solid + """ def __init__(self, obj): - """ - A Face - """ + self.wrapped = obj self.facetypes = { @@ -611,6 +624,9 @@ class Face(Shape): class Shell(Shape): + """ + the outer boundary of a surface + """ def __init__(self, wrapped): """ A Shell @@ -626,6 +642,9 @@ class Shell(Shape): class Solid(Shape): + """ + a single solid + """ def __init__(self, obj): """ A Solid @@ -649,36 +668,36 @@ class Solid(Shape): @classmethod def makeBox(cls, length, width, height, pnt=Vector(0, 0, 0), dir=Vector(0, 0, 1)): """ - makeBox(length,width,height,[pnt,dir]) -- Make a box located\nin pnt with the d - imensions (length,width,height)\nBy default pnt=Vector(0,0,0) and dir=Vector(0,0,1)' + makeBox(length,width,height,[pnt,dir]) -- Make a box located\nin pnt with the d + imensions (length,width,height)\nBy default pnt=Vector(0,0,0) and dir=Vector(0,0,1)' """ return Shape.cast(FreeCADPart.makeBox(length, width, height, pnt.wrapped, dir.wrapped)) @classmethod def makeCone(cls, radius1, radius2, height, pnt=Vector(0, 0, 0), dir=Vector(0, 0, 1), angleDegrees=360): """ - 'makeCone(radius1,radius2,height,[pnt,dir,angle]) -- - Make a cone with given radii and height\nBy default pnt=Vector(0,0,0), - dir=Vector(0,0,1) and angle=360' + 'makeCone(radius1,radius2,height,[pnt,dir,angle]) -- + Make a cone with given radii and height\nBy default pnt=Vector(0,0,0), + dir=Vector(0,0,1) and angle=360' """ return Shape.cast(FreeCADPart.makeCone(radius1, radius2, height, pnt.wrapped, dir.wrapped, angleDegrees)) @classmethod def makeCylinder(cls, radius, height, pnt=Vector(0, 0, 0), dir=Vector(0, 0, 1), angleDegrees=360): """ - makeCylinder(radius,height,[pnt,dir,angle]) -- - Make a cylinder with a given radius and height - By default pnt=Vector(0,0,0),dir=Vector(0,0,1) and angle=360' + makeCylinder(radius,height,[pnt,dir,angle]) -- + Make a cylinder with a given radius and height + By default pnt=Vector(0,0,0),dir=Vector(0,0,1) and angle=360' """ return Shape.cast(FreeCADPart.makeCylinder(radius, height, pnt.wrapped, dir.wrapped, angleDegrees)) @classmethod def makeTorus(cls, radius1, radius2, pnt=None, dir=None, angleDegrees1=None, angleDegrees2=None): """ - makeTorus(radius1,radius2,[pnt,dir,angle1,angle2,angle]) -- - Make a torus with agiven radii and angles - By default pnt=Vector(0,0,0),dir=Vector(0,0,1),angle1=0 - ,angle1=360 and angle=360' + makeTorus(radius1,radius2,[pnt,dir,angle1,angle2,angle]) -- + Make a torus with agiven radii and angles + By default pnt=Vector(0,0,0),dir=Vector(0,0,1),angle1=0 + ,angle1=360 and angle=360' """ return Shape.cast(FreeCADPart.makeTorus(radius1, radius2, pnt, dir, angleDegrees1, angleDegrees2)) @@ -930,6 +949,10 @@ class Solid(Shape): class Compound(Shape): + """ + a collection of disconnected solids + """ + def __init__(self, obj): """ An Edge diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index ed35aa2..0000000 --- a/doc/Makefile +++ /dev/null @@ -1,153 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/CadQuery.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/CadQuery.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/CadQuery" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/CadQuery" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/doc/README b/doc/README index aa3cf52..b89ab3d 100644 --- a/doc/README +++ b/doc/README @@ -1 +1,2 @@ -This documentation should be generated with sphinxdoc +This documentation should be generated with sphinxdoc. +see ../build-docs.sh diff --git a/doc/_static/block.png b/doc/_static/block.png index 1ab7ec7..d3e63a6 100644 Binary files a/doc/_static/block.png and b/doc/_static/block.png differ diff --git a/cadquery/cheatsheet/cadquery_cheatsheet.html b/doc/_static/cadquery_cheatsheet.html similarity index 100% rename from cadquery/cheatsheet/cadquery_cheatsheet.html rename to doc/_static/cadquery_cheatsheet.html diff --git a/doc/_static/cqlogo.png b/doc/_static/cqlogo.png new file mode 100644 index 0000000..529ffef Binary files /dev/null and b/doc/_static/cqlogo.png differ diff --git a/doc/_static/pillowblock.png b/doc/_static/pillowblock.png new file mode 100644 index 0000000..00f5c62 Binary files /dev/null and b/doc/_static/pillowblock.png differ diff --git a/doc/_static/quickstart/000.png b/doc/_static/quickstart/000.png new file mode 100644 index 0000000..6b03524 Binary files /dev/null and b/doc/_static/quickstart/000.png differ diff --git a/doc/_static/quickstart/001.png b/doc/_static/quickstart/001.png new file mode 100644 index 0000000..76d8796 Binary files /dev/null and b/doc/_static/quickstart/001.png differ diff --git a/doc/_static/quickstart/002.png b/doc/_static/quickstart/002.png new file mode 100644 index 0000000..8b8ab36 Binary files /dev/null and b/doc/_static/quickstart/002.png differ diff --git a/doc/_static/quickstart/003.png b/doc/_static/quickstart/003.png new file mode 100644 index 0000000..8aaa128 Binary files /dev/null and b/doc/_static/quickstart/003.png differ diff --git a/doc/_static/quickstart/004.png b/doc/_static/quickstart/004.png new file mode 100644 index 0000000..880ffd0 Binary files /dev/null and b/doc/_static/quickstart/004.png differ diff --git a/doc/_static/quickstart/005.png b/doc/_static/quickstart/005.png new file mode 100644 index 0000000..0dbbb12 Binary files /dev/null and b/doc/_static/quickstart/005.png differ diff --git a/doc/_static/simpleblock.png b/doc/_static/simpleblock.png new file mode 100644 index 0000000..5ac6905 Binary files /dev/null and b/doc/_static/simpleblock.png differ diff --git a/doc/apireference.rst b/doc/apireference.rst index 83108b6..cb58f3b 100644 --- a/doc/apireference.rst +++ b/doc/apireference.rst @@ -4,34 +4,30 @@ CadQuery API Reference *********************** +The CadQuery API is made up of 3 main objects: +* **CQ** - An object that wraps a topological entity. +* **Workplane** -- A subclass of CQ, that applies in a 2-D modelling context. +* **Selector** -- Filter and select things + +This page lists methods of these objects grouped by **functional area** .. seealso:: This page lists api methods grouped by functional area. Use :ref:`classreference` to see methods alphabetically by class. -Primary Objects ----------------- - -The CadQuery API is made up of 3 main objects: - -* **CQ** - Basic Selection, and 3d operations -* **Workplane** -- Draw in 2-d to make 3d features -* **Selector** -- Filter and select things - -The sections below list methods of these objects grouped by **functional area** +.. module:: cadquery Initialization ---------------- -.. automodule:: cadquery +.. currentmodule:: cadquery.CQ Creating new workplanes and object chains .. autosummary:: CQ Workplane - CQ.workplane .. _2dOperations: @@ -39,7 +35,9 @@ Creating new workplanes and object chains 2-d Operations ----------------- -Creating 2-d constructs that can be used to create 3 d features +Creating 2-d constructs that can be used to create 3 d features. + +All 2-d operations require a **Workplane** object to be created. .. autosummary:: Workplane.center @@ -67,7 +65,9 @@ Creating 2-d constructs that can be used to create 3 d features 3-d Operations ----------------- -Methods that create 3d features +Some 3-d operations also require an active 2-d workplane, but some do not. + +3-d operations that require a 2-d workplane to be active: .. autosummary:: Workplane.cboreHole @@ -80,12 +80,24 @@ Methods that create 3d features Workplane.box Workplane.union Workplane.combine + +3-d operations that do NOT require a 2-d workplane to be active: + +.. autosummary:: CQ.shell CQ.fillet CQ.split + CQ.rotate CQ.rotateAboutCenter CQ.translate +File Management and Export +--------------------------------- + +.. autosummary:: + CQ.toSvg + CQ.exportSvg + Iteration Methods ------------------ @@ -99,8 +111,8 @@ Methods that allow iteration over the stack or objects .. _stackMethods: -Stack Methods ------------------ +Stack and Selector Methods +------------------------------ CadQuery methods that operate on the stack @@ -127,14 +139,24 @@ CadQuery methods that operate on the stack Selectors ------------------------ -Objects that filter and select CAD objects +Objects that filter and select CAD objects. Selectors are used to select existing geometry +as a basis for futher operations. +.. currentmodule:: cadquery.selectors .. autosummary:: - NearestToPointSelector - ParallelDirSelector - DirectionSelector - PerpendicularDirSelector - TypeSelector - DirectionMinMaxSelector - StringSyntaxSelector + + NearestToPointSelector + BoxSelector + BaseDirSelector + ParallelDirSelector + DirectionSelector + PerpendicularDirSelector + TypeSelector + DirectionMinMaxSelector + BinarySelector + AndSelector + SumSelector + SubtractSelector + InverseSelector + StringSyntaxSelector \ No newline at end of file diff --git a/doc/cadquerybasics.rst b/doc/cadquerybasics.rst deleted file mode 100644 index 5b8b169..0000000 --- a/doc/cadquerybasics.rst +++ /dev/null @@ -1,243 +0,0 @@ -.. _cadquerybasics: - -.. automodule:: cadquery - -************************* -Introduction to CadQuery -************************* - -This page describes basic CadQuery concepts and goals. CadQuery is still under development, but already offers a lot. - -====================== -Goals and Principles -====================== - - -Principle 1: Intuitive Construction -==================================== - -CadQuery aims to make building models using python scripting easy and intuitive. -CadQuery strives to allow scripts to read roughly as a human would describe an object verbally. - -For example, consider this object: - -.. image:: _static/quickstart.png - -A human would describe this as: - - "A block 80mm square x 30mm thick , with countersunk holes for M2 socket head cap screws - at the corners, and a circular pocket 22mm in diameter in the middle for a bearing" - -The goal is to have the CadQuery script that produces this object be as close as possible to the english phrase -a human would use. - - -Principle 2: Capture Design Intent -==================================== - -The features that are **not** part of the part description above are just as important as those that are. For example, most -humans will assume that: - - * The countersunk holes are spaced a uniform distance from the edges - * The circular pocket is in the center of the block, no matter how big the block is - -If you have experience with 3D CAD systems, you also know that there is a key design intent built into this object. -After the base block is created, how the hole is located is key. If it is located from one edge, changing the block -size will have a different affect than if the hole is located from the center. - -Many scripting langauges to not provide a way to capture design intent-- because they require that you always work in -global coordinates. CadQuery is different-- you can locate features relative to others in a relative way-- preserving -the design intent just like a human would when creating a drawing or building an object. - -In fact, though many people know how to use 3D CAD systems, few understand how important the way that an object is built -impact its maintainability and resiliency to design changes. - - -Principle 3: Plugins as first class citizens -============================================ - -Any system for building 3D models will evolve to contain an immense number of libraries and feature builders. It is -important that these can be seamlessly included into the core and used alongside the built in libraries. Plugins -should be easy to install and familiar to use. - - -Principle 4: CAD models as source code makes sense -================================================================== - -It is surprising that the world of 3D CAD is primarily dominated by systems that create opaque binary files. -Just like the world of software, CAD models are very complex. - -CAD models have many things in common with software, and would benefit greatly from the use of tools that are standard -in the software industry, such as: - - 1. Easily re-using features between objects - 2. Storing objects using version control systems - 3. Computing the differences between objects by using source control tools - 4. Share objects on the internet - 5. Automate testing and generation by allowing objects to be built from within libraries - -CadQuery is designed to make 3D content creation easy enough that the above benefits can be attained without more work -than using existing 'opaque', 'point and click' solutions. - -====================== -3D Topology Primer -====================== - -Before talking about CadQuery, it makes sense to talk a little about 3D CAD Topology. CadQuery is based upon the -OpenCascade kernel, which is uses Boundary Representations ( BREP ) for objects. This just means that objects -are defined by their enclosing surfaces. - -When working in a BREP system, these fundamental constructs exist to define a shape ( working up the food chain): - - :vertex: a single point in space - :edge: a connection between two or more vertices along a particular path ( called a curve ) - :wire: a collection of edges that are connected together. - :face: a set of edges or wires that enclose a surface - :shell: a collection of faces that are connected together along some of their edges - :solid: a shell that has a closed interior - :compound: a collection of solids - -When using CadQuery, all of these objects are created, hopefully with the least possible work. In the actual CAD -kernel, there are another set of Geometrical constructs involved as well. For example, an arc-shaped edge will -hold a reference to an underlying curve that is a full cricle, and each linear edge holds underneath it the equation -for a line. CadQuery shields you from these constructs. - -====================== -CadQuery Concepts -====================== - -CadQuery provides functions in several key areas. As you would expect, many are devoted to easy creation of -2D and 3D features. But just as many, if not more, are for navigating and selecting objects. - - * CQ, the CadQuery object - * Workplanes - * Selection - * 2D Construction - * 3D Construction - * construction geometry - * easy iteration - - -CQ, the CadQuery Object -======================== - -The CadQuery object wraps a BREP feature, and provides functionality around it. Typical examples include rotating, -transforming, combining objects, and creating workplanes. - -See :ref:`apireference` to learn more. - - -Workplanes -====================== - -Workplanes represent a plane in space, from which other features can be located. They have a center point and a local -coordinate system. - -The most common way to create a workplane is to locate one on the face of a solid. You can also create new workplanes -in space, 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 build 3D features based on local coordinates. This makes scripts much easier to create and maintain. - -See :py:class:`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 primatives such as boxes, spheres, wedges, and cylinders 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, for use to define new features. As an example, you might -extrude a box, and then select the top face as the location for a new feture. 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, were you to build an object using a conventional CAD system. - -You can learn more about selectors :ref:`selectors` - - -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 a 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 CadQuery object with the result of that operations. Each CadQuery -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:: - - CQ(someObject).faces(">Z").first().vertices() - -returns a CadQuery object that contains all of the vertices on highest face of someObject. But you can always move -backwards in the stack to get the face as well:: - - CQ(someObject).faces(">Z").first().vertices().end() #returns the same as CQ(someObject).faces(">Z").first() - -You can browse stack access methods here :ref:`stackMethods` - - -Chaining -====================== - -All CadQuery methods return another CadQuery object, so that you can chain the methods together fluently. Use -the core CQ methods to get at the objects that were created. - - -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() - -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 specified 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:`Workplane.each` is useful for this purpose. diff --git a/doc/classreference.rst b/doc/classreference.rst index d86fcea..423af35 100644 --- a/doc/classreference.rst +++ b/doc/classreference.rst @@ -1,7 +1,7 @@ .. _classreference: ************************* -CadQuery Class Reference +CadQuery Class Summary ************************* This page documents all of the methods and functions of the CadQuery classes, organized alphabatically. @@ -10,120 +10,80 @@ This page documents all of the methods and functions of the CadQuery classes, or For a listing organized by functional area, see the :ref:`apireference` -.. automodule:: cadquery +.. module:: cadquery Core Classes --------------------- +.. currentmodule:: cadquery.CQ .. autosummary:: + CQ - Plane Workplane -Primitives ------------------ +Topological Classes +---------------------- +.. currentmodule:: cadquery.freecad_impl.shapes .. autosummary:: - Plane - Vector - Solid - Shell - Wire - Edge + Shape Vertex - - - -Selectors ---------------------- - -.. autosummary:: - NearestToPointSelector - ParallelDirSelector - DirectionSelector - PerpendicularDirSelector - TypeSelector - DirectionMinMaxSelector - StringSyntaxSelector + Edge + Wire + Face + Shell + Solid + Compound Geometry Classes ------------------ -.. autoclass:: Vector - :members: +.. currentmodule:: cadquery.freecad_impl.geom +.. autosummary:: -.. autoclass:: Plane - :members: + Vector + Matrix + Plane -Shape Base Class -------------------- - -All objects inherit from Shape, which as basic manipulation methods: - -.. autoclass:: Shape - :members: - -Primitive Classes --------------------- - -.. autoclass:: Solid - :members: - - -.. autoclass:: Shell - :members: - - -.. autoclass:: Wire - :members: - - -.. autoclass:: Edge - :members: - - -.. autoclass:: Vertex - :members: - - -Core Classes ------------------------- - -.. autoclass:: CQ - :members: - -.. autoclass:: Plane - :members: - -.. autoclass:: Workplane - :members: - :inherited-members: - - Selector Classes ------------------------- - -.. autoclass:: Selector +--------------------- + +.. currentmodule:: cadquery.selectors +.. autosummary:: + + Selector + NearestToPointSelector + BoxSelector + BaseDirSelector + ParallelDirSelector + DirectionSelector + PerpendicularDirSelector + TypeSelector + DirectionMinMaxSelector + BinarySelector + AndSelector + SumSelector + SubtractSelector + InverseSelector + StringSyntaxSelector + +.. currentmodule:: cadquery + +Class Details +--------------- + +.. autoclass:: cadquery.CQ.CQ :members: -.. autoclass:: NearestToPointSelector +.. autoclass:: cadquery.CQ.Workplane :members: -.. autoclass:: ParallelDirSelector +.. automodule:: cadquery.selectors :members: -.. autoclass:: DirectionSelector +.. automodule:: cadquery.freecad_impl.geom :members: -.. autoclass:: PerpendicularDirSelector +.. automodule:: cadquery.freecad_impl.shapes :members: - -.. autoclass:: TypeSelector - :members: - -.. autoclass:: DirectionMinMaxSelector - :members: - -.. autoclass:: StringSyntaxSelector - :members: \ No newline at end of file diff --git a/doc/conf.py b/doc/conf.py index d0ba453..da7610a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -13,8 +13,8 @@ import sys, os import os.path -print "working path is %s" % os.getcwd() -sys.path.append("..") +#print "working path is %s" % os.getcwd() +#sys.path.append("../cadquery") import cadquery #settings._target = None @@ -55,9 +55,9 @@ copyright = u'Parametric Products Intellectual Holdings LLC, All Rights Reserved # built documents. # # The short X.Y version. -version = '0.1' +version = '0.3' # The full version, including alpha/beta/rc tags. -release = '0.1' +release = '0.3.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -99,7 +99,8 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. #html_theme = 'timlinux-linfiniti-sphinx' -html_theme = 'pparts' +html_theme = 'sphinx_rtd_theme' + # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -136,14 +137,14 @@ html_theme = 'pparts' # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -html_title = "Documentation" +html_title = "CadQuery Documentation" # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = "logo.png" +html_logo = "_static/cqlogo.png" # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -261,7 +262,7 @@ man_pages = [ # dir menu entry, description, category) texinfo_documents = [ ('index', 'CadQuery', u'CadQuery Documentation', - u'David Cowden', 'CadQuery', 'One line description of project.', + u'David Cowden', 'CadQuery', 'A Fluent CAD api', 'Miscellaneous'), ] diff --git a/doc/designprinciples.rst b/doc/designprinciples.rst new file mode 100644 index 0000000..763f1e3 --- /dev/null +++ b/doc/designprinciples.rst @@ -0,0 +1,75 @@ +.. _designprinciples: + +.. automodule:: cadquery + +=========================== +CadQuery Design Principles +=========================== + + +Principle 1: Intuitive Construction +==================================== + +CadQuery aims to make building models using python scripting easy and intuitive. +CadQuery strives to allow scripts to read roughly as a human would describe an object verbally. + +For example, consider this object: + +.. image:: _static/quickstart.png + +A human would describe this as: + + "A block 80mm square x 30mm thick , with countersunk holes for M2 socket head cap screws + at the corners, and a circular pocket 22mm in diameter in the middle for a bearing" + +The goal is to have the CadQuery script that produces this object be as close as possible to the english phrase +a human would use. + + +Principle 2: Capture Design Intent +==================================== + +The features that are **not** part of the part description above are just as important as those that are. For example, most +humans will assume that: + + * The countersunk holes are spaced a uniform distance from the edges + * The circular pocket is in the center of the block, no matter how big the block is + +If you have experience with 3D CAD systems, you also know that there is a key design intent built into this object. +After the base block is created, how the hole is located is key. If it is located from one edge, changing the block +size will have a different affect than if the hole is located from the center. + +Many scripting langauges to not provide a way to capture design intent-- because they require that you always work in +global coordinates. CadQuery is different-- you can locate features relative to others in a relative way-- preserving +the design intent just like a human would when creating a drawing or building an object. + +In fact, though many people know how to use 3D CAD systems, few understand how important the way that an object is built +impact its maintainability and resiliency to design changes. + + +Principle 3: Plugins as first class citizens +============================================ + +Any system for building 3D models will evolve to contain an immense number of libraries and feature builders. It is +important that these can be seamlessly included into the core and used alongside the built in libraries. Plugins +should be easy to install and familiar to use. + + +Principle 4: CAD models as source code makes sense +================================================================== + +It is surprising that the world of 3D CAD is primarily dominated by systems that create opaque binary files. +Just like the world of software, CAD models are very complex. + +CAD models have many things in common with software, and would benefit greatly from the use of tools that are standard +in the software industry, such as: + + 1. Easily re-using features between objects + 2. Storing objects using version control systems + 3. Computing the differences between objects by using source control tools + 4. Share objects on the internet + 5. Automate testing and generation by allowing objects to be built from within libraries + +CadQuery is designed to make 3D content creation easy enough that the above benefits can be attained without more work +than using existing 'opaque', 'point and click' solutions. + diff --git a/doc/examples.rst b/doc/examples.rst index d4461ad..2f97825 100644 --- a/doc/examples.rst +++ b/doc/examples.rst @@ -23,11 +23,14 @@ Items introduced in the example are marked with a **!** 2. add the line 'return result' at the end. The samples below are autogenerated, but they use a different syntax than the models on the website need to be. +.. note:: + + We strongly recommend installing FreeCAD, and the `cadquery-freecad-module `_, + so that you can work along with these examples interactively. See :ref:`installation` for more info. + .. warning:: * You have to have an svg capable browser to view these! - * For brevity, these examples do not include the MetaData and Header sections required for a - fully functional parametric part. See the :ref:`quickstart` for a guide that includes those portions .. contents:: List of Examples :backlinks: entry @@ -515,6 +518,22 @@ Here we fillet all of the edges of a simple plate. * :py:meth:`Workplane.edges` * :py:meth:`Workplane` +A Parametric Bearing Pillow Block +------------------------------------ + +Combining a few basic functions, its possible to make a very good parametric bearing pillow block, +with just a few lines of code. + +.. cq_plot:: + + (length,height,bearing_diam, thickness,padding) = ( 30.0,40.0,22.0,10.0,8.0) + + result = Workplane("XY").box(length,height,thickness).faces(">Z").workplane().hole(bearing_diam) \ + .faces(">Z").workplane() \ + .rect(length-padding,height-padding,forConstruction=True) \ + .vertices().cboreHole(2.4,4.4,2.1) + + Splitting an Object --------------------- @@ -685,4 +704,11 @@ A Parametric Enclosure * :py:meth:`Workplane.rotateAboutCenter` * :py:meth:`Workplane.cboreHole` * :py:meth:`Workplane.cskHole` - * :py:meth:`Workplane.hole` \ No newline at end of file + * :py:meth:`Workplane.hole` + + +More Examples available in cadquery-freecad-modules +---------------------------------------------------- + +If you have installed the `cadquery-freecad-module `_, +there are > 20 examples available that you can interact with diff --git a/doc/extending.rst b/doc/extending.rst index e126c06..7080f64 100644 --- a/doc/extending.rst +++ b/doc/extending.rst @@ -1,10 +1,9 @@ .. _extending: -****************** Extending CadQuery -****************** +====================== -.. automodule:: cadfile.cadutils.cadquery +.. module:: cadquery If you find that CadQuery doesnt suit your needs, you can easily extend it. CadQuery provides several extension methods: @@ -13,13 +12,9 @@ methods: * you can define your own plugins. * you can use FreeCAD script directly -Loading external Plugins ------------------------ - -You can load a plugin using the tools.loadScript(*URL*) directive in your script. Using FreeCAD Script --------------------- +----------------------- The easiest way to extend CadQuery is to simply use FreeCAD script inside of your build method. Just about any valid FreeCAD script will execute just fine. For example, this simple CadQuery script:: @@ -45,19 +40,20 @@ a lot of the complexity of the FreeCAD api. You can get the best of both worlds by wrapping your freecad script into a CadQuery plugin. -A CadQuery plugin is simply a function that is attached to the CadQuery :py:meth:`CQ` or :py:meth:`Workplane` class. +A CadQuery plugin is simply a function that is attached to the CadQuery :py:meth:`cadquery.CQ.CQ` or :py:meth:`cadquery.CQ.Workplane` class. When connected, your plugin can be used in the chain just like the built-in functions. There are a few key concepts important to understand when building a plugin The Stack -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------- Every CadQuery object has a local stack, which contains a list of items. The items on the stack will be one of these types: -* **A CadQuery SolidReference object**, which holds a reference to a FreeCAD solid -* **A FreeCAD object**, a Vertex, Edge, Wire, Face, Shell, Solid, or Compound + + * **A CadQuery SolidReference object**, which holds a reference to a FreeCAD solid + * **A FreeCAD object**, a Vertex, Edge, Wire, Face, Shell, Solid, or Compound The stack is available by using self.objects, and will always contain at least one object. @@ -68,58 +64,58 @@ The stack is available by using self.objects, and will always contain at least o Preserving the Chain -^^^^^^^^^^^^^^^^^^^^^^^^^ +----------------------- CadQuery's fluent api relies on the ability to chain calls together one after another. For this to work, you must return a valid CadQuery object as a return value. If you choose not to return a CadQuery object, -then your plugin will end the chain. Sometimes this is desired for example :py:meth:`CQ.size` +then your plugin will end the chain. Sometimes this is desired for example :py:meth:`cadquery.CQ.CQ.size` There are two ways you can safely continue the chain: 1. **return self** If you simply wish to modify the stack contents, you can simply return a reference to self. This approach is destructive, because the contents of the stack are modified, but it is also the simplest. - 2. :py:meth:`CQ.newObject` Most of the time, you will want to return a new object. Using newObject will + 2. :py:meth:`cadquery.CQ.CQ.newObject` Most of the time, you will want to return a new object. Using newObject will return a new CQ or Workplane object having the stack you specify, and will link this object to the previous one. This preserves the original object and its stack. Helper Methods -^^^^^^^^^^^^^^^^^^^^^^^^^ +----------------------- When you implement a CadQuery plugin, you are extending CadQuery's base objects. As a result, you can call any CadQuery or Workplane methods from inside of your extension. You can also call a number of internal methods that are designed to aid in plugin creation: - * :py:meth:`Workplane._pointsOnStack` returns a FreeCAD Vector ( a point ) for each item on the stack. Useful if you - are writing a plugin that you'd like to operate on all values on the stack, like :py:meth:`Workplane.circle` and + * :py:meth:`cadquery.CQ.Workplane._pointsOnStack` returns a FreeCAD Vector ( a point ) for each item on the stack. Useful if you + are writing a plugin that you'd like to operate on all values on the stack, like :py:meth:`cadquery.CQ.Workplane.circle` and most other built-ins do - * :py:meth:`Workplane._makeWireAtPoints` will invoke a factory function you supply for all points on the stack, + * :py:meth:`cadquery.CQ.Workplane._makeWireAtPoints` will invoke a factory function you supply for all points on the stack, and return a properly constructed cadquery object. This function takes care of registering wires for you and everything like that - * :py:meth:`Workplane.newObject` returns a new Workplane object with the provided stack, and with its parent set + * :py:meth:`cadquery.CQ.Workplane.newObject` returns a new Workplane object with the provided stack, and with its parent set to the current object. The preferred way to continue the chain - * :py:meth:`Workplane.findSolid` returns the first Solid found in the chain, working from the current object upwards + * :py:meth:`cadquery.CQ.Workplane.findSolid` returns the first Solid found in the chain, working from the current object upwards in the chain. commonly used when your plugin will modify an existing solid, or needs to create objects and then combine them onto the 'main' part that is in progress - * :py:meth:`Workplane._addWire` must be called if you add a wire. This allows the base class to track all the wires + * :py:meth:`cadquery.CQ.Workplane._addWire` must be called if you add a wire. This allows the base class to track all the wires that are created, so that they can be managed when extrusion occurs. - * :py:meth:`Workplane.wire` gathers up all of the edges that have been drawn ( eg, by line, vline, etc ), and + * :py:meth:`cadquery.CQ.Workplane.wire` gathers up all of the edges that have been drawn ( eg, by line, vline, etc ), and attempts to combine them into a single wire, which is returned. This should be used when your plugin creates 2-d edges, and you know it is time to collect them into a single wire. - * :py:meth:`Workplane.plane` provides a reference to the workplane, which allows you to convert between workplane + * :py:meth:`cadquery.CQ.Workplane.plane` provides a reference to the workplane, which allows you to convert between workplane coordinates and global coordinates: - * :py:meth:`Plane.toWorldCoords` will convert local coordinates to global ones - * :py:meth:`Plane.toLocalCoords` will convet from global coordinates to local coordinates + * :py:meth:`cadquery.freecad_impl.geom.Plane.toWorldCoords` will convert local coordinates to global ones + * :py:meth:`cadquery.freecad_impl.geom.Plane.toLocalCoords` will convet from global coordinates to local coordinates Coordinate Systems -^^^^^^^^^^^^^^^^^^^^^^ +----------------------- Keep in mind that the user may be using a work plane that has created a local coordinate system. Consequently, the orientation of shapes that you create are often implicitly defined by the user's workplane. @@ -129,7 +125,7 @@ inputs may be defined in terms of local coordinates. Linking in your plugin -^^^^^^^^^^^^^^^^^^^^^^^ +----------------------- Your plugin is a single method, which is attached to the main Workplane or CadQuery object. @@ -146,8 +142,17 @@ To install it, simply attach it to the CadQuery or Workplane object, like this:: That's it! +CadQueryExample Plugins +----------------------- +Some core cadquery code is intentionally written exactly like a plugin. +If you are writing your own plugins, have a look at these methods for inspiration: + + * :py:meth:`cadquery.CQ.Workplane.polygon` + * :py:meth:`cadquery.CQ.Workplane.cboreHole` + + Plugin Example -^^^^^^^^^^^^^^^ +----------------------- This ultra simple plugin makes cubes of the specified size for each stack point. @@ -172,7 +177,8 @@ This ultra simple plugin makes cubes of the specified size for each stack point. Workplane.makeCubes = makeCubes #use the plugin - result = Workplane("XY").box(6.0,8.0,0.5).faces(">Z").rect(4.0,4.0,forConstruction=True).vertices() \ + result = Workplane("XY").box(6.0,8.0,0.5).faces(">Z")\ + .rect(4.0,4.0,forConstruction=True).vertices() \ .makeCubes(1.0).combineSolids() diff --git a/doc/fileformat.rst b/doc/fileformat.rst index 13733f8..53c42fd 100644 --- a/doc/fileformat.rst +++ b/doc/fileformat.rst @@ -1,202 +1,42 @@ .. _cadquery_reference: -******************************** -ModelScript Format Reference -******************************** +CadQuery Scripts and Object Output +====================================== -ParametricParts ModelScripts define a parametric 3D model that can be executed and customized by an end user. -CadQuery scripts are pure python scripts that follow a standard format. Each script contains these main components: +CadQuery scripts are pure python scripts that follow a standard format. - :MetaData: - *(Mandatory)* Defines the attributes that describe the model, such as version and unit of measure +Each script generally has three sections: - :Parameters: - *(Optional)* Defines parameters and their default values, which can be - manipulated by users to customize the object. Parameters are defined by creating local variables - of a particular class type. Presets and groups organize parameters to make them easier to use + * Variable Assignments + * cadquery and other python code + * object exports, via the export_object() function - :build script: - *(Mandatory)* Constructs the model once parameter values are collected and the model is validated. - The script must return a solid object, or a cadquery solid +Execution Environments +----------------------- +When your script runs, the container does not know which objects you wish to yeild for output. +Further, what 'output' means is different depending on the execution environment. -The Script Life-cycle ----------------------- +Most containers supply an export_object() method that allows you to export an object. -CadQuery scripts have the following lifecycle when they are executed by a user via the web interface: +There are three execution environments: - 1. **Load Script** If it is valid, the parameters and MetaData - are loaded. A number of special objects are automatically available to your script + 1. **Native Library**. In this context, there is no execution environment. Your scripts will only generate output + when you manually invoke a method to save your object to disk, for example using the exporters library - 2. **Display Model to User** The parameters and default values are displayed to the user. - The model is rendered and displayed to the user using the default values + 1. **cadquery-freecad-module**. In this context, exporting an object means displaying it on the screen, and + registering it with FreeCAD for further manipulation. - 3. **User selects new parameter values** , either by selecting - preset combinations, or by providing values for each parameter + 2. **parametricparts.com** In this context, exporting an object means exporting it into a format chosen by the + user executing the script. - 4. **Build the model** If validation is successful, the model is re-built, and the preview window is updated - - 5. **User downloads** If the user chooses to download the model as STL, STEP, or AMF, the model is re-built - again for download. - - -A Full Example Script ----------------------- - -This script demonstrates all of the model elements available. Each is briefly introduced in the sample text, -and then described in more detail after the sample:: - - """ - Comments and Copyright Statement - """ - - # - # metadata describes your model - # - UOM = "mm" - VERSION = 1.0 - - # - # parameter definitions. Valid parameter types are FloatParam,IntParam,and BooleanParam - # each paraemter can have min and max values, a description, and a set of named preset values - # - p_diam = FloatParam(min=1.0,max=500.0,presets={'default':40.0,'small':2.0,'big':200.0},group="Basics", desc="Diameter"); - - # - # build the model based on user selected parameter values. - # Must return a FreeCAD solid before exiting. - # - def build(): - return Part.makeSphere(p_diam.value); - - -Each section of the script is described in more detail below - -Metadata ----------------- - -Model metadata is provided by setting a dictionary variable called METADATA in the script. You can provide -any metadata you choose, but only these values are currently used: - -:UOM: - The unit of measure of your model. in and mm are common values, but others are allowed. - Some model formats like AMF can accept units of measure, which streamlines the printing process. **[OPTIONAL]** - -:VERSION: - The script format version. Valid versions are established by ParametricParts, currently only version 1.0 is - valid. If omitted, the latest version is assumed. **[OPTIONAL]** - - -Other metadata fields may be added in the future. - -Parameters ----------------- - -Model parameters provide the flexibility users need to customize your model. Parameters are optional, but most -users will expect at least a couple of parameters for your model to qualify as 'parametric'. - - -Parameters can be named whatever you would like. By convention, it is common to name them *p_*, indicating -"parameter". - - -Each parameter has a particular type ( Float, Integer, Boolean ). Parameters also have optional attributes, which are -provided as keyword arguments: - -:desc: - A description of the parameter, displayed to the user if help is needed [Optional] - -:min: - The minimum value ( not applicable to Boolean ) [Optional] - -:max: - The maximum value ( not applicable to Boolean ) [Optional] - -:presets: - A dictionary containing key-value pairs. Each key is the name of a preset, and the value is the value the - parameter will take when the preset is selected by the user. - - - When a model defines presets, the user is presented with a choice of available presets in a drop-down-list. - Selecting a preset changes the values of all parameters to their associated values. - - If it exists, the special preset named 'default' will be used to populate the default values when the user - is initially presented with the model. - - When the model is built, the parameters are checked to ensure they meet the constraints. If they do not, - an error occurs. - -:group: - If provided, parameters will be grouped together when displayed to the user. Any ungrouped parameters - will display in a special group named `default`. Groups help divide a long list of parameters to make - them easier to understand. Examples might include 'basics' and 'advanced' - - -Build Method +Variable Substitution ----------------------- -The heart of your model is the build method. Your build method must be called 'build':: +When a cadquery script runs, the values of the variables assume their hard-coded values. - def build(): - return Workplane("XY").box(1,1,1) +Some execution environments, such as the `The CadQuery Freecad Module `_ + or `parametricParts.com `_ , may subsitute other values supplied by a user of your script. -Your build method use any combination of FreeCAD, python, and CadQuery to construct objects. -You must return one of two things: - - 1. A CadQuery object, or - 2. A FreeCAD object - -In your build script,you retrieve the values of the parameters by using ``.value``. - -The following modules are available when your script runs: - -Scripts Using CadQuery Syntax -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - :python syntax: - Python loops, dictionaries, lists, and other standard language structures are available. - - :math: - Python's math package is imported for you to use - - :FloatParam,IntegerParam,BooleanParam: - Parameter types used to declare parameters - - :Workplane: - The CadQuery workplane object, which is the typical starting point for most scripts - - :CQ: - The CadQuery object, in case you need to decorate a normal FreeCAD object - - :Plane: - The CadQuery Plane object, in case you need to create non-standard planes - - -.. warning:: - - Though your script is a standard python script, it does **not** run in a standard python environment. - - For security reasons, most python packages, like sys, os, import, and urllib are restricted. - - -FreeCAD Build Scripts -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -It is recommended that you use CadQuery for your model scripts-- the syntax is much shorter and more convienient. - -But if you are willing to write more code, you can get access to all of the features that the FreeCAD library provides. - -When your script executes, these FreeCAD objects are in scope as well: - - :Part: - FreeCAD.Part - :Vector: - FreeCAD.Base.Vector - :Base: - FreeCAD.Base - -**If you use a FreeCAD build script, your build method must return a FreeCAD shape object.** - -Should you choose to write your model with the lower-level FreeCAD scripts, you may find this documentation useful: - -http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=FreeCAD_API + When this happens, your script will not know the difference: variables will appear to have been initialized the same + as they had be before. diff --git a/doc/index.rst b/doc/index.rst index d93cf81..f7c1a00 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -3,29 +3,51 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -CadQuery Documentation Home +CadQuery Documentation =================================== +CadQuery is an intuitive, easy-to-use python library for building parametric 3D CAD models. It has several goals: + * Build models with scripts that are as close as possible to how you'd describe the object to a human, + using a standard, already established programming language + * Create parametric models that can be very easily customized by end users -Contents -================== + * Output high quality CAD formats like STEP and AMF in addition to traditional STL + + * Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser + +Quick Links +------------------- + +For the impatient, here's where you probably want to get started + + ==================== ============================ ========================================================== ==================== + :ref:`quickstart` :ref:`installation` `CadQuery CheatSheet <_static/cadquery_cheatsheet.html>`_ :ref:`apireference` + ==================== ============================ ========================================================== ==================== + +Table Of Contents +------------------- .. toctree:: :maxdepth: 2 intro.rst + installation.rst quickstart.rst - cadquerybasics.rst + designprinciples.rst + primer.rst + fileformat.rst examples.rst apireference.rst selectors.rst classreference.rst + extending.rst + roadmap.rst Indices and tables -================== +------------------- * :ref:`genindex` * :ref:`modindex` diff --git a/doc/installation.rst b/doc/installation.rst new file mode 100644 index 0000000..c19c2e4 --- /dev/null +++ b/doc/installation.rst @@ -0,0 +1,54 @@ +.. _installation: + +Installing CadQuery +=================================== + +CadQuery is based on `FreeCAD `_, +which is turn based on the open-source `OpenCascade `_ modelling kernel. + +Prerequisites--FreeCAD and Python 2.6 or 2.7 +---------------------------------------------- +CadQuery requires FreeCAD and Python version 2.6.x or 2.7.x *Python 3.x is NOT supported* + +Ubuntu Command Line Installation +------------------------------------------ + +On Ubuntu, you can type:: + + sudo apt-get install -y freecad freecad-doc + pip install cadquery + +Installation: Other Platforms +------------------------------------------ + + 1. Install FreeCAD using the appropriate installer for your platform, on `www.freecadweb.org `_ + 2. pip install cadquery + + +Test Your Installation +------------------------ + +If all has gone well, you can open a command line/prompt, and type:: + + $python + $import cadquery + $cadquery.Workplane('XY').box(1,2,3).toSvg() + +Adding a Nicer GUI via the cadquery-freecad-module +-------------------------------------------------------- + +If you prefer to have a GUI available, your best option is to use +the `The CadQuery Freecad Module `_. + +Simply extract cadquery-freecad-module into your FreeCAD installation. You'll end up +with a cadquery workbench that allows you to interactively run scripts, and then see the results in the FreeCAD GUI + +Zero Step Install +------------------------------------------------- + +If you would like to use cadquery with no installation all, you can +use `ParametricParts.com `_, a web-based platform that runs cadQuery scripts + +It is free, and allows running and viewing cadquery scripts in your web browser or mobile phone + + diff --git a/doc/intro.rst b/doc/intro.rst index 53eea28..b2d64fd 100644 --- a/doc/intro.rst +++ b/doc/intro.rst @@ -7,9 +7,10 @@ Introduction What is CadQuery ======================================== -CadQuery is an intuitive, easy-to-use language for building parametric 3D CAD models. It has several goals: +CadQuery is an intuitive, easy-to-use python library for building parametric 3D CAD models. It has several goals: - * Build models with scripts that are as close as possible to how you'd describe the object to a human. + * Build models with scripts that are as close as possible to how you'd describe the object to a human, + using a standard, already established programming language * Create parametric models that can be very easily customized by end users @@ -17,35 +18,49 @@ CadQuery is an intuitive, easy-to-use language for building parametric 3D CAD mo * Provide a non-proprietary, plain text model format that can be edited and executed with only a web browser +CadQuery is based on +`FreeCAD `_, +which is turn based on the open-source `OpenCascade `_ modelling kernel. -CadQuery is a Python module that provides a high-level wrapper around the -(`FreeCAD `_) python libraries. +Using CadQuery, you can build fully parametric models with a very small amount of code. For example, this simple script +produces a flat plate with a hole in the middle:: -Where does the name CadQuery come from? -======================================== + thickness = 0.5 + width=2.0 + result = Workplane("front").box(width,width,thickness).faces(">Z").hole(thickness) -CadQuery is inspired by ( `jQuery `_ ), a popular framework that -revolutionized web development involving javascript. +.. image:: _static/simpleblock.png -CadQuery is for 3D CAD what jQuery is for javascript. -If you are familiar with how jQuery works, you will probably recognize several jQuery features that CadQuery uses: +That's a bit of a dixie-cup example. But it is pretty similar to a more useful part: a parametric pillow block for a +standard 608-size ball bearing:: - * A fluent api to create clean, easy to read code + (length,height,diam, thickness,padding) = ( 30.0,40.0,22.0,10.0,8.0) - * Ability to use the library along side other python libraries + result = Workplane("XY").box(length,height,thickness).faces(">Z").workplane().hole(diam)\ + .faces(">Z").workplane() \ + .rect(length-padding,height-padding,forConstruction=True) \ + .vertices().cboreHole(2.4,4.4,2.1) - * Clear and complete documentation, with plenty of samples. +.. image:: _static/pillowblock.png + +Lots more examples are available in the :ref:`examples` + +CadQuery is a library, GUIs are separate +============================================== + +CadQuery is a library, that's intentionally designed to be usable as a GUI-less library. This enables +its use in a variety of engineering and scientific applications that create 3d models programmatically. + +If you'd like a GUI, you have a couple of options: + + * Install cadquery as a part of `The CadQuery Freecad Module `_ + * Use `ParametricParts.com `_, a web-based platform that runs cadQuery scripts -Why ParametricParts instead of OpenSCAD? +Why CadQuery instead of OpenSCAD? ============================================ -CadQuery is based on FreeCAD,which is in turn based on the OpenCascade modelling kernel. CadQuery/FreeCAD scripts -share many features with OpenSCAD, another open source, script based, parametric model generator. - -The primary advantage of OpenSCAD is the large number of model libaries that exist already. So why not simply use OpenSCAD? - -CadQuery scripts run from ParametricParts.com have several key advantages over OpenSCAD ( including the various web-based SCAD solutions): +Like OpenSCAD, CadQuery is an open-source, script based, parametric model generator. But CadQuery has several key advantages: 1. **The scripts use a standard programming language**, python, and thus can benefit from the associated infrastructure. This includes many standard libraries and IDEs @@ -62,3 +77,19 @@ CadQuery scripts run from ParametricParts.com have several key advantages over O 5. **Better Performance** CadQuery scripts can build STL, STEP, and AMF faster than OpenSCAD. +Where does the name CadQuery come from? +======================================== + +CadQuery is inspired by `jQuery `_ , a popular framework that +revolutionized web development involving javascript. + +CadQuery is for 3D CAD what jQuery is for javascript. +If you are familiar with how jQuery works, you will probably recognize several jQuery features that CadQuery uses: + + * A fluent api to create clean, easy to read code + + * Ability to use the library along side other python libraries + + * Clear and complete documentation, with plenty of samples. + + diff --git a/doc/make.bat b/doc/make.bat deleted file mode 100644 index 0217e3f..0000000 --- a/doc/make.bat +++ /dev/null @@ -1,190 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -set I18NSPHINXOPTS=%SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\CadQuery.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\CadQuery.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -:end diff --git a/doc/primer.rst b/doc/primer.rst index c10e52e..85f6d0c 100644 --- a/doc/primer.rst +++ b/doc/primer.rst @@ -1,9 +1,154 @@ .. _3d_cad_primer: -*********************** -3D CAD Primer -*********************** +.. module:: cadquery + +CadQuery Concepts +=================================== + + +3D BREP Topology Concepts +--------------------------- +Before talking about CadQuery, it makes sense to talk a little about 3D CAD Topology. CadQuery is based upon the +OpenCascade kernel, which is uses Boundary Representations ( BREP ) for objects. This just means that objects +are defined by their enclosing surfaces. + +When working in a BREP system, these fundamental constructs exist to define a shape ( working up the food chain): + + :vertex: a single point in space + :edge: a connection between two or more vertices along a particular path ( called a curve ) + :wire: a collection of edges that are connected together. + :face: a set of edges or wires that enclose a surface + :shell: a collection of faces that are connected together along some of their edges + :solid: a shell that has a closed interior + :compound: a collection of solids + +When using CadQuery, all of these objects are created, hopefully with the least possible work. In the actual CAD +kernel, there are another set of Geometrical constructs involved as well. For example, an arc-shaped edge will +hold a reference to an underlying curve that is a full cricle, and each linear edge holds underneath it the equation +for a line. CadQuery shields you from these constructs. + + +CQ, the CadQuery Object +--------------------------- + +The CadQuery object wraps a BREP feature, and provides functionality around it. Typical examples include rotating, +transforming, combining objects, and creating workplanes. + +See :ref:`apireference` to learn more. + + +Workplanes +--------------------------- + +Workplanes represent a plane in space, from which other features can be located. They have a center point and a local +coordinate system. + +The most common way to create a workplane is to locate one on the face of a solid. You can also create new workplanes +in space, 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 build 3D features based on local coordinates. This makes scripts much easier to create and maintain. + +See :py:class:`cadquery.CQ.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 primatives such as boxes, spheres, wedges, and cylinders 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, for use to define new features. As an example, you might +extrude a box, and then select the top face as the location for a new feture. 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, were you to build an object using a conventional CAD system. + +You can learn more about selectors :ref:`selectors` + + +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 a 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 CadQuery object with the result of that operations. Each CadQuery +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:: + + CQ(someObject).faces(">Z").first().vertices() + +returns a CadQuery object that contains all of the vertices on highest face of someObject. But you can always move +backwards in the stack to get the face as well:: + + CQ(someObject).faces(">Z").first().vertices().end() #returns the same as CQ(someObject).faces(">Z").first() + +You can browse stack access methods here :ref:`stackMethods` + + +Chaining +--------------------------- + +All CadQuery methods return another CadQuery object, so that you can chain the methods together fluently. Use +the core CQ methods to get at the objects that were created. + + +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() + +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 specified 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.CQ.Workplane.each` is useful for this purpose. -This section provides a basic introduction to 3D modeling. It will get you started with the basics. After that, -you may want to do some heavier reading on the subject (PUT LINKS HERE ) diff --git a/doc/primitiveref.rst b/doc/primitiveref.rst deleted file mode 100644 index 480752c..0000000 --- a/doc/primitiveref.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. _primreference: - -*********************** -Primitive Class Reference -*********************** - -.. automodule:: cadfile.cadutils.cad - - -.. autosummary:: - - Plane - Vector - Solid - Shell - Wire - Edge - Vertex - -Geometry Classes ------------------- - -.. autoclass:: Vector - :members: - -.. autoclass:: Plane - :members: - -Shape Base Class -------------------- - -All objects inherit from Shape, which as basic manipulation methods: - -.. autoclass:: Shape - :members: - -Primitive Classes --------------------- - -.. autoclass:: Solid - :members: - - -.. autoclass:: Shell - :members: - - -.. autoclass:: Wire - :members: - - -.. autoclass:: Edge - :members: - - -.. autoclass:: Vertex - :members: diff --git a/doc/quickstart.rst b/doc/quickstart.rst index ccca09f..5535ed9 100644 --- a/doc/quickstart.rst +++ b/doc/quickstart.rst @@ -7,25 +7,28 @@ CadQuery QuickStart *********************** -Want a quick glimpse of Parametric Parts ModelScripts? You're at the right place! -This quickstart will demonstrate the basics of ModelScripts using a simple example +Want a quick glimpse of what CadQuery can do? This quickstart will demonstrate the basics of cadQuery using a simple example -Prerequisites -============= +Prerequisites: FreeCAD + cadQuery-freeCAD-module in FreeCAD +============================================================== -**WebGL Capable Browser** +If you have not already done so, follow the :ref:`installation`, and to install cadquery, FreeCAD, +and the cadquery-freecad-module - CadQuery renders models in your browser using WebGL-- which is supported by most browsers *except for IE* - You can follow along without IE, but you will not be able to see the model dynamically rendered +After installation, open the CadQuery workbench: +.. image:: _static/quickstart/001.png + +You'll see that we start out with a single block. Find the cadquery Code Window, at the bottom left. + +If you want check out a couple of the examples in the CadQuery->Examples menu. What we'll accomplish -===================== +======================== -Our finished object will look like this: - -.. image:: quickstart.png +We will build a fully parametric bearing pillow block in this quickstart. Our finished object will look like this: +.. image:: _static/quickstart/000.png **We would like our block to have these features:** @@ -43,80 +46,33 @@ Hopefully our finished script will not be too much more complex than this human- Let's see how we do. -Start a new Model -================================== +Start With A single, simple Plate +====================================== -CadQuery comes with an online, interactive default model as a starting point. Lets open up that tool -`here `_ - -You should see the dynamic model creator page, which will display a sample model: - - .. image:: _static/quickstart-1.png - -Take a minute to play with this model. Here are a few things to try: - -1. Use the mouse to rotate the block -2. Play with the view controls under the image -3. change the length ( the only available parameter), - and use the preview button to re-display the updated model -4. Change the preset value to `short` -5. Edit the model script itself. Change the hard-coded width and thickness values and click 'update script' - to re-display the model. - -At this point, you should have some idea how to interact with the sample model, so lets get to work on the project. - -Modify MetaData and Parameters -============================== - -Each model has metadata that describes the model's properties. The default Unit of Measure (UOM) will work: +Lets start with a simple model that makes nothing but a rectangular block, but +with place-holders for the dimensions. Paste this into the CodeWindow: .. code-block:: python :linenos: - :emphasize-lines: 1 - UOM = "mm" + import cadquery + from Helpers import show - -Next, lets set up the parameters. Parameters are `placeholders` that users can modify separately from the script itself. -The default model has a single parameter, ``length``. Lets add a ``height`` parameter too - -.. code-block:: python - :linenos: - :emphasize-lines: 4 - - UOM = "mm" - - length = FloatParam(min=30.0,max=200.0,presets={'default':80.0,'short':30.0},desc="Length of the block") - height = FloatParam(min=30.0,max=200.0,presets={'default':60.0,'short':30.0},desc="Height of the block") + height = 60.0 + width = 80.0 thickness = 10.0 - def build(): - return Workplane("XY").box(length.value,height.value,thickness) + # make the base + result = cadquery.Workplane("XY").box(height, width, thickness) -We've set the minimum values to 30 mm, since that's about as small as it could be while having room for a bearing 22mm -in diameter. We've also set the default values to be those we'd like to start with: 80mm for the length and 60mm for the -height. + # Render the solid + show(result) -Now, modify the build script to use your width value to make the block by changing ``height`` to -``height.value`` +Press F2 to run the script. You should see Our basic base. -.. code-block:: python - :linenos: - :emphasize-lines: 3 - - ... - def build(): - return Workplane("XY").box(length.value,height.value,thickness) - -The value property always returns the ``user-adjusted`` value of the parameter. That's good enough for now. -Click "Save Changes" and you should see your 80x60x10mm base plate, like this: - - .. image:: _static/quickstart-2.png - -If you'd like to come back to this model later, the url bar links to the newly created part. - -Now lets move on and make this boring plate into a pillow block. +.. image:: _static/quickstart/002.png +Nothing special, but its a start! Add the Holes ================ @@ -127,21 +83,37 @@ This modification will do the trick: .. code-block:: python :linenos: - :emphasize-lines: 3 + :emphasize-lines: 7,11 - ... - def build(): - return Workplane("XY").box(length.value,height.value,thickness).faces(">Z").workplane().hole(22.0) + import cadquery + from Helpers import show -Rebuild your model by clicking "Save Model" at the bottom. Your block should look like this: + height = 60.0 + width = 80.0 + thickness = 10.0 + diameter = 22.0 - .. image:: _static/quickstart-3.png + # make the base + result = cadquery.Workplane("XY").box(height, width, thickness)\ + .faces(">Z").workplane().hole(diameter) + + # Render the solid + show(result) + +Rebuild your model by pressing F2. Your block should look like this: + +.. image:: _static/quickstart/003.png -The code is pretty compact, and works like this: - * :py:meth:`Workplane.faces` selects the top-most face in the Z direction, and - * :py:meth:`Workplane.workplane` begins a new workplane located on this face - * :py:meth:`Workplane.hole` drills a hole through the part 22mm in diamter +The code is pretty compact, lets step through it. + +**Line 7** adds a new parameter, diameter, for the diamter of the hole + +**Line 11**, we're adding the hole. +:py:meth:`cadquery.CQ.CQ.faces` selects the top-most face in the Z direction, and then +:py:meth:`cadquery.CQ.CQ.workplane` begins a new workplane located on this face. The center of this workplane +is located at the geometric center of the shape, which in this case is the center of the plate. +Finally, :py:meth:`cadquery.CQ.Workplane.hole` drills a hole through the part 22mm in diamter .. note:: @@ -163,60 +135,48 @@ The centers of these holes should be 4mm from the edges of the block. And, we want the block to work correctly even when the block is re-sized by the user. **Don't tell me** we'll have to repeat the steps above 8 times to get counter-bored holes? - Good news!-- we can get the job done with just two lines of code. Here's the code we need: .. code-block:: python :linenos: - :emphasize-lines: 4-5 + :emphasize-lines: 8,13-15 - ... - def build(): - return Workplane("XY").box(length.value,height.value,thickness).faces(">Z").workplane().hole(22.0) \ - .faces(">Z").workplane() \ - .rect(length.value-8.0,height.value-8.0,forConstruction=True) \ - .vertices().cboreHole(2.4,4.4,2.1) + import cadquery + from Helpers import show -You should see something like this: + height = 60.0 + width = 80.0 + thickness = 10.0 + diameter = 22.0 + padding = 12.0 - .. image:: _static/quickstart-4.png + # make the base + result = cadquery.Workplane("XY").box(height, width, thickness)\ + .faces(">Z").workplane().hole(diameter)\ + .faces(">Z").workplane() \ + .rect(height - padding,width - padding,forConstruction=True)\ + .vertices()\ + .cboreHole(2.4, 4.4, 2.1) -Lets Break that down a bit -^^^^^^^^^^^^^^^^^^^^^^^^^^ + # Render the solid + show(result) -**Line 4** selects the top-most face of the block, and creates a workplane on the top that face, which we'll use to -define the centers of the holes in the corners: +After pressing F2 to re-execute the model, you should see something like this: -.. code-block:: python - :linenos: - :emphasize-lines: 4 - - ... - def build(): - return Workplane("XY").box(length.value,height.value,thickness).faces(">Z").workplane().hole(22.0) \ - .faces(">Z").workplane() \ - .rect(length.value-8.0,width.value-8.0,forConstruction=True) \ - .vertices().cboreHole(2.4,4.4,2.1) + .. image:: _static/quickstart/004.png -**Line 5** draws a rectangle 8mm smaller than the overall length and width of the block,which we will use to -locate the corner holes: +There is quite a bit going on here, so lets break it down a bit. -.. code-block:: python - :linenos: - :emphasize-lines: 5 +**Line 8** creates a new padding parameter that decides how far the holes are from the edges of the plate. - ... - def build(): - return Workplane("XY").box(length.value,height.value,thickness).faces(">Z").workplane().hole(22.0) \ - .faces(">Z").workplane() \ - .rect(length.value-8.0,width.value-8.0,forConstruction=True) \ - .vertices().cboreHole(2.4,4.4,2.1) +**Line 13** selects the top-most face of the block, and creates a workplane on the top that face, which we'll use to +define the centers of the holes in the corners. There are a couple of things to note about this line: - 1. The :py:meth:`Workplane.rect` function draws a rectangle. **forConstruction=True** + 1. The :py:meth:`cadquery.CQ.Workplane.rect` function draws a rectangle. **forConstruction=True** tells CadQuery that this rectangle will not form a part of the solid, but we are just using it to help define some other geometry. 2. The center point of a workplane on a face is always at the center of the face, which works well here @@ -224,81 +184,71 @@ There are a couple of things to note about this line: this case, the center of the top face of the block. So this rectangle will be centered on the face -**Line 6** selects the corners of the rectangle, and makes the holes: +**Line 14** draws a rectangle 8mm smaller than the overall length and width of the block,which we will use to +locate the corner holes. We'll use the vertices ( corners ) of this rectangle to locate the holes. The rectangle's +center is at the center of the workplane, which in this case co-incides with the center of the bearing hole. -.. code-block:: python - :linenos: - :emphasize-lines: 6 +**Line 15** selects the vertices of the rectangle, which we will use for the centers of the holes. +The :py:meth:`cadquery.CQ.CQ.vertices` function selects the corners of the rectangle - ... - def build(): - return Workplane("XY").box(length.value,height.value,thickness).faces(">Z").workplane().hole(22.0) \ - .faces(">Z").workplane() \ - .rect(length.value-8.0,width.value-8.0,forConstruction=True) \ - .vertices().cboreHole(2.4,4.4,2.1) +**Line 16** uses the cboreHole function to draw the holes. +The :py:meth:`cadquery.CQ.Workplane.cboreHole` function is a handy CadQuery function that makes a counterbored hole, +like most other CadQuery functions, operate on the values on the stack. In this case, since we +selected the four vertices before calling the function, the function operates on each of the four points-- +which results in a counterbore hole at the corners. -Notes about this line: - 1. The :py:meth:`CQ.vertices` function selects the corners of the rectangle - 2. The :py:meth:`Workplane.cboreHole` function is a handy CadQuery function that makes a counterbored hole - 3. ``cboreHole``, like most other CadQuery functions, operate on the values on the stack. In this case, since - selected the four vertices before calling the function, the function operates on each of the four points-- - which results in a counterbore hole at the corners. - -Presets +Filleting =========== -Almost done. This model is pretty easy to configure, but we can make it even easier by providing users with a few -'out of the box' options to choose from. Lets provide two preset options: - - * **Small** : 30 mm x 40mm - * **Square-Medium** : 50 mm x 50mm +Almost done. Let's just round the corners of the block a bit. That's easy, we just need to select the edges +and then fillet them: We can do that using the preset dictionaries in the parameter definition: .. code-block:: python :linenos: - :emphasize-lines: 2-3 + :emphasize-lines: 16 - ... - length = FloatParam(min=10.0,max=500.0,presets={'default':100.0,'small':30.0,'square-medium':50},desc="Length of the box") - height = FloatParam(min=30.0,max=200.0,presets={'default':60.0,'small':40.0,'square-medium':50},desc="Height of the block") + import cadquery + from Helpers import show -Now save the model and have a look at the preset DDLB-- you'll see that you can easily switch between these -configurations: + height = 60.0 + width = 80.0 + thickness = 10.0 + diameter = 22.0 + padding = 12.0 - .. image:: _static/quickstart-5.png + # make the base + result = cadquery.Workplane("XY").box(height, width, thickness)\ + .faces(">Z").workplane().hole(diameter)\ + .faces(">Z").workplane() \ + .rect(height - padding, width - padding, forConstruction=True)\ + .vertices().cboreHole(2.4, 4.4, 2.1)\ + .edges("|Z").fillet(2.0) + + # Render the solid + show(result) + +On **Line 16**, we're filleting the edges using the :py:meth:`cadquery.CQ.CQ.fillet` method. +To grab the right edges, the :py:meth:`cadquery.CQ.CQ.edges` +selects all of the edges that are parallel to the Z axis ("|Z"), + +The finished product looks like this: + + .. image:: _static/quickstart/005.png Done! ============ -And... We're done! Congratulations, you just made a parametric, 3d model with 15 lines of code.Users can use this -model to generate pillow blocks in any size they would like - -For completeness, Here's a copy of the finished model: - -.. code-block:: python - :linenos: - - UOM = "mm" - - length = FloatParam(min=10.0,max=500.0,presets={'default':100.0,'small':30.0,'square-medium':50},desc="Length of the box") - height = FloatParam(min=30.0,max=200.0,presets={'default':60.0,'small':40.0,'square-medium':50},desc="Height of the block") - - width = 40.0 - thickness = 10.0 - - def build(): - return Workplane("XY").box(length.value,height.value,thickness).faces(">Z").workplane().hole(22.0) \ - .faces(">Z").workplane() \ - .rect(length.value-8.0,height.value-8.0,forConstruction=True) \ - .vertices().cboreHole(2.4,4.4,2.1) - +You just made a parametric, model that can generate pretty much any bearing pillow block +with < 20 lines of code. Want to learn more? ==================== + * Use the CadQuery->Examples menu of the cadquery workbench to explore a lot of other examples. * The :ref:`examples` contains lots of examples demonstrating cadquery features * The :ref:`apireference` is a good overview of language features grouped by function * The :ref:`classreference` is the hard-core listing of all functions available. \ No newline at end of file diff --git a/doc/restservice.rst b/doc/restservice.rst deleted file mode 100644 index 6a9139b..0000000 --- a/doc/restservice.rst +++ /dev/null @@ -1,114 +0,0 @@ -.. _buildservice: - -****************************************** -The Parametric Parts Build Service -****************************************** - - -If you have registered for an account, you can use the REST api to build models from your website or platform. -Each request to the service will construct a model in the format you choose. - - -Using the Build Service -------------------------- - -The Build Service endpoint is ``_ - -In each request, you provide four main things via either a GET or a POST : - - 1. **An API Key**, to identify yourself. - 2. **A ModelScript to build**, either by providing the entire script, or the id of a model stored on - parametricparts.com, - 3. **The type of output** you want, - 4. **The Model parameters** that should be supplied to the model. - -.. note:: - - GET or POSTs are allowed, but be aware that URLs for GET requests are limited to 4K, - so POSTs are advised if you are sending your modelScript via the URL - -The output streamed in the format you have requested. - -Errors are provided using standard HTTP error codes: - - :200: if the build is a success - :403: if the APIKey is invalid, or if your account cannot execute any more downloads - :404: if the requested model cannot be found - :50X: if there is a problem generating the model - -Build Service Parameters --------------------------- - -All parameters must be URL encoded: - - :key: - (Required) Your API Key. See :ref:`gettingakey` If you do not have one. - - :id: - (Either id or s is Required) The id of the ParametricParts.com ModelScript to build. The id is the last part of the url - when viewing the model: http://parametricparts.com/parts/. Model ids are between 7 and 9 - characters, for example '4hskpb69'. - - :s: - (Either id or s is Required) The ModelScript to build. This should be a valid parametricparts.com ModelScript. - If both id and s are provided, s takes precedence. - - :type: - (Required) ("STL" | "STEP" | "AMF" | "TJS" ). The type of output you want to receive. STL, STEP, - and AMF return the corresponding industry standard format. - TJS will return JSON content suitable for display in a Three.js scene. - - :preset: - (Optional) The name of a preset defined in the ModelScript. If omitted, other parameters are used. - If a preset is provided in addition to parameters, then the preset is applied first, and then - parameters are set afterwards. - - :: - (Optional) Remaining URL parameters are mapped onto ModelScript parameters of the same name. Each - parameter value must have the datatype corresponding to the parameter in the ModelScript. To supply multiple - parameters, send an HTTP parameter for each desired value, having name matching the name of the ModelScript - parameter, and value having the value for that parameter. If no - parameters are provided, output is generated using ModelScript defaults. - -Example --------------------------- - -This example builds STEP for a trivial model, without supplying any model parameters or presets:: - - POST https://parametricparts.com/parts/build HTTP/1.1 - key:259cd575c9a2998420ac65f21b2d6b2a - s:def+build%28%29%3A%0D%0A++++return+Part.makeBox%281%2C2%2C3%29%0D%0A++++++++ - type:AMF - - -This example selects an existing model (2qus7a32 ) on the server, and requests -preset 'short', as well as adjusting parameter 'p_length' to value 120:: - - POST https://parametricparts.com/parts/build HTTP/1.1 - key:259cd575c9a2998420ac65f21b2d6b2a - id:2qus7a32 - type:STL - preset:short - p_length:120 - - -.. _gettingakey: - -Signing Up ------------------------ - -In order to use the API, you first need to have an API key. To get one: - - 1. `Sign Up `_ for a ParametricParts account - 2. `Contact ParametricParts Support `_ to request API key access. - API keys usually require an enterprise license, but are available for free evaluation if you request access - 3. Log onto your ParametricParts account, and generate an API Key using the `API Keys `_ link. - 4. Test your api key using the api key tester `Here `_ - If the test goes well, you'll see STL output from the sample script. - -Now you are ready to make REST requests to build models. - -.. warning:: - - Make sure to keep your API Key secret, as any requests that use your key will be charged to your account. - You can disable or generate a new API Key from your account page. \ No newline at end of file diff --git a/doc/roadmap.rst b/doc/roadmap.rst index 12865d1..5e37c3d 100644 --- a/doc/roadmap.rst +++ b/doc/roadmap.rst @@ -1,8 +1,8 @@ .. _roadmap: -************************** + RoadMap: Planned Features -************************** +============================== **CadQuery is not even close to finished!!!** diff --git a/doc/selectors.rst b/doc/selectors.rst index 2f861c9..fb06ce0 100644 --- a/doc/selectors.rst +++ b/doc/selectors.rst @@ -1,21 +1,21 @@ .. _selector_reference: -************************* -CadQuery String Selectors -************************* +String Selectors Reference +============================= -.. automodule:: cadquery +.. module:: cadquery CadQuery selector strings allow filtering various types of object lists. Most commonly, Edges, Faces, and Vertices are used, but all objects types can be filtered. -String selectors are used as arguments to the various selection methods: +String selectors are simply shortcuts for using the full object equivalents. If you pass one of the +string patterns in, CadQuery will automatically use the associated selector object. - * :py:meth:`CQ.faces` - * :py:meth:`CQ.edges` - * :py:meth:`CQ.vertices` - * :py:meth:`CQ.solids` - * :py:meth:`CQ.shells` + * :py:meth:`cadquery.CQ.CQ.faces` + * :py:meth:`cadquery.CQ.CQ.edges` + * :py:meth:`cadquery.CQ.CQ.vertices` + * :py:meth:`cadquery.CQ.CQ.solids` + * :py:meth:`cadquery.CQ.CQ.shells` .. note:: @@ -42,17 +42,17 @@ of the face. The axis used in the listing below are for illustration: any axis would work similarly in each case. -========= ==================================== ====================================== ========================== -Selector Selector Class Selects # objects returned -========= ==================================== ====================================== ========================== -+Z :py:class:`DirectionSelector` Faces with normal in +z direction 0 or 1 -\|Z :py:class:`ParallelDirSelector` Faces parallel to xy plane 0..many --X :py:class:`DirectionSelector` Faces with normal in neg x direction 0..many -#Z :py:class:`PerpendicularDirSelector` Faces perpendicular to z direction 0..many -%Plane :py:class:`TypeSelector` Faces of type plane 0..many ->Y :py:class:`DirectionMinMaxSelector` Face farthest in the positive y dir 0 or 1 -Y Face farthest in the positive y dir :py:class:`cadquery.selectors.DirectionMinMaxSelector` 0 or 1 +Y :py:class:`DirectionMinMaxSelector` Edges farthest in the positive y dir 0 or 1 -Y Edges farthest in the positive y dir :py:class:`cadquery.selectors.DirectionMinMaxSelector` 0 or 1 +Y :py:class:`DirectionMinMaxSelector` Vertices farthest in the positive y dir 0 or 1 -Y Vertices farthest in the positive y dir :py:class:`cadquery.selectors.DirectionMinMaxSelector` 0 or 1 + - - - -{% endblock %} - -{% block header %} -{%- if logo %} - -{%- endif %} - -{% endblock %} - -{%- block sidebarlogo %}{%- endblock %} -{%- block sidebarsourcelink %}{%- endblock %} diff --git a/doc/themes/pparts/static/body.jpg b/doc/themes/pparts/static/body.jpg deleted file mode 100644 index f10460c..0000000 Binary files a/doc/themes/pparts/static/body.jpg and /dev/null differ diff --git a/doc/themes/pparts/static/dialog-note.png b/doc/themes/pparts/static/dialog-note.png deleted file mode 100644 index 263fbd5..0000000 Binary files a/doc/themes/pparts/static/dialog-note.png and /dev/null differ diff --git a/doc/themes/pparts/static/dialog-seealso.png b/doc/themes/pparts/static/dialog-seealso.png deleted file mode 100644 index 3eb7b05..0000000 Binary files a/doc/themes/pparts/static/dialog-seealso.png and /dev/null differ diff --git a/doc/themes/pparts/static/dialog-topic.png b/doc/themes/pparts/static/dialog-topic.png deleted file mode 100644 index 2ac5747..0000000 Binary files a/doc/themes/pparts/static/dialog-topic.png and /dev/null differ diff --git a/doc/themes/pparts/static/dialog-warning.png b/doc/themes/pparts/static/dialog-warning.png deleted file mode 100644 index 7233d45..0000000 Binary files a/doc/themes/pparts/static/dialog-warning.png and /dev/null differ diff --git a/doc/themes/pparts/static/epub.css b/doc/themes/pparts/static/epub.css deleted file mode 100644 index 28dff73..0000000 --- a/doc/themes/pparts/static/epub.css +++ /dev/null @@ -1,310 +0,0 @@ -/* - * default.css_t - * ~~~~~~~~~~~~~ - * - * Sphinx stylesheet -- default theme. - * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: {{ theme_bodyfont }}; - font-size: 100%; - background-color: {{ theme_footerbgcolor }}; - color: #000; - margin: 0; - padding: 0; -} - -div.document { - background-color: {{ theme_sidebarbgcolor }}; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 230px; -} - -div.body { - background-color: {{ theme_bgcolor }}; - color: {{ theme_textcolor }}; - padding: 0 20px 30px 20px; -} - -{%- if theme_rightsidebar|tobool %} -div.bodywrapper { - margin: 0 230px 0 0; -} -{%- endif %} - -div.footer { - color: {{ theme_footertextcolor }}; - width: 100%; - padding: 9px 0 9px 0; - text-align: center; - font-size: 75%; -} - -div.footer a { - color: {{ theme_footertextcolor }}; - text-decoration: underline; -} - -div.related { - background-color: {{ theme_relbarbgcolor }}; - line-height: 30px; - color: {{ theme_relbartextcolor }}; -} - -div.related a { - color: {{ theme_relbarlinkcolor }}; -} - -div.sphinxsidebar { - {%- if theme_stickysidebar|tobool %} - top: 30px; - bottom: 0; - margin: 0; - position: fixed; - overflow: auto; - height: auto; - {%- endif %} - {%- if theme_rightsidebar|tobool %} - float: right; - {%- if theme_stickysidebar|tobool %} - right: 0; - {%- endif %} - {%- endif %} -} - -{%- if theme_stickysidebar|tobool %} -/* this is nice, but it it leads to hidden headings when jumping - to an anchor */ -/* -div.related { - position: fixed; -} - -div.documentwrapper { - margin-top: 30px; -} -*/ -{%- endif %} - -div.sphinxsidebar h3 { - font-family: {{ theme_headfont }}; - color: {{ theme_sidebartextcolor }}; - font-size: 1.4em; - font-weight: normal; - margin: 0; - padding: 0; -} - -div.sphinxsidebar h3 a { - color: {{ theme_sidebartextcolor }}; -} - -div.sphinxsidebar h4 { - font-family: {{ theme_headfont }}; - color: {{ theme_sidebartextcolor }}; - font-size: 1.3em; - font-weight: normal; - margin: 5px 0 0 0; - padding: 0; -} - -div.sphinxsidebar p { - color: {{ theme_sidebartextcolor }}; -} - -div.sphinxsidebar p.topless { - margin: 5px 10px 10px 10px; -} - -div.sphinxsidebar ul { - margin: 10px; - padding: 0; - color: {{ theme_sidebartextcolor }}; -} - -div.sphinxsidebar a { - color: {{ theme_sidebarlinkcolor }}; -} - -div.sphinxsidebar input { - border: 1px solid {{ theme_sidebarlinkcolor }}; - font-family: sans-serif; - font-size: 1em; -} - -{% if theme_collapsiblesidebar|tobool %} -/* for collapsible sidebar */ -div#sidebarbutton { - background-color: {{ theme_sidebarbtncolor }}; -} -{% endif %} - -/* -- hyperlink styles ------------------------------------------------------ */ - -a { - color: {{ theme_linkcolor }}; - text-decoration: none; -} - -a:visited { - color: {{ theme_visitedlinkcolor }}; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -{% if theme_externalrefs|tobool %} -a.external { - text-decoration: none; - border-bottom: 1px dashed {{ theme_linkcolor }}; -} - -a.external:hover { - text-decoration: none; - border-bottom: none; -} - -a.external:visited { - text-decoration: none; - border-bottom: 1px dashed {{ theme_visitedlinkcolor }}; -} -{% endif %} - -/* -- body styles ----------------------------------------------------------- */ - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: {{ theme_headfont }}; - background-color: {{ theme_headbgcolor }}; - font-weight: normal; - color: {{ theme_headtextcolor }}; - border-bottom: 1px solid #ccc; - margin: 20px -20px 10px -20px; - padding: 3px 0 3px 10px; -} - -div.body h1 { margin-top: 0; font-size: 200%; } -div.body h2 { font-size: 160%; } -div.body h3 { font-size: 140%; } -div.body h4 { font-size: 120%; } -div.body h5 { font-size: 110%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: {{ theme_headlinkcolor }}; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - background-color: {{ theme_headlinkcolor }}; - color: white; -} - -div.body p, div.body dd, div.body li { - text-align: justify; - line-height: 130%; -} - -div.admonition p.admonition-title + p { - display: inline; -} - -div.admonition p { - margin-bottom: 5px; -} - -div.admonition pre { - margin-bottom: 5px; -} - -div.admonition ul, div.admonition ol { - margin-bottom: 5px; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre { - padding: 5px; - background-color: {{ theme_codebgcolor }}; - color: {{ theme_codetextcolor }}; - line-height: 120%; - border: 1px solid #ac9; - border-left: none; - border-right: none; -} - -tt { - background-color: #ecf0f3; - padding: 0 1px 0 1px; - font-size: 0.95em; -} - -th { - background-color: #ede; -} - -.warning tt { - background: #efc2c2; -} - -.note tt { - background: #d6d6d6; -} - -.viewcode-back { - font-family: {{ theme_bodyfont }}; -} - -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} diff --git a/doc/themes/pparts/static/footerbg.png b/doc/themes/pparts/static/footerbg.png deleted file mode 100644 index 1fbc873..0000000 Binary files a/doc/themes/pparts/static/footerbg.png and /dev/null differ diff --git a/doc/themes/pparts/static/headerbg.png b/doc/themes/pparts/static/headerbg.png deleted file mode 100644 index 0596f20..0000000 Binary files a/doc/themes/pparts/static/headerbg.png and /dev/null differ diff --git a/doc/themes/pparts/static/ie6.css b/doc/themes/pparts/static/ie6.css deleted file mode 100644 index 74baa5d..0000000 --- a/doc/themes/pparts/static/ie6.css +++ /dev/null @@ -1,7 +0,0 @@ -* html img, -* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", -this.src = "_static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", -this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) -);} diff --git a/doc/themes/pparts/static/logo.png b/doc/themes/pparts/static/logo.png deleted file mode 100644 index fa68e82..0000000 Binary files a/doc/themes/pparts/static/logo.png and /dev/null differ diff --git a/doc/themes/pparts/static/middlebg.png b/doc/themes/pparts/static/middlebg.png deleted file mode 100644 index 2369cfb..0000000 Binary files a/doc/themes/pparts/static/middlebg.png and /dev/null differ diff --git a/doc/themes/pparts/static/pparts.css_t b/doc/themes/pparts/static/pparts.css_t deleted file mode 100644 index 64229c1..0000000 --- a/doc/themes/pparts/static/pparts.css_t +++ /dev/null @@ -1,387 +0,0 @@ -/* - * pylons.css_t - * ~~~~~~~~~~~~ - * - * Sphinx stylesheet -- pylons theme. - * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -html {background-image:url(../img/bg/html.png);} -body {color:#333;background-position:50% -400px;background-repeat:repeat-x;} -#home {background-position:50% 0;} -body, input, textarea, button {font:13px/20px Arial,sans-serif;} - -/* Color for the links */ -a {color:#84B51E; text-decoration:none;} - -* {margin:0;} -p, ul, ol, table, form, pre {margin-bottom:20px;} -img {border:none;max-width:100%;} -ul {list-style:none;} -:focus {outline:0;} -.clear {clear:both;} -article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block;} -.wrapper:after, #login:after {content:".";display:block;height:0;clear:both;visibility:hidden;} - -/* Overall background color and image */ -html, #login {background-color:#f5f5f5;} -body {background-image:url('../img/bg/body.jpg');} - -/* Background and border color for drop-down navigation */ -nav ul ul {background-color:#13171A;border-color:#84B51E;} - -/* Footer background color */ -footer, footer h3 span {background-color:#13171A;} - -/* Primary navigation color */ -nav>ul>li>a {color:#ddd;} - -/* Header colors */ -h1, h1 a {color:#13171A;} -h2, h2 a, h3, h4, .pricing thead th {color:#444;} - - -/* Color for the links */ -p a, .wrapper ul li a {color:#84B51E;} - -body { - font-family: 'Open Sans',Arial,sans-serif; - font-size: 100%; - background-color: #333; - color: #ffffff; - margin: 0; - padding: 0; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 {{ theme_sidebarwidth }}px; -} - -hr { - border: 1px solid #B1B4B6; -} - -div.document { - background-color: #f5f5f5; -} - -div.header { - width:100%; - height:142px; - background: #eaad32 url(body.jpg) bottom; - position:relative; -} -div.header ul > li > a{ - text-decoration:none; - line-height:30px; - font-size:15px; - padding: 0 12p 0 13px; -} -div.header ul { - background:none; -} - -div.logo { - text-align: left; - padding: 15px 40px; -} - -div.body { - background-color: #ffffff; - color: #3E4349; - padding: 0 30px 30px 30px; - font-size: 1em; - border-left: 1px solid #333; - border-right-style: none; - overflow: auto; -} - -div.footer { - color: #ffffff; - background-color:#13171A; - width: 100%; - padding: 13px 0; - text-align: center; - font-size: 75%; - background: transparent; - clear:both; -} - -div.footer a { - color: #ffffff; - text-decoration: none; -} - -div.footer a:hover { - color: #e88f00; - text-decoration: underline; -} - -div.related { - position:absolute; - top: 52px; - width:100%; - margin:0; - list-style:none; - line-height: 30px; - color: #373839; - font-size: 15px; - background-color: transparent; -} - -div.related a { - color: #1b61d6; -} -div.related h3{ - display:none; -} - -div.related ul { - padding-left: 450px; -} -div.related li{ - display:none; -} -div.related li.right{ - display:inline; -} -div.related ul > li a{ - font-size: 30px; - text-decoration: none; - line-height:30px; - color: #ddd; - font-weight:bold; - display:none; -} -div.related ul > li.right a{ - font-size: 15px; - font-weight:normal; - display:inline; -} -div.sphinxsidebar { - font-size: 14px; - line-height: 1.5em; -} - -div.sphinxsidebarwrapper{ - padding: 10px 0; -} - -div.sphinxsidebar h3, -div.sphinxsidebar h4 { - color: #373839; - font-size: 15px; - font-weight: bold; - color: #444; - margin: 0; - padding: 5px 10px; - -} - -div.sphinxsidebar h3{ - font-size: 1.3em; -} - -div.sphinxsidebar h3 a { - color: #444; -} - - -div.sphinxsidebar p { - color: #888; - padding: 5px 20px; -} - -div.sphinxsidebar p.topless { -} - -div.sphinxsidebar ul { - margin: 10px 20px; - padding: 0; - color: #373839; -} - - -div.sphinxsidebar input { - border: 1px solid #ccc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar input[type=text]{ - margin-left: 20px; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 2px solid #c6d880; - background-color: #e6efc2; - width: 40%; - float: right; - border-right-style: none; - border-left-style: none; - padding: 10px 20px; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- body styles ----------------------------------------------------------- */ - - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: 'Open Sans',Arial,sans-serif; - background-color: #ffffff; - font-weight: normal; - color: #444; - margin: 30px 0px 10px 0px; - padding: 5px 0; -} - -div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } -div.body h2 { font-size: 150%; background-color: #ffffff; } -div.body h3 { font-size: 120%; background-color: #ffffff; } -div.body h4 { font-size: 110%; background-color: #ffffff; } -div.body h5 { font-size: 100%; background-color: #ffffff; } -div.body h6 { font-size: 100%; background-color: #ffffff; } - -a.headerlink { - color: #1b61d6; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - text-decoration: underline; -} - -div.body p, div.body dd, div.body li { - line-height: 1.5em; -} - -div.admonition p.admonition-title + p { - display: inline; -} - -div.highlight{ - background-color: white; -} - -div.note { - border: 2px solid #7a9eec; - border-right-style: none; - border-left-style: none; - padding: 10px 20px 10px 60px; - background: #e1ecfe url(dialog-note.png) no-repeat 10px 8px; -} - -div.seealso { - background: #fff6bf url(dialog-seealso.png) no-repeat 10px 8px; - border: 2px solid #ffd324; - border-left-style: none; - border-right-style: none; - padding: 10px 20px 10px 60px; -} - -div.topic { - background: #eeeeee; - border: 2px solid #C6C9CB; - padding: 10px 20px; - border-right-style: none; - border-left-style: none; -} - -div.warning { - background: #fbe3e4 url(dialog-warning.png) no-repeat 10px 8px; - border: 2px solid #fbc2c4; - border-right-style: none; - border-left-style: none; - padding: 10px 20px 10px 60px; -} - -p.admonition-title { - display: none; -} - -p.admonition-title:after { - content: ":"; -} - -pre { - padding: 10px; - background-color: #fafafa; - color: #222; - line-height: 1.2em; - border: 2px solid #C6C9CB; - font-size: 1.1em; - margin: 1.5em 0 1.5em 0; - border-right-style: none; - border-left-style: none; -} - -tt { - background-color: transparent; - color: #222; - font-size: 1.1em; - font-family: monospace; -} - -.viewcode-back { - font-family: "Nobile", sans-serif; -} - -div.viewcode-block:target { - background-color: #fff6bf; - border: 2px solid #ffd324; - border-left-style: none; - border-right-style: none; - padding: 10px 20px; -} - -table.highlighttable { - width: 100%; -} - -table.highlighttable td { - padding: 0; -} - -a em.std-term { - color: #007f00; -} - -a:hover em.std-term { - text-decoration: underline; -} - -.download { - font-family: "Nobile", sans-serif; - font-weight: normal; - font-style: normal; -} - -tt.xref { - font-weight: normal; - font-style: normal; -} diff --git a/doc/themes/pparts/static/transparent.gif b/doc/themes/pparts/static/transparent.gif deleted file mode 100644 index 0341802..0000000 Binary files a/doc/themes/pparts/static/transparent.gif and /dev/null differ diff --git a/doc/themes/pparts/theme.conf b/doc/themes/pparts/theme.conf deleted file mode 100644 index 11043fe..0000000 --- a/doc/themes/pparts/theme.conf +++ /dev/null @@ -1,4 +0,0 @@ -[theme] -inherit = basic -stylesheet = pparts.css -pygments_style = friendly