diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 2796ac2ff..ba84756d6 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -2381,10 +2381,10 @@ class Offset(Modifier): occmode = self.ui.occOffset.isChecked() if hasMod(arg,MODALT) or self.ui.isCopy.isChecked(): copymode = True if self.npts: - #print "offset:npts=",self.npts + print "offset:npts=",self.npts self.commit(translate("draft","Offset"), ['import Draft', - 'Draft.offset(FreeCAD.ActiveDocument.'+self.sel.Name+','+DraftVecUtils.toString(self.ntps)+',copy='+str(copymode)+')']) + 'Draft.offset(FreeCAD.ActiveDocument.'+self.sel.Name+','+DraftVecUtils.toString(self.npts)+',copy='+str(copymode)+')']) elif self.dvec: if isinstance(self.dvec,float): d = str(self.dvec) diff --git a/src/Mod/Draft/DraftVecUtils.py b/src/Mod/Draft/DraftVecUtils.py index 2b15d9df0..efba2d249 100644 --- a/src/Mod/Draft/DraftVecUtils.py +++ b/src/Mod/Draft/DraftVecUtils.py @@ -32,119 +32,136 @@ from FreeCAD import Vector, Matrix params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") def precision(): - return params.GetInt("precision") + return params.GetInt("precision") def typecheck (args_and_types, name="?"): - for v,t in args_and_types: - if not isinstance (v,t): - FreeCAD.Console.PrintWarning("typecheck[" + str(name) + "]: " + str(v) + " is not " + str(t) + "\n") - raise TypeError("fcvec." + str(name)) + for v,t in args_and_types: + if not isinstance (v,t): + FreeCAD.Console.PrintWarning("typecheck[" + str(name) + "]: " + str(v) + " is not " + str(t) + "\n") + raise TypeError("fcvec." + str(name)) def toString(u): - "returns a string containing a python command to recreate this vector" + "returns a string containing a python command to recreate this vector" + if isinstance(u,list): + s = "[" + first = True + for v in u: + s += "FreeCAD.Vector("+str(v.x)+","+str(v.y)+","+str(v.z)+")" + if first: + s += "," + first = True + s += "]" + return s + else: return "FreeCAD.Vector("+str(u.x)+","+str(u.y)+","+str(u.z)+")" def tup(u,array=False): - "returns a tuple (x,y,z) with the vector coords, or an array if array=true" - typecheck ([(u,Vector)], "tup"); - if array: - return [u.x,u.y,u.z] - else: - return (u.x,u.y,u.z) + "returns a tuple (x,y,z) with the vector coords, or an array if array=true" + typecheck ([(u,Vector)], "tup"); + if array: + return [u.x,u.y,u.z] + else: + return (u.x,u.y,u.z) def neg(u): - "neg(Vector) - returns an opposite (negative) vector" - typecheck ([(u,Vector)],"neg") - return Vector(-u.x, -u.y, -u.z) + "neg(Vector) - returns an opposite (negative) vector" + typecheck ([(u,Vector)],"neg") + return Vector(-u.x, -u.y, -u.z) def equals(u,v): - "returns True if vectors differ by less than precision (from ParamGet), elementwise " - typecheck ([(u,Vector), (v,Vector)], "equals") - return isNull (u.sub(v)) + "returns True if vectors differ by less than precision (from ParamGet), elementwise " + typecheck ([(u,Vector), (v,Vector)], "equals") + return isNull (u.sub(v)) def scale(u,scalar): - "scale(Vector,Float) - scales (multiplies) a vector by a factor" - typecheck ([(u,Vector), (scalar,(int,long,float))], "scale") - return Vector(u.x*scalar, u.y*scalar, u.z*scalar) + "scale(Vector,Float) - scales (multiplies) a vector by a factor" + typecheck ([(u,Vector), (scalar,(int,long,float))], "scale") + return Vector(u.x*scalar, u.y*scalar, u.z*scalar) def scaleTo(u,l): - "scaleTo(Vector,length) - scales a vector to a given length" - typecheck ([(u,Vector),(l,(int,long,float))], "scaleTo") - if u.Length == 0: - return Vector(u) - else: - a = l/u.Length - return Vector(u.x*a, u.y*a, u.z*a) + "scaleTo(Vector,length) - scales a vector to a given length" + typecheck ([(u,Vector),(l,(int,long,float))], "scaleTo") + if u.Length == 0: + return Vector(u) + else: + a = l/u.Length + return Vector(u.x*a, u.y*a, u.z*a) def dist(u, v): - "dist(Vector,Vector) - returns the distance between both points/vectors" - typecheck ([(u,Vector), (v,Vector)], "dist") - x=u.sub(v).Length - return u.sub(v).Length + "dist(Vector,Vector) - returns the distance between both points/vectors" + typecheck ([(u,Vector), (v,Vector)], "dist") + x=u.sub(v).Length + return u.sub(v).Length def angle(u,v=Vector(1,0,0),normal=Vector(0,0,1)): - ''' + ''' angle(Vector,[Vector],[Vector]) - returns the angle in radians between the two vectors. If only one is given, angle is between the vector and the horizontal East direction. - If a third vector is given, it is the normal used to determine + If a third vector is given, it is the normal used to determine the sign of the angle. - ''' - typecheck ([(u,Vector), (v,Vector)], "angle") - ll = u.Length*v.Length - if ll==0: return 0 - dp=u.dot(v)/ll - if (dp < -1): dp = -1 # roundoff errors can push dp out of the ... - elif (dp > 1): dp = 1 # ...geometrically meaningful interval [-1,1] - ang = math.acos(dp) - normal1 = u.cross(v) - coeff = normal.dot(normal1) - if coeff >= 0: - return ang - else: - return -ang + ''' + typecheck ([(u,Vector), (v,Vector)], "angle") + ll = u.Length*v.Length + if ll==0: + return 0 + dp=u.dot(v)/ll + if (dp < -1): + dp = -1 # roundoff errors can push dp out of the ... + elif (dp > 1): + dp = 1 # ...geometrically meaningful interval [-1,1] + ang = math.acos(dp) + normal1 = u.cross(v) + coeff = normal.dot(normal1) + if coeff >= 0: + return ang + else: + return -ang def project(u,v): - "project(Vector,Vector): projects the first vector onto the second one" - typecheck([(u,Vector), (v,Vector)], "project") - dp = v.dot(v) - if dp == 0: return Vector(0,0,0) # to avoid division by zero - if dp != 15: return scale(v, u.dot(v)/dp) - return Vector(0,0,0) + "project(Vector,Vector): projects the first vector onto the second one" + typecheck([(u,Vector), (v,Vector)], "project") + dp = v.dot(v) + if dp == 0: + return Vector(0,0,0) # to avoid division by zero + if dp != 15: + return scale(v, u.dot(v)/dp) + return Vector(0,0,0) def rotate2D(u,angle): - "rotate2D(Vector,angle): rotates the given vector around the Z axis" - return Vector(math.cos(-angle)*u.x-math.sin(-angle)*u.y, - math.sin(-angle)*u.x+math.cos(-angle)*u.y,u.z) + "rotate2D(Vector,angle): rotates the given vector around the Z axis" + return Vector(math.cos(-angle)*u.x-math.sin(-angle)*u.y, + math.sin(-angle)*u.x+math.cos(-angle)*u.y,u.z) def rotate(u,angle,axis=Vector(0,0,1)): - '''rotate(Vector,Float,axis=Vector): rotates the first Vector - around the given axis, at the given angle. - If axis is omitted, the rotation is made on the xy plane.''' - typecheck ([(u,Vector), (angle,(int,long,float)), (axis,Vector)], "rotate") + '''rotate(Vector,Float,axis=Vector): rotates the first Vector + around the given axis, at the given angle. + If axis is omitted, the rotation is made on the xy plane.''' + typecheck ([(u,Vector), (angle,(int,long,float)), (axis,Vector)], "rotate") - if angle == 0: return u + if angle == 0: + return u - l=axis.Length - x=axis.x/l - y=axis.y/l - z=axis.z/l - c = math.cos(angle) - s = math.sin(angle) - t = 1 - c; + l=axis.Length + x=axis.x/l + y=axis.y/l + z=axis.z/l + c = math.cos(angle) + s = math.sin(angle) + t = 1 - c - xyt = x*y*t - xzt = x*z*t - yzt = y*z*t - xs = x*s - ys = y*s - zs = z*s + xyt = x*y*t + xzt = x*z*t + yzt = y*z*t + xs = x*s + ys = y*s + zs = z*s - m = Matrix(c + x*x*t, xyt - zs, xzt + ys, 0, - xyt + zs, c + y*y*t, yzt - xs, 0, - xzt - ys, yzt + xs, c + z*z*t, 0) + m = Matrix(c + x*x*t, xyt - zs, xzt + ys, 0, + xyt + zs, c + y*y*t, yzt - xs, 0, + xzt - ys, yzt + xs, c + z*z*t, 0) - return m.multiply(u) + return m.multiply(u) def getRotation(vector,reference=Vector(1,0,0)): '''getRotation(vector,[reference]): returns a tuple @@ -153,57 +170,60 @@ def getRotation(vector,reference=Vector(1,0,0)): c = vector.cross(reference) c.normalize() return (c.x,c.y,c.z,math.sqrt((vector.Length ** 2) * (reference.Length ** 2)) + vector.dot(reference)) - + def isNull(vector): - '''isNull(vector): Tests if a vector is nul vector''' - p = precision() - return (round(vector.x,p)==0 and round(vector.y,p)==0 and round(vector.z,p)==0) + '''isNull(vector): Tests if a vector is nul vector''' + p = precision() + return (round(vector.x,p)==0 and round(vector.y,p)==0 and round(vector.z,p)==0) def find(vector,vlist): - '''find(vector,vlist): finds a vector in a list of vectors. returns - the index of the matching vector, or None if none is found. - ''' - typecheck ([(vector,Vector), (vlist,list)], "find") - for i,v in enumerate(vlist): - if equals(vector,v): - return i - return None + '''find(vector,vlist): finds a vector in a list of vectors. returns + the index of the matching vector, or None if none is found. + ''' + typecheck ([(vector,Vector), (vlist,list)], "find") + for i,v in enumerate(vlist): + if equals(vector,v): + return i + return None def isColinear(vlist): - '''isColinear(list_of_vectors): checks if vectors in given list are colinear''' - typecheck ([(vlist,list)], "isColinear"); - if len(vlist) < 3: return True - p = precision() - first = vlist[1].sub(vlist[0]) - for i in range(2,len(vlist)): - if round(angle(vlist[i].sub(vlist[0]),first),p) != 0: - return False - return True + '''isColinear(list_of_vectors): checks if vectors in given list are colinear''' + typecheck ([(vlist,list)], "isColinear"); + if len(vlist) < 3: + return True + p = precision() + first = vlist[1].sub(vlist[0]) + for i in range(2,len(vlist)): + if round(angle(vlist[i].sub(vlist[0]),first),p) != 0: + return False + return True def rounded(v): - "returns a rounded vector" - p = precision() - return Vector(round(v.x,p),round(v.y,p),round(v.z,p)) + "returns a rounded vector" + p = precision() + return Vector(round(v.x,p),round(v.y,p),round(v.z,p)) def getPlaneRotation(u,v,w=None): - "returns a rotation matrix defining the (u,v,w) coordinates system" - if (not u) or (not v): return None - if not w: w = u.cross(v) - typecheck([(u,Vector), (v,Vector), (w,Vector)], "getPlaneRotation") - m = FreeCAD.Matrix( - u.x,v.x,w.x,0, - u.y,v.y,w.y,0, - u.z,v.z,w.z,0, - 0.0,0.0,0.0,1.0) - return m + "returns a rotation matrix defining the (u,v,w) coordinates system" + if (not u) or (not v): + return None + if not w: + w = u.cross(v) + typecheck([(u,Vector), (v,Vector), (w,Vector)], "getPlaneRotation") + m = FreeCAD.Matrix(u.x,v.x,w.x,0, + u.y,v.y,w.y,0, + u.z,v.z,w.z,0, + 0.0,0.0,0.0,1.0) + return m def removeDoubles(vlist): - "removes consecutive doubles from a list of vectors" - typecheck ([(vlist,list)], "removeDoubles"); - nlist = [] - if len(vlist) < 2: return vlist - for i in range(len(vlist)-1): - if not equals(vlist[i],vlist[i+1]): - nlist.append(vlist[i]) - nlist.append(vlist[-1]) - return nlist + "removes consecutive doubles from a list of vectors" + typecheck ([(vlist,list)], "removeDoubles"); + nlist = [] + if len(vlist) < 2: + return vlist + for i in range(len(vlist)-1): + if not equals(vlist[i],vlist[i+1]): + nlist.append(vlist[i]) + nlist.append(vlist[-1]) + return nlist