From 632af9810292e269e944d4facb704504fdf8356d Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Mon, 16 Jan 2012 19:00:34 -0200 Subject: [PATCH] Draft offset now works on BSplines --- src/Mod/Draft/Draft.py | 11 ++++++++++- src/Mod/Draft/DraftTools.py | 31 +++++++++++++++++++++++++------ src/Mod/Draft/draftlibs/fcgeo.py | 15 +++++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index b6e22cd6e..fcf427afe 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -873,6 +873,8 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): if getType(obj) == "Circle": pass + elif getType(obj) == "BSpline": + pass else: if sym: d1 = delta.multiply(0.5) @@ -923,7 +925,10 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): newobj.Placement = pl elif getType(obj) == "Part": newobj = makeWire(p) - newobj.Closed = obj.Shape.isClosed() + newobj.Closed = obj.Shape.isClosed() + elif getType(obj) == "BSpline": + newobj = makeBSpline(delta) + newobj.Closed = obj.Closed formatObject(newobj,obj) else: if sym: return None @@ -933,6 +938,10 @@ def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): obj.Base = None obj.Tool = None obj.Points = p + elif getType(obj) == "BSpline": + print delta + obj.Points = delta + print "done" elif getType(obj) == "Rectangle": length,height,plac = getRect(p,obj) obj.Placement = plac diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 6e21bb347..a416b7d62 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -1651,14 +1651,14 @@ class Modifier: self.extendedCopy = False self.ui.setTitle(name) self.featureName = name - self.snap = snapTracker() - self.extsnap = lineTracker(dotted=True) + #self.snap = snapTracker() + #self.extsnap = lineTracker(dotted=True) self.planetrack = PlaneTracker() def finish(self): self.node = [] - self.snap.finalize() - self.extsnap.finalize() + #self.snap.finalize() + #self.extsnap.finalize() FreeCAD.activeDraftCommand = None if self.ui: self.ui.offUi() @@ -2066,6 +2066,7 @@ class Offset(Modifier): else: self.step = 0 self.dvec = None + self.npts = None self.constrainSeg = None self.ui.offsetUi() self.linetrack = lineTracker() @@ -2080,6 +2081,9 @@ class Offset(Modifier): self.ghost.setCenter(self.center) self.ghost.setStartAngle(math.radians(self.sel.FirstAngle)) self.ghost.setEndAngle(math.radians(self.sel.LastAngle)) + elif Draft.getType(self.sel) == "BSpline": + self.ghost = bsplineTracker(points=self.sel.Points) + self.mode = "BSpline" else: self.ghost = wireTracker(self.shape) self.mode = "Wire" @@ -2116,6 +2120,17 @@ class Offset(Modifier): self.dvec = fcvec.rotate(d,a,plane.axis) occmode = self.ui.occOffset.isChecked() self.ghost.update(fcgeo.offsetWire(self.shape,self.dvec,occ=occmode),forceclosed=occmode) + elif self.mode == "BSpline": + d = fcvec.neg(dist[0]) + e = self.shape.Edges[0] + basetan = fcgeo.getTangent(e,point) + self.npts = [] + for p in self.sel.Points: + currtan = fcgeo.getTangent(e,p) + a = -fcvec.angle(currtan,basetan) + self.dvec = fcvec.rotate(d,a,plane.axis) + self.npts.append(p.add(self.dvec)) + self.ghost.update(self.npts) elif self.mode == "Circle": self.dvec = point.sub(self.center).Length self.ghost.setRadius(self.dvec) @@ -2140,7 +2155,11 @@ class Offset(Modifier): copymode = False occmode = self.ui.occOffset.isChecked() if hasMod(arg,MODALT) or self.ui.isCopy.isChecked(): copymode = True - if self.dvec: + if self.npts: + self.commit(translate("draft","Offset"), + partial(Draft.offset,self.sel, + self.npts,copymode,occ=False)) + elif self.dvec: self.commit(translate("draft","Offset"), partial(Draft.offset,self.sel, self.dvec,copymode,occ=occmode)) @@ -2150,11 +2169,11 @@ class Offset(Modifier): self.finish() def finish(self,closed=False): - Modifier.finish(self) if self.ui and self.running: self.linetrack.finalize() self.constraintrack.finalize() self.ghost.finalize() + Modifier.finish(self) def numericRadius(self,rad): '''this function gets called by the toolbar when diff --git a/src/Mod/Draft/draftlibs/fcgeo.py b/src/Mod/Draft/draftlibs/fcgeo.py index 0c5c95089..275f9a0de 100755 --- a/src/Mod/Draft/draftlibs/fcgeo.py +++ b/src/Mod/Draft/draftlibs/fcgeo.py @@ -842,6 +842,16 @@ def findDistance(point,edge,strict=False): return None else: return dist + elif isinstance(edge.Curve,Part.BSplineCurve): + try: + pr = edge.Curve.parameter(point) + np = edge.Curve.value(pr) + dist = np.sub(point) + except: + print "fcgeo: Unable to get curve parameter for point ",point + return None + else: + return dist else: print "fcgeo: Couldn't project point" return None @@ -933,6 +943,11 @@ def getTangent(edge,frompoint=None): ''' if isinstance(edge.Curve,Part.Line): return vec(edge) + elif isinstance(edge.Curve,Part.BSplineCurve): + if not frompoint: + return None + cp = edge.Curve.parameter(frompoint) + return edge.Curve.tangent(cp)[0] elif isinstance(edge.Curve,Part.Circle): if not frompoint: v1 = edge.Vertexes[0].Point.sub(edge.Curve.Center)