From 21200cc10d137cef0be50f41046d528226255b5e Mon Sep 17 00:00:00 2001 From: Jeremy Mack Wright Date: Mon, 11 Sep 2017 21:49:14 -0400 Subject: [PATCH] Added CQGI debug objects. --- Gui/Command.py | 13 ++++++- Libs/cadquery-lib/cadquery/cq.py | 46 ++++++++++++++++++++++--- Libs/cadquery-lib/cadquery/cqgi.py | 9 +++-- Libs/cadquery-lib/tests/TestCadQuery.py | 27 ++++++++++----- 4 files changed, 77 insertions(+), 18 deletions(-) diff --git a/Gui/Command.py b/Gui/Command.py index 329496b..bb5254f 100644 --- a/Gui/Command.py +++ b/Gui/Command.py @@ -9,6 +9,7 @@ import ExportCQ, ImportCQ import module_locator import Settings import Shared +from random import random from cadquery import cqgi from Helpers import show @@ -130,7 +131,7 @@ class CadQueryExecuteScript: scriptText = cqCodePane.toPlainText().encode('utf-8') # Check to see if we are executig a CQGI compliant script - if "build_object(" in scriptText and "# build_object(" not in scriptText and "#build_boject(" not in scriptText: + if ("build_object(" in scriptText and "# build_object(" not in scriptText and "#build_boject(" not in scriptText) or ("debug(" in scriptText and "# debug(" not in scriptText and "#debug(" not in scriptText): FreeCAD.Console.PrintMessage("Executing CQGI-compliant script.\r\n") # A repreentation of the CQ script with all the metadata attached @@ -173,6 +174,16 @@ class CadQueryExecuteScript: show(result.shape, result.options["rgba"]) else: show(result.shape) + + for debugObj in build_result.debugObjects: + # Mark this as a debug object + debugObj.shape.val().label = "Debug" + str(random()) + + # Apply options to the show function if any were provided + if debugObj.options and debugObj.options["rgba"]: + show(debugObj.shape, debugObj.options["rgba"]) + else: + show(debugObj.shape, (255, 0, 0, 0.80)) else: FreeCAD.Console.PrintError("Error executing CQGI-compliant script. " + str(build_result.exception) + "\r\n") else: diff --git a/Libs/cadquery-lib/cadquery/cq.py b/Libs/cadquery-lib/cadquery/cq.py index 97f135b..dc685c9 100644 --- a/Libs/cadquery-lib/cadquery/cq.py +++ b/Libs/cadquery-lib/cadquery/cq.py @@ -341,7 +341,7 @@ class CQ(object): if not all(_isCoPlanar(self.objects[0], f) for f in self.objects[1:]): raise ValueError("Selected faces must be co-planar.") - if centerOption == 'CenterOfMass': + if centerOption == 'CenterOfMass': center = Shape.CombinedCenter(self.objects) elif centerOption == 'CenterOfBoundBox': center = Shape.CombinedCenterOfBoundBox(self.objects) @@ -1991,9 +1991,9 @@ class Workplane(CQ): Support for non-prismatic extrusion ( IE, sweeping along a profile, not just perpendicular to the plane extrude to surface. this is quite tricky since the surface selected may not be planar - """ + """ r = self._extrude(distance,both=both) # returns a Solid (or a compound if there were multiple) - + if combine: newS = self._combineWithBase(r) else: @@ -2184,6 +2184,44 @@ class Workplane(CQ): return self.newObject([newS]) + def intersect(self, toIntersect, combine=True, clean=True): + """ + Intersects the provided solid from the current solid. + + if combine=True, the result and the original are updated to point to the new object + if combine=False, the result will be on the stack, but the original is unmodified + + :param toIntersect: object to intersect + :type toIntersect: a solid object, or a CQ object having a solid, + :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape + :raises: ValueError if there is no solid to intersect with in the chain + :return: a CQ object with the resulting object selected + """ + + # look for parents to intersect with + solidRef = self.findSolid(searchStack=True, searchParents=True) + + if solidRef is None: + raise ValueError("Cannot find solid to intersect with") + solidToIntersect = None + + if isinstance(toIntersect, CQ): + solidToIntersect = toIntersect.val() + elif isinstance(toIntersect, Solid): + solidToIntersect = toIntersect + else: + raise ValueError("Cannot intersect type '{}'".format(type(toIntersect))) + + newS = solidRef.intersect(solidToIntersect) + + if clean: newS = newS.clean() + + if combine: + solidRef.wrapped = newS.wrapped + + return self.newObject([newS]) + + def cutBlind(self, distanceToCut, clean=True): """ Use all un-extruded wires in the parent chain to create a prismatic cut from existing solid. @@ -2308,7 +2346,7 @@ class Workplane(CQ): for ws in wireSets: thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir) toFuse.append(thisObj) - + if both: thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir.multiply(-1.)) toFuse.append(thisObj) diff --git a/Libs/cadquery-lib/cadquery/cqgi.py b/Libs/cadquery-lib/cadquery/cqgi.py index d0777a8..d654d72 100644 --- a/Libs/cadquery-lib/cadquery/cqgi.py +++ b/Libs/cadquery-lib/cadquery/cqgi.py @@ -109,10 +109,8 @@ class CQModel(object): c = compile(self.ast_tree, CQSCRIPT, 'exec') exec (c, env) result.set_debug(collector.debugObjects ) - if collector.has_results(): - result.set_success_result(collector.outputObjects) - else: - raise NoOutputError("Script did not call build_object-- no output available.") + result.set_success_result(collector.outputObjects) + except Exception, ex: #print "Error Executing Script:" result.set_failure_result(ex) @@ -171,7 +169,8 @@ class BuildResult(object): def set_success_result(self, results): self.results = results - self.first_result = self.results[0] + if len(self.results) > 0: + self.first_result = self.results[0] self.success = True diff --git a/Libs/cadquery-lib/tests/TestCadQuery.py b/Libs/cadquery-lib/tests/TestCadQuery.py index f12165a..12f41b7 100644 --- a/Libs/cadquery-lib/tests/TestCadQuery.py +++ b/Libs/cadquery-lib/tests/TestCadQuery.py @@ -604,6 +604,20 @@ class TestCadQuery(BaseTest): self.assertEqual(10,currentS.faces().size()) + def testIntersect(self): + """ + Tests the intersect function. + """ + s = Workplane(Plane.XY()) + currentS = s.rect(2.0, 2.0).extrude(0.5) + toIntersect = s.rect(1.0, 1.0).extrude(1) + + currentS.intersect(toIntersect.val()) + + self.assertEqual(6, currentS.faces().size()) + bb = currentS.val().BoundingBox() + self.assertListEqual([bb.xlen, bb.ylen, bb.zlen], [1, 1, 0.5]) + def testBoundingBox(self): """ Tests the boudingbox center of a model @@ -1387,7 +1401,7 @@ class TestCadQuery(BaseTest): result =topOfLid.union(bottom) self.saveModel(result) - + def testExtrude(self): """ Test symmetric extrude @@ -1395,19 +1409,16 @@ class TestCadQuery(BaseTest): r = 1. h = 1. decimal_places = 9. - + #extrude symmetrically s = Workplane("XY").circle(r).extrude(h,both=True) - + top_face = s.faces(">Z") bottom_face = s.faces("