Added CQGI debug objects.

This commit is contained in:
Jeremy Mack Wright 2017-09-11 21:49:14 -04:00
parent 2cdd504888
commit 21200cc10d
4 changed files with 77 additions and 18 deletions

View File

@ -9,6 +9,7 @@ import ExportCQ, ImportCQ
import module_locator import module_locator
import Settings import Settings
import Shared import Shared
from random import random
from cadquery import cqgi from cadquery import cqgi
from Helpers import show from Helpers import show
@ -130,7 +131,7 @@ class CadQueryExecuteScript:
scriptText = cqCodePane.toPlainText().encode('utf-8') scriptText = cqCodePane.toPlainText().encode('utf-8')
# Check to see if we are executig a CQGI compliant script # 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") FreeCAD.Console.PrintMessage("Executing CQGI-compliant script.\r\n")
# A repreentation of the CQ script with all the metadata attached # A repreentation of the CQ script with all the metadata attached
@ -173,6 +174,16 @@ class CadQueryExecuteScript:
show(result.shape, result.options["rgba"]) show(result.shape, result.options["rgba"])
else: else:
show(result.shape) 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: else:
FreeCAD.Console.PrintError("Error executing CQGI-compliant script. " + str(build_result.exception) + "\r\n") FreeCAD.Console.PrintError("Error executing CQGI-compliant script. " + str(build_result.exception) + "\r\n")
else: else:

View File

@ -341,7 +341,7 @@ class CQ(object):
if not all(_isCoPlanar(self.objects[0], f) for f in self.objects[1:]): if not all(_isCoPlanar(self.objects[0], f) for f in self.objects[1:]):
raise ValueError("Selected faces must be co-planar.") raise ValueError("Selected faces must be co-planar.")
if centerOption == 'CenterOfMass': if centerOption == 'CenterOfMass':
center = Shape.CombinedCenter(self.objects) center = Shape.CombinedCenter(self.objects)
elif centerOption == 'CenterOfBoundBox': elif centerOption == 'CenterOfBoundBox':
center = Shape.CombinedCenterOfBoundBox(self.objects) center = Shape.CombinedCenterOfBoundBox(self.objects)
@ -1991,9 +1991,9 @@ class Workplane(CQ):
Support for non-prismatic extrusion ( IE, sweeping along a profile, not just 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 perpendicular to the plane extrude to surface. this is quite tricky since the surface
selected may not be planar selected may not be planar
""" """
r = self._extrude(distance,both=both) # returns a Solid (or a compound if there were multiple) r = self._extrude(distance,both=both) # returns a Solid (or a compound if there were multiple)
if combine: if combine:
newS = self._combineWithBase(r) newS = self._combineWithBase(r)
else: else:
@ -2184,6 +2184,44 @@ class Workplane(CQ):
return self.newObject([newS]) 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): def cutBlind(self, distanceToCut, clean=True):
""" """
Use all un-extruded wires in the parent chain to create a prismatic cut from existing solid. 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: for ws in wireSets:
thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir) thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir)
toFuse.append(thisObj) toFuse.append(thisObj)
if both: if both:
thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir.multiply(-1.)) thisObj = Solid.extrudeLinear(ws[0], ws[1:], eDir.multiply(-1.))
toFuse.append(thisObj) toFuse.append(thisObj)

View File

@ -109,10 +109,8 @@ class CQModel(object):
c = compile(self.ast_tree, CQSCRIPT, 'exec') c = compile(self.ast_tree, CQSCRIPT, 'exec')
exec (c, env) exec (c, env)
result.set_debug(collector.debugObjects ) result.set_debug(collector.debugObjects )
if collector.has_results(): result.set_success_result(collector.outputObjects)
result.set_success_result(collector.outputObjects)
else:
raise NoOutputError("Script did not call build_object-- no output available.")
except Exception, ex: except Exception, ex:
#print "Error Executing Script:" #print "Error Executing Script:"
result.set_failure_result(ex) result.set_failure_result(ex)
@ -171,7 +169,8 @@ class BuildResult(object):
def set_success_result(self, results): def set_success_result(self, results):
self.results = results self.results = results
self.first_result = self.results[0] if len(self.results) > 0:
self.first_result = self.results[0]
self.success = True self.success = True

View File

@ -604,6 +604,20 @@ class TestCadQuery(BaseTest):
self.assertEqual(10,currentS.faces().size()) 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): def testBoundingBox(self):
""" """
Tests the boudingbox center of a model Tests the boudingbox center of a model
@ -1387,7 +1401,7 @@ class TestCadQuery(BaseTest):
result =topOfLid.union(bottom) result =topOfLid.union(bottom)
self.saveModel(result) self.saveModel(result)
def testExtrude(self): def testExtrude(self):
""" """
Test symmetric extrude Test symmetric extrude
@ -1395,19 +1409,16 @@ class TestCadQuery(BaseTest):
r = 1. r = 1.
h = 1. h = 1.
decimal_places = 9. decimal_places = 9.
#extrude symmetrically #extrude symmetrically
s = Workplane("XY").circle(r).extrude(h,both=True) s = Workplane("XY").circle(r).extrude(h,both=True)
top_face = s.faces(">Z") top_face = s.faces(">Z")
bottom_face = s.faces("<Z") bottom_face = s.faces("<Z")
#calculate the distance between the top and the bottom face #calculate the distance between the top and the bottom face
delta = top_face.val().Center().sub(bottom_face.val().Center()) delta = top_face.val().Center().sub(bottom_face.val().Center())
self.assertTupleAlmostEquals(delta.toTuple(), self.assertTupleAlmostEquals(delta.toTuple(),
(0.,0.,2.*h), (0.,0.,2.*h),
decimal_places) decimal_places)