diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index c015ccead..e8f25025a 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -72,12 +72,18 @@ How it works / how to extend: ''' # import FreeCAD modules - -import FreeCAD, FreeCADGui, math, sys, os, WorkingPlane +import FreeCAD, math, sys, os from FreeCAD import Vector from draftlibs import fcvec from pivy import coin +if FreeCAD.GuiUp: + import FreeCADGui, WorkingPlane + gui = True +else: + print "FreeCAD Gui not present. Draft module will have some features disabled." + gui = False + #--------------------------------------------------------------------------- # General functions #--------------------------------------------------------------------------- @@ -245,95 +251,104 @@ def formatObject(target,origin=None): It also places the object in construction group if needed. ''' obrep = target.ViewObject - ui = FreeCADGui.draftToolBar - doc = FreeCAD.ActiveDocument - if ui.isConstructionMode(): - col = fcol = ui.getDefaultColor("constr") - gname = getParam("constructiongroupname") - if not gname: - gname = "Construction" - grp = doc.getObject(gname) - if not grp: - grp = doc.addObject("App::DocumentObjectGroup",gname) - grp.addObject(target) - obrep.Transparency = 80 - else: - col = ui.getDefaultColor("ui") - fcol = ui.getDefaultColor("face") - col = (float(col[0]),float(col[1]),float(col[2]),0.0) - fcol = (float(fcol[0]),float(fcol[1]),float(fcol[2]),0.0) - lw = ui.linewidth - fs = ui.fontsize - if not origin: - if "FontSize" in obrep.PropertiesList: obrep.FontSize = fs - if "TextColor" in obrep.PropertiesList: obrep.TextColor = col - if "LineWidth" in obrep.PropertiesList: obrep.LineWidth = lw - if "PointColor" in obrep.PropertiesList: obrep.PointColor = col - if "LineColor" in obrep.PropertiesList: obrep.LineColor = col - if "ShapeColor" in obrep.PropertiesList: obrep.ShapeColor = fcol - else: - matchrep = origin.ViewObject - for p in matchrep.PropertiesList: - if not p in ["DisplayMode","BoundingBox","Proxy","RootNode"]: - if p in obrep.PropertiesList: - val = getattr(matchrep,p) - setattr(obrep,p,val) - if matchrep.DisplayMode in obrep.listDisplayModes(): - obrep.DisplayMode = matchrep.DisplayMode + ui = None + if gui: + if hasattr(FreeCADGui,"draftToolBar"): + ui = FreeCADGui.draftToolBar + if ui: + doc = FreeCAD.ActiveDocument + if ui.isConstructionMode(): + col = fcol = ui.getDefaultColor("constr") + gname = getParam("constructiongroupname") + if not gname: + gname = "Construction" + grp = doc.getObject(gname) + if not grp: + grp = doc.addObject("App::DocumentObjectGroup",gname) + grp.addObject(target) + obrep.Transparency = 80 + else: + col = ui.getDefaultColor("ui") + fcol = ui.getDefaultColor("face") + col = (float(col[0]),float(col[1]),float(col[2]),0.0) + fcol = (float(fcol[0]),float(fcol[1]),float(fcol[2]),0.0) + lw = ui.linewidth + fs = ui.fontsize + if not origin: + if "FontSize" in obrep.PropertiesList: obrep.FontSize = fs + if "TextColor" in obrep.PropertiesList: obrep.TextColor = col + if "LineWidth" in obrep.PropertiesList: obrep.LineWidth = lw + if "PointColor" in obrep.PropertiesList: obrep.PointColor = col + if "LineColor" in obrep.PropertiesList: obrep.LineColor = col + if "ShapeColor" in obrep.PropertiesList: obrep.ShapeColor = fcol + else: + matchrep = origin.ViewObject + for p in matchrep.PropertiesList: + if not p in ["DisplayMode","BoundingBox","Proxy","RootNode"]: + if p in obrep.PropertiesList: + val = getattr(matchrep,p) + setattr(obrep,p,val) + if matchrep.DisplayMode in obrep.listDisplayModes(): + obrep.DisplayMode = matchrep.DisplayMode def getSelection(): "getSelection(): returns the current FreeCAD selection" - return FreeCADGui.Selection.getSelection() + if gui: + return FreeCADGui.Selection.getSelection() + return None def select(objs=None): "select(object): deselects everything and selects only the passed object or list" - FreeCADGui.Selection.clearSelection() - if objs: - if not isinstance(objs,list): - objs = [objs] - for obj in objs: - FreeCADGui.Selection.addSelection(obj) + if gui: + FreeCADGui.Selection.clearSelection() + if objs: + if not isinstance(objs,list): + objs = [objs] + for obj in objs: + FreeCADGui.Selection.addSelection(obj) def loadTexture(filename): "loadTexture(filename): returns a SoSFImage from a file" - from pivy import coin - from PyQt4 import QtGui - try: - p = QtGui.QImage(filename) - size = coin.SbVec2s(p.width(), p.height()) - buffersize = p.numBytes() - numcomponents = int (buffersize / ( size[0] * size[1] )) + if gui: + from pivy import coin + from PyQt4 import QtGui + try: + p = QtGui.QImage(filename) + size = coin.SbVec2s(p.width(), p.height()) + buffersize = p.numBytes() + numcomponents = int (buffersize / ( size[0] * size[1] )) - img = coin.SoSFImage() - width = size[0] - height = size[1] - bytes = "" - - for y in range(height): - #line = width*numcomponents*(height-(y)); - for x in range(width): - rgb = p.pixel(x,y) - if numcomponents == 1: - bytes = bytes + chr(QtGui.qGray( rgb )) - elif numcomponents == 2: - bytes = bytes + chr(QtGui.qGray( rgb )) - bytes = bytes + chr(QtGui.qAlpha( rgb )) - elif numcomponents == 3: - bytes = bytes + chr(QtGui.qRed( rgb )) - bytes = bytes + chr(QtGui.qGreen( rgb )) - bytes = bytes + chr(QtGui.qBlue( rgb )) - elif numcomponents == 4: - bytes = bytes + chr(QtGui.qRed( rgb )) - bytes = bytes + chr(QtGui.qGreen( rgb )) - bytes = bytes + chr(QtGui.qBlue( rgb )) - bytes = bytes + chr(QtGui.qAlpha( rgb )) - #line += numcomponents + img = coin.SoSFImage() + width = size[0] + height = size[1] + bytes = "" + + for y in range(height): + #line = width*numcomponents*(height-(y)); + for x in range(width): + rgb = p.pixel(x,y) + if numcomponents == 1: + bytes = bytes + chr(QtGui.qGray( rgb )) + elif numcomponents == 2: + bytes = bytes + chr(QtGui.qGray( rgb )) + bytes = bytes + chr(QtGui.qAlpha( rgb )) + elif numcomponents == 3: + bytes = bytes + chr(QtGui.qRed( rgb )) + bytes = bytes + chr(QtGui.qGreen( rgb )) + bytes = bytes + chr(QtGui.qBlue( rgb )) + elif numcomponents == 4: + bytes = bytes + chr(QtGui.qRed( rgb )) + bytes = bytes + chr(QtGui.qGreen( rgb )) + bytes = bytes + chr(QtGui.qBlue( rgb )) + bytes = bytes + chr(QtGui.qAlpha( rgb )) + #line += numcomponents - img.setValue(size, numcomponents, bytes) - except: - return None - else: - return img + img.setValue(size, numcomponents, bytes) + except: + return None + else: + return img + return None def makeCircle(radius, placement=None, face=True, startangle=None, endangle=None, support=None): '''makeCircle(radius,[placement,face,startangle,endangle]) @@ -347,7 +362,6 @@ def makeCircle(radius, placement=None, face=True, startangle=None, endangle=None if placement: typecheck([(placement,FreeCAD.Placement)], "makeCircle") obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Circle") _Circle(obj) - _ViewProviderDraft(obj.ViewObject) if isinstance(radius,Part.Edge): edge = radius if isinstance(edge.Curve,Part.Circle): @@ -369,11 +383,13 @@ def makeCircle(radius, placement=None, face=True, startangle=None, endangle=None if startangle == -0: startangle = 0 obj.FirstAngle = startangle obj.LastAngle = endangle - if not face: obj.ViewObject.DisplayMode = "Wireframe" obj.Support = support if placement: obj.Placement = placement - formatObject(obj) - select(obj) + if gui: + _ViewProviderDraft(obj.ViewObject) + if not face: obj.ViewObject.DisplayMode = "Wireframe" + formatObject(obj) + select(obj) FreeCAD.ActiveDocument.recompute() return obj @@ -385,14 +401,16 @@ def makeRectangle(length, height, placement=None, face=True, support=None): if placement: typecheck([(placement,FreeCAD.Placement)], "makeRectangle") obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Rectangle") _Rectangle(obj) - _ViewProviderRectangle(obj.ViewObject) + obj.Length = length obj.Height = height obj.Support = support - if not face: obj.ViewObject.DisplayMode = "Wireframe" if placement: obj.Placement = placement - formatObject(obj) - select(obj) + if gui: + _ViewProviderRectangle(obj.ViewObject) + if not face: obj.ViewObject.DisplayMode = "Wireframe" + formatObject(obj) + select(obj) FreeCAD.ActiveDocument.recompute() return obj @@ -411,7 +429,6 @@ def makeDimension(p1,p2,p3=None,p4=None): ''' obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython","Dimension") _Dimension(obj) - _ViewProviderDimension(obj.ViewObject) if isinstance(p1,Vector) and isinstance(p2,Vector): obj.Start = p1 obj.End = p2 @@ -433,8 +450,10 @@ def makeDimension(p1,p2,p3=None,p4=None): p3.multiply(0.5) p3 = p1.add(p3) obj.Dimline = p3 - formatObject(obj) - select(obj) + if gui: + _ViewProviderDimension(obj.ViewObject) + formatObject(obj) + select(obj) FreeCAD.ActiveDocument.recompute() return obj @@ -444,7 +463,6 @@ def makeAngularDimension(center,angles,p3): ''' obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython","Dimension") _AngularDimension(obj) - _ViewProviderAngularDimension(obj.ViewObject) obj.Center = center for a in range(len(angles)): if angles[a] > 2*math.pi: @@ -452,8 +470,10 @@ def makeAngularDimension(center,angles,p3): obj.FirstAngle = math.degrees(angles[1]) obj.LastAngle = math.degrees(angles[0]) obj.Dimline = p3 - formatObject(obj) - select(obj) + if gui: + _ViewProviderAngularDimension(obj.ViewObject) + formatObject(obj) + select(obj) FreeCAD.ActiveDocument.recompute() return obj @@ -481,14 +501,15 @@ def makeWire(pointslist,closed=False,placement=None,face=True,support=None): else: fname = "Wire" obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython",fname) _Wire(obj) - _ViewProviderWire(obj.ViewObject) obj.Points = pointslist obj.Closed = closed obj.Support = support - if not face: obj.ViewObject.DisplayMode = "Wireframe" if placement: obj.Placement = placement - formatObject(obj) - select(obj) + if gui: + _ViewProviderWire(obj.ViewObject) + if not face: obj.ViewObject.DisplayMode = "Wireframe" + formatObject(obj) + select(obj) FreeCAD.ActiveDocument.recompute() return obj @@ -502,18 +523,19 @@ def makePolygon(nfaces,radius=1,inscribed=True,placement=None,face=True,support= if nfaces < 3: return None obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Polygon") _Polygon(obj) - _ViewProviderDraft(obj.ViewObject) obj.FacesNumber = nfaces obj.Radius = radius if inscribed: obj.DrawMode = "inscribed" else: obj.DrawMode = "circumscribed" - if not face: obj.ViewObject.DisplayMode = "Wireframe" obj.Support = support if placement: obj.Placement = placement - formatObject(obj) - select(obj) + if gui: + _ViewProviderDraft(obj.ViewObject) + if not face: obj.ViewObject.DisplayMode = "Wireframe" + formatObject(obj) + select(obj) FreeCAD.ActiveDocument.recompute() return obj @@ -538,14 +560,15 @@ def makeBSpline(pointslist,closed=False,placement=None,face=True,support=None): else: fname = "BSpline" obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython",fname) _BSpline(obj) - _ViewProviderBSpline(obj.ViewObject) obj.Points = pointslist obj.Closed = closed obj.Support = support - if not face: obj.ViewObject.DisplayMode = "Wireframe" if placement: obj.Placement = placement - formatObject(obj) - select(obj) + if gui: + _ViewProviderBSpline(obj.ViewObject) + if not face: obj.ViewObject.DisplayMode = "Wireframe" + formatObject(obj) + select(obj) FreeCAD.ActiveDocument.recompute() return obj @@ -577,51 +600,62 @@ def makeCopy(obj,force=None,reparent=False): if (getType(obj) == "Rectangle") or (force == "Rectangle"): newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) _Rectangle(newobj) - _ViewProviderRectangle(newobj.ViewObject) + if gui: + _ViewProviderRectangle(newobj.ViewObject) elif (getType(obj) == "Dimension") or (force == "Dimension"): newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) _Dimension(newobj) - _ViewProviderDimension(newobj.ViewObject) + if gui: + _ViewProviderDimension(newobj.ViewObject) elif (getType(obj) == "Wire") or (force == "Wire"): newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) _Wire(newobj) - _ViewProviderWire(newobj.ViewObject) + if gui: + _ViewProviderWire(newobj.ViewObject) elif (getType(obj) == "Circle") or (force == "Circle"): newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) _Circle(newobj) - _ViewProviderDraft(newobj.ViewObject) + if gui: + _ViewProviderDraft(newobj.ViewObject) elif (getType(obj) == "Polygon") or (force == "Polygon"): newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) _Polygon(newobj) - _ViewProviderPolygon(newobj.ViewObject) + if gui: + _ViewProviderPolygon(newobj.ViewObject) elif (getType(obj) == "BSpline") or (force == "BSpline"): newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) _BSpline(newobj) - _ViewProviderBSpline(newobj.ViewObject) + if gui: + _ViewProviderBSpline(newobj.ViewObject) elif (getType(obj) == "Block") or (force == "BSpline"): newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) _Block(newobj) - _ViewProviderDraftPart(newobj.ViewObject) + if gui: + _ViewProviderDraftPart(newobj.ViewObject) elif (getType(obj) == "Structure") or (force == "Structure"): import ArchStructure newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) ArchStructure._Structure(newobj) - ArchStructure._ViewProviderStructure(newobj.ViewObject) + if gui: + ArchStructure._ViewProviderStructure(newobj.ViewObject) elif (getType(obj) == "Wall") or (force == "Wall"): import ArchWall newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) ArchWall._Wall(newobj) - ArchWall._ViewProviderWall(newobj.ViewObject) + if gui: + ArchWall._ViewProviderWall(newobj.ViewObject) elif (getType(obj) == "Window") or (force == "Window"): import ArchWindow newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) ArchWindow._Window(newobj) - Archwindow._ViewProviderWindow(newobj.ViewObject) + if gui: + Archwindow._ViewProviderWindow(newobj.ViewObject) elif (getType(obj) == "Cell") or (force == "Cell"): import ArchCell newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name)) ArchCell._Cell(newobj) - ArchCell._ViewProviderCell(newobj.ViewObject) + if gui: + ArchCell._ViewProviderCell(newobj.ViewObject) elif obj.isDerivedFrom("Part::Feature"): newobj = FreeCAD.ActiveDocument.addObject("Part::Feature",getRealName(obj.Name)) newobj.Shape = obj.Shape @@ -649,11 +683,12 @@ def makeBlock(objectslist): '''makeBlock(objectslist): Creates a Draft Block from the given objects''' obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Block") _Block(obj) - _ViewProviderDraftPart(obj.ViewObject) obj.Components = objectslist - for o in objectslist: - o.ViewObject.Visibility = False - select(obj) + if gui: + _ViewProviderDraftPart(obj.ViewObject) + for o in objectslist: + o.ViewObject.Visibility = False + select(obj) return obj def makeArray(baseobject,arg1,arg2,arg3,arg4=None): @@ -667,7 +702,6 @@ def makeArray(baseobject,arg1,arg2,arg3,arg4=None): The result is a parametric Draft Array.''' obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Array") _Array(obj) - _ViewProviderDraftPart(obj.ViewObject) obj.Base = baseobject if arg4: obj.ArrayType = "ortho" @@ -679,9 +713,11 @@ def makeArray(baseobject,arg1,arg2,arg3,arg4=None): obj.ArrayType = "polar" obj.Center = arg1 obj.Angle = arg2 - obj.NumberPolar = arg3 - baseobject.ViewObject.hide() - select(obj) + obj.NumberPolar = arg3 + if gui: + _ViewProviderDraftPart(obj.ViewObject) + baseobject.ViewObject.hide() + select(obj) return obj def extrude(obj,vector): @@ -705,14 +741,16 @@ def fuse(object1,object2): if fcgeo.isCoplanar(object1.Shape.fuse(object2.Shape).Faces): obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Fusion") _Wire(obj) - _ViewProviderWire(obj.ViewObject) + if gui: + _ViewProviderWire(obj.ViewObject) else: obj = FreeCAD.ActiveDocument.addObject("Part::Fuse","Fusion") obj.Base = object1 obj.Tool = object2 - object1.ViewObject.Visibility = False - object2.ViewObject.Visibility = False - formatObject(obj,object1) + if gui: + object1.ViewObject.Visibility = False + object2.ViewObject.Visibility = False + formatObject(obj,object1) FreeCAD.ActiveDocument.recompute() return obj @@ -756,7 +794,8 @@ def move(objectslist,vector,copy=False): if copy: newobj = FreeCAD.ActiveDocument.addObject("App::FeaturePython",getRealName(obj.Name)) _Dimension(newobj) - _ViewProviderDimension(newobj.ViewObject) + if gui: + _ViewProviderDimension(newobj.ViewObject) else: newobj = obj newobj.Start = obj.Start.add(vector) @@ -922,7 +961,6 @@ def scale(objectslist,delta=Vector(1,1,1),center=Vector(0,0,0),copy=False,legacy else: obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Scale") _Clone(obj) - _ViewProviderDraftPart(obj.ViewObject) obj.Objects = objectslist obj.Scale = delta corr = Vector(center.x,center.y,center.z) @@ -934,8 +972,10 @@ def scale(objectslist,delta=Vector(1,1,1),center=Vector(0,0,0),copy=False,legacy if not copy: for o in objectslist: o.ViewObject.hide() - formatObject(obj,objectslist[-1]) - select(obj) + if gui: + _ViewProviderDraftPart(obj.ViewObject) + formatObject(obj,objectslist[-1]) + select(obj) return obj def offset(obj,delta,copy=False,bind=False,sym=False,occ=False): @@ -1396,7 +1436,8 @@ def makeShape2DView(baseobj,projectionVector=None): ''' obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Shape2DView") _Shape2DView(obj) - _ViewProviderDraft(obj.ViewObject) + if gui: + _ViewProviderDraft(obj.ViewObject) obj.Base = baseobj if projectionVector: obj.Projection = projectionVector @@ -1517,17 +1558,18 @@ def makePoint(X=0, Y=0, Z=0,color=None,name = "Point", point_size= 5): p1.X = 1 #move it in x p1.ViewObject.PointColor =(0.0,0.0,1.0) #change the color-make sure values are floats ''' - if not color: - color = FreeCADGui.draftToolBar.getDefaultColor('ui') obj=FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name) _Point(obj,X,Y,Z) - _ViewProviderPoint(obj.ViewObject) obj.X = X obj.Y = Y obj.Z = Z - obj.ViewObject.PointColor = (float(color[0]), float(color[1]), float(color[2])) - obj.ViewObject.PointSize = point_size - obj.ViewObject.Visibility = True + if gui: + _ViewProviderPoint(obj.ViewObject) + if not color: + color = FreeCADGui.draftToolBar.getDefaultColor('ui') + obj.ViewObject.PointColor = (float(color[0]), float(color[1]), float(color[2])) + obj.ViewObject.PointSize = point_size + obj.ViewObject.Visibility = True FreeCAD.ActiveDocument.recompute() return obj diff --git a/src/Mod/Draft/draftlibs/fcgeo.py b/src/Mod/Draft/draftlibs/fcgeo.py index 44690d49d..9863a2b1a 100755 --- a/src/Mod/Draft/draftlibs/fcgeo.py +++ b/src/Mod/Draft/draftlibs/fcgeo.py @@ -27,7 +27,7 @@ __url__ = ["http://free-cad.sourceforge.net"] "this file contains generic geometry functions for manipulating Part shapes" -import FreeCAD, Part, fcvec, math, cmath, FreeCADGui +import FreeCAD, Part, fcvec, math, cmath from FreeCAD import Vector NORM = Vector(0,0,1) # provisory normal direction for all geometry ops. @@ -364,12 +364,14 @@ def geom(edge): return Part.Circle(edge.Curve.Center,edge.Curve.Axis,edge.Curve.Radius) else: ref = edge.Placement.multVec(Vector(1,0,0)) + ref = ref.sub(edge.Placement.Base) # we only want the orientation v1 = edge.Vertexes[0].Point v2 = edge.Vertexes[-1].Point c = edge.Curve.Center cu = Part.Circle(edge.Curve.Center,edge.Curve.Axis,edge.Curve.Radius) - a1 = -fcvec.angle(v1.sub(c),ref) - a2 = -fcvec.angle(v2.sub(c),ref) + a1 = -fcvec.angle(v1.sub(c),ref,edge.Curve.Axis) + a2 = -fcvec.angle(v2.sub(c),ref,edge.Curve.Axis) + 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 else: @@ -701,8 +703,10 @@ def getNormal(shape): if 0.1 < abs(e1.getAngle(e2)) < 1.56: n = e1.cross(e2).normalize() break - vdir = FreeCADGui.ActiveDocument.ActiveView.getViewDirection() - if n.getAngle(vdir) < 0.78: n = fcvec.neg(n) + if FreeCAD.GuiUp: + import FreeCADGui + vdir = FreeCADGui.ActiveDocument.ActiveView.getViewDirection() + if n.getAngle(vdir) < 0.78: n = fcvec.neg(n) return n def offsetWire(wire,dvec,bind=False,occ=False):