Draft: bugfix in offset - fixes #270
This commit is contained in:
parent
f3a4c36155
commit
2bc15af126
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user