Fixed Draft.makeSketch to work with planes other than xy.

This commit is contained in:
Wolfgang E. Sanyer 2016-08-08 16:01:36 -04:00
parent ff5869acae
commit d4bb01835c
2 changed files with 74 additions and 44 deletions

View File

@ -2321,7 +2321,9 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S
creating a new one. If delete is True, the original object will be deleted''' creating a new one. If delete is True, the original object will be deleted'''
import Part, DraftGeomUtils import Part, DraftGeomUtils
from Sketcher import Constraint from Sketcher import Constraint
import Sketcher
from DraftTools import translate from DraftTools import translate
import math
StartPoint = 1 StartPoint = 1
EndPoint = 2 EndPoint = 2
@ -2330,12 +2332,18 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S
if not isinstance(objectslist,list): if not isinstance(objectslist,list):
objectslist = [objectslist] objectslist = [objectslist]
for obj in objectslist:
if not DraftGeomUtils.isPlanar(obj.Shape):
FreeCAD.Console.PrintError(translate("draft","All Shapes must be co-planar"))
return None
if addTo: if addTo:
nobj = addTo nobj = addTo
else: else:
nobj = FreeCAD.ActiveDocument.addObject("Sketcher::SketchObject",name) nobj = FreeCAD.ActiveDocument.addObject("Sketcher::SketchObject", "Sketch")
deletable = nobj deletable = nobj
nobj.ViewObject.Autoconstraints = False nobj.ViewObject.Autoconstraints = False
rotation = None
for obj in objectslist: for obj in objectslist:
ok = False ok = False
tp = getType(obj) tp = getType(obj)
@ -2344,14 +2352,31 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S
if deletable: FreeCAD.ActiveDocument.removeObject(deletable.Name) if deletable: FreeCAD.ActiveDocument.removeObject(deletable.Name)
return None return None
elif tp in ["Circle","Ellipse"]: elif tp in ["Circle","Ellipse"]:
g = (DraftGeomUtils.geom(obj.Shape.Edges[0],nobj.Placement)) if rotation is None:
nobj.addGeometry(g) rotation = obj.Placement.Rotation
edge = obj.Shape.Edges[0]
if len(edge.Vertexes) == 1:
newEdge = DraftGeomUtils.orientEdge(edge)
nobj.addGeometry(newEdge)
else:
# make new ArcOfCircle
circle = DraftGeomUtils.orientEdge(edge)
angle = edge.Placement.Rotation.Angle
axis = edge.Placement.Rotation.Axis
circle.Center = DraftVecUtils.rotate(edge.Curve.Center, -angle, axis)
first = math.radians(obj.FirstAngle)
last = math.radians(obj.LastAngle)
arc = Part.ArcOfCircle(circle, first, last)
nobj.addGeometry(arc)
# TODO add Radius constraits # TODO add Radius constraits
ok = True ok = True
elif tp == "Rectangle": elif tp == "Rectangle":
if rotation is None:
rotation = obj.Placement.Rotation
if obj.FilletRadius.Value == 0: if obj.FilletRadius.Value == 0:
for edge in obj.Shape.Edges: for edge in obj.Shape.Edges:
nobj.addGeometry(edge.Curve) nobj.addGeometry(DraftGeomUtils.orientEdge(edge))
if autoconstraints: if autoconstraints:
last = nobj.GeometryCount - 1 last = nobj.GeometryCount - 1
segs = [last-3,last-2,last-1,last] segs = [last-3,last-2,last-1,last]
@ -2372,8 +2397,24 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S
closed = True closed = True
elif hasattr(obj,"Closed"): elif hasattr(obj,"Closed"):
closed = obj.Closed closed = obj.Closed
if len(obj.Shape.Vertexes) < 3:
FreeCAD.Console.PrintError(translate("draft","Need at least 3 points in order to convert to Sketch"))
return None
# Use the first three points to make a working plane. We've already
# checked to make sure everything is coplanar
plane = Part.Plane(*[i.Point for i in obj.Shape.Vertexes[:3]])
normal = plane.Axis
if rotation is None:
axis = FreeCAD.Vector(0,0,1).cross(normal)
angle = DraftVecUtils.angle(normal, FreeCAD.Vector(0,0,1)) * FreeCAD.Units.Radian
rotation = FreeCAD.Rotation(axis, angle)
for edge in obj.Shape.Edges: for edge in obj.Shape.Edges:
nobj.addGeometry(edge.Curve) # edge.rotate(FreeCAD.Vector(0,0,0), rotAxis, rotAngle)
edge = DraftGeomUtils.orientEdge(edge, normal)
nobj.addGeometry(edge)
if autoconstraints: if autoconstraints:
last = nobj.GeometryCount last = nobj.GeometryCount
segs = list(range(last-len(obj.Shape.Edges),last-1)) segs = list(range(last-len(obj.Shape.Edges),last-1))
@ -2386,7 +2427,9 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S
if closed: if closed:
nobj.addConstraint(Constraint("Coincident",last-1,EndPoint,segs[0],StartPoint)) nobj.addConstraint(Constraint("Coincident",last-1,EndPoint,segs[0],StartPoint))
ok = True ok = True
if (not ok) and obj.isDerivedFrom("Part::Feature"): elif obj.isDerivedFrom("Part::Feature"):
if rotation is None:
rotation = obj.Placement.Rotation
if not DraftGeomUtils.isPlanar(obj.Shape): if not DraftGeomUtils.isPlanar(obj.Shape):
FreeCAD.Console.PrintError(translate("draft","The given object is not planar and cannot be converted into a sketch.")) FreeCAD.Console.PrintError(translate("draft","The given object is not planar and cannot be converted into a sketch."))
return None return None
@ -2394,17 +2437,18 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S
if DraftGeomUtils.geomType(e) in ["BSplineCurve","BezierCurve"]: if DraftGeomUtils.geomType(e) in ["BSplineCurve","BezierCurve"]:
FreeCAD.Console.PrintError(translate("draft","BSplines and Bezier curves are not supported by this tool")) FreeCAD.Console.PrintError(translate("draft","BSplines and Bezier curves are not supported by this tool"))
return None return None
if not addTo: # if not addTo:
nobj.Placement.Rotation = DraftGeomUtils.calculatePlacement(obj.Shape).Rotation # nobj.Placement.Rotation = DraftGeomUtils.calculatePlacement(obj.Shape).Rotation
edges = [] for edge in obj.Shape.Edges:
for e in obj.Shape.Edges: nobj.addGeometry(DraftGeomUtils.orientEdge(edge))
g = (DraftGeomUtils.geom(e,nobj.Placement))
if g:
nobj.addGeometry(g)
ok = True ok = True
formatObject(nobj,obj) formatObject(nobj,obj)
if ok and delete: if ok and delete:
FreeCAD.ActiveDocument.removeObject(obj.Name) FreeCAD.ActiveDocument.removeObject(obj.Name)
if not rotation is None:
nobj.Placement.Rotation = rotation
else:
print("-----error!!! rotation is still None...")
FreeCAD.ActiveDocument.recompute() FreeCAD.ActiveDocument.recompute()
return nobj return nobj

View File

@ -520,38 +520,24 @@ def pocket2d(shape,offset):
offsetWires = [o for o in offsetWires if o != None] offsetWires = [o for o in offsetWires if o != None]
return offsetWires return offsetWires
def orientEdge(edge, normal=None):
"""Re-orients 'edge' such that it is in the x-y plane. If 'normal' is passed, this
is used as the basis for the rotation, otherwise the Placement property of 'edge'
is used"""
import DraftVecUtils
# This 'normalizes' the placement to the xy plane
edge = edge.copy()
xyDir = FreeCAD.Vector(0, 0, 1)
base = FreeCAD.Vector(0,0,0)
def geom(edge,plac=FreeCAD.Placement()): if normal:
"returns a Line, ArcOfCircle or Circle geom from the given edge, according to the given placement" angle = DraftVecUtils.angle(normal, xyDir)*FreeCAD.Units.Radian
if geomType(edge) == "Line": axis = normal.cross(xyDir)
return edge.Curve
elif geomType(edge) == "Circle":
if len(edge.Vertexes) == 1:
return Part.Circle(edge.Curve.Center,edge.Curve.Axis,edge.Curve.Radius)
else: else:
# reorienting the arc along the correct normal axis = edge.Placement.Rotation.Axis
normal = plac.Rotation.multVec(FreeCAD.Vector(0,0,1)) angle = -1*edge.Placement.Rotation.Angle*FreeCAD.Units.Radian
v1 = edge.Vertexes[0].Point
v2 = edge.Vertexes[-1].Point
c = edge.Curve.Center
cu = Part.Circle(edge.Curve.Center,normal,edge.Curve.Radius)
ref = plac.Rotation.multVec(Vector(1,0,0))
a1 = DraftVecUtils.angle(v1.sub(c),ref,normal.negative())
a2 = DraftVecUtils.angle(v2.sub(c),ref,normal.negative())
# direction check edge.rotate(base, axis, angle)
if edge.Curve.Axis.getAngle(normal) > 1:
a1,a2 = a2,a1
#print("creating sketch arc from ",cu, ", p1=",v1, " (",math.degrees(a1), "d) p2=",v2," (", math.degrees(a2),"d)")
p= Part.ArcOfCircle(cu,a1,a2)
return p
elif geomType(edge) == "Ellipse":
if len(edge.Vertexes) == 1:
return edge.Curve
else:
return Part.ArcOfEllipse(edge.Curve,edge.FirstParameter,edge.LastParameter)
else:
return edge.Curve return edge.Curve
def mirror (point, edge): def mirror (point, edge):