Skip to content

Commit

Permalink
Fixed Draft.makeSketch to work with planes other than xy.
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzieyguywuf committed Aug 13, 2016
1 parent ff5869a commit d4bb018
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 45 deletions.
70 changes: 57 additions & 13 deletions src/Mod/Draft/Draft.py
Expand Up @@ -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'''
import Part, DraftGeomUtils
from Sketcher import Constraint
import Sketcher
from DraftTools import translate
import math

StartPoint = 1
EndPoint = 2
Expand All @@ -2330,12 +2332,18 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S

if not isinstance(objectslist,list):
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:
nobj = addTo
else:
nobj = FreeCAD.ActiveDocument.addObject("Sketcher::SketchObject",name)
nobj = FreeCAD.ActiveDocument.addObject("Sketcher::SketchObject", "Sketch")
deletable = nobj
nobj.ViewObject.Autoconstraints = False

rotation = None
for obj in objectslist:
ok = False
tp = getType(obj)
Expand All @@ -2344,14 +2352,31 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S
if deletable: FreeCAD.ActiveDocument.removeObject(deletable.Name)
return None
elif tp in ["Circle","Ellipse"]:
g = (DraftGeomUtils.geom(obj.Shape.Edges[0],nobj.Placement))
nobj.addGeometry(g)
if rotation is None:
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
ok = True
elif tp == "Rectangle":
if rotation is None:
rotation = obj.Placement.Rotation
if obj.FilletRadius.Value == 0:
for edge in obj.Shape.Edges:
nobj.addGeometry(edge.Curve)
nobj.addGeometry(DraftGeomUtils.orientEdge(edge))
if autoconstraints:
last = nobj.GeometryCount - 1
segs = [last-3,last-2,last-1,last]
Expand All @@ -2372,8 +2397,24 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S
closed = True
elif hasattr(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:
nobj.addGeometry(edge.Curve)
# edge.rotate(FreeCAD.Vector(0,0,0), rotAxis, rotAngle)
edge = DraftGeomUtils.orientEdge(edge, normal)
nobj.addGeometry(edge)
if autoconstraints:
last = nobj.GeometryCount
segs = list(range(last-len(obj.Shape.Edges),last-1))
Expand All @@ -2386,25 +2427,28 @@ def makeSketch(objectslist,autoconstraints=False,addTo=None,delete=False,name="S
if closed:
nobj.addConstraint(Constraint("Coincident",last-1,EndPoint,segs[0],StartPoint))
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):
FreeCAD.Console.PrintError(translate("draft","The given object is not planar and cannot be converted into a sketch."))
return None
for e in obj.Shape.Edges:
if DraftGeomUtils.geomType(e) in ["BSplineCurve","BezierCurve"]:
FreeCAD.Console.PrintError(translate("draft","BSplines and Bezier curves are not supported by this tool"))
return None
if not addTo:
nobj.Placement.Rotation = DraftGeomUtils.calculatePlacement(obj.Shape).Rotation
edges = []
for e in obj.Shape.Edges:
g = (DraftGeomUtils.geom(e,nobj.Placement))
if g:
nobj.addGeometry(g)
# if not addTo:
# nobj.Placement.Rotation = DraftGeomUtils.calculatePlacement(obj.Shape).Rotation
for edge in obj.Shape.Edges:
nobj.addGeometry(DraftGeomUtils.orientEdge(edge))
ok = True
formatObject(nobj,obj)
if ok and delete:
FreeCAD.ActiveDocument.removeObject(obj.Name)
if not rotation is None:
nobj.Placement.Rotation = rotation
else:
print("-----error!!! rotation is still None...")
FreeCAD.ActiveDocument.recompute()
return nobj

Expand Down
50 changes: 18 additions & 32 deletions src/Mod/Draft/DraftGeomUtils.py
Expand Up @@ -519,40 +519,26 @@ def pocket2d(shape,offset):
offsetWires.append(w)
offsetWires = [o for o in offsetWires if o != None]
return offsetWires


def geom(edge,plac=FreeCAD.Placement()):
"returns a Line, ArcOfCircle or Circle geom from the given edge, according to the given placement"
if geomType(edge) == "Line":
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:
# reorienting the arc along the correct normal
normal = plac.Rotation.multVec(FreeCAD.Vector(0,0,1))
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
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)
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)

if normal:
angle = DraftVecUtils.angle(normal, xyDir)*FreeCAD.Units.Radian
axis = normal.cross(xyDir)
else:
return edge.Curve
axis = edge.Placement.Rotation.Axis
angle = -1*edge.Placement.Rotation.Angle*FreeCAD.Units.Radian

edge.rotate(base, axis, angle)
return edge.Curve

def mirror (point, edge):
"finds mirror point relative to an edge"
Expand Down

0 comments on commit d4bb018

Please sign in to comment.