Merge pull request #95 from hyOzd/add-boxselector
Added 3d box selector with an option to use the bounding box for selection.
This commit is contained in:
commit
645e3cd6f7
|
@ -70,6 +70,49 @@ class NearestToPointSelector(Selector):
|
|||
|
||||
return [ min(objectList,key=dist) ]
|
||||
|
||||
class BoxSelector(Selector):
|
||||
"""
|
||||
Selects objects inside the 3D box defined by 2 points.
|
||||
|
||||
If `boundingbox` is True only the objects that have their bounding
|
||||
box inside the given box is selected. Otherwise only center point
|
||||
of the object is tested.
|
||||
|
||||
Applicability: all types of shapes
|
||||
|
||||
Example::
|
||||
|
||||
CQ(aCube).edges(BoxSelector((0,1,0), (1,2,1))
|
||||
"""
|
||||
def __init__(self, point0, point1, boundingbox=False):
|
||||
self.p0 = Vector(*point0)
|
||||
self.p1 = Vector(*point1)
|
||||
self.test_boundingbox = boundingbox
|
||||
|
||||
def filter(self, objectList):
|
||||
|
||||
result = []
|
||||
x0, y0, z0 = self.p0.toTuple()
|
||||
x1, y1, z1 = self.p1.toTuple()
|
||||
|
||||
def isInsideBox(p):
|
||||
# using XOR for checking if x/y/z is in between regardless
|
||||
# of order of x/y/z0 and x/y/z1
|
||||
return ((p.x < x0) ^ (p.x < x1)) and \
|
||||
((p.y < y0) ^ (p.y < y1)) and \
|
||||
((p.z < z0) ^ (p.z < z1))
|
||||
|
||||
for o in objectList:
|
||||
if self.test_boundingbox:
|
||||
bb = o.BoundingBox()
|
||||
if isInsideBox(Vector(bb.xmin, bb.ymin, bb.zmin)) and \
|
||||
isInsideBox(Vector(bb.xmax, bb.ymax, bb.zmax)):
|
||||
result.append(o)
|
||||
else:
|
||||
if isInsideBox(o.Center()):
|
||||
result.append(o)
|
||||
|
||||
return result
|
||||
|
||||
class BaseDirSelector(Selector):
|
||||
"""
|
||||
|
|
|
@ -178,6 +178,102 @@ class TestCQSelectors(BaseTest):
|
|||
s = c.solids(selectors.NearestToPointSelector(t)).vals()
|
||||
self.assertEqual(1,len(s))
|
||||
|
||||
def testBox(self):
|
||||
c = CQ(makeUnitCube())
|
||||
|
||||
# test vertice selection
|
||||
test_data_vertices = [
|
||||
# box point0, box point1, selected vertice
|
||||
((0.9, 0.9, 0.9), (1.1, 1.1, 1.1), (1.0, 1.0, 1.0)),
|
||||
((-0.1, 0.9, 0.9), (0.9, 1.1, 1.1), (0.0, 1.0, 1.0)),
|
||||
((-0.1, -0.1, 0.9), (0.1, 0.1, 1.1), (0.0, 0.0, 1.0)),
|
||||
((-0.1, -0.1, -0.1), (0.1, 0.1, 0.1), (0.0, 0.0, 0.0)),
|
||||
((0.9, -0.1, -0.1), (1.1, 0.1, 0.1), (1.0, 0.0, 0.0)),
|
||||
((0.9, 0.9, -0.1), (1.1, 1.1, 0.1), (1.0, 1.0, 0.0)),
|
||||
((-0.1, 0.9, -0.1), (0.1, 1.1, 0.1), (0.0, 1.0, 0.0)),
|
||||
((0.9, -0.1, 0.9), (1.1, 0.1, 1.1), (1.0, 0.0, 1.0))
|
||||
]
|
||||
|
||||
for d in test_data_vertices:
|
||||
vl = c.vertices(selectors.BoxSelector(d[0], d[1])).vals()
|
||||
self.assertEqual(1, len(vl))
|
||||
v = vl[0]
|
||||
self.assertTupleAlmostEquals(d[2], (v.X, v.Y, v.Z), 3)
|
||||
|
||||
# this time box points are swapped
|
||||
vl = c.vertices(selectors.BoxSelector(d[1], d[0])).vals()
|
||||
self.assertEqual(1, len(vl))
|
||||
v = vl[0]
|
||||
self.assertTupleAlmostEquals(d[2], (v.X, v.Y, v.Z), 3)
|
||||
|
||||
# test multiple vertices selection
|
||||
vl = c.vertices(selectors.BoxSelector((-0.1, -0.1, 0.9),(0.1, 1.1, 1.1))).vals()
|
||||
self.assertEqual(2, len(vl))
|
||||
vl = c.vertices(selectors.BoxSelector((-0.1, -0.1, -0.1),(0.1, 1.1, 1.1))).vals()
|
||||
self.assertEqual(4, len(vl))
|
||||
|
||||
# test edge selection
|
||||
test_data_edges = [
|
||||
# box point0, box point1, edge center
|
||||
((0.4, -0.1, -0.1), (0.6, 0.1, 0.1), (0.5, 0.0, 0.0)),
|
||||
((-0.1, -0.1, 0.4), (0.1, 0.1, 0.6), (0.0, 0.0, 0.5)),
|
||||
((0.9, 0.9, 0.4), (1.1, 1.1, 0.6), (1.0, 1.0, 0.5)),
|
||||
((0.4, 0.9, 0.9), (0.6, 1.1, 1.1,), (0.5, 1.0, 1.0))
|
||||
]
|
||||
|
||||
for d in test_data_edges:
|
||||
el = c.edges(selectors.BoxSelector(d[0], d[1])).vals()
|
||||
self.assertEqual(1, len(el))
|
||||
ec = el[0].Center()
|
||||
self.assertTupleAlmostEquals(d[2], (ec.x, ec.y, ec.z), 3)
|
||||
|
||||
# test again by swapping box points
|
||||
el = c.edges(selectors.BoxSelector(d[1], d[0])).vals()
|
||||
self.assertEqual(1, len(el))
|
||||
ec = el[0].Center()
|
||||
self.assertTupleAlmostEquals(d[2], (ec.x, ec.y, ec.z), 3)
|
||||
|
||||
# test multiple edge selection
|
||||
el = c.edges(selectors.BoxSelector((-0.1, -0.1, -0.1), (0.6, 0.1, 0.6))).vals()
|
||||
self.assertEqual(2, len(el))
|
||||
el = c.edges(selectors.BoxSelector((-0.1, -0.1, -0.1), (1.1, 0.1, 0.6))).vals()
|
||||
self.assertEqual(3, len(el))
|
||||
|
||||
# test face selection
|
||||
test_data_faces = [
|
||||
# box point0, box point1, face center
|
||||
((0.4, -0.1, 0.4), (0.6, 0.1, 0.6), (0.5, 0.0, 0.5)),
|
||||
((0.9, 0.4, 0.4), (1.1, 0.6, 0.6), (1.0, 0.5, 0.5)),
|
||||
((0.4, 0.4, 0.9), (0.6, 0.6, 1.1), (0.5, 0.5, 1.0)),
|
||||
((0.4, 0.4, -0.1), (0.6, 0.6, 0.1), (0.5, 0.5, 0.0))
|
||||
]
|
||||
|
||||
for d in test_data_faces:
|
||||
fl = c.faces(selectors.BoxSelector(d[0], d[1])).vals()
|
||||
self.assertEqual(1, len(fl))
|
||||
fc = fl[0].Center()
|
||||
self.assertTupleAlmostEquals(d[2], (fc.x, fc.y, fc.z), 3)
|
||||
|
||||
# test again by swapping box points
|
||||
fl = c.faces(selectors.BoxSelector(d[1], d[0])).vals()
|
||||
self.assertEqual(1, len(fl))
|
||||
fc = fl[0].Center()
|
||||
self.assertTupleAlmostEquals(d[2], (fc.x, fc.y, fc.z), 3)
|
||||
|
||||
# test multiple face selection
|
||||
fl = c.faces(selectors.BoxSelector((0.4, 0.4, 0.4), (0.6, 1.1, 1.1))).vals()
|
||||
self.assertEqual(2, len(fl))
|
||||
fl = c.faces(selectors.BoxSelector((0.4, 0.4, 0.4), (1.1, 1.1, 1.1))).vals()
|
||||
self.assertEqual(3, len(fl))
|
||||
|
||||
# test boundingbox option
|
||||
el = c.edges(selectors.BoxSelector((-0.1, -0.1, -0.1), (1.1, 0.1, 0.6), True)).vals()
|
||||
self.assertEqual(1, len(el))
|
||||
fl = c.faces(selectors.BoxSelector((0.4, 0.4, 0.4), (1.1, 1.1, 1.1), True)).vals()
|
||||
self.assertEqual(0, len(fl))
|
||||
fl = c.faces(selectors.BoxSelector((-0.1, 0.4, -0.1), (1.1, 1.1, 1.1), True)).vals()
|
||||
self.assertEqual(1, len(fl))
|
||||
|
||||
def testFaceCount(self):
|
||||
c = CQ(makeUnitCube())
|
||||
self.assertEqual( 6, c.faces().size() )
|
||||
|
@ -194,4 +290,4 @@ class TestCQSelectors(BaseTest):
|
|||
self.assertEqual(1,v2.size() ) #another way
|
||||
#make sure the vertex is the right one
|
||||
|
||||
self.assertTupleAlmostEquals((0.0,0.0,1.0),v2.val().toTuple() ,3)
|
||||
self.assertTupleAlmostEquals((0.0,0.0,1.0),v2.val().toTuple() ,3)
|
||||
|
|
Loading…
Reference in New Issue
Block a user