<s> """<STR_LIT>""" <EOL> import time <EOL> import math <EOL> from cadquery import * <EOL> from cadquery import selectors <EOL> from cadquery import exporters <EOL> class CQContext ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . pendingWires = [ ] <EOL> self . pendingEdges = [ ] <EOL> self . firstPoint = None <EOL> self . tolerance = <NUM_LIT> <EOL> class CQ ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , obj ) : <EOL> """<STR_LIT>""" <EOL> self . objects = [ ] <EOL> self . ctx = CQContext ( ) <EOL> self . parent = None <EOL> if obj : <EOL> self . objects . append ( obj ) <EOL> def newObject ( self , objlist ) : <EOL> """<STR_LIT>""" <EOL> r = CQ ( None ) <EOL> r . parent = self <EOL> r . ctx = self . ctx <EOL> r . objects = list ( objlist ) <EOL> return r <EOL> def _collectProperty ( self , propName ) : <EOL> """<STR_LIT>""" <EOL> all = { } <EOL> for o in self . objects : <EOL> if propName == '<STR_LIT>' and isinstance ( o , Solid ) and o . ShapeType ( ) == '<STR_LIT>' : <EOL> for i in getattr ( o , '<STR_LIT>' ) ( ) : <EOL> all [ i . hashCode ( ) ] = i <EOL> else : <EOL> if hasattr ( o , propName ) : <EOL> for i in getattr ( o , propName ) ( ) : <EOL> all [ i . hashCode ( ) ] = i <EOL> return list ( all . values ( ) ) <EOL> def split ( self , keepTop = False , keepBottom = False ) : <EOL> """<STR_LIT>""" <EOL> solid = self . findSolid ( ) <EOL> if ( not keepTop ) and ( not keepBottom ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> maxDim = solid . BoundingBox ( ) . DiagonalLength * <NUM_LIT> <EOL> topCutBox = self . rect ( maxDim , maxDim ) . _extrude ( maxDim ) <EOL> bottomCutBox = self . rect ( maxDim , maxDim ) . _extrude ( - maxDim ) <EOL> top = solid . cut ( bottomCutBox ) <EOL> bottom = solid . cut ( topCutBox ) <EOL> if keepTop and keepBottom : <EOL> return self . newObject ( [ top , bottom ] ) <EOL> else : <EOL> if keepTop : <EOL> solid . wrapped = top . wrapped <EOL> return self . newObject ( [ top ] ) <EOL> else : <EOL> solid . wrapped = bottom . wrapped <EOL> return self . newObject ( [ bottom ] ) <EOL> def combineSolids ( self , otherCQToCombine = None ) : <EOL> """<STR_LIT>""" <EOL> toCombine = self . solids ( ) . vals ( ) <EOL> if otherCQToCombine : <EOL> for obj in otherCQToCombine . solids ( ) . vals ( ) : <EOL> toCombine . append ( obj ) <EOL> if len ( toCombine ) < <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> ctxSolid = self . findSolid ( searchStack = False , searchParents = True ) <EOL> if ctxSolid is None : <EOL> ctxSolid = toCombine . pop ( <NUM_LIT:0> ) <EOL> s = ctxSolid <EOL> for tc in toCombine : <EOL> s = s . fuse ( tc ) <EOL> ctxSolid . wrapped = s . wrapped <EOL> return self . newObject ( [ s ] ) <EOL> def all ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ self . newObject ( [ o ] ) for o in self . objects ] <EOL> def size ( self ) : <EOL> """<STR_LIT>""" <EOL> return len ( self . objects ) <EOL> def vals ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . objects <EOL> def add ( self , obj ) : <EOL> """<STR_LIT>""" <EOL> if type ( obj ) == list : <EOL> self . objects . extend ( obj ) <EOL> elif type ( obj ) == CQ or type ( obj ) == Workplane : <EOL> self . objects . extend ( obj . objects ) <EOL> else : <EOL> self . objects . append ( obj ) <EOL> return self <EOL> def val ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . objects [ <NUM_LIT:0> ] <EOL> def toFreecad ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . objects [ <NUM_LIT:0> ] . wrapped <EOL> def workplane ( self , offset = <NUM_LIT:0.0> , invert = False , centerOption = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> def _isCoPlanar ( f0 , f1 ) : <EOL> """<STR_LIT>""" <EOL> p0 = f0 . Center ( ) <EOL> p1 = f1 . Center ( ) <EOL> n0 = f0 . normalAt ( ) <EOL> n1 = f1 . normalAt ( ) <EOL> if not ( ( abs ( n0 . x - n1 . x ) < self . ctx . tolerance ) or <EOL> ( abs ( n0 . y - n1 . y ) < self . ctx . tolerance ) or <EOL> ( abs ( n0 . z - n1 . z ) < self . ctx . tolerance ) ) : <EOL> return False <EOL> return abs ( n0 . dot ( p0 . sub ( p1 ) ) < self . ctx . tolerance ) <EOL> def _computeXdir ( normal ) : <EOL> """<STR_LIT>""" <EOL> xd = Vector ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:1> ) . cross ( normal ) <EOL> if xd . Length < self . ctx . tolerance : <EOL> xd = Vector ( <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> return xd <EOL> if len ( self . objects ) > <NUM_LIT:1> : <EOL> if not all ( o . geomType ( ) == '<STR_LIT>' for o in self . objects ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if not all ( _isCoPlanar ( self . objects [ <NUM_LIT:0> ] , f ) for f in self . objects [ <NUM_LIT:1> : ] ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if centerOption == '<STR_LIT>' : <EOL> center = Shape . CombinedCenter ( self . objects ) <EOL> elif centerOption == '<STR_LIT>' : <EOL> center = Shape . CombinedCenterOfBoundBox ( self . objects ) <EOL> normal = self . objects [ <NUM_LIT:0> ] . normalAt ( ) <EOL> xDir = _computeXdir ( normal ) <EOL> else : <EOL> obj = self . objects [ <NUM_LIT:0> ] <EOL> if isinstance ( obj , Face ) : <EOL> if centerOption == '<STR_LIT>' : <EOL> center = obj . Center ( ) <EOL> elif centerOption == '<STR_LIT>' : <EOL> center = obj . CenterOfBoundBox ( ) <EOL> normal = obj . normalAt ( center ) <EOL> xDir = _computeXdir ( normal ) <EOL> else : <EOL> if hasattr ( obj , '<STR_LIT>' ) : <EOL> if centerOption == '<STR_LIT>' : <EOL> center = obj . Center ( ) <EOL> elif centerOption == '<STR_LIT>' : <EOL> center = obj . CenterOfBoundBox ( ) <EOL> normal = self . plane . zDir <EOL> xDir = self . plane . xDir <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if invert : <EOL> normal = normal . multiply ( - <NUM_LIT:1.0> ) <EOL> offsetVector = normal . normalized ( ) . multiply ( offset ) <EOL> offsetCenter = center . add ( offsetVector ) <EOL> plane = Plane ( offsetCenter , xDir , normal ) <EOL> s = Workplane ( plane ) <EOL> s . parent = self <EOL> s . ctx = self . ctx <EOL> return s <EOL> def first ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . newObject ( self . objects [ <NUM_LIT:0> : <NUM_LIT:1> ] ) <EOL> def item ( self , i ) : <EOL> """<STR_LIT>""" <EOL> return self . newObject ( [ self . objects [ i ] ] ) <EOL> def last ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . newObject ( [ self . objects [ - <NUM_LIT:1> ] ] ) <EOL> def end ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . parent : <EOL> return self . parent <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> def findSolid ( self , searchStack = True , searchParents = True ) : <EOL> """<STR_LIT>""" <EOL> if searchStack : <EOL> for s in self . objects : <EOL> if isinstance ( s , Solid ) : <EOL> return s <EOL> elif isinstance ( s , Compound ) : <EOL> return s . Solids ( ) <EOL> if searchParents and self . parent is not None : <EOL> return self . parent . findSolid ( searchStack = True , searchParents = searchParents ) <EOL> return None <EOL> def _selectObjects ( self , objType , selector = None ) : <EOL> """<STR_LIT>""" <EOL> toReturn = self . _collectProperty ( objType ) <EOL> if selector is not None : <EOL> if isinstance ( selector , str ) or isinstance ( selector , unicode ) : <EOL> selectorObj = selectors . StringSyntaxSelector ( selector ) <EOL> else : <EOL> selectorObj = selector <EOL> toReturn = selectorObj . filter ( toReturn ) <EOL> return self . newObject ( toReturn ) <EOL> def vertices ( self , selector = None ) : <EOL> """<STR_LIT>""" <EOL> return self . _selectObjects ( '<STR_LIT>' , selector ) <EOL> def faces ( self , selector = None ) : <EOL> """<STR_LIT>""" <EOL> return self . _selectObjects ( '<STR_LIT>' , selector ) <EOL> def edges ( self , selector = None ) : <EOL> """<STR_LIT>""" <EOL> return self . _selectObjects ( '<STR_LIT>' , selector ) <EOL> def wires ( self , selector = None ) : <EOL> """<STR_LIT>""" <EOL> return self . _selectObjects ( '<STR_LIT>' , selector ) <EOL> def solids ( self , selector = None ) : <EOL> """<STR_LIT>""" <EOL> return self . _selectObjects ( '<STR_LIT>' , selector ) <EOL> def shells ( self , selector = None ) : <EOL> """<STR_LIT>""" <EOL> return self . _selectObjects ( '<STR_LIT>' , selector ) <EOL> def compounds ( self , selector = None ) : <EOL> """<STR_LIT>""" <EOL> return self . _selectObjects ( '<STR_LIT>' , selector ) <EOL> def toSvg ( self , opts = None ) : <EOL> """<STR_LIT>""" <EOL> return exporters . getSVG ( self . val ( ) . wrapped , opts ) <EOL> def exportSvg ( self , fileName ) : <EOL> """<STR_LIT>""" <EOL> exporters . exportSVG ( self , fileName ) <EOL> def rotateAboutCenter ( self , axisEndPoint , angleDegrees ) : <EOL> """<STR_LIT>""" <EOL> endVec = Vector ( axisEndPoint ) <EOL> def _rot ( obj ) : <EOL> startPt = obj . Center ( ) <EOL> endPt = startPt + endVec <EOL> return obj . rotate ( startPt , endPt , angleDegrees ) <EOL> return self . each ( _rot , False ) <EOL> def rotate ( self , axisStartPoint , axisEndPoint , angleDegrees ) : <EOL> """<STR_LIT>""" <EOL> return self . newObject ( [ o . rotate ( axisStartPoint , axisEndPoint , angleDegrees ) <EOL> for o in self . objects ] ) <EOL> def mirror ( self , mirrorPlane = "<STR_LIT>" , basePointVector = ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) ) : <EOL> """<STR_LIT>""" <EOL> newS = self . newObject ( [ self . objects [ <NUM_LIT:0> ] . mirror ( mirrorPlane , basePointVector ) ] ) <EOL> return newS . first ( ) <EOL> def translate ( self , vec ) : <EOL> """<STR_LIT>""" <EOL> return self . newObject ( [ o . translate ( vec ) for o in self . objects ] ) <EOL> def shell ( self , thickness ) : <EOL> """<STR_LIT>""" <EOL> solidRef = self . findSolid ( ) <EOL> for f in self . objects : <EOL> if type ( f ) != Face : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> s = solidRef . shell ( self . objects , thickness ) <EOL> solidRef . wrapped = s . wrapped <EOL> return self . newObject ( [ s ] ) <EOL> def fillet ( self , radius ) : <EOL> """<STR_LIT>""" <EOL> solid = self . findSolid ( ) <EOL> edgeList = self . edges ( ) . vals ( ) <EOL> if len ( edgeList ) < <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> s = solid . fillet ( radius , edgeList ) <EOL> solid . wrapped = s . wrapped <EOL> return self . newObject ( [ s ] ) <EOL> def chamfer ( self , length , length2 = None ) : <EOL> """<STR_LIT>""" <EOL> solid = self . findSolid ( ) <EOL> edgeList = self . edges ( ) . vals ( ) <EOL> if len ( edgeList ) < <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> s = solid . chamfer ( length , length2 , edgeList ) <EOL> solid . wrapped = s . wrapped <EOL> return self . newObject ( [ s ] ) <EOL> class Workplane ( CQ ) : <EOL> """<STR_LIT>""" <EOL> FOR_CONSTRUCTION = '<STR_LIT>' <EOL> def __init__ ( self , inPlane , origin = ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) , obj = None ) : <EOL> """<STR_LIT>""" <EOL> if inPlane . __class__ . __name__ == '<STR_LIT>' : <EOL> tmpPlane = inPlane <EOL> elif isinstance ( inPlane , str ) or isinstance ( inPlane , unicode ) : <EOL> tmpPlane = Plane . named ( inPlane , origin ) <EOL> else : <EOL> tmpPlane = None <EOL> if tmpPlane is None : <EOL> raise ValueError ( <EOL> '<STR_LIT>' . format ( inPlane ) ) <EOL> self . obj = obj <EOL> self . plane = tmpPlane <EOL> self . firstPoint = None <EOL> self . objects = [ self . plane . origin ] <EOL> self . parent = None <EOL> self . ctx = CQContext ( ) <EOL> def transformed ( self , rotate = ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) , offset = ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) ) : <EOL> """<STR_LIT>""" <EOL> if rotate . __class__ . __name__ == '<STR_LIT>' : <EOL> rotate = rotate . toTuple ( ) <EOL> if offset . __class__ . __name__ == '<STR_LIT>' : <EOL> offset = offset . toTuple ( ) <EOL> p = self . plane . rotated ( rotate ) <EOL> p . origin = self . plane . toWorldCoords ( offset ) <EOL> ns = self . newObject ( [ p . origin ] ) <EOL> ns . plane = p <EOL> return ns <EOL> def newObject ( self , objlist ) : <EOL> """<STR_LIT>""" <EOL> ns = Workplane ( "<STR_LIT>" ) <EOL> ns . plane = self . plane <EOL> ns . parent = self <EOL> ns . objects = list ( objlist ) <EOL> ns . ctx = self . ctx <EOL> return ns <EOL> def _findFromPoint ( self , useLocalCoords = False ) : <EOL> """<STR_LIT>""" <EOL> obj = self . objects [ - <NUM_LIT:1> ] <EOL> if isinstance ( obj , Edge ) : <EOL> p = obj . endPoint ( ) <EOL> elif isinstance ( obj , Vector ) : <EOL> p = obj <EOL> else : <EOL> raise RuntimeError ( "<STR_LIT>" % type ( obj ) ) <EOL> if useLocalCoords : <EOL> return self . plane . toLocalCoords ( p ) <EOL> else : <EOL> return p <EOL> def rarray ( self , xSpacing , ySpacing , xCount , yCount , center = True ) : <EOL> """<STR_LIT>""" <EOL> if xSpacing < <NUM_LIT:1> or ySpacing < <NUM_LIT:1> or xCount < <NUM_LIT:1> or yCount < <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> lpoints = [ ] <EOL> for x in range ( xCount ) : <EOL> for y in range ( yCount ) : <EOL> lpoints . append ( ( xSpacing * x , ySpacing * y ) ) <EOL> if center : <EOL> xc = xSpacing * ( xCount - <NUM_LIT:1> ) * <NUM_LIT:0.5> <EOL> yc = ySpacing * ( yCount - <NUM_LIT:1> ) * <NUM_LIT:0.5> <EOL> cpoints = [ ] <EOL> for p in lpoints : <EOL> cpoints . append ( ( p [ <NUM_LIT:0> ] - xc , p [ <NUM_LIT:1> ] - yc ) ) <EOL> lpoints = list ( cpoints ) <EOL> return self . pushPoints ( lpoints ) <EOL> def pushPoints ( self , pntList ) : <EOL> """<STR_LIT>""" <EOL> vecs = [ ] <EOL> for pnt in pntList : <EOL> vec = self . plane . toWorldCoords ( pnt ) <EOL> vecs . append ( vec ) <EOL> return self . newObject ( vecs ) <EOL> def center ( self , x , y ) : <EOL> """<STR_LIT>""" <EOL> "<STR_LIT>" <EOL> self . plane . setOrigin2d ( x , y ) <EOL> n = self . newObject ( [ self . plane . origin ] ) <EOL> return n <EOL> def lineTo ( self , x , y , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> startPoint = self . _findFromPoint ( False ) <EOL> endPoint = self . plane . toWorldCoords ( ( x , y ) ) <EOL> p = Edge . makeLine ( startPoint , endPoint ) <EOL> if not forConstruction : <EOL> self . _addPendingEdge ( p ) <EOL> return self . newObject ( [ p ] ) <EOL> def line ( self , xDist , yDist , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> p = self . _findFromPoint ( True ) <EOL> return self . lineTo ( p . x + xDist , yDist + p . y , forConstruction ) <EOL> def vLine ( self , distance , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> return self . line ( <NUM_LIT:0> , distance , forConstruction ) <EOL> def hLine ( self , distance , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> return self . line ( distance , <NUM_LIT:0> , forConstruction ) <EOL> def vLineTo ( self , yCoord , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> p = self . _findFromPoint ( True ) <EOL> return self . lineTo ( p . x , yCoord , forConstruction ) <EOL> def hLineTo ( self , xCoord , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> p = self . _findFromPoint ( True ) <EOL> return self . lineTo ( xCoord , p . y , forConstruction ) <EOL> def moveTo ( self , x = <NUM_LIT:0> , y = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> newCenter = Vector ( x , y , <NUM_LIT:0> ) <EOL> return self . newObject ( [ self . plane . toWorldCoords ( newCenter ) ] ) <EOL> def move ( self , xDist = <NUM_LIT:0> , yDist = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> p = self . _findFromPoint ( True ) <EOL> newCenter = p + Vector ( xDist , yDist , <NUM_LIT:0> ) <EOL> return self . newObject ( [ self . plane . toWorldCoords ( newCenter ) ] ) <EOL> def spline ( self , listOfXYTuple , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> gstartPoint = self . _findFromPoint ( False ) <EOL> gEndPoint = self . plane . toWorldCoords ( listOfXYTuple [ - <NUM_LIT:1> ] ) <EOL> vecs = [ self . plane . toWorldCoords ( p ) for p in listOfXYTuple ] <EOL> allPoints = [ gstartPoint ] + vecs <EOL> e = Edge . makeSpline ( allPoints ) <EOL> if not forConstruction : <EOL> self . _addPendingEdge ( e ) <EOL> return self . newObject ( [ e ] ) <EOL> def threePointArc ( self , point1 , point2 , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> gstartPoint = self . _findFromPoint ( False ) <EOL> gpoint1 = self . plane . toWorldCoords ( point1 ) <EOL> gpoint2 = self . plane . toWorldCoords ( point2 ) <EOL> arc = Edge . makeThreePointArc ( gstartPoint , gpoint1 , gpoint2 ) <EOL> if not forConstruction : <EOL> self . _addPendingEdge ( arc ) <EOL> return self . newObject ( [ arc ] ) <EOL> def rotateAndCopy ( self , matrix ) : <EOL> """<STR_LIT>""" <EOL> n = self . wire ( forConstruction = False ) <EOL> consolidated = n . consolidateWires ( ) <EOL> rotatedWires = self . plane . rotateShapes ( consolidated . wires ( ) . vals ( ) , matrix ) <EOL> for w in rotatedWires : <EOL> consolidated . objects . append ( w ) <EOL> consolidated . _addPendingWire ( w ) <EOL> c = consolidated . consolidateWires ( ) <EOL> return c <EOL> def mirrorY ( self ) : <EOL> """<STR_LIT>""" <EOL> tm = Matrix ( ) <EOL> tm . rotateY ( math . pi ) <EOL> return self . rotateAndCopy ( tm ) <EOL> def mirrorX ( self ) : <EOL> """<STR_LIT>""" <EOL> tm = Matrix ( ) <EOL> tm . rotateX ( math . pi ) <EOL> return self . rotateAndCopy ( tm ) <EOL> def _addPendingEdge ( self , edge ) : <EOL> """<STR_LIT>""" <EOL> self . ctx . pendingEdges . append ( edge ) <EOL> if self . ctx . firstPoint is None : <EOL> self . ctx . firstPoint = self . plane . toLocalCoords ( edge . startPoint ( ) ) <EOL> def _addPendingWire ( self , wire ) : <EOL> """<STR_LIT>""" <EOL> self . ctx . pendingWires . append ( wire ) <EOL> def consolidateWires ( self ) : <EOL> """<STR_LIT>""" <EOL> wires = self . wires ( ) . vals ( ) <EOL> if len ( wires ) < <NUM_LIT:2> : <EOL> return self <EOL> w = Wire . combine ( wires ) <EOL> r = self . newObject ( [ w ] ) <EOL> r . ctx . pendingWires = [ ] <EOL> r . _addPendingWire ( w ) <EOL> return r <EOL> def wire ( self , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> edges = self . ctx . pendingEdges <EOL> if len ( edges ) == <NUM_LIT:0> : <EOL> return self <EOL> self . ctx . pendingEdges = [ ] <EOL> others = [ ] <EOL> for e in self . objects : <EOL> if type ( e ) != Edge : <EOL> others . append ( e ) <EOL> w = Wire . assembleEdges ( edges ) <EOL> if not forConstruction : <EOL> self . _addPendingWire ( w ) <EOL> return self . newObject ( others + [ w ] ) <EOL> def each ( self , callBackFunction , useLocalCoordinates = False ) : <EOL> """<STR_LIT>""" <EOL> results = [ ] <EOL> for obj in self . objects : <EOL> if useLocalCoordinates : <EOL> r = callBackFunction ( self . plane . toLocalCoords ( obj ) ) <EOL> r = r . transformShape ( self . plane . rG ) <EOL> else : <EOL> r = callBackFunction ( obj ) <EOL> if type ( r ) == Wire : <EOL> if not r . forConstruction : <EOL> self . _addPendingWire ( r ) <EOL> results . append ( r ) <EOL> return self . newObject ( results ) <EOL> def eachpoint ( self , callbackFunction , useLocalCoordinates = False ) : <EOL> """<STR_LIT>""" <EOL> pnts = [ ] <EOL> if len ( self . objects ) == <NUM_LIT:0> : <EOL> pnts . append ( self . plane . origin ) <EOL> else : <EOL> for v in self . objects : <EOL> pnts . append ( v . Center ( ) ) <EOL> return self . newObject ( pnts ) . each ( callbackFunction , useLocalCoordinates ) <EOL> def rect ( self , xLen , yLen , centered = True , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> def makeRectangleWire ( pnt ) : <EOL> if centered : <EOL> p1 = pnt . add ( Vector ( xLen / - <NUM_LIT> , yLen / - <NUM_LIT> , <NUM_LIT:0> ) ) <EOL> p2 = pnt . add ( Vector ( xLen / <NUM_LIT> , yLen / - <NUM_LIT> , <NUM_LIT:0> ) ) <EOL> p3 = pnt . add ( Vector ( xLen / <NUM_LIT> , yLen / <NUM_LIT> , <NUM_LIT:0> ) ) <EOL> p4 = pnt . add ( Vector ( xLen / - <NUM_LIT> , yLen / <NUM_LIT> , <NUM_LIT:0> ) ) <EOL> else : <EOL> p1 = pnt <EOL> p2 = pnt . add ( Vector ( xLen , <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> p3 = pnt . add ( Vector ( xLen , yLen , <NUM_LIT:0> ) ) <EOL> p4 = pnt . add ( Vector ( <NUM_LIT:0> , yLen , <NUM_LIT:0> ) ) <EOL> w = Wire . makePolygon ( [ p1 , p2 , p3 , p4 , p1 ] , forConstruction ) <EOL> return w <EOL> return self . eachpoint ( makeRectangleWire , True ) <EOL> def circle ( self , radius , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> def makeCircleWire ( obj ) : <EOL> cir = Wire . makeCircle ( radius , obj , Vector ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:1> ) ) <EOL> cir . forConstruction = forConstruction <EOL> return cir <EOL> return self . eachpoint ( makeCircleWire , useLocalCoordinates = True ) <EOL> def polygon ( self , nSides , diameter , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> def _makePolygon ( center ) : <EOL> angle = <NUM_LIT> * math . pi / nSides <EOL> pnts = [ ] <EOL> for i in range ( nSides + <NUM_LIT:1> ) : <EOL> pnts . append ( center + Vector ( ( diameter / <NUM_LIT> * math . cos ( angle * i ) ) , <EOL> ( diameter / <NUM_LIT> * math . sin ( angle * i ) ) , <NUM_LIT:0> ) ) <EOL> return Wire . makePolygon ( pnts , forConstruction ) <EOL> return self . eachpoint ( _makePolygon , True ) <EOL> def polyline ( self , listOfXYTuple , forConstruction = False ) : <EOL> """<STR_LIT>""" <EOL> edges = [ ] <EOL> startPoint = self . _findFromPoint ( False ) <EOL> for curTuple in listOfXYTuple : <EOL> endPoint = self . plane . toWorldCoords ( curTuple ) <EOL> edges . append ( Edge . makeLine ( startPoint , endPoint ) ) <EOL> startPoint = endPoint <EOL> if not forConstruction : <EOL> self . _addPendingEdge ( edges [ - <NUM_LIT:1> ] ) <EOL> return self . newObject ( edges ) <EOL> def close ( self ) : <EOL> """<STR_LIT>""" <EOL> self . lineTo ( self . ctx . firstPoint . x , self . ctx . firstPoint . y ) <EOL> self . ctx . firstPoint = None <EOL> return self . wire ( ) <EOL> def largestDimension ( self ) : <EOL> """<STR_LIT>""" <EOL> s = self . findSolid ( ) <EOL> if s : <EOL> return s . BoundingBox ( ) . DiagonalLength * <NUM_LIT> <EOL> else : <EOL> return - <NUM_LIT:1> <EOL> def cutEach ( self , fcn , useLocalCoords = False , clean = True ) : <EOL> """<STR_LIT>""" <EOL> ctxSolid = self . findSolid ( ) <EOL> if ctxSolid is None : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> results = self . eachpoint ( fcn , useLocalCoords ) . vals ( ) <EOL> s = ctxSolid <EOL> for cb in results : <EOL> s = s . cut ( cb ) <EOL> if clean : s = s . clean ( ) <EOL> ctxSolid . wrapped = s . wrapped <EOL> return self . newObject ( [ s ] ) <EOL> def cboreHole ( self , diameter , cboreDiameter , cboreDepth , depth = None , clean = True ) : <EOL> """<STR_LIT>""" <EOL> if depth is None : <EOL> depth = self . largestDimension ( ) <EOL> def _makeCbore ( center ) : <EOL> """<STR_LIT>""" <EOL> boreDir = Vector ( <NUM_LIT:0> , <NUM_LIT:0> , - <NUM_LIT:1> ) <EOL> hole = Solid . makeCylinder ( diameter / <NUM_LIT> , depth , center , boreDir ) <EOL> cbore = Solid . makeCylinder ( cboreDiameter / <NUM_LIT> , cboreDepth , center , boreDir ) <EOL> r = hole . fuse ( cbore ) <EOL> return r <EOL> return self . cutEach ( _makeCbore , True , clean ) <EOL> def cskHole ( self , diameter , cskDiameter , cskAngle , depth = None , clean = True ) : <EOL> """<STR_LIT>""" <EOL> if depth is None : <EOL> depth = self . largestDimension ( ) <EOL> def _makeCsk ( center ) : <EOL> boreDir = Vector ( <NUM_LIT:0> , <NUM_LIT:0> , - <NUM_LIT:1> ) <EOL> hole = Solid . makeCylinder ( diameter / <NUM_LIT> , depth , center , boreDir ) <EOL> r = cskDiameter / <NUM_LIT> <EOL> h = r / math . tan ( math . radians ( cskAngle / <NUM_LIT> ) ) <EOL> csk = Solid . makeCone ( r , <NUM_LIT:0.0> , h , center , boreDir ) <EOL> r = hole . fuse ( csk ) <EOL> return r <EOL> return self . cutEach ( _makeCsk , True , clean ) <EOL> def hole ( self , diameter , depth = None , clean = True ) : <EOL> """<STR_LIT>""" <EOL> if depth is None : <EOL> depth = self . largestDimension ( ) <EOL> def _makeHole ( center ) : <EOL> """<STR_LIT>""" <EOL> boreDir = Vector ( <NUM_LIT:0> , <NUM_LIT:0> , - <NUM_LIT:1> ) <EOL> hole = Solid . makeCylinder ( diameter / <NUM_LIT> , depth , center , boreDir ) <EOL> return hole <EOL> return self . cutEach ( _makeHole , True , clean ) <EOL> def twistExtrude ( self , distance , angleDegrees , combine = True , clean = True ) : <EOL> """<STR_LIT>""" <EOL> wireSets = sortWiresByBuildOrder ( list ( self . ctx . pendingWires ) , self . plane , [ ] ) <EOL> self . ctx . pendingWires = [ ] <EOL> eDir = self . plane . zDir . multiply ( distance ) <EOL> r = None <EOL> for ws in wireSets : <EOL> thisObj = Solid . extrudeLinearWithRotation ( ws [ <NUM_LIT:0> ] , ws [ <NUM_LIT:1> : ] , self . plane . origin , <EOL> eDir , angleDegrees ) <EOL> if r is None : <EOL> r = thisObj <EOL> else : <EOL> r = r . fuse ( thisObj ) <EOL> if combine : <EOL> newS = self . _combineWithBase ( r ) <EOL> else : <EOL> newS = self . newObject ( [ r ] ) <EOL> if clean : newS = newS . clean ( ) <EOL> return newS <EOL> def extrude ( self , distance , combine = True , clean = True ) : <EOL> """<STR_LIT>""" <EOL> r = self . _extrude ( distance ) <EOL> if combine : <EOL> newS = self . _combineWithBase ( r ) <EOL> else : <EOL> newS = self . newObject ( [ r ] ) <EOL> if clean : newS = newS . clean ( ) <EOL> return newS <EOL> def revolve ( self , angleDegrees = <NUM_LIT> , axisStart = None , axisEnd = None , combine = True , clean = True ) : <EOL> """<STR_LIT>""" <EOL> angleDegrees %= <NUM_LIT> <EOL> angleDegrees = <NUM_LIT> if angleDegrees == <NUM_LIT:0> else angleDegrees <EOL> if axisStart is None : <EOL> axisStart = self . plane . toWorldCoords ( ( <NUM_LIT:0> , <NUM_LIT:0> ) ) . toTuple ( ) <EOL> else : <EOL> axisStart = self . plane . toWorldCoords ( axisStart ) . toTuple ( ) <EOL> if axisEnd is None : <EOL> if axisStart [ <NUM_LIT:1> ] != <NUM_LIT:0> : <EOL> axisEnd = self . plane . toWorldCoords ( ( <NUM_LIT:0> , axisStart [ <NUM_LIT:1> ] ) ) . toTuple ( ) <EOL> else : <EOL> axisEnd = self . plane . toWorldCoords ( ( <NUM_LIT:0> , <NUM_LIT:1> ) ) . toTuple ( ) <EOL> else : <EOL> axisEnd = self . plane . toWorldCoords ( axisEnd ) . toTuple ( ) <EOL> r = self . _revolve ( angleDegrees , axisStart , axisEnd ) <EOL> if combine : <EOL> newS = self . _combineWithBase ( r ) <EOL> else : <EOL> newS = self . newObject ( [ r ] ) <EOL> if clean : newS = newS . clean ( ) <EOL> return newS <EOL> def sweep ( self , path , makeSolid = True , isFrenet = False , combine = True , clean = True ) : <EOL> """<STR_LIT>""" <EOL> r = self . _sweep ( path . wire ( ) , makeSolid , isFrenet ) <EOL> if combine : <EOL> newS = self . _combineWithBase ( r ) <EOL> else : <EOL> newS = self . newObject ( [ r ] ) <EOL> if clean : newS = newS . clean ( ) <EOL> return newS <EOL> def _combineWithBase ( self , obj ) : <EOL> """<STR_LIT>""" <EOL> baseSolid = self . findSolid ( searchParents = True ) <EOL> r = obj <EOL> if baseSolid is not None : <EOL> r = baseSolid . fuse ( obj ) <EOL> baseSolid . wrapped = r . wrapped <EOL> return self . newObject ( [ r ] ) <EOL> def combine ( self , clean = True ) : <EOL> """<STR_LIT>""" <EOL> items = list ( self . objects ) <EOL> s = items . pop ( <NUM_LIT:0> ) <EOL> for ss in items : <EOL> s = s . fuse ( ss ) <EOL> if clean : s = s . clean ( ) <EOL> return self . newObject ( [ s ] ) <EOL> def union ( self , toUnion = None , combine = True , clean = True ) : <EOL> """<STR_LIT>""" <EOL> if type ( toUnion ) == CQ or type ( toUnion ) == Workplane : <EOL> solids = toUnion . solids ( ) . vals ( ) <EOL> if len ( solids ) < <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> newS = solids . pop ( <NUM_LIT:0> ) <EOL> for s in solids : <EOL> newS = newS . fuse ( s ) <EOL> elif type ( toUnion ) == Solid : <EOL> newS = toUnion <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" . format ( type ( toUnion ) ) ) <EOL> solidRef = self . findSolid ( searchStack = True , searchParents = True ) <EOL> if combine and solidRef is not None : <EOL> r = solidRef . fuse ( newS ) <EOL> solidRef . wrapped = newS . wrapped <EOL> else : <EOL> r = newS <EOL> if clean : r = r . clean ( ) <EOL> return self . newObject ( [ r ] ) <EOL> def cut ( self , toCut , combine = True , clean = True ) : <EOL> """<STR_LIT>""" <EOL> solidRef = self . findSolid ( searchStack = True , searchParents = True ) <EOL> if solidRef is None : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> solidToCut = None <EOL> if type ( toCut ) == CQ or type ( toCut ) == Workplane : <EOL> solidToCut = toCut . val ( ) <EOL> elif type ( toCut ) == Solid : <EOL> solidToCut = toCut <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" . format ( type ( toCut ) ) ) <EOL> newS = solidRef . cut ( solidToCut ) <EOL> if clean : newS = newS . clean ( ) <EOL> if combine : <EOL> solidRef . wrapped = newS . wrapped <EOL> return self . newObject ( [ newS ] ) <EOL> def cutBlind ( self , distanceToCut , clean = True ) : <EOL> """<STR_LIT>""" <EOL> toCut = self . _extrude ( distanceToCut ) <EOL> solidRef = self . findSolid ( ) <EOL> s = solidRef . cut ( toCut ) <EOL> if clean : s = s . clean ( ) <EOL> solidRef . wrapped = s . wrapped <EOL> return self . newObject ( [ s ] ) <EOL> def cutThruAll ( self , positive = False , clean = True ) : <EOL> """<STR_LIT>""" <EOL> maxDim = self . largestDimension ( ) <EOL> if not positive : <EOL> maxDim *= ( - <NUM_LIT:1.0> ) <EOL> return self . cutBlind ( maxDim , clean ) <EOL> def loft ( self , filled = True , ruled = False , combine = True ) : <EOL> """<STR_LIT>""" <EOL> wiresToLoft = self . ctx . pendingWires <EOL> self . ctx . pendingWires = [ ] <EOL> r = Solid . makeLoft ( wiresToLoft , ruled ) <EOL> if combine : <EOL> parentSolid = self . findSolid ( searchStack = False , searchParents = True ) <EOL> if parentSolid is not None : <EOL> r = parentSolid . fuse ( r ) <EOL> parentSolid . wrapped = r . wrapped <EOL> return self . newObject ( [ r ] ) <EOL> def _extrude ( self , distance ) : <EOL> """<STR_LIT>""" <EOL> s = time . time ( ) <EOL> wireSets = sortWiresByBuildOrder ( list ( self . ctx . pendingWires ) , self . plane , [ ] ) <EOL> self . ctx . pendingWires = [ ] <EOL> eDir = self . plane . zDir . multiply ( distance ) <EOL> toFuse = [ ] <EOL> for ws in wireSets : <EOL> thisObj = Solid . extrudeLinear ( ws [ <NUM_LIT:0> ] , ws [ <NUM_LIT:1> : ] , eDir ) <EOL> toFuse . append ( thisObj ) <EOL> return Compound . makeCompound ( toFuse ) <EOL> def _revolve ( self , angleDegrees , axisStart , axisEnd ) : <EOL> """<STR_LIT>""" <EOL> wireSets = sortWiresByBuildOrder ( list ( self . ctx . pendingWires ) , self . plane , [ ] ) <EOL> self . ctx . pendingWires = [ ] <EOL> toFuse = [ ] <EOL> for ws in wireSets : <EOL> thisObj = Solid . revolve ( ws [ <NUM_LIT:0> ] , ws [ <NUM_LIT:1> : ] , angleDegrees , axisStart , axisEnd ) <EOL> toFuse . append ( thisObj ) <EOL> return Compound . makeCompound ( toFuse ) <EOL> def _sweep ( self , path , makeSolid = True , isFrenet = False ) : <EOL> """<STR_LIT>""" <EOL> s = time . time ( ) <EOL> wireSets = sortWiresByBuildOrder ( list ( self . ctx . pendingWires ) , self . plane , [ ] ) <EOL> self . ctx . pendingWires = [ ] <EOL> toFuse = [ ] <EOL> for ws in wireSets : <EOL> thisObj = Solid . sweep ( ws [ <NUM_LIT:0> ] , ws [ <NUM_LIT:1> : ] , path . val ( ) , makeSolid , isFrenet ) <EOL> toFuse . append ( thisObj ) <EOL> return Compound . makeCompound ( toFuse ) <EOL> def box ( self , length , width , height , centered = ( True , True , True ) , combine = True , clean = True ) : <EOL> """<STR_LIT>""" <EOL> def _makebox ( pnt ) : <EOL> ( xp , yp , zp ) = pnt . toTuple ( ) <EOL> if centered [ <NUM_LIT:0> ] : <EOL> xp -= ( length / <NUM_LIT> ) <EOL> if centered [ <NUM_LIT:1> ] : <EOL> yp -= ( width / <NUM_LIT> ) <EOL> if centered [ <NUM_LIT:2> ] : <EOL> zp -= ( height / <NUM_LIT> ) <EOL> return Solid . makeBox ( length , width , height , Vector ( xp , yp , zp ) ) <EOL> boxes = self . eachpoint ( _makebox , True ) <EOL> if not combine : <EOL> return boxes <EOL> else : <EOL> return self . union ( boxes , clean = clean ) <EOL> def sphere ( self , radius , direct = ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:1> ) , angle1 = - <NUM_LIT> , angle2 = <NUM_LIT> , angle3 = <NUM_LIT> , <EOL> centered = ( True , True , True ) , combine = True , clean = True ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( direct , tuple ) : <EOL> direct = Vector ( direct ) <EOL> def _makesphere ( pnt ) : <EOL> """<STR_LIT>""" <EOL> ( xp , yp , zp ) = pnt . toTuple ( ) <EOL> if not centered [ <NUM_LIT:0> ] : <EOL> xp += radius <EOL> if not centered [ <NUM_LIT:1> ] : <EOL> yp += radius <EOL> if not centered [ <NUM_LIT:2> ] : <EOL> zp += radius <EOL> return Solid . makeSphere ( radius , Vector ( xp , yp , zp ) , direct , angle1 , angle2 , angle3 ) <EOL> spheres = self . eachpoint ( _makesphere , True ) <EOL> if not combine : <EOL> return spheres <EOL> else : <EOL> return self . union ( spheres , clean = clean ) <EOL> def clean ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> cleanObjects = [ obj . clean ( ) for obj in self . objects ] <EOL> except AttributeError : <EOL> raise AttributeError ( "<STR_LIT>" % obj . ShapeType ( ) ) <EOL> return self . newObject ( cleanObjects ) </s>
