-
Notifications
You must be signed in to change notification settings - Fork 56
Developer Documentation
This section describes some basic test cases for how CQ would work when Feature trees are implemented
Based on PM conversations with Dave we're a ways from getting serious about a GUI, but I wanted to capture these thoughts somewhere.
UI
- Full featured editor capabilities (syntax highlighting, auto-indent, auto-complete, etc). Sublime Text could be a good model for this feature set.
- Could this be done with a plugin to PyCharm where the solid is rendered in a new tab? https://plugins.jetbrains.com/pycharm
- Good syntax error highlighting. Closely tied to the item above, but could be integrated into the editor, or just be a separate status pane.
- Tight integration between the code window and 3D view. If you click on a feature, edge, etc, the corresponding code would be highlighted and vice versa. It would also be nice to get a context sensitive menu in the 3D view to tell the GUI to generate certain code for you for things like fillets.
- Common keys such as F5 to render? This would keep it similar to OpenSCAD and several IDEs that use that key to compile/build the code.
- "New Project" menu item for generating the directory structure and stub in files for a project. I outlined a possible project directory structure on the OpenSCAD forums. http://forum.openscad.org/OpenSCAD-Usage-Standards-td7774.html
- Integrated support for a parameters file that all parts and assemblies within a project can reference. Closely tied to the item above.
- Workplane visualization.
- Integration with ParametricParts.com.
- Integration with version control systems such as git, Mercurial and SVN.
- Support for themes. Just having both a light and a dark theme would help.
- Collaborative real-time editing. This could be done using something like Screenhero instead of making it a feature.
- Light weight and real-time preview of the changes the code is making to the 3D model(s).
- 3D mouse support: http://www.3dconnexion.com/products/spacenavigator.html
- BOM auto-generation
3D Functionality
- Ability to easily handle exploded assemblies (could be done in straight Python code too)
- Interference detection and highlighting between assembly parts
- Hole mis-alignment detection and highlighting between assembly parts
- Convert native FreeCAD objects that have been created through the GUI into native CadQuery objects
2D Functionality
- Easily generated drawings that update automatically when the assemblies are changed
- Separate "record" from "display" (LaTex style). This would allow drawing information to be embedded in the CadQuery file so that drawings could be auto-generated.
- Record = Doesn't assume manufacturing: tolerance, material selection, etc. If the user meets these specs, it will do what the designer says.
- Overall - Material, heat treat, etc
- Feature - Tolerances
- Template - Title block display information
- Record = Doesn't assume manufacturing: tolerance, material selection, etc. If the user meets these specs, it will do what the designer says.
- LaTex uses an imported template. You have to write the template first.
- Has built-in language commands
- Internationalization could be supported
- Meta data should show that code was auto generated
- Add DXF import per issue #76
- Add Polar Coordinate lineTo Variation per issue #75
Currently, CQ has a reasonable base feature set, but there is a lot of work left to do! This page lists some of the future work needed.
This section lists things that we'd like to improve or change about CQ. If you're willing to help, we'd love to have you!
The current version of CQ is based on a FreeCAD backend, because that was easier to get started with. But FreeCAD imposes a number of limitations. Some of these include flakey behavor, a fairly slow release schedule, and no direct access to the OpenCascade layer. FreeCAD is itself based on OpenCascade, so the next major version should be based directly on OpenCascade. To stay with python, the closest we can get is https://github.com/tpaviot/oce and pythonOCC.
Using FreeCAD as a backend, we are able to easily build a FreeCAD module that provides a GUI for CQ. That's ( https://github.com/jmwright/cadquery-freecad-module). But we want to go further, providing a stand-alone GUI. In fact, pythonOCC should make this fairly easy, as there are example viewers already available.
Today's CQ implementation uses a simple stack to provide a powerful selector model. This model, combined with a fluent API, makes writing code much simpler. The stack, however, has proven insufficient to model the feature tree of the part, and has resulted in very hard to understand code and behavior.
What's needed is a separate notion of a feature tree in addition to the selector stack. It is analogous to the way that jQuery selects against an HTML DOM-- we need both a tree, which respresents the geometric features that are created, and a way to select them.
One scenario that create this need is the ability to select features created in the most recent operation, rather than all of the features for the resulting solid. This is a common need-- for example to select the face I've just created, while ignoring all of the other faces that were already there an unchanged. This can be done only if we can differentiate which features were available in various versions of the solid as it was created.
Many projects need the ability to support 3d text that's generated automatically from code. FreeCAD cannot support this, but moving to OCE, ( OCC version 6.8.0) we should have this capability. This would be a huge step forward
While we want to target the OCC backend, we would like to support other BREP kernels in the future. One example could be Parasolid. To ensure this is possible, we need to ensure that there is an interface layer between the CQ code and underlying implementations. This will keep the code modular.
Many, many objects are built from pre-created 2-d drawings. We really need the ability to import 2D geometry. The most popular format is probably DXF, but there are others too, for example SVG.
The challenge with CQ is how to allow these to be parametric. The simplest solution is to import them as fixed points, and leave it to the author to make them parametric. This might be the best initial implementation-- it would be a lot better than nothing!
A better implementation would be to also add functionality to scale or otherwise impart parametric behavior to the imported drawing.
CQ scripts do not include any way to represent parameter metadata, or, in fact, any way at all to specify which variables in a script are intended for use by other users. A CQ script will often have a public interface, and then private variables that are not really intended for changes.
We need a way to describe parameters designed to be changed, and the validation rules associated with those. It is surprisingly complex, because even the most simple models have variables that are inter-related. Take, for example, a simple cylinder with a hole in. This object might have three parameters: its height, h: its outder diameter, D, and the hole diameter, d. In this case, {h,D,d} > 0. Easy. But also d<D to create a valid shape. How to represent this?
The ideal way would allow the metadata to be used by GUIs, to provide user input guidance.
For a CodeCAD framework, working examples are crucial-- both to get people started, and to make sure that the product works. Though unit tests are fine, there's simply no substitute for running a script and checking that that resulting 3d object looks right.
These examples http://parametricparts.com/docs/examples.html are created automatically by sphinxdoc, with the help of a script. It allows the examples, documentation, and test cases all to be the same document. Really quite nice.
We really need to set up a CI loop, and publish somethign similar from the CQ repo. Right now, the best examples are over on ParametricParts-- which uses CQ but an older version.
There are quite a few geometric features that we need. These are too numerous to list in the roadmap, they are on a separate page https://github.com/dcowden/cadquery/wiki/Future-Ideas
This section lists things that we will probably NOT change about CQ anytime soon, and why.
There have been many discussions about using a CSG, rather than BREP, based Kernel. CSG is more inherently stable, so models do not get into weird rendering problems as often. But there are a lot of problems too. Simple operations, like chamfers and rounds, are much harder than they need to be. Performance suffers for large models. Probably most important, though, is that humans generally do not think in terms of CSG naturally. Many objects are more simply envisioned as a 2-d construct extruded, etc. OpenCascade is the best open source BREP kernel available. Its not perfect, but the price is right.
If CQ becomes large enough, we would like to develop a backend for Parasolid, the world's most commonly used BREP Kernel. This would be a substantial undertaking
Python 3.x introduces a lot of changes. Last time we checked, pythonOCC does not support 3.x yet. Honestly, there are TONS of libraries that dont support 3.x yet. Its just not a high priority to support python 3.
It is key that CQ stay open source. We want the concept of CodeCAD to grow. CQ is the best implementation of CodeCAD we know of, and we want to make it easy to adopt. The current license is LGPL, but we may move to a more commercial friendly license like BSD soon if there is interest.
CadQuery selectors are inspired by jQuery selectors. The concepts are nearly the same-- only with jQuery you are querying an HTML document, and in CadQuery you are querying a feature tree.
Before writing cadQuery selectors, it is good to have a look at how they work in jQuery. Its been an incredibly easy to use, powerful, and flexible approach:
http://api.jquery.com/category/selectors/
You should be able to chain selectors, similar to how you can do it with jQuery:
Workplane("XY").box(1,2,3).faces(">Z <X >Y" ) # s
You should be able to select the nth object in a collection, rather than the first or last, like:
.faces('>>Z') #maximize to the next face
.faces('<<Z') #minimize to the next face
.faces('n>Z') #maximize to the nth face
.faces('n<Z') #minimize to the nth face
would take a container: a closed wire, face, or solid, and return things interior or exterior to that container. >[somecontainer]< # next inner thing >>[somecontainer]<< # innermost thing
<[somecontainer]> # next outer thing
<<[somecontainer]>> # outermost thing
would select things based on the cardinal directions (N,W,E,S,NW...) could take an optional plane-like argument (default is the nearest plane-like parent) directions relative to the coordinate system of that argument (i.e. N is always in the direction of (1, 0) in local coordinates. think this would look something like ".NW" read this to mean "north-west-most thing" so it' really a short-hand for "maximize in the direction of"
sometimes you just need to pick an arbitrary object and get the nearest things to it. will be useful for models based on skeletal geometry -- i.e. where the model is constructed from a series of reference planes. will also be needed in situations where there's simply no other way to select what you want -- i.e. all the selectors return no matches or multiple matches, and no combination reliably gets you just the thing you want.
for a vertex, the faces and edges it's a part of for an edge or face, the solids it's part of for a solid, perhaps the larger group or assembly it belongs to.
i.e., for a vertex, the other vertices along the same edges / faces / wires it composes for an edge, the other edges along the same face it composes for a face, the other faces adjacent to it in the same solid
It would be highly useful if you could tag any feature you create with an ID, and then later limit selectors to that feature. for example consider this:
r = Workplane("XY").circle(2.0).extrude(2.0,featureId="myCylinder") \
.faces(">Z").circle(0.5).cut(-1.0,featureId="MyHole")
.faces('featureID') #select a feature by ID
.faces('featureType') #select all the features of type
.faces('parentID.*') #select all child faces of the parent