diff --git a/CadQuery/Libs/cadquery-lib/README.md b/CadQuery/Libs/cadquery-lib/README.md index befb338..60fc9d4 100644 --- a/CadQuery/Libs/cadquery-lib/README.md +++ b/CadQuery/Libs/cadquery-lib/README.md @@ -1,7 +1,7 @@ What is a CadQuery? ======================================== -[![Travis Build Status](https://travis-ci.org/dcowden/cadquery.svg)](https://travis-ci.org/dcowden/cadquery) +[![Travis Build Status](https://travis-ci.org/dcowden/cadquery.svg?branch=master)](https://travis-ci.org/dcowden/cadquery?branch=master) [![Coverage Status](https://coveralls.io/repos/dcowden/cadquery/badge.svg)](https://coveralls.io/r/dcowden/cadquery) [![GitHub version](https://badge.fury.io/gh/dcowden%2Fcadquery.svg)](https://github.com/dcowden/cadquery/releases/tag/v0.3.0) [![License](https://img.shields.io/badge/license-Apache2-blue.svg)](https://github.com/dcowden/cadquery/blob/master/LICENSE) @@ -46,6 +46,7 @@ This resin mold was modeled using cadquery and then created on a CNC machine: The cadquery script is surprisingly short, and allows easily customizing any of the variables:: +```python import cadquery as cq from Helpers import show BS = cq.selectors.BoxSelector @@ -108,7 +109,7 @@ The cadquery script is surprisingly short, and allows easily customizing any of ]).hole(fhd, mw/2.) show(r) - +``` Thanks go to cadquery contributor hyOzd ( Altu Technology ) for the example! @@ -171,26 +172,30 @@ Use these steps if you would like to write CadQuery scripts as a python API. In preferably one that has virtualenv available. To use FreeCAD from any python interpreter, just append the FreeCAD lib directory to your path. On (*Nix):: - import sys +```python + import sys sys.path.append('/usr/lib/freecad/lib') +``` or on Windows:: - import sys +```python + import sys sys.path.append('/c/apps/FreeCAD/bin') +``` *NOTE* FreeCAD on Windows will not work with python 2.7-- you must use pthon 2.6.X!!!! 3. install cadquery:: - +```bash pip install cadquery - +``` 3. test your installation:: - +```python from cadquery import * box = Workplane("XY").box(1,2,3) exporters.toString(box,'STL') - +``` You're up and running! Installing -- Using CadQuery from Inside FreeCAD @@ -204,17 +209,16 @@ It includes a distribution of the latest version of cadquery. Roadmap/Future Work ======================= -Work is underway on two other installation methods for cadquery: - - 1. a conda package, which will install CQ and all of its depedencies, if you are using Anaconda - 2. a Docker image, which comes ready-to-run after you have installed docker. - -Work has also begun on Cadquery 2.0, which will feature: +Work has begun on Cadquery 2.0, which will feature: 1. Feature trees, for more powerful selection 2. Direct use of OpenCascade Community Edition(OCE), so that it is no longer required to install FreeCAD 3. https://github.com/jmwright/cadquery-gui, which will allow visualization of workplanes +The project page can be found here: https://github.com/dcowden/cadquery/projects/1 + +A more detailed description of the plan for CQ 2.0 is here: https://docs.google.com/document/d/1cXuxBkVeYmGOo34MGRdG7E3ILypQqkrJ26oVf3CUSPQ + Where does the name CadQuery come from? ======================================== diff --git a/CadQuery/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO b/CadQuery/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO index 8d759fc..823c3bd 100644 --- a/CadQuery/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO +++ b/CadQuery/Libs/cadquery-lib/cadquery.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cadquery -Version: 0.4.0 +Version: 1.0.0 Summary: CadQuery is a parametric scripting language for creating and traversing CAD models Home-page: https://github.com/dcowden/cadquery Author: David Cowden diff --git a/CadQuery/Libs/cadquery-lib/cadquery/__init__.py b/CadQuery/Libs/cadquery-lib/cadquery/__init__.py index 4e6dd4a..a9b77e4 100644 --- a/CadQuery/Libs/cadquery-lib/cadquery/__init__.py +++ b/CadQuery/Libs/cadquery-lib/cadquery/__init__.py @@ -13,9 +13,9 @@ from .cq import * __all__ = [ 'CQ','Workplane','plugins','selectors','Plane','BoundBox','Matrix','Vector','sortWiresByBuildOrder', - 'Shape','Vertex','Edge','Wire','Solid','Shell','Compound','exporters', 'importers', + 'Shape','Vertex','Edge','Wire','Face','Solid','Shell','Compound','exporters', 'importers', 'NearestToPointSelector','ParallelDirSelector','DirectionSelector','PerpendicularDirSelector', 'TypeSelector','DirectionMinMaxSelector','StringSyntaxSelector','Selector','plugins' ] -__version__ = "0.5.1" +__version__ = "1.0.0" diff --git a/CadQuery/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py b/CadQuery/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py index 3e041e3..05ed957 100644 --- a/CadQuery/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py +++ b/CadQuery/Libs/cadquery-lib/cadquery/freecad_impl/__init__.py @@ -16,23 +16,19 @@ You should have received a copy of the GNU Lesser General Public License along with this library; If not, see """ -import os, sys +import os +import sys def _fc_path(): """Find FreeCAD""" - _PATH = "" - if _PATH: + # Look for FREECAD_LIB env variable + _PATH = os.environ.get('FREECAD_LIB', '') + if _PATH and os.path.exists(_PATH): return _PATH - #look for FREECAD_LIB env variable - if os.environ.has_key('FREECAD_LIB'): - _PATH = os.environ.get('FREECAD_LIB') - if os.path.exists( _PATH): - return _PATH - if sys.platform.startswith('linux'): - #Make some dangerous assumptions... + # Make some dangerous assumptions... for _PATH in [ os.path.join(os.path.expanduser("~"), "lib/freecad/lib"), "/usr/local/lib/freecad/lib", @@ -40,12 +36,13 @@ def _fc_path(): "/opt/freecad/lib/", "/usr/bin/freecad/lib", "/usr/lib/freecad", + "/usr/lib64/freecad/lib", ]: if os.path.exists(_PATH): return _PATH elif sys.platform.startswith('win'): - #try all the usual suspects + # Try all the usual suspects for _PATH in [ "c:/Program Files/FreeCAD0.12/bin", "c:/Program Files/FreeCAD0.13/bin", @@ -86,27 +83,24 @@ def _fc_path(): ]: if os.path.exists(_PATH): return _PATH + elif sys.platform.startswith('darwin'): - #Assume we're dealing with a Mac + # Assume we're dealing with a Mac for _PATH in [ "/Applications/FreeCAD.app/Contents/lib", - os.path.join(os.path.expanduser("~"), "Library/Application Support/FreeCAD/lib"), + os.path.join(os.path.expanduser("~"), + "Library/Application Support/FreeCAD/lib"), ]: if os.path.exists(_PATH): return _PATH + raise ImportError('cadquery was unable to determine freecad library path') -#Make sure that the correct FreeCAD path shows up in Python's system path -no_library_path = ImportError('cadquery was unable to determine freecads library path') +# Make sure that the correct FreeCAD path shows up in Python's system path try: import FreeCAD except ImportError: path = _fc_path() - if path: - sys.path.insert(0, path) - try: - import FreeCAD - except ImportError: - raise no_library_path - else: raise no_library_path + sys.path.insert(0, path) + import FreeCAD diff --git a/CadQuery/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py b/CadQuery/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py index 4cec80a..12567e9 100644 --- a/CadQuery/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py +++ b/CadQuery/Libs/cadquery-lib/cadquery/freecad_impl/shapes.py @@ -216,7 +216,8 @@ class Shape(object): else: raise ValueError("Cannot find the center of %s object type" % str(type(self.Solids()[0].wrapped))) - def CenterOfBoundBox(self): + def CenterOfBoundBox(self, tolerance = 0.1): + self.wrapped.tessellate(tolerance) if isinstance(self.wrapped, FreeCADPart.Shape): # If there are no Solids, we're probably dealing with a Face or something similar if len(self.Solids()) == 0: @@ -258,14 +259,18 @@ class Shape(object): return object.wrapped.Mass @staticmethod - def CombinedCenterOfBoundBox(objects): + def CombinedCenterOfBoundBox(objects, tolerance = 0.1): """ Calculates the center of BoundBox of multiple objects. :param objects: a list of objects with mass 1 """ total_mass = len(objects) - weighted_centers = [o.wrapped.BoundBox.Center.multiply(1.0) for o in objects] + + weighted_centers = [] + for o in objects: + o.wrapped.tessellate(tolerance) + weighted_centers.append(o.wrapped.BoundBox.Center.multiply(1.0)) sum_wc = weighted_centers[0] for wc in weighted_centers[1:] : @@ -470,7 +475,9 @@ class Edge(Shape): @classmethod def makeCircle(cls, radius, pnt=(0, 0, 0), dir=(0, 0, 1), angle1=360.0, angle2=360): - return Edge(FreeCADPart.makeCircle(radius, toVector(pnt), toVector(dir), angle1, angle2)) + center = Vector(pnt) + normal = Vector(dir) + return Edge(FreeCADPart.makeCircle(radius, center.wrapped, normal.wrapped, angle1, angle2)) @classmethod def makeSpline(cls, listOfVector): @@ -621,8 +628,10 @@ class Face(Shape): return Vector(self.wrapped.normalAt(u, v).normalize()) @classmethod - def makePlane(cls, length, width, basePnt=None, dir=None): - return Face(FreeCADPart.makePlan(length, width, toVector(basePnt), toVector(dir))) + def makePlane(cls, length, width, basePnt=(0, 0, 0), dir=(0, 0, 1)): + basePnt = Vector(basePnt) + dir = Vector(dir) + return Face(FreeCADPart.makePlane(length, width, basePnt.wrapped, dir.wrapped)) @classmethod def makeRuledSurface(cls, edgeOrWire1, edgeOrWire2, dist=None): diff --git a/CadQuery/Libs/cadquery-lib/cadquery/selectors.py b/CadQuery/Libs/cadquery-lib/cadquery/selectors.py index 5d81e8a..72174e1 100644 --- a/CadQuery/Libs/cadquery-lib/cadquery/selectors.py +++ b/CadQuery/Libs/cadquery-lib/cadquery/selectors.py @@ -20,8 +20,9 @@ import re import math from cadquery import Vector,Edge,Vertex,Face,Solid,Shell,Compound -from pyparsing import Literal,Word,nums,Optional,Combine,oneOf,\ - upcaseTokens,CaselessLiteral,Group +from pyparsing import Literal,Word,nums,Optional,Combine,oneOf,upcaseTokens,\ + CaselessLiteral,Group,infixNotation,opAssoc,Forward,\ + ZeroOrMore,Keyword class Selector(object): @@ -288,10 +289,6 @@ class DirectionMinMaxSelector(Selector): CQ(aCube).faces( ">Z" ) - Future Enhancements: - provide a nicer way to select in arbitrary directions. IE, a bit more code could - allow '>(0,0,1)' to work. - """ def __init__(self, vector, directionMax=True, tolerance=0.0001): self.vector = vector @@ -423,7 +420,7 @@ class InverseSelector(Selector): def _makeGrammar(): """ - Define the string selector grammar using PyParsing + Define the simple string selector grammar using PyParsing """ #float definition @@ -476,44 +473,14 @@ def _makeGrammar(): _grammar = _makeGrammar() #make a grammar instance -class StringSyntaxSelector(Selector): +class _SimpleStringSyntaxSelector(Selector): """ - Filter lists objects using a simple string syntax. All of the filters available in the string syntax - are also available ( usually with more functionality ) through the creation of full-fledged - selector objects. see :py:class:`Selector` and its subclasses - - Filtering works differently depending on the type of object list being filtered. - - :param selectorString: A two-part selector string, [selector][axis] - - :return: objects that match the specified selector - - ***Modfiers*** are ``('|','+','-','<','>','%')`` - - :\|: - parallel to ( same as :py:class:`ParallelDirSelector` ). Can return multiple objects. - :#: - perpendicular to (same as :py:class:`PerpendicularDirSelector` ) - :+: - positive direction (same as :py:class:`DirectionSelector` ) - :-: - negative direction (same as :py:class:`DirectionSelector` ) - :>: - maximize (same as :py:class:`DirectionMinMaxSelector` with directionMax=True) - :<: - minimize (same as :py:class:`DirectionMinMaxSelector` with directionMax=False ) - :%: - curve/surface type (same as :py:class:`TypeSelector`) - - ***axisStrings*** are: ``X,Y,Z,XY,YZ,XZ`` - - Selectors are a complex topic: see :ref:`selector_reference` for more information - - - + This is a private class that converts a parseResults object into a simple + selector object """ - def __init__(self,selectorString): - + def __init__(self,parseResults): + + #define all token to object mappings self.axes = { 'X': Vector(1,0,0), 'Y': Vector(0,1,0), @@ -545,9 +512,8 @@ class StringSyntaxSelector(Selector): '#' : PerpendicularDirSelector, '|' : ParallelDirSelector} - self.selectorString = selectorString - parsing_result = _grammar.parseString(selectorString) - self.mySelector = self._chooseSelector(parsing_result) + self.parseResults = parseResults + self.mySelector = self._chooseSelector(parseResults) def _chooseSelector(self,pr): """ @@ -593,3 +559,113 @@ class StringSyntaxSelector(Selector): [+\|-\|<\|>\|] \ """ return self.mySelector.filter(objectList) + +def _makeExpressionGrammar(atom): + """ + Define the complex string selector grammar using PyParsing (which supports + logical operations and nesting) + """ + + #define operators + and_op = Literal('and') + or_op = Literal('or') + delta_op = oneOf(['exc','except']) + not_op = Literal('not') + + def atom_callback(res): + return _SimpleStringSyntaxSelector(res) + + atom.setParseAction(atom_callback) #construct a simple selector from every matched + + #define callback functions for all operations + def and_callback(res): + items = res.asList()[0][::2] #take every secend items, i.e. all operands + return reduce(AndSelector,items) + + def or_callback(res): + items = res.asList()[0][::2] #take every secend items, i.e. all operands + return reduce(SumSelector,items) + + def exc_callback(res): + items = res.asList()[0][::2] #take every secend items, i.e. all operands + return reduce(SubtractSelector,items) + + def not_callback(res): + right = res.asList()[0][1] #take second item, i.e. the operand + return InverseSelector(right) + + #construct the final grammar and set all the callbacks + expr = infixNotation(atom, + [(and_op,2,opAssoc.LEFT,and_callback), + (or_op,2,opAssoc.LEFT,or_callback), + (delta_op,2,opAssoc.LEFT,exc_callback), + (not_op,1,opAssoc.RIGHT,not_callback)]) + + return expr + +_expression_grammar = _makeExpressionGrammar(_grammar) + +class StringSyntaxSelector(Selector): + """ + Filter lists objects using a simple string syntax. All of the filters available in the string syntax + are also available ( usually with more functionality ) through the creation of full-fledged + selector objects. see :py:class:`Selector` and its subclasses + + Filtering works differently depending on the type of object list being filtered. + + :param selectorString: A two-part selector string, [selector][axis] + + :return: objects that match the specified selector + + ***Modfiers*** are ``('|','+','-','<','>','%')`` + + :\|: + parallel to ( same as :py:class:`ParallelDirSelector` ). Can return multiple objects. + :#: + perpendicular to (same as :py:class:`PerpendicularDirSelector` ) + :+: + positive direction (same as :py:class:`DirectionSelector` ) + :-: + negative direction (same as :py:class:`DirectionSelector` ) + :>: + maximize (same as :py:class:`DirectionMinMaxSelector` with directionMax=True) + :<: + minimize (same as :py:class:`DirectionMinMaxSelector` with directionMax=False ) + :%: + curve/surface type (same as :py:class:`TypeSelector`) + + ***axisStrings*** are: ``X,Y,Z,XY,YZ,XZ`` or ``(x,y,z)`` which defines an arbitrary direction + + It is possible to combine simple selectors together using logical operations. + The following operations are suuported + + :and: + Logical AND, e.g. >X and >Y + :or: + Logical OR, e.g. |X or |Y + :not: + Logical NOT, e.g. not #XY + :exc(ept): + Set difference (equivalent to AND NOT): |X exc >Z + + Finally, it is also possible to use even more complex expressions with nesting + and arbitrary number of terms, e.g. + + (not >X[0] and #XY) or >XY[0] + + Selectors are a complex topic: see :ref:`selector_reference` for more information + """ + def __init__(self,selectorString): + """ + Feed the input string through the parser and construct an relevant complex selector object + """ + self.selectorString = selectorString + parse_result = _expression_grammar.parseString(selectorString, + parseAll=True) + self.mySelector = parse_result.asList()[0] + + def filter(self,objectList): + """ + Filter give object list through th already constructed complex selector object + """ + return self.mySelector.filter(objectList) \ No newline at end of file diff --git a/CadQuery/Libs/cadquery-lib/changes.md b/CadQuery/Libs/cadquery-lib/changes.md index 8a4cd0b..24d08ab 100644 --- a/CadQuery/Libs/cadquery-lib/changes.md +++ b/CadQuery/Libs/cadquery-lib/changes.md @@ -4,32 +4,32 @@ Changes v0.1 ----- - * Initial Version + * Initial Version v0.1.6 ----- - * Added STEP import and supporting tests + * Added STEP import and supporting tests v0.1.7 ----- - * Added revolve operation and supporting tests - * Fixed minor documentation errors + * Added revolve operation and supporting tests + * Fixed minor documentation errors v0.1.8 ----- - * Added toFreecad() function as a convenience for val().wrapped - * Converted all examples to use toFreecad() - * Updated all version numbers that were missed before - * Fixed import issues in Windows caused by fc_import - * Added/fixed Mac OS support - * Improved STEP import - * Fixed bug in rotateAboutCenter that negated its effect on solids - * Added Travis config (thanks @krasin) - * Removed redundant workplane.py file left over from the PParts.com migration - * Fixed toWorldCoordinates bug in moveTo (thanks @xix-xeaon) - * Added new tests for 2D drawing functions - * Integrated Coveralls.io, with a badge in README.md - * Integrated version badge in README.md + * Added toFreecad() function as a convenience for val().wrapped + * Converted all examples to use toFreecad() + * Updated all version numbers that were missed before + * Fixed import issues in Windows caused by fc_import + * Added/fixed Mac OS support + * Improved STEP import + * Fixed bug in rotateAboutCenter that negated its effect on solids + * Added Travis config (thanks @krasin) + * Removed redundant workplane.py file left over from the PParts.com migration + * Fixed toWorldCoordinates bug in moveTo (thanks @xix-xeaon) + * Added new tests for 2D drawing functions + * Integrated Coveralls.io, with a badge in README.md + * Integrated version badge in README.md v0.2.0 ----- @@ -89,7 +89,12 @@ v0.5.2 ------ * Added the sweep operation #33 -v1.0.0 (unreleased) +v1.0.0 ------ * Added an option to do symmetric extrusion about the workplane (thanks @adam-urbanczyk) * Extended selector syntax to include Nth selector and re-implemented selectors using pyparsing (thanks @adam-urbanczyk) + * Added logical operations to string selectors (thanks @adam-urbanczyk) + * Cleanup of README.md and changes.md (thanks @baoboa) + * Fixed bugs with toVector and Face 'Not Defined' errors (thanks @huskier) + * Refactor of the initialization code for PEP8 compliance and Python 3 compatibility (thanks @Peque) + * Making sure that the new pyparsing library dependency is handled properly (thanks @Peque) diff --git a/CadQuery/Libs/cadquery-lib/doc/conf.py b/CadQuery/Libs/cadquery-lib/doc/conf.py index 2937aed..fb76407 100644 --- a/CadQuery/Libs/cadquery-lib/doc/conf.py +++ b/CadQuery/Libs/cadquery-lib/doc/conf.py @@ -55,9 +55,9 @@ copyright = u'Parametric Products Intellectual Holdings LLC, All Rights Reserved # built documents. # # The short X.Y version. -version = '0.3' +version = '1.0' # The full version, including alpha/beta/rc tags. -release = '0.3.0' +release = '1.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/CadQuery/Libs/cadquery-lib/requirements.txt b/CadQuery/Libs/cadquery-lib/requirements.txt index e69de29..d6e1198 100644 --- a/CadQuery/Libs/cadquery-lib/requirements.txt +++ b/CadQuery/Libs/cadquery-lib/requirements.txt @@ -0,0 +1 @@ +-e . diff --git a/CadQuery/Libs/cadquery-lib/setup.py b/CadQuery/Libs/cadquery-lib/setup.py index 9a25b9e..2e7018b 100644 --- a/CadQuery/Libs/cadquery-lib/setup.py +++ b/CadQuery/Libs/cadquery-lib/setup.py @@ -19,7 +19,7 @@ from setuptools import setup version = '0.5-SNAPSHOT' if 'TRAVIS_TAG' in os.environ.keys(): version= os.environ['TRAVIS_TAG'] - + setup( name='cadquery', @@ -31,6 +31,7 @@ setup( description='CadQuery is a parametric scripting language for creating and traversing CAD models', long_description=open('README.md').read(), packages=['cadquery','cadquery.contrib','cadquery.freecad_impl','cadquery.plugins','tests'], + install_requires=['pyparsing'], include_package_data=True, zip_safe=False, platforms='any', diff --git a/CadQuery/Libs/cadquery-lib/tests/TestCQSelectors.py b/CadQuery/Libs/cadquery-lib/tests/TestCQSelectors.py index fdb20cf..9b5e12f 100644 --- a/CadQuery/Libs/cadquery-lib/tests/TestCQSelectors.py +++ b/CadQuery/Libs/cadquery-lib/tests/TestCQSelectors.py @@ -338,6 +338,10 @@ class TestCQSelectors(BaseTest): # test 'and' (intersection) operator el = c.edges(S('|X') & BS((-2,-2,0.1), (2,2,2))).vals() self.assertEqual(2, len(el)) + + # test using extended string syntax + v = c.vertices(">X and >Y").vals() + self.assertEqual(2, len(v)) def testSumSelector(self): c = CQ(makeUnitCube()) @@ -354,6 +358,12 @@ class TestCQSelectors(BaseTest): self.assertEqual(2, len(fl)) el = c.edges(S("|X") + S("|Y")).vals() self.assertEqual(8, len(el)) + + # test using extended string syntax + fl = c.faces(">Z or X")).vals() self.assertEqual(3, len(fl)) + + # test using extended string syntax + fl = c.faces("#Z exc >X").vals() + self.assertEqual(3, len(fl)) def testInverseSelector(self): c = CQ(makeUnitCube()) @@ -382,6 +396,19 @@ class TestCQSelectors(BaseTest): self.assertEqual(5, len(fl)) el = c.faces('>Z').edges(-S('>X')).vals() self.assertEqual(3, len(el)) + + # test using extended string syntax + fl = c.faces('not >Z').vals() + self.assertEqual(5, len(fl)) + el = c.faces('>Z').edges('not >X').vals() + self.assertEqual(3, len(el)) + + def testComplexStringSelector(self): + c = CQ(makeUnitCube()) + + v = c.vertices('(>X and >Y) or ((0,0,1) or XY except >(1,1,1)[-1]', + '(not |(1,1,0) and >(0,0,1)) exc XY and (Z or X)', + 'not ( X or Y )'] + + for e in expressions: gram.parseString(e,parseAll=True) \ No newline at end of file diff --git a/CadQuery/Libs/cadquery-lib/tests/TestCadObjects.py b/CadQuery/Libs/cadquery-lib/tests/TestCadObjects.py index f78878a..3b2f98e 100644 --- a/CadQuery/Libs/cadquery-lib/tests/TestCadObjects.py +++ b/CadQuery/Libs/cadquery-lib/tests/TestCadObjects.py @@ -41,6 +41,24 @@ class TestCadObjects(BaseTest): self.assertTupleAlmostEquals((1.0, 2.0, 3.0), e.Center().toTuple(), 3) + def testEdgeWrapperMakeCircle(self): + halfCircleEdge = Edge.makeCircle(radius=10, pnt=(0, 0, 0), dir=(0, 0, 1), angle1=0, angle2=180) + + self.assertTupleAlmostEquals((0.0, 5.0, 0.0), halfCircleEdge.CenterOfBoundBox(0.0001).toTuple(),3) + self.assertTupleAlmostEquals((10.0, 0.0, 0.0), halfCircleEdge.startPoint().toTuple(), 3) + self.assertTupleAlmostEquals((-10.0, 0.0, 0.0), halfCircleEdge.endPoint().toTuple(), 3) + + def testFaceWrapperMakePlane(self): + mplane = Face.makePlane(10,10) + + self.assertTupleAlmostEquals((0.0, 0.0, 1.0), mplane.normalAt().toTuple(), 3) + + def testCenterOfBoundBox(self): + pass + + def testCombinedCenterOfBoundBox(self): + pass + def testCompoundCenter(self): """ Tests whether or not a proper weighted center can be found for a compound diff --git a/CadQuery/__init__.py b/CadQuery/__init__.py index 4b10038..4aa1216 100644 --- a/CadQuery/__init__.py +++ b/CadQuery/__init__.py @@ -1,6 +1,6 @@ __author__ = "Jeremy Wright (jmwright)" -__copyright__ = "Copyright 2014-2016" +__copyright__ = "Copyright 2014-2017" __license__ = "LGPL v3" -__version__ = "0.5.2" +__version__ = "1.0.0" __maintainer__ = "Jeremy Wright" __status__ = "Production/Stable" diff --git a/changes.md b/changes.md index 77c21ac..f58dd5d 100644 --- a/changes.md +++ b/changes.md @@ -28,7 +28,7 @@ v0.5.1 * Version updates for CadQuery v0.4.0, v0.4.1, v0.5.0-stable and v0.5.1 * Updated CadQuery license to Apache 2.0 -v1.0.0 (Unreleased) +v1.0.0 ----- * Embedded pyparsing package as a supporting library for new selector syntax * Added a check to remove any disallowed characters from the document name when executing a script