Merge pull request #147 from adam-urbanczyk/master
DirectionNthSelector --> selects Nth face/wire normal/parallel to given direction
This commit is contained in:
commit
0ef569ab84
|
@ -306,15 +306,66 @@ class DirectionMinMaxSelector(Selector):
|
||||||
# pnt = tShape.Center()
|
# pnt = tShape.Center()
|
||||||
#return pnt.dot(self.vector)
|
#return pnt.dot(self.vector)
|
||||||
|
|
||||||
|
# import OrderedDict
|
||||||
|
from collections import OrderedDict
|
||||||
|
#make and distance to object dict
|
||||||
|
objectDict = {distance(el) : el for el in objectList}
|
||||||
|
#transform it into an ordered dict
|
||||||
|
objectDict = OrderedDict(sorted(objectDict.items(),
|
||||||
|
key=lambda x: x[0]))
|
||||||
|
|
||||||
# find out the max/min distance
|
# find out the max/min distance
|
||||||
if self.directionMax:
|
if self.directionMax:
|
||||||
d = max(map(distance, objectList))
|
d = objectDict.keys()[-1]
|
||||||
else:
|
else:
|
||||||
d = min(map(distance, objectList))
|
d = objectDict.keys()[0]
|
||||||
|
|
||||||
# return all objects at the max/min distance (within a tolerance)
|
# return all objects at the max/min distance (within a tolerance)
|
||||||
return filter(lambda o: abs(d - distance(o)) < self.TOLERANCE, objectList)
|
return filter(lambda o: abs(d - distance(o)) < self.TOLERANCE, objectList)
|
||||||
|
|
||||||
|
class DirectionNthSelector(ParallelDirSelector):
|
||||||
|
"""
|
||||||
|
Selects nth object parallel (or normal) to the specified direction
|
||||||
|
Used for faces and edges
|
||||||
|
|
||||||
|
Applicability:
|
||||||
|
Linear Edges
|
||||||
|
Planar Faces
|
||||||
|
"""
|
||||||
|
def __init__(self, vector, n, directionMax=True, tolerance=0.0001):
|
||||||
|
self.direction = vector
|
||||||
|
self.max = max
|
||||||
|
self.directionMax = directionMax
|
||||||
|
self.TOLERANCE = tolerance
|
||||||
|
if directionMax:
|
||||||
|
self.N = n #do we want indexing from 0 or from 1?
|
||||||
|
else:
|
||||||
|
self.N = -n
|
||||||
|
|
||||||
|
def filter(self,objectList):
|
||||||
|
#select first the objects that are normal/parallel to a given dir
|
||||||
|
objectList = super(DirectionNthSelector,self).filter(objectList)
|
||||||
|
|
||||||
|
def distance(tShape):
|
||||||
|
return tShape.Center().dot(self.direction)
|
||||||
|
#if tShape.ShapeType == 'Vertex':
|
||||||
|
# pnt = tShape.Point
|
||||||
|
#else:
|
||||||
|
# pnt = tShape.Center()
|
||||||
|
#return pnt.dot(self.vector)
|
||||||
|
|
||||||
|
#make and distance to object dict
|
||||||
|
objectDict = {distance(el) : el for el in objectList}
|
||||||
|
#calculate how many digits of precision do we need
|
||||||
|
digits = int(1/self.TOLERANCE)
|
||||||
|
# create a rounded distance to original distance mapping (implicitly perfroms unique operation)
|
||||||
|
dist_round_dist = {round(d,digits) : d for d in objectDict.keys()}
|
||||||
|
# choose the Nth unique rounded distance
|
||||||
|
nth_d = dist_round_dist[sorted(dist_round_dist.keys())[self.N]]
|
||||||
|
|
||||||
|
# map back to original objects and return
|
||||||
|
return [objectDict[d] for d in objectDict.keys() if abs(d-nth_d) < self.TOLERANCE]
|
||||||
|
|
||||||
class BinarySelector(Selector):
|
class BinarySelector(Selector):
|
||||||
"""
|
"""
|
||||||
Base class for selectors that operates with two other
|
Base class for selectors that operates with two other
|
||||||
|
|
|
@ -167,6 +167,28 @@ class TestCQSelectors(BaseTest):
|
||||||
el = c.edges("<Z").vals()
|
el = c.edges("<Z").vals()
|
||||||
self.assertEqual(4, len(el))
|
self.assertEqual(4, len(el))
|
||||||
|
|
||||||
|
def testNthDistance(self):
|
||||||
|
c = Workplane('XY').pushPoints([(-2,0),(2,0)]).box(1,1,1)
|
||||||
|
|
||||||
|
#2nd face
|
||||||
|
val = c.faces(selectors.DirectionNthSelector(Vector(1,0,0),1)).val()
|
||||||
|
self.assertAlmostEqual(val.Center().x,-1.5)
|
||||||
|
|
||||||
|
#2nd face with inversed selection vector
|
||||||
|
val = c.faces(selectors.DirectionNthSelector(Vector(-1,0,0),1)).val()
|
||||||
|
self.assertAlmostEqual(val.Center().x,1.5)
|
||||||
|
|
||||||
|
#2nd last face
|
||||||
|
val = c.faces(selectors.DirectionNthSelector(Vector(1,0,0),-2)).val()
|
||||||
|
self.assertAlmostEqual(val.Center().x,1.5)
|
||||||
|
|
||||||
|
#Last face
|
||||||
|
val = c.faces(selectors.DirectionNthSelector(Vector(1,0,0),-1)).val()
|
||||||
|
self.assertAlmostEqual(val.Center().x,2.5)
|
||||||
|
|
||||||
|
#check if the selected face if normal to the specified Vector
|
||||||
|
self.assertAlmostEqual(val.normalAt().cross(Vector(1,0,0)).Length,0.0)
|
||||||
|
|
||||||
def testNearestTo(self):
|
def testNearestTo(self):
|
||||||
c = CQ(makeUnitCube())
|
c = CQ(makeUnitCube())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user