From 30d0f6dc0412563e8435af35041a8dbd39c02721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hasan=20Yavuz=20=C3=96ZDERYA?= Date: Mon, 15 Jun 2015 11:01:22 +0300 Subject: [PATCH 01/10] added box selector --- cadquery/selectors.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/cadquery/selectors.py b/cadquery/selectors.py index 07fc31e..5051f0f 100644 --- a/cadquery/selectors.py +++ b/cadquery/selectors.py @@ -70,6 +70,36 @@ class NearestToPointSelector(Selector): return [ min(objectList,key=dist) ] +class BoxSelector(Selector): + """ + Selects objects inside the 3D box defined by 2 points. + + Applicability: all types of shapes + + Example:: + + CQ(aCube).edges(BoxSelector((0,1,0), (1,2,1)) + """ + def __init__(self, point0, point1): + self.p0 = Vector(*point0) + self.p1 = Vector(*point1) + + def filter(self, objectList): + + result = [] + x0, y0, z0 = self.p0.toTuple() + x1, y1, z1 = self.p1.toTuple() + + for o in objectList: + c = o.Center() + # using XOR for checking if x/y/z is in between regardless + # of order of x/y/z0 and x/y/z1 + if ((c.x < x0) ^ (c.x < x1)) and \ + ((c.y < y0) ^ (c.y < y1)) and \ + ((c.z < z0) ^ (c.z < z1)): + result.append(o) + + return result class BaseDirSelector(Selector): """ From 6e15431d0a694f65ae1d7fced63b9a9857e0ef20 Mon Sep 17 00:00:00 2001 From: hyOzd Date: Mon, 15 Jun 2015 23:11:23 +0300 Subject: [PATCH 02/10] added boundingbox option to BoxSelector --- cadquery/selectors.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/cadquery/selectors.py b/cadquery/selectors.py index 5051f0f..72362c8 100644 --- a/cadquery/selectors.py +++ b/cadquery/selectors.py @@ -74,15 +74,20 @@ 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): + def __init__(self, point0, point1, boundingbox=False): self.p0 = Vector(*point0) self.p1 = Vector(*point1) + self.test_boundingbox = boundingbox def filter(self, objectList): @@ -90,14 +95,22 @@ class BoxSelector(Selector): x0, y0, z0 = self.p0.toTuple() x1, y1, z1 = self.p1.toTuple() - for o in objectList: - c = o.Center() + 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 - if ((c.x < x0) ^ (c.x < x1)) and \ - ((c.y < y0) ^ (c.y < y1)) and \ - ((c.z < z0) ^ (c.z < z1)): - result.append(o) + 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 From 27948156b262724427921cf156b70670fc101164 Mon Sep 17 00:00:00 2001 From: hyOzd Date: Tue, 16 Jun 2015 21:51:31 +0300 Subject: [PATCH 03/10] added tests for selecting vertices with BoxSelector --- tests/TestCQSelectors.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/TestCQSelectors.py b/tests/TestCQSelectors.py index e81a393..977f6f2 100644 --- a/tests/TestCQSelectors.py +++ b/tests/TestCQSelectors.py @@ -178,6 +178,28 @@ 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) + def testFaceCount(self): c = CQ(makeUnitCube()) self.assertEqual( 6, c.faces().size() ) @@ -194,4 +216,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) \ No newline at end of file + self.assertTupleAlmostEquals((0.0,0.0,1.0),v2.val().toTuple() ,3) From d5b9b38c7fbe3fe078e121cfbac9617d95c0db40 Mon Sep 17 00:00:00 2001 From: hyOzd Date: Tue, 16 Jun 2015 21:55:28 +0300 Subject: [PATCH 04/10] test boxselector again by swapping box points --- tests/TestCQSelectors.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/TestCQSelectors.py b/tests/TestCQSelectors.py index 977f6f2..ab62491 100644 --- a/tests/TestCQSelectors.py +++ b/tests/TestCQSelectors.py @@ -200,6 +200,12 @@ class TestCQSelectors(BaseTest): 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) + def testFaceCount(self): c = CQ(makeUnitCube()) self.assertEqual( 6, c.faces().size() ) From f3fc050913e193a1955d2d80b378f25fe0157515 Mon Sep 17 00:00:00 2001 From: hyOzd Date: Tue, 16 Jun 2015 22:11:48 +0300 Subject: [PATCH 05/10] added tests for selecting edges with BoxSelector --- tests/TestCQSelectors.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/TestCQSelectors.py b/tests/TestCQSelectors.py index ab62491..f8256de 100644 --- a/tests/TestCQSelectors.py +++ b/tests/TestCQSelectors.py @@ -206,6 +206,27 @@ class TestCQSelectors(BaseTest): v = vl[0] self.assertTupleAlmostEquals(d[2], (v.X, v.Y, v.Z), 3) + # 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) + def testFaceCount(self): c = CQ(makeUnitCube()) self.assertEqual( 6, c.faces().size() ) From c9a8d5d72d1b5b8c565105b483445cec17a17464 Mon Sep 17 00:00:00 2001 From: hyOzd Date: Tue, 16 Jun 2015 22:23:12 +0300 Subject: [PATCH 06/10] added test for selecting faces with BoxSelector --- tests/TestCQSelectors.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/TestCQSelectors.py b/tests/TestCQSelectors.py index f8256de..de74437 100644 --- a/tests/TestCQSelectors.py +++ b/tests/TestCQSelectors.py @@ -227,6 +227,28 @@ class TestCQSelectors(BaseTest): ec = el[0].Center() self.assertTupleAlmostEquals(d[2], (ec.x, ec.y, ec.z), 3) + # 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) + + def testFaceCount(self): c = CQ(makeUnitCube()) self.assertEqual( 6, c.faces().size() ) From 7be4d5a90a8d9e155efe0df444eb843999d367a9 Mon Sep 17 00:00:00 2001 From: hyOzd Date: Tue, 16 Jun 2015 22:25:36 +0300 Subject: [PATCH 07/10] test multiple vertices selection with boxselector --- tests/TestCQSelectors.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/TestCQSelectors.py b/tests/TestCQSelectors.py index de74437..75c701b 100644 --- a/tests/TestCQSelectors.py +++ b/tests/TestCQSelectors.py @@ -206,6 +206,12 @@ class TestCQSelectors(BaseTest): 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 From 67b1844798bbe10b0f0e5c38fe0ff60127d63bbc Mon Sep 17 00:00:00 2001 From: hyOzd Date: Tue, 16 Jun 2015 22:46:31 +0300 Subject: [PATCH 08/10] test multiple edge selection with boxselector --- tests/TestCQSelectors.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/TestCQSelectors.py b/tests/TestCQSelectors.py index 75c701b..5e76910 100644 --- a/tests/TestCQSelectors.py +++ b/tests/TestCQSelectors.py @@ -233,6 +233,12 @@ class TestCQSelectors(BaseTest): 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 From b3352790d0dc9ffed4edf5ec164796f3c328fb03 Mon Sep 17 00:00:00 2001 From: hyOzd Date: Tue, 16 Jun 2015 22:49:08 +0300 Subject: [PATCH 09/10] test multiple face selection with boxselector --- tests/TestCQSelectors.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/TestCQSelectors.py b/tests/TestCQSelectors.py index 5e76910..b1f710a 100644 --- a/tests/TestCQSelectors.py +++ b/tests/TestCQSelectors.py @@ -260,6 +260,11 @@ class TestCQSelectors(BaseTest): 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)) def testFaceCount(self): c = CQ(makeUnitCube()) From c97eb8aed603155dd535d74294314e99aeb73ca3 Mon Sep 17 00:00:00 2001 From: hyOzd Date: Tue, 16 Jun 2015 22:56:01 +0300 Subject: [PATCH 10/10] test boundingbox option of the boxselector --- tests/TestCQSelectors.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/TestCQSelectors.py b/tests/TestCQSelectors.py index b1f710a..678766a 100644 --- a/tests/TestCQSelectors.py +++ b/tests/TestCQSelectors.py @@ -266,6 +266,14 @@ class TestCQSelectors(BaseTest): 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() )