From 256d42e2dec5533b249967e4a5af457d8d0a0953 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Wed, 29 Aug 2018 21:46:03 -0700 Subject: [PATCH] Fixed unit tests to support multiple base models. --- src/Mod/Path/PathScripts/PathJob.py | 3 +++ src/Mod/Path/PathScripts/PathOp.py | 16 ++++++++++------ src/Mod/Path/PathScripts/PathProfileFaces.py | 17 ++++++++++------- src/Mod/Path/PathScripts/PathUtils.py | 6 ++++++ .../Path/PathTests/TestPathDressupDogbone.py | 2 +- src/Mod/Path/PathTests/TestPathStock.py | 6 ++++-- 6 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathJob.py b/src/Mod/Path/PathScripts/PathJob.py index 09266664eb..5a2f294ae0 100644 --- a/src/Mod/Path/PathScripts/PathJob.py +++ b/src/Mod/Path/PathScripts/PathJob.py @@ -160,6 +160,9 @@ class ObjectJob: obj.Model.removeObject(base) obj.Document.removeObject(base.Name) + def modelBoundBox(self, obj): + return PathStock.shapeBoundBox(obj.Model.Group) + def onDelete(self, obj, arg2=None): '''Called by the view provider, there doesn't seem to be a callback on the obj itself.''' PathLog.track(obj.Label, arg2) diff --git a/src/Mod/Path/PathScripts/PathOp.py b/src/Mod/Path/PathScripts/PathOp.py index 6be0a97bd1..5a3ce4e2c2 100644 --- a/src/Mod/Path/PathScripts/PathOp.py +++ b/src/Mod/Path/PathScripts/PathOp.py @@ -332,12 +332,12 @@ class ObjectOp(object): if not ignoreErrors: PathLog.error(translate("Path", "No parent job found for operation.")) return False - if not job.Base: + if not job.Model.Group: if not ignoreErrors: PathLog.error(translate("Path", "Parent job %s doesn't have a base object") % job.Label) return False self.job = job - self.baseobject = job.Base + self.model = job.Model.Group self.stock = job.Stock return True @@ -385,7 +385,7 @@ class ObjectOp(object): # clearing with stock boundaries job = PathUtils.findParentJob(obj) zmax = stockBB.ZMax - zmin = job.Base.Shape.BoundBox.ZMax + zmin = job.Proxy.modelBoundBox(job).ZMax if FeatureDepths & self.opFeatures(obj): # first set update final depth, it's value is not negotiable @@ -419,7 +419,7 @@ class ObjectOp(object): Verifies that the operation is assigned to a job and that the job also has a valid Base. It also sets the following instance variables that can and should be safely be used by implementation of opExecute(): - self.baseobject ... Base object of the Job itself + self.model ... List of base objects of the Job itself self.stock ... Stock object fo the Job itself self.vertFeed ... vertical feed rate of assigned tool self.vertRapid ... vertical rapid rate of assigned tool @@ -489,11 +489,15 @@ class ObjectOp(object): base = PathUtil.getPublicObject(base) if self._setBaseAndStock(obj): - if base == self.job.Proxy.baseObject(self.job): - base = self.baseobject + for model in self.job.Model.Group: + if base == self.job.Proxy.baseObject(self.job, model): + base = model + break + baselist = obj.Base if baselist is None: baselist = [] + for p, el in baselist: if p == base and sub in el: PathLog.notice((translate("Path", "Base object %s.%s already in the list")+"\n") % (base.Label, sub)) diff --git a/src/Mod/Path/PathScripts/PathProfileFaces.py b/src/Mod/Path/PathScripts/PathProfileFaces.py index 5bdd0dfb82..1b9c21783c 100644 --- a/src/Mod/Path/PathScripts/PathProfileFaces.py +++ b/src/Mod/Path/PathScripts/PathProfileFaces.py @@ -89,27 +89,30 @@ class ObjectProfile(PathProfileBase.ObjectProfile): if isinstance(shape, Part.Face): faces.append(shape) if numpy.isclose(abs(shape.normalAt(0, 0).z), 1): # horizontal face - holes += shape.Wires[1:] + for wire in shape.Wires[1:]: + holes.append((b[0].Shape, wire)) else: FreeCAD.Console.PrintWarning("found a base object which is not a face. Can't continue.") return - for wire in holes: + for shape, wire in holes: f = Part.makeFace(wire, 'Part::FaceMakerSimple') - drillable = PathUtils.isDrillable(self.baseobject.Shape, wire) + drillable = PathUtils.isDrillable(shape, wire) if (drillable and obj.processCircles) or (not drillable and obj.processHoles): - env = PathUtils.getEnvelope(self.baseobject.Shape, subshape=f, depthparams=self.depthparams) + env = PathUtils.getEnvelope(shape, subshape=f, depthparams=self.depthparams) shapes.append((env, True)) if len(faces) > 0: profileshape = Part.makeCompound(faces) if obj.processPerimeter: - env = PathUtils.getEnvelope(self.baseobject.Shape, subshape=profileshape, depthparams=self.depthparams) - shapes.append((env, False)) + for obj in self.model: + env = PathUtils.getEnvelope(obj.Shape, subshape=profileshape, depthparams=self.depthparams) + shapes.append((env, False)) else: # Try to build targets from the job base - if hasattr(self.baseobject, "Proxy"): + # XXX ArchPanels support not implemented yet + if False and hasattr(self.baseobject, "Proxy"): if isinstance(self.baseobject.Proxy, ArchPanel.PanelSheet): # process the sheet if obj.processCircles or obj.processHoles: for shape in self.baseobject.Proxy.getHoles(self.baseobject, transform=True): diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 5dcb77d343..bb2733ff66 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -130,6 +130,12 @@ def isDrillable(obj, candidate, tooldiameter=None, includePartials=False): tooldiameter=float """ PathLog.track('obj: {} candidate: {} tooldiameter {}'.format(obj, candidate, tooldiameter)) + if list == type(obj): + for shape in obj: + if isDrillable(shape, candidate, tooldiameter, includePartials): + return (True, shape) + return (False, None) + drillable = False try: if candidate.ShapeType == 'Face': diff --git a/src/Mod/Path/PathTests/TestPathDressupDogbone.py b/src/Mod/Path/PathTests/TestPathDressupDogbone.py index eaead79823..55759fdf13 100644 --- a/src/Mod/Path/PathTests/TestPathDressupDogbone.py +++ b/src/Mod/Path/PathTests/TestPathDressupDogbone.py @@ -113,7 +113,7 @@ class TestDressupDogbone(PathTestBase): if f.Surface.Axis == FreeCAD.Vector(0,0,1) and f.Orientation == 'Forward': break - job = PathJob.Create('Job', cut, None) + job = PathJob.Create('Job', [cut], None) profile = PathProfileFaces.Create('Profile Faces') profile.Base = (cut, face) diff --git a/src/Mod/Path/PathTests/TestPathStock.py b/src/Mod/Path/PathTests/TestPathStock.py index e60ac12d3e..7e4762799f 100644 --- a/src/Mod/Path/PathTests/TestPathStock.py +++ b/src/Mod/Path/PathTests/TestPathStock.py @@ -45,8 +45,10 @@ class TestPathStock(PathTestBase): self.base.Width = 200 self.base.Height = 300 self.job = self.doc.addObject('App::FeaturePython', 'Job') - self.job.addProperty('App::PropertyLink', 'Base') - self.job.Base = self.base + self.job.addProperty('App::PropertyLink', 'Model') + model = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", "Model") + model.addObject(self.base) + self.job.Model = model self.job.addProperty('App::PropertyLink', 'Proxy') self.job.Proxy = FakeJobProxy()