diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py
index 1d9b9ac590..ceb67df1d9 100644
--- a/src/Mod/Draft/Draft.py
+++ b/src/Mod/Draft/Draft.py
@@ -30,45 +30,45 @@ __url__ = "http://free-cad.sourceforge.net"
'''
General description:
- The Draft module is a FreeCAD module for drawing/editing 2D entities.
- The aim is to give FreeCAD basic 2D-CAD capabilities (similar
- to Autocad and other similar software). This modules is made to be run
- inside FreeCAD and needs the PyQt4 and pivy modules available.
+ The Draft module is a FreeCAD module for drawing/editing 2D entities.
+ The aim is to give FreeCAD basic 2D-CAD capabilities (similar
+ to Autocad and other similar software). This modules is made to be run
+ inside FreeCAD and needs the PyQt4 and pivy modules available.
User manual:
- http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=2d_Drafting_Module
+ http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=2d_Drafting_Module
How it works / how to extend:
- This module is written entirely in python. If you know a bit of python
- language, you are welcome to modify this module or to help us to improve it.
- Suggestions are also welcome on the FreeCAD discussion forum.
+ This module is written entirely in python. If you know a bit of python
+ language, you are welcome to modify this module or to help us to improve it.
+ Suggestions are also welcome on the FreeCAD discussion forum.
+
+ If you want to have a look at the code, here is a general explanation. The
+ Draft module is divided in several files:
- If you want to have a look at the code, here is a general explanation. The
- Draft module is divided in several files:
-
- - Draft.py: Hosts the functions that are useful for scripting outside of
- the Draft module, it is the "Draft API"
- - draftGui.py: Creates and manages the special Draft toolbar
- - draftTools.py: Contains the user tools of the Draft module (the commands
- from the Draft menu), and a couple of helpers such as the "Trackers"
- (temporary geometry used while drawing)
- - draftlibs/fcvec.py: a vector math library, contains functions that are not
- implemented in the standard FreeCAD vector
- - draftlibs/fcgeo.py: a library of misc functions to manipulate shapes.
+ - Draft.py: Hosts the functions that are useful for scripting outside of
+ the Draft module, it is the "Draft API"
+ - draftGui.py: Creates and manages the special Draft toolbar
+ - draftTools.py: Contains the user tools of the Draft module (the commands
+ from the Draft menu), and a couple of helpers such as the "Trackers"
+ (temporary geometry used while drawing)
+ - draftlibs/fcvec.py: a vector math library, contains functions that are not
+ implemented in the standard FreeCAD vector
+ - draftlibs/fcgeo.py: a library of misc functions to manipulate shapes.
- The Draft.py contains everything to create geometry in the scene. You
- should start there if you intend to modify something. Then, the draftTools
- are where the FreeCAD commands are defined, while in draftGui.py
- you have the ui part, ie. the draft command bar. Both draftTools and
- draftGui are loaded at module init by InitGui.py, which is called directly by FreeCAD.
- The tools all have an Activated() function, which is called by FreeCAD when the
- corresponding FreeCAD command is invoked. Most tools then create the trackers they
- will need during operation, then place a callback mechanism, which will detect
- user input and do the necessary cad operations. They also send commands to the
- command bar, which will display the appropriate controls. While the scene event
- callback watches mouse events, the keyboard is being watched by the command bar.
+ The Draft.py contains everything to create geometry in the scene. You
+ should start there if you intend to modify something. Then, the draftTools
+ are where the FreeCAD commands are defined, while in draftGui.py
+ you have the ui part, ie. the draft command bar. Both draftTools and
+ draftGui are loaded at module init by InitGui.py, which is called directly by FreeCAD.
+ The tools all have an Activated() function, which is called by FreeCAD when the
+ corresponding FreeCAD command is invoked. Most tools then create the trackers they
+ will need during operation, then place a callback mechanism, which will detect
+ user input and do the necessary cad operations. They also send commands to the
+ command bar, which will display the appropriate controls. While the scene event
+ callback watches mouse events, the keyboard is being watched by the command bar.
'''
# import FreeCAD modules
@@ -83,1573 +83,1572 @@ from pivy import coin
#---------------------------------------------------------------------------
def typecheck (args_and_types, name="?"):
- "typecheck([arg1,type),(arg2,type),...]): checks arguments types"
- for v,t in args_and_types:
- if not isinstance (v,t):
- w = "typecheck[" + str(name) + "]: "
- w += str(v) + " is not " + str(t) + "\n"
- FreeCAD.Console.PrintWarning(w)
- raise TypeError("Draft." + str(name))
+ "typecheck([arg1,type),(arg2,type),...]): checks arguments types"
+ for v,t in args_and_types:
+ if not isinstance (v,t):
+ w = "typecheck[" + str(name) + "]: "
+ w += str(v) + " is not " + str(t) + "\n"
+ FreeCAD.Console.PrintWarning(w)
+ raise TypeError("Draft." + str(name))
def getParamType(param):
- if param in ["dimsymbol","dimPrecision","dimorientation","precision","defaultWP",
- "snapRange","gridEvery","linewidth","UiMode","modconstrain","modsnap",
- "modalt"]:
- return "int"
- elif param in ["constructiongroupname","textfont","patternFile","template"]:
- return "string"
- elif param in ["textheight","tolerance","gridSpacing"]:
- return "float"
- elif param in ["selectBaseObjects","alwaysSnap","grid","fillmode","saveonexit"]:
- return "bool"
- elif param in ["color","constructioncolor","snapcolor"]:
- return "unsigned"
- else:
- return None
+ if param in ["dimsymbol","dimPrecision","dimorientation","precision","defaultWP",
+ "snapRange","gridEvery","linewidth","UiMode","modconstrain","modsnap",
+ "modalt"]:
+ return "int"
+ elif param in ["constructiongroupname","textfont","patternFile","template"]:
+ return "string"
+ elif param in ["textheight","tolerance","gridSpacing"]:
+ return "float"
+ elif param in ["selectBaseObjects","alwaysSnap","grid","fillmode","saveonexit"]:
+ return "bool"
+ elif param in ["color","constructioncolor","snapcolor"]:
+ return "unsigned"
+ else:
+ return None
def getParam(param):
- "getParam(parameterName): returns a Draft parameter value from the current config"
- p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
- t = getParamType(param)
- if t == "int": return p.GetInt(param)
- elif t == "string": return p.GetString(param)
- elif t == "float": return p.GetFloat(param)
- elif t == "bool": return p.GetBool(param)
- elif t == "unsigned": return p.GetUnsigned(param)
- else: return None
+ "getParam(parameterName): returns a Draft parameter value from the current config"
+ p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
+ t = getParamType(param)
+ if t == "int": return p.GetInt(param)
+ elif t == "string": return p.GetString(param)
+ elif t == "float": return p.GetFloat(param)
+ elif t == "bool": return p.GetBool(param)
+ elif t == "unsigned": return p.GetUnsigned(param)
+ else: return None
def setParam(param,value):
- "setParam(parameterName,value): sets a Draft parameter with the given value"
- p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
- t = getParamType(param)
- if t == "int": p.SetInt(param,value)
- elif t == "string": p.SetString(param,value)
- elif t == "float": p.SetFloat(param,value)
- elif t == "bool": p.SetBool(param,value)
- elif t == "unsigned": p.SetUnsigned(param,value)
+ "setParam(parameterName,value): sets a Draft parameter with the given value"
+ p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
+ t = getParamType(param)
+ if t == "int": p.SetInt(param,value)
+ elif t == "string": p.SetString(param,value)
+ elif t == "float": p.SetFloat(param,value)
+ elif t == "bool": p.SetBool(param,value)
+ elif t == "unsigned": p.SetUnsigned(param,value)
def precision():
- "precision(): returns the precision value from Draft user settings"
- return getParam("precision")
+ "precision(): returns the precision value from Draft user settings"
+ return getParam("precision")
def tolerance():
- "tolerance(): returns the tolerance value from Draft user settings"
- return getParam("tolerance")
+ "tolerance(): returns the tolerance value from Draft user settings"
+ return getParam("tolerance")
def getRealName(name):
- "getRealName(string): strips the trailing numbers from a string name"
- for i in range(1,len(name)):
- if not name[-i] in '1234567890':
- return name[:len(name)-(i-1)]
- return name
+ "getRealName(string): strips the trailing numbers from a string name"
+ for i in range(1,len(name)):
+ if not name[-i] in '1234567890':
+ return name[:len(name)-(i-1)]
+ return name
def getType(obj):
- "getType(object): returns the Draft type of the given object"
- if "Proxy" in obj.PropertiesList:
- if hasattr(obj.Proxy,"Type"):
- return obj.Proxy.Type
- if obj.isDerivedFrom("Part::Feature"):
- return "Part"
- if (obj.Type == "App::Annotation"):
- return "Annotation"
- if obj.isDerivedFrom("Mesh::Feature"):
- return "Mesh"
- if (obj.Type == "App::DocumentObjectGroup"):
- return "Group"
- return "Unknown"
+ "getType(object): returns the Draft type of the given object"
+ if "Proxy" in obj.PropertiesList:
+ if hasattr(obj.Proxy,"Type"):
+ return obj.Proxy.Type
+ if obj.isDerivedFrom("Part::Feature"):
+ return "Part"
+ if (obj.Type == "App::Annotation"):
+ return "Annotation"
+ if obj.isDerivedFrom("Mesh::Feature"):
+ return "Mesh"
+ if (obj.Type == "App::DocumentObjectGroup"):
+ return "Group"
+ return "Unknown"
def getGroupNames():
- "returns a list of existing groups in the document"
- glist = []
- doc = FreeCAD.ActiveDocument
- for obj in doc.Objects:
- if obj.Type == "App::DocumentObjectGroup":
- glist.append(obj.Name)
- return glist
+ "returns a list of existing groups in the document"
+ glist = []
+ doc = FreeCAD.ActiveDocument
+ for obj in doc.Objects:
+ if obj.Type == "App::DocumentObjectGroup":
+ glist.append(obj.Name)
+ return glist
def ungroup(obj):
- "removes the current object from any group it belongs to"
- for g in getGroupNames():
- grp = FreeCAD.ActiveDocument.getObject(g)
- if grp.hasObject(obj):
- grp.removeObject(obj)
+ "removes the current object from any group it belongs to"
+ for g in getGroupNames():
+ grp = FreeCAD.ActiveDocument.getObject(g)
+ if grp.hasObject(obj):
+ grp.removeObject(obj)
def dimSymbol():
- "returns the current dim symbol from the preferences as a pivy SoMarkerSet"
- s = getParam("dimsymbol")
- marker = coin.SoMarkerSet()
- if s == 0: marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_5_5
- elif s == 1: marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_7_7
- elif s == 2: marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_9_9
- elif s == 3: marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_5_5
- elif s == 4: marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_7_7
- elif s == 5: marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_9_9
- elif s == 6: marker.markerIndex = coin.SoMarkerSet.SLASH_5_5
- elif s == 7: marker.markerIndex = coin.SoMarkerSet.SLASH_7_7
- elif s == 8: marker.markerIndex = coin.SoMarkerSet.SLASH_9_9
- elif s == 9: marker.markerIndex = coin.SoMarkerSet.BACKSLASH_5_5
- elif s == 10: marker.markerIndex = coin.SoMarkerSet.BACKSLASH_7_7
- elif s == 11: marker.markerIndex = coin.SoMarkerSet.BACKSLASH_9_9
- return marker
+ "returns the current dim symbol from the preferences as a pivy SoMarkerSet"
+ s = getParam("dimsymbol")
+ marker = coin.SoMarkerSet()
+ if s == 0: marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_5_5
+ elif s == 1: marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_7_7
+ elif s == 2: marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_9_9
+ elif s == 3: marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_5_5
+ elif s == 4: marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_7_7
+ elif s == 5: marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_9_9
+ elif s == 6: marker.markerIndex = coin.SoMarkerSet.SLASH_5_5
+ elif s == 7: marker.markerIndex = coin.SoMarkerSet.SLASH_7_7
+ elif s == 8: marker.markerIndex = coin.SoMarkerSet.SLASH_9_9
+ elif s == 9: marker.markerIndex = coin.SoMarkerSet.BACKSLASH_5_5
+ elif s == 10: marker.markerIndex = coin.SoMarkerSet.BACKSLASH_7_7
+ elif s == 11: marker.markerIndex = coin.SoMarkerSet.BACKSLASH_9_9
+ return marker
def shapify(obj):
- '''shapify(object): transforms a parametric shape object into
- non-parametric and returns the new object'''
- if not (obj.isDerivedFrom("Part::Feature")): return None
- if not "Shape" in obj.PropertiesList: return None
- if obj.Type == "Part::Feature": return obj
- shape = obj.Shape
- name = getRealName(obj.Name)
- FreeCAD.ActiveDocument.removeObject(obj.Name)
- newobj = FreeCAD.ActiveDocument.addObject("Part::Feature",name)
- newobj.Shape = shape
- FreeCAD.ActiveDocument.recompute()
- return newobj
+ '''shapify(object): transforms a parametric shape object into
+ non-parametric and returns the new object'''
+ if not (obj.isDerivedFrom("Part::Feature")): return None
+ if not "Shape" in obj.PropertiesList: return None
+ if obj.Type == "Part::Feature": return obj
+ shape = obj.Shape
+ name = getRealName(obj.Name)
+ FreeCAD.ActiveDocument.removeObject(obj.Name)
+ newobj = FreeCAD.ActiveDocument.addObject("Part::Feature",name)
+ newobj.Shape = shape
+ FreeCAD.ActiveDocument.recompute()
+ return newobj
def getGroupContents(objectslist):
- '''getGroupContents(objectlist): if any object of the given list
- is a group, its content is appened to the list, which is returned'''
- newlist = []
- for obj in objectslist:
- if obj.Type == "App::DocumentObjectGroup":
- newlist.extend(getGroupContents(obj.Group))
- else:
- newlist.append(obj)
- return newlist
+ '''getGroupContents(objectlist): if any object of the given list
+ is a group, its content is appened to the list, which is returned'''
+ newlist = []
+ for obj in objectslist:
+ if obj.Type == "App::DocumentObjectGroup":
+ newlist.extend(getGroupContents(obj.Group))
+ else:
+ newlist.append(obj)
+ return newlist
def formatObject(target,origin=None):
- '''
- formatObject(targetObject,[originObject]): This function applies
- to the given target object the current properties
- set on the toolbar (line color and line width),
- or copies the properties of another object if given as origin.
- 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 gname:
- 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
- if ("LineWidth" in obrep.PropertiesList) and \
- ("LineWidth" in matchrep.PropertiesList):
- obrep.LineWidth = matchrep.LineWidth
- if ("PointColor" in obrep.PropertiesList) and \
- ("PointColor" in matchrep.PropertiesList):
- obrep.PointColor = matchrep.PointColor
- if ("LineColor" in obrep.PropertiesList) and \
- ("LineColor" in matchrep.PropertiesList):
- obrep.LineColor = matchrep.LineColor
- if ("ShapeColor" in obrep.PropertiesList) and \
- ("ShapeColor" in matchrep.PropertiesList):
- obrep.ShapeColor = matchrep.ShapeColor
- if matchrep.DisplayMode in obrep.listDisplayModes():
- obrep.DisplayMode = matchrep.DisplayMode
+ '''
+ formatObject(targetObject,[originObject]): This function applies
+ to the given target object the current properties
+ set on the toolbar (line color and line width),
+ or copies the properties of another object if given as origin.
+ 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 gname:
+ 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
+ if ("LineWidth" in obrep.PropertiesList) and \
+ ("LineWidth" in matchrep.PropertiesList):
+ obrep.LineWidth = matchrep.LineWidth
+ if ("PointColor" in obrep.PropertiesList) and \
+ ("PointColor" in matchrep.PropertiesList):
+ obrep.PointColor = matchrep.PointColor
+ if ("LineColor" in obrep.PropertiesList) and \
+ ("LineColor" in matchrep.PropertiesList):
+ obrep.LineColor = matchrep.LineColor
+ if ("ShapeColor" in obrep.PropertiesList) and \
+ ("ShapeColor" in matchrep.PropertiesList):
+ obrep.ShapeColor = matchrep.ShapeColor
+ if matchrep.DisplayMode in obrep.listDisplayModes():
+ obrep.DisplayMode = matchrep.DisplayMode
def getSelection():
- "getSelection(): returns the current FreeCAD selection"
- return FreeCADGui.Selection.getSelection()
+ "getSelection(): returns the current FreeCAD selection"
+ return FreeCADGui.Selection.getSelection()
def select(objs):
- "select(object): deselects everything and selects only the passed object or list"
- FreeCADGui.Selection.clearSelection()
- if not isinstance(objs,list):
- objs = [objs]
- for obj in objs:
- FreeCADGui.Selection.addSelection(obj)
+ "select(object): deselects everything and selects only the passed object or list"
+ FreeCADGui.Selection.clearSelection()
+ if not isinstance(objs,list):
+ objs = [objs]
+ for obj in objs:
+ FreeCADGui.Selection.addSelection(obj)
def makeCircle(radius, placement=None, face=True, startangle=None, endangle=None, support=None):
- '''makeCircle(radius,[placement,face,startangle,endangle]): Creates a circle
- object with given radius. If placement is given, it is
- used. If face is False, the circle is shown as a
- wireframe, otherwise as a face. If startangle AND endangle are given
- (in degrees), they are used and the object appears as an arc.'''
- if placement: typecheck([(placement,FreeCAD.Placement)], "makeCircle")
- obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Circle")
- Circle(obj)
- ViewProviderDraft(obj.ViewObject)
- obj.Radius = radius
- if not face: obj.ViewObject.DisplayMode = "Wireframe"
- if (startangle != None) and (endangle != None):
- if startangle == -0: startangle = 0
- obj.FirstAngle = startangle
- obj.LastAngle = endangle
- obj.Support = support
- if placement: obj.Placement = placement
- formatObject(obj)
- select(obj)
- FreeCAD.ActiveDocument.recompute()
- return obj
-
+ '''makeCircle(radius,[placement,face,startangle,endangle]): Creates a circle
+ object with given radius. If placement is given, it is
+ used. If face is False, the circle is shown as a
+ wireframe, otherwise as a face. If startangle AND endangle are given
+ (in degrees), they are used and the object appears as an arc.'''
+ if placement: typecheck([(placement,FreeCAD.Placement)], "makeCircle")
+ obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Circle")
+ Circle(obj)
+ ViewProviderDraft(obj.ViewObject)
+ obj.Radius = radius
+ if not face: obj.ViewObject.DisplayMode = "Wireframe"
+ if (startangle != None) and (endangle != None):
+ if startangle == -0: startangle = 0
+ obj.FirstAngle = startangle
+ obj.LastAngle = endangle
+ obj.Support = support
+ if placement: obj.Placement = placement
+ formatObject(obj)
+ select(obj)
+ FreeCAD.ActiveDocument.recompute()
+ return obj
+
def makeRectangle(length, height, placement=None, face=True, support=None):
- '''makeRectangle(length,width,[placement],[face]): Creates a Rectangle
- object with length in X direction and height in Y direction.
- If a placement is given, it is used. If face is False, the
- rectangle is shown as a wireframe, otherwise as a face.'''
- 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)
- FreeCAD.ActiveDocument.recompute()
- return obj
+ '''makeRectangle(length,width,[placement],[face]): Creates a Rectangle
+ object with length in X direction and height in Y direction.
+ If a placement is given, it is used. If face is False, the
+ rectangle is shown as a wireframe, otherwise as a face.'''
+ 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)
+ FreeCAD.ActiveDocument.recompute()
+ return obj
def makeDimension(p1,p2,p3=None,p4=None):
- '''makeDimension(p1,p2,[p3]) or makeDimension(object,i1,i2,p3)
- or makeDimension(objlist,indices,p3): Creates a Dimension object with
- the dimension line passign through p3.The current line width and color
- will be used. There are multiple ways to create a dimension, depending on
- the arguments you pass to it:
- - (p1,p2,p3): creates a standard dimension from p1 to p2
- - (object,i1,i2,p3): creates a linked dimension to the given object,
- measuring the distance between its vertices indexed i1 and i2
- - (object,i1,mode,p3): creates a linked dimension
- to the given object, i1 is the index of the (curved) edge to measure,
- and mode is either "radius" or "diameter".
- '''
- 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
- elif isinstance(p2,int) and isinstance(p3,int):
- obj.Base = p1
- obj.LinkedVertices = [p2,p3]
- p3 = p4
- elif isinstance(p3,str):
- obj.Base = p1
- if p3 == "radius":
- obj.LinkedVertices = [p2,1,1]
- obj.ViewObject.Override = "rdim"
- elif p3 == "diameter":
- obj.LinkedVertices = [p2,2,1]
- obj.ViewObject.Override = "ddim"
- p3 = p4
- if not p3:
- p3 = p2.sub(p1)
- p3.multiply(0.5)
- p3 = p1.add(p3)
- obj.Dimline = p3
- formatObject(obj)
- select(obj)
- FreeCAD.ActiveDocument.recompute()
- return obj
+ '''makeDimension(p1,p2,[p3]) or makeDimension(object,i1,i2,p3)
+ or makeDimension(objlist,indices,p3): Creates a Dimension object with
+ the dimension line passign through p3.The current line width and color
+ will be used. There are multiple ways to create a dimension, depending on
+ the arguments you pass to it:
+ - (p1,p2,p3): creates a standard dimension from p1 to p2
+ - (object,i1,i2,p3): creates a linked dimension to the given object,
+ measuring the distance between its vertices indexed i1 and i2
+ - (object,i1,mode,p3): creates a linked dimension
+ to the given object, i1 is the index of the (curved) edge to measure,
+ and mode is either "radius" or "diameter".
+ '''
+ 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
+ elif isinstance(p2,int) and isinstance(p3,int):
+ obj.Base = p1
+ obj.LinkedVertices = [p2,p3]
+ p3 = p4
+ elif isinstance(p3,str):
+ obj.Base = p1
+ if p3 == "radius":
+ obj.LinkedVertices = [p2,1,1]
+ obj.ViewObject.Override = "rdim"
+ elif p3 == "diameter":
+ obj.LinkedVertices = [p2,2,1]
+ obj.ViewObject.Override = "ddim"
+ p3 = p4
+ if not p3:
+ p3 = p2.sub(p1)
+ p3.multiply(0.5)
+ p3 = p1.add(p3)
+ obj.Dimline = p3
+ formatObject(obj)
+ select(obj)
+ FreeCAD.ActiveDocument.recompute()
+ return obj
def makeAngularDimension(center,angles,p3):
- '''makeAngularDimension(center,[angle1,angle2],p3): creates an angular Dimension
- from the given center, with the given list of angles, passing through 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:
- angles[a] = angles[a]-(2*math.pi)
- obj.FirstAngle = math.degrees(angles[1])
- obj.LastAngle = math.degrees(angles[0])
- obj.Dimline = p3
- formatObject(obj)
- select(obj)
- FreeCAD.ActiveDocument.recompute()
- return obj
+ '''makeAngularDimension(center,[angle1,angle2],p3): creates an angular Dimension
+ from the given center, with the given list of angles, passing through 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:
+ angles[a] = angles[a]-(2*math.pi)
+ obj.FirstAngle = math.degrees(angles[1])
+ obj.LastAngle = math.degrees(angles[0])
+ obj.Dimline = p3
+ formatObject(obj)
+ select(obj)
+ FreeCAD.ActiveDocument.recompute()
+ return obj
def makeWire(pointslist,closed=False,placement=None,face=True,support=None):
- '''makeWire(pointslist,[closed],[placement]): Creates a Wire object
- from the given list of vectors. If closed is True or first
- and last points are identical, the wire is closed. If face is
- true (and wire is closed), the wire will appear filled. Instead of
- a pointslist, you can also pass a Part Wire.'''
- if not isinstance(pointslist,list):
- nlist = []
- for v in pointslist.Vertexes:
- nlist.append(v.Point)
- if fcgeo.isReallyClosed(pointslist):
- nlist.append(pointslist.Vertexes[0].Point)
- pointslist = nlist
- if placement: typecheck([(placement,FreeCAD.Placement)], "makeWire")
- if len(pointslist) == 2: fname = "Line"
- 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)
- FreeCAD.ActiveDocument.recompute()
- return obj
+ '''makeWire(pointslist,[closed],[placement]): Creates a Wire object
+ from the given list of vectors. If closed is True or first
+ and last points are identical, the wire is closed. If face is
+ true (and wire is closed), the wire will appear filled. Instead of
+ a pointslist, you can also pass a Part Wire.'''
+ if not isinstance(pointslist,list):
+ nlist = []
+ for v in pointslist.Vertexes:
+ nlist.append(v.Point)
+ if fcgeo.isReallyClosed(pointslist):
+ nlist.append(pointslist.Vertexes[0].Point)
+ pointslist = nlist
+ if placement: typecheck([(placement,FreeCAD.Placement)], "makeWire")
+ if len(pointslist) == 2: fname = "Line"
+ 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)
+ FreeCAD.ActiveDocument.recompute()
+ return obj
def makePolygon(nfaces,radius=1,inscribed=True,placement=None,face=True,support=None):
- '''makePolgon(nfaces,[radius],[inscribed],[placement],[face]): Creates a
- polygon object with the given number of faces and the radius.
- if inscribed is False, the polygon is circumscribed around a circle
- with the given radius, otherwise it is inscribed. If face is True,
- the resulting shape is displayed as a face, otherwise as a wireframe.
- '''
- 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)
- FreeCAD.ActiveDocument.recompute()
- return obj
+ '''makePolgon(nfaces,[radius],[inscribed],[placement],[face]): Creates a
+ polygon object with the given number of faces and the radius.
+ if inscribed is False, the polygon is circumscribed around a circle
+ with the given radius, otherwise it is inscribed. If face is True,
+ the resulting shape is displayed as a face, otherwise as a wireframe.
+ '''
+ 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)
+ FreeCAD.ActiveDocument.recompute()
+ return obj
def makeLine(p1,p2):
- '''makeLine(p1,p2): Creates a line between p1 and p2.'''
- obj = makeWire([p1,p2])
- return obj
+ '''makeLine(p1,p2): Creates a line between p1 and p2.'''
+ obj = makeWire([p1,p2])
+ return obj
def makeBSpline(pointslist,closed=False,placement=None,face=True,support=None):
- '''makeBSpline(pointslist,[closed],[placement]): Creates a B-Spline object
- from the given list of vectors. If closed is True or first
- and last points are identical, the wire is closed. If face is
- true (and wire is closed), the wire will appear filled. Instead of
- a pointslist, you can also pass a Part Wire.'''
- if not isinstance(pointslist,list):
- nlist = []
- for v in pointslist.Vertexes:
- nlist.append(v.Point)
- pointslist = nlist
- if placement: typecheck([(placement,FreeCAD.Placement)], "makeBSpline")
- if len(pointslist) == 2: fname = "Line"
- 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)
- FreeCAD.ActiveDocument.recompute()
- return obj
+ '''makeBSpline(pointslist,[closed],[placement]): Creates a B-Spline object
+ from the given list of vectors. If closed is True or first
+ and last points are identical, the wire is closed. If face is
+ true (and wire is closed), the wire will appear filled. Instead of
+ a pointslist, you can also pass a Part Wire.'''
+ if not isinstance(pointslist,list):
+ nlist = []
+ for v in pointslist.Vertexes:
+ nlist.append(v.Point)
+ pointslist = nlist
+ if placement: typecheck([(placement,FreeCAD.Placement)], "makeBSpline")
+ if len(pointslist) == 2: fname = "Line"
+ 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)
+ FreeCAD.ActiveDocument.recompute()
+ return obj
def makeText(stringslist,point=Vector(0,0,0),screen=False):
- '''makeText(strings,[point],[screen]): Creates a Text object at the given point,
- containing the strings given in the strings list, one string by line (strings
- can also be one single string). The current color and text height and font
- specified in preferences are used.
- If screen is True, the text always faces the view direction.'''
- typecheck([(point,Vector)], "makeText")
- if not isinstance(stringslist,list): stringslist = [stringslist]
- textbuffer = []
- for l in stringslist: textbuffer.append(unicode(l).encode('utf-8'))
- obj=FreeCAD.ActiveDocument.addObject("App::Annotation","Text")
- obj.LabelText=textbuffer
- obj.Position=point
- if not screen: obj.ViewObject.DisplayMode="World"
- h = getParam("textheight")
- if screen: h = h*10
- obj.ViewObject.FontSize = h
- obj.ViewObject.FontName = getParam("textfont")
- obj.ViewObject.LineSpacing = 0.6
- formatObject(obj)
- select(obj)
- return obj
+ '''makeText(strings,[point],[screen]): Creates a Text object at the given point,
+ containing the strings given in the strings list, one string by line (strings
+ can also be one single string). The current color and text height and font
+ specified in preferences are used.
+ If screen is True, the text always faces the view direction.'''
+ typecheck([(point,Vector)], "makeText")
+ if not isinstance(stringslist,list): stringslist = [stringslist]
+ textbuffer = []
+ for l in stringslist: textbuffer.append(unicode(l).encode('utf-8'))
+ obj=FreeCAD.ActiveDocument.addObject("App::Annotation","Text")
+ obj.LabelText=textbuffer
+ obj.Position=point
+ if not screen: obj.ViewObject.DisplayMode="World"
+ h = getParam("textheight")
+ if screen: h = h*10
+ obj.ViewObject.FontSize = h
+ obj.ViewObject.FontName = getParam("textfont")
+ obj.ViewObject.LineSpacing = 0.6
+ formatObject(obj)
+ select(obj)
+ return obj
def makeCopy(obj):
- '''makeCopy(object): returns an exact copy of an object'''
- newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name))
- if getType(obj) == "Rectangle":
- Rectangle(newobj)
- ViewProviderRectangle(newobj.ViewObject)
- elif getType(obj) == "Wire":
- Wire(newobj)
- ViewProviderWire(newobj.ViewObject)
- elif getType(obj) == "Circle":
- Circle(newobj)
- ViewProviderCircle(newobj.ViewObject)
- elif getType(obj) == "Polygon":
- Polygon(newobj)
- ViewProviderPolygon(newobj.ViewObject)
- elif getType(obj) == "BSpline":
- BSpline(newobj)
- ViewProviderBSpline(newobj.ViewObject)
- elif getType(obj) == "Block":
- Block(newobj)
- ViewProviderBlock(newobj.ViewObject)
- elif getType(obj) == "Structure":
- import Structure
- Structure.Structure(newobj)
- Structure.ViewProviderStructure(newobj.ViewObject)
- elif getType(obj) == "Wall":
- import Wall
- Wall.Wall(newobj)
- Wall.ViewProviderWall(newobj.ViewObject)
- elif obj.isDerivedFrom("Part::Feature"):
- newobj.Shape = obj.Shape
- else:
- print "Error: Object type cannot be copied"
- return None
- for p in obj.PropertiesList:
- if p in newobj.PropertiesList:
- setattr(newobj,p,obj.getPropertyByName(p))
- formatObject(newobj,obj)
- return newobj
+ '''makeCopy(object): returns an exact copy of an object'''
+ newobj = FreeCAD.ActiveDocument.addObject(obj.Type,getRealName(obj.Name))
+ if getType(obj) == "Rectangle":
+ Rectangle(newobj)
+ ViewProviderRectangle(newobj.ViewObject)
+ elif getType(obj) == "Wire":
+ Wire(newobj)
+ ViewProviderWire(newobj.ViewObject)
+ elif getType(obj) == "Circle":
+ Circle(newobj)
+ ViewProviderCircle(newobj.ViewObject)
+ elif getType(obj) == "Polygon":
+ Polygon(newobj)
+ ViewProviderPolygon(newobj.ViewObject)
+ elif getType(obj) == "BSpline":
+ BSpline(newobj)
+ ViewProviderBSpline(newobj.ViewObject)
+ elif getType(obj) == "Block":
+ Block(newobj)
+ ViewProviderBlock(newobj.ViewObject)
+ elif getType(obj) == "Structure":
+ import Structure
+ Structure.Structure(newobj)
+ Structure.ViewProviderStructure(newobj.ViewObject)
+ elif getType(obj) == "Wall":
+ import Wall
+ Wall.Wall(newobj)
+ Wall.ViewProviderWall(newobj.ViewObject)
+ elif obj.isDerivedFrom("Part::Feature"):
+ newobj.Shape = obj.Shape
+ else:
+ print "Error: Object type cannot be copied"
+ return None
+ for p in obj.PropertiesList:
+ if p in newobj.PropertiesList:
+ setattr(newobj,p,obj.getPropertyByName(p))
+ formatObject(newobj,obj)
+ return newobj
def makeBlock(objectslist):
- '''makeBlock(objectslist): Creates a Draft Block from the given objects'''
- obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Block")
- Block(obj)
- ViewProviderBlock(obj.ViewObject)
- obj.Components = objectslist
- for o in objectslist:
- o.ViewObject.Visibility = False
- select(obj)
- return obj
+ '''makeBlock(objectslist): Creates a Draft Block from the given objects'''
+ obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Block")
+ Block(obj)
+ ViewProviderBlock(obj.ViewObject)
+ obj.Components = objectslist
+ for o in objectslist:
+ o.ViewObject.Visibility = False
+ select(obj)
+ return obj
def extrude(obj,vector):
- '''makeExtrusion(object,vector): extrudes the given object
- in the direction given by the vector. The original object
- gets hidden.'''
- newobj = FreeCAD.ActiveDocument.addObject("Part::Extrusion","Extrusion")
- newobj.Base = obj
- newobj.Dir = vector
- obj.ViewObject.Visibility = False
- formatObject(newobj,obj)
- FreeCAD.ActiveDocument.recompute()
- return newobj
+ '''makeExtrusion(object,vector): extrudes the given object
+ in the direction given by the vector. The original object
+ gets hidden.'''
+ newobj = FreeCAD.ActiveDocument.addObject("Part::Extrusion","Extrusion")
+ newobj.Base = obj
+ newobj.Dir = vector
+ obj.ViewObject.Visibility = False
+ formatObject(newobj,obj)
+ FreeCAD.ActiveDocument.recompute()
+ return newobj
def fuse(object1,object2):
- '''fuse(oject1,object2): returns an object made from
- the union of the 2 given objects. If the objects are
- coplanar, a special Draft Wire is used, otherwise we use
- a standard Part fuse.'''
- if fcgeo.isCoplanar(object1.Shape.fuse(object2.Shape).Faces):
- obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Fusion")
- Wire(obj)
- 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)
- FreeCAD.ActiveDocument.recompute()
- return obj
+ '''fuse(oject1,object2): returns an object made from
+ the union of the 2 given objects. If the objects are
+ coplanar, a special Draft Wire is used, otherwise we use
+ a standard Part fuse.'''
+ if fcgeo.isCoplanar(object1.Shape.fuse(object2.Shape).Faces):
+ obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Fusion")
+ Wire(obj)
+ 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)
+ FreeCAD.ActiveDocument.recompute()
+ return obj
def cut(object1,object2):
- '''cut(oject1,object2): returns a cut object made from
- the difference of the 2 given objects.'''
- obj = FreeCAD.ActiveDocument.addObject("Part::Cut","Cut")
- obj.Base = object1
- obj.Tool = object2
- object1.ViewObject.Visibility = False
- object2.ViewObject.Visibility = False
- formatObject(obj,object1)
- FreeCAD.ActiveDocument.recompute()
- return obj
+ '''cut(oject1,object2): returns a cut object made from
+ the difference of the 2 given objects.'''
+ obj = FreeCAD.ActiveDocument.addObject("Part::Cut","Cut")
+ obj.Base = object1
+ obj.Tool = object2
+ object1.ViewObject.Visibility = False
+ object2.ViewObject.Visibility = False
+ formatObject(obj,object1)
+ FreeCAD.ActiveDocument.recompute()
+ return obj
def move(objectslist,vector,copy=False):
- '''move(objects,vector,[copy]): Moves the objects contained
- in objects (that can be an object or a list of objects)
- in the direction and distance indicated by the given
- vector. If copy is True, the actual objects are not moved, but copies
- are created instead.he objects (or their copies) are returned.'''
- typecheck([(vector,Vector), (copy,bool)], "move")
- if not isinstance(objectslist,list): objectslist = [objectslist]
- newobjlist = []
- for obj in objectslist:
- if (obj.isDerivedFrom("Part::Feature")):
- if copy:
- newobj = makeCopy(obj)
- else:
- newobj = obj
- pla = newobj.Placement
- pla.move(vector)
- elif getType(obj) == "Annotation":
- if copy:
- newobj = FreeCAD.ActiveDocument.addObject("App::Annotation",getRealName(obj.Name))
- newobj.LabelText = obj.LabelText
- else:
- newobj = obj
- newobj.Position = obj.Position.add(vector)
- elif getType(obj) == "Dimension":
- if copy:
- newobj = FreeCAD.ActiveDocument.addObject("App::FeaturePython",getRealName(obj.Name))
- Dimension(newobj)
- DimensionViewProvider(newobj.ViewObject)
- else:
- newobj = obj
- newobj.Start = obj.Start.add(vector)
- newobj.End = obj.End.add(vector)
- newobj.Dimline = obj.Dimline.add(vector)
- else:
- if copy: print "Mesh copy not supported at the moment" # TODO
- newobj = obj
- if "Placement" in obj.PropertiesList:
- pla = obj.Placement
- pla.move(vector)
- newobjlist.append(newobj)
- if copy and getParam("selectBaseObjects"):
- select(objectslist)
+ '''move(objects,vector,[copy]): Moves the objects contained
+ in objects (that can be an object or a list of objects)
+ in the direction and distance indicated by the given
+ vector. If copy is True, the actual objects are not moved, but copies
+ are created instead.he objects (or their copies) are returned.'''
+ typecheck([(vector,Vector), (copy,bool)], "move")
+ if not isinstance(objectslist,list): objectslist = [objectslist]
+ newobjlist = []
+ for obj in objectslist:
+ if (obj.isDerivedFrom("Part::Feature")):
+ if copy:
+ newobj = makeCopy(obj)
+ else:
+ newobj = obj
+ pla = newobj.Placement
+ pla.move(vector)
+ elif getType(obj) == "Annotation":
+ if copy:
+ newobj = FreeCAD.ActiveDocument.addObject("App::Annotation",getRealName(obj.Name))
+ newobj.LabelText = obj.LabelText
+ else:
+ newobj = obj
+ newobj.Position = obj.Position.add(vector)
+ elif getType(obj) == "Dimension":
+ if copy:
+ newobj = FreeCAD.ActiveDocument.addObject("App::FeaturePython",getRealName(obj.Name))
+ Dimension(newobj)
+ DimensionViewProvider(newobj.ViewObject)
+ else:
+ newobj = obj
+ newobj.Start = obj.Start.add(vector)
+ newobj.End = obj.End.add(vector)
+ newobj.Dimline = obj.Dimline.add(vector)
else:
- select(newobjlist)
- if len(newobjlist) == 1: return newobjlist[0]
- return newobjlist
+ if copy: print "Mesh copy not supported at the moment" # TODO
+ newobj = obj
+ if "Placement" in obj.PropertiesList:
+ pla = obj.Placement
+ pla.move(vector)
+ newobjlist.append(newobj)
+ if copy and getParam("selectBaseObjects"):
+ select(objectslist)
+ else:
+ select(newobjlist)
+ if len(newobjlist) == 1: return newobjlist[0]
+ return newobjlist
def array(objectslist,arg1,arg2,arg3,arg4=None):
- '''array(objectslist,xvector,yvector,xnum,ynum) for rectangular array, or
- array(objectslist,center,totalangle,totalnum) for polar array: Creates an array
- of the objects contained in list (that can be an object or a list of objects)
- with, in case of rectangular array, xnum of iterations in the x direction
- at xvector distance between iterations, and same for y direction with yvector
- and ynum. In case of polar array, center is a vector, totalangle is the angle
- to cover (in degrees) and totalnum is the number of objects, including the original.'''
-
- def rectArray(objectslist,xvector,yvector,xnum,ynum):
- typecheck([(xvector,Vector), (yvector,Vector), (xnum,int), (ynum,int)], "rectArray")
- if not isinstance(objectslist,list): objectslist = [objectslist]
- for xcount in range(xnum):
- currentxvector=fcvec.scale(xvector,xcount)
- if not xcount==0:
- move(objectslist,currentxvector,True)
- for ycount in range(ynum):
- currentxvector=FreeCAD.Base.Vector(currentxvector)
- currentyvector=currentxvector.add(fcvec.scale(yvector,ycount))
- if not ycount==0:
- move(objectslist,currentyvector,True)
- def polarArray(objectslist,center,angle,num):
- typecheck([(center,Vector), (num,int)], "polarArray")
- if not isinstance(objectslist,list): objectslist = [objectslist]
- fraction = angle/num
- for i in range(num):
- currangle = fraction + (i*fraction)
- rotate(objectslist,currangle,center,copy=True)
+ '''array(objectslist,xvector,yvector,xnum,ynum) for rectangular array, or
+ array(objectslist,center,totalangle,totalnum) for polar array: Creates an array
+ of the objects contained in list (that can be an object or a list of objects)
+ with, in case of rectangular array, xnum of iterations in the x direction
+ at xvector distance between iterations, and same for y direction with yvector
+ and ynum. In case of polar array, center is a vector, totalangle is the angle
+ to cover (in degrees) and totalnum is the number of objects, including the original.'''
+
+ def rectArray(objectslist,xvector,yvector,xnum,ynum):
+ typecheck([(xvector,Vector), (yvector,Vector), (xnum,int), (ynum,int)], "rectArray")
+ if not isinstance(objectslist,list): objectslist = [objectslist]
+ for xcount in range(xnum):
+ currentxvector=fcvec.scale(xvector,xcount)
+ if not xcount==0:
+ move(objectslist,currentxvector,True)
+ for ycount in range(ynum):
+ currentxvector=FreeCAD.Base.Vector(currentxvector)
+ currentyvector=currentxvector.add(fcvec.scale(yvector,ycount))
+ if not ycount==0:
+ move(objectslist,currentyvector,True)
+ def polarArray(objectslist,center,angle,num):
+ typecheck([(center,Vector), (num,int)], "polarArray")
+ if not isinstance(objectslist,list): objectslist = [objectslist]
+ fraction = angle/num
+ for i in range(num):
+ currangle = fraction + (i*fraction)
+ rotate(objectslist,currangle,center,copy=True)
- if arg4:
- rectArray(objectslist,arg1,arg2,arg3,arg4)
- else:
- polarArray(objectslist,arg1,arg2,arg3)
+ if arg4:
+ rectArray(objectslist,arg1,arg2,arg3,arg4)
+ else:
+ polarArray(objectslist,arg1,arg2,arg3)
def rotate(objectslist,angle,center=Vector(0,0,0),axis=Vector(0,0,1),copy=False):
- '''rotate(objects,angle,[center,axis,copy]): Rotates the objects contained
- in objects (that can be a list of objects or an object) of the given angle
- (in degrees) around the center, using axis as a rotation axis. If axis is
- omitted, the rotation will be around the vertical Z axis.
- If copy is True, the actual objects are not moved, but copies
- are created instead. The objects (or their copies) are returned.'''
- typecheck([(copy,bool)], "rotate")
- if not isinstance(objectslist,list): objectslist = [objectslist]
- newobjlist = []
- for obj in objectslist:
- if copy:
- newobj = makeCopy(obj)
- else:
- newobj = obj
- if (obj.isDerivedFrom("Part::Feature")):
- shape = obj.Shape.copy()
- shape.rotate(fcvec.tup(center), fcvec.tup(axis), angle)
- newobj.Shape = shape
- elif hasattr(obj,"Placement"):
- shape = Part.Shape()
- shape.Placement = obj.Placement
- shape.rotate(fcvec.tup(center), fcvec.tup(axis), angle)
- newobj.Placement = shape.Placement
- if copy:
- formatObject(newobj,obj)
- newobjlist.append(newobj)
- if copy and getParam("selectBaseObjects"):
- select(objectslist)
+ '''rotate(objects,angle,[center,axis,copy]): Rotates the objects contained
+ in objects (that can be a list of objects or an object) of the given angle
+ (in degrees) around the center, using axis as a rotation axis. If axis is
+ omitted, the rotation will be around the vertical Z axis.
+ If copy is True, the actual objects are not moved, but copies
+ are created instead. The objects (or their copies) are returned.'''
+ typecheck([(copy,bool)], "rotate")
+ if not isinstance(objectslist,list): objectslist = [objectslist]
+ newobjlist = []
+ for obj in objectslist:
+ if copy:
+ newobj = makeCopy(obj)
else:
- select(newobjlist)
- if len(newobjlist) == 1: return newobjlist[0]
- return newobjlist
+ newobj = obj
+ if (obj.isDerivedFrom("Part::Feature")):
+ shape = obj.Shape.copy()
+ shape.rotate(fcvec.tup(center), fcvec.tup(axis), angle)
+ newobj.Shape = shape
+ elif hasattr(obj,"Placement"):
+ shape = Part.Shape()
+ shape.Placement = obj.Placement
+ shape.rotate(fcvec.tup(center), fcvec.tup(axis), angle)
+ newobj.Placement = shape.Placement
+ if copy:
+ formatObject(newobj,obj)
+ newobjlist.append(newobj)
+ if copy and getParam("selectBaseObjects"):
+ select(objectslist)
+ else:
+ select(newobjlist)
+ if len(newobjlist) == 1: return newobjlist[0]
+ return newobjlist
def scale(objectslist,delta,center=Vector(0,0,0),copy=False):
- '''scale(objects,vector,[center,copy]): Scales the objects contained
- in objects (that can be a list of objects or an object) of the given scale
- factors defined by the given vector (in X, Y and Z directions) around
- given center. If copy is True, the actual objects are not moved, but copies
- are created instead. The objects (or their copies) are returned.'''
- if not isinstance(objectslist,list): objectslist = [objectslist]
- newobjlist = []
- for obj in objectslist:
- if copy:
- newobj = makeCopy(obj)
- else:
- newobj = obj
- sh = obj.Shape.copy()
- m = FreeCAD.Matrix()
- m.scale(delta)
- sh = sh.transformGeometry(m)
- corr = Vector(center.x,center.y,center.z)
- corr.scale(delta.x,delta.y,delta.z)
- corr = fcvec.neg(corr.sub(center))
- sh.translate(corr)
- if getType(obj) == "Rectangle":
- p = []
- for v in sh.Vertexes: p.append(v.Point)
- pl = obj.Placement.copy()
- pl.Base = p[0]
- diag = p[2].sub(p[0])
- bb = p[1].sub(p[0])
- bh = p[3].sub(p[0])
- nb = fcvec.project(diag,bb)
- nh = fcvec.project(diag,bh)
- if obj.Length < 0: l = -nb.Length
- else: l = nb.Length
- if obj.Height < 0: h = -nh.Length
- else: h = nh.Length
- newobj.Length = l
- newobj.Height = h
- tr = p[0].sub(obj.Shape.Vertexes[0].Point)
- newobj.Placement = pl
- elif getType(obj) == "Wire":
- p = []
- for v in sh.Vertexes: p.append(v.Point)
- newobj.Points = p
- elif (obj.isDerivedFrom("Part::Feature")):
- newobj.Shape = sh
- elif (obj.Type == "App::Annotation"):
- factor = delta.x * delta.y * delta.z * obj.ViewObject.FontSize
- obj.ViewObject.Fontsize = factor
- if copy: formatObject(newobj,obj)
- newobjlist.append(newobj)
- if copy and getParam("selectBaseObjects"):
- select(objectslist)
+ '''scale(objects,vector,[center,copy]): Scales the objects contained
+ in objects (that can be a list of objects or an object) of the given scale
+ factors defined by the given vector (in X, Y and Z directions) around
+ given center. If copy is True, the actual objects are not moved, but copies
+ are created instead. The objects (or their copies) are returned.'''
+ if not isinstance(objectslist,list): objectslist = [objectslist]
+ newobjlist = []
+ for obj in objectslist:
+ if copy:
+ newobj = makeCopy(obj)
else:
- select(newobjlist)
- if len(newobjlist) == 1: return newobjlist[0]
- return newobjlist
+ newobj = obj
+ sh = obj.Shape.copy()
+ m = FreeCAD.Matrix()
+ m.scale(delta)
+ sh = sh.transformGeometry(m)
+ corr = Vector(center.x,center.y,center.z)
+ corr.scale(delta.x,delta.y,delta.z)
+ corr = fcvec.neg(corr.sub(center))
+ sh.translate(corr)
+ if getType(obj) == "Rectangle":
+ p = []
+ for v in sh.Vertexes: p.append(v.Point)
+ pl = obj.Placement.copy()
+ pl.Base = p[0]
+ diag = p[2].sub(p[0])
+ bb = p[1].sub(p[0])
+ bh = p[3].sub(p[0])
+ nb = fcvec.project(diag,bb)
+ nh = fcvec.project(diag,bh)
+ if obj.Length < 0: l = -nb.Length
+ else: l = nb.Length
+ if obj.Height < 0: h = -nh.Length
+ else: h = nh.Length
+ newobj.Length = l
+ newobj.Height = h
+ tr = p[0].sub(obj.Shape.Vertexes[0].Point)
+ newobj.Placement = pl
+ elif getType(obj) == "Wire":
+ p = []
+ for v in sh.Vertexes: p.append(v.Point)
+ newobj.Points = p
+ elif (obj.isDerivedFrom("Part::Feature")):
+ newobj.Shape = sh
+ elif (obj.Type == "App::Annotation"):
+ factor = delta.x * delta.y * delta.z * obj.ViewObject.FontSize
+ obj.ViewObject.Fontsize = factor
+ if copy: formatObject(newobj,obj)
+ newobjlist.append(newobj)
+ if copy and getParam("selectBaseObjects"):
+ select(objectslist)
+ else:
+ select(newobjlist)
+ if len(newobjlist) == 1: return newobjlist[0]
+ return newobjlist
def offset(obj,delta,copy=False,bind=False,sym=False,occ=False):
- '''offset(object,Vector,[copymode],[bind]): offsets the given wire by
- applying the given Vector to its first vertex. If copymode is
- True, another object is created, otherwise the same object gets
- offsetted. If bind is True, and provided the wire is open, the original
- and the offsetted wires will be bound by their endpoints, forming a face
- if sym is True, bind must be true too, and the offset is made on both
- sides, the total width being the given delta length.'''
+ '''offset(object,Vector,[copymode],[bind]): offsets the given wire by
+ applying the given Vector to its first vertex. If copymode is
+ True, another object is created, otherwise the same object gets
+ offsetted. If bind is True, and provided the wire is open, the original
+ and the offsetted wires will be bound by their endpoints, forming a face
+ if sym is True, bind must be true too, and the offset is made on both
+ sides, the total width being the given delta length.'''
- def getRect(p,obj):
- "returns length,heigh,placement"
- pl = obj.Placement.copy()
- pl.Base = p[0]
- diag = p[2].sub(p[0])
- bb = p[1].sub(p[0])
- bh = p[3].sub(p[0])
- nb = fcvec.project(diag,bb)
- nh = fcvec.project(diag,bh)
- if obj.Length < 0: l = -nb.Length
- else: l = nb.Length
- if obj.Height < 0: h = -nh.Length
- else: h = nh.Length
- return l,h,pl
+ def getRect(p,obj):
+ "returns length,heigh,placement"
+ pl = obj.Placement.copy()
+ pl.Base = p[0]
+ diag = p[2].sub(p[0])
+ bb = p[1].sub(p[0])
+ bh = p[3].sub(p[0])
+ nb = fcvec.project(diag,bb)
+ nh = fcvec.project(diag,bh)
+ if obj.Length < 0: l = -nb.Length
+ else: l = nb.Length
+ if obj.Height < 0: h = -nh.Length
+ else: h = nh.Length
+ return l,h,pl
- def getRadius(obj,delta):
- "returns a new radius for a regular polygon"
- an = math.pi/obj.FacesNumber
- nr = fcvec.rotate(delta,-an)
- nr.multiply(1/math.cos(an))
- nr = obj.Shape.Vertexes[0].Point.add(nr)
- nr = nr.sub(obj.Placement.Base)
- nr = nr.Length
- if obj.DrawMode == "inscribed":
- return nr
- else:
- return nr * math.cos(math.pi/obj.FacesNumber)
+ def getRadius(obj,delta):
+ "returns a new radius for a regular polygon"
+ an = math.pi/obj.FacesNumber
+ nr = fcvec.rotate(delta,-an)
+ nr.multiply(1/math.cos(an))
+ nr = obj.Shape.Vertexes[0].Point.add(nr)
+ nr = nr.sub(obj.Placement.Base)
+ nr = nr.Length
+ if obj.DrawMode == "inscribed":
+ return nr
+ else:
+ return nr * math.cos(math.pi/obj.FacesNumber)
- if getType(obj) == "Circle":
- pass
+ if getType(obj) == "Circle":
+ pass
+ else:
+ if sym:
+ d1 = delta.multiply(0.5)
+ d2 = fcvec.neg(d1)
+ n1 = fcgeo.offsetWire(obj.Shape,d1)
+ n2 = fcgeo.offsetWire(obj.Shape,d2)
else:
- if sym:
- d1 = delta.multiply(0.5)
- d2 = fcvec.neg(d1)
- n1 = fcgeo.offsetWire(obj.Shape,d1)
- n2 = fcgeo.offsetWire(obj.Shape,d2)
- else:
- newwire = fcgeo.offsetWire(obj.Shape,delta)
- p = fcgeo.getVerts(newwire)
- if occ:
- newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Offset")
- newobj.Shape = fcgeo.offsetWire(obj.Shape,delta,occ=True)
- formatObject(newobj,obj)
- elif bind:
- if not fcgeo.isReallyClosed(obj.Shape):
- if sym:
- s1 = n1
- s2 = n2
- else:
- s1 = obj.Shape
- s2 = newwire
- w1 = s1.Edges
- w2 = s2.Edges
- w3 = Part.Line(s1.Vertexes[0].Point,s2.Vertexes[0].Point).toShape()
- w4 = Part.Line(s1.Vertexes[-1].Point,s2.Vertexes[-1].Point).toShape()
- newobj = Part.Face(Part.Wire(w1+[w3]+w2+[w4]))
- else:
- newobj = Part.Face(obj.Shape.Wires[0])
- elif copy:
- if sym: return None
- if getType(obj) == "Wire":
- newobj = makeWire(p)
- newobj.Closed = obj.Closed
- elif getType(obj) == "Rectangle":
- length,height,plac = getRect(p,obj)
- newobj = makeRectangle(length,height,plac)
- elif getType(obj) == "Circle":
- pl = obj.Placement
- newobj = makeCircle(delta)
- newobj.FirstAngle = obj.FirstAngle
- newobj.LastAngle = obj.LastAngle
- newobj.Placement = pl
- elif getType(obj) == "Polygon":
- pl = obj.Placement
- newobj = makePolygon(obj.FacesNumber)
- newobj.Radius = getRadius(obj,delta)
- newobj.DrawMode = obj.DrawMode
- newobj.Placement = pl
- elif getType(obj) == "Part":
- newobj = makeWire(p)
- newobj.Closed = obj.Shape.isClosed()
- formatObject(newobj,obj)
+ newwire = fcgeo.offsetWire(obj.Shape,delta)
+ p = fcgeo.getVerts(newwire)
+ if occ:
+ newobj = FreeCAD.ActiveDocument.addObject("Part::Feature","Offset")
+ newobj.Shape = fcgeo.offsetWire(obj.Shape,delta,occ=True)
+ formatObject(newobj,obj)
+ elif bind:
+ if not fcgeo.isReallyClosed(obj.Shape):
+ if sym:
+ s1 = n1
+ s2 = n2
+ else:
+ s1 = obj.Shape
+ s2 = newwire
+ w1 = s1.Edges
+ w2 = s2.Edges
+ w3 = Part.Line(s1.Vertexes[0].Point,s2.Vertexes[0].Point).toShape()
+ w4 = Part.Line(s1.Vertexes[-1].Point,s2.Vertexes[-1].Point).toShape()
+ newobj = Part.Face(Part.Wire(w1+[w3]+w2+[w4]))
else:
- if sym: return None
- if getType(obj) == "Wire":
- if obj.Base or obj.Tool:
- FreeCAD.Console.PrintWarning("Warning: object history removed\n")
- obj.Base = None
- obj.Tool = None
- obj.Points = p
- elif getType(obj) == "Rectangle":
- length,height,plac = getRect(p,obj)
- obj.Placement = plac
- obj.Length = length
- obj.Height = height
- elif getType(obj) == "Circle":
- obj.Radius = delta
- elif getType(obj) == "Polygon":
- obj.Radius = getRadius(obj,delta)
- elif getType(obj) == 'Part':
- print "unsupported object" # TODO
- newobj = obj
- if copy and getParam("selectBaseObjects"):
- select(newobj)
- else:
- select(obj)
- return newobj
+ newobj = Part.Face(obj.Shape.Wires[0])
+ elif copy:
+ if sym: return None
+ if getType(obj) == "Wire":
+ newobj = makeWire(p)
+ newobj.Closed = obj.Closed
+ elif getType(obj) == "Rectangle":
+ length,height,plac = getRect(p,obj)
+ newobj = makeRectangle(length,height,plac)
+ elif getType(obj) == "Circle":
+ pl = obj.Placement
+ newobj = makeCircle(delta)
+ newobj.FirstAngle = obj.FirstAngle
+ newobj.LastAngle = obj.LastAngle
+ newobj.Placement = pl
+ elif getType(obj) == "Polygon":
+ pl = obj.Placement
+ newobj = makePolygon(obj.FacesNumber)
+ newobj.Radius = getRadius(obj,delta)
+ newobj.DrawMode = obj.DrawMode
+ newobj.Placement = pl
+ elif getType(obj) == "Part":
+ newobj = makeWire(p)
+ newobj.Closed = obj.Shape.isClosed()
+ formatObject(newobj,obj)
+ else:
+ if sym: return None
+ if getType(obj) == "Wire":
+ if obj.Base or obj.Tool:
+ FreeCAD.Console.PrintWarning("Warning: object history removed\n")
+ obj.Base = None
+ obj.Tool = None
+ obj.Points = p
+ elif getType(obj) == "Rectangle":
+ length,height,plac = getRect(p,obj)
+ obj.Placement = plac
+ obj.Length = length
+ obj.Height = height
+ elif getType(obj) == "Circle":
+ obj.Radius = delta
+ elif getType(obj) == "Polygon":
+ obj.Radius = getRadius(obj,delta)
+ elif getType(obj) == 'Part':
+ print "unsupported object" # TODO
+ newobj = obj
+ if copy and getParam("selectBaseObjects"):
+ select(newobj)
+ else:
+ select(obj)
+ return newobj
def draftify(objectslist):
- '''draftify(objectslist): turns each object of the given list
- (objectslist can also be a single object) into a Draft parametric
- wire'''
- if not isinstance(objectslist,list): objectslist = [objectslist]
- newobjlist = []
- for obj in objectslist:
- if obj.isDerivedFrom('Part::Feature'):
- for w in obj.Shape.Wires:
- verts = []
- edges = fcgeo.sortEdges(w.Edges)
- for e in edges:
- verts.append(e.Vertexes[0].Point)
- if w.isClosed():
- verts.append(edges[-1].Vertexes[-1].Point)
- newobj = makeWire(verts)
- if obj.Shape.Faces:
- newobj.Closed = True
- newobj.ViewObject.DisplayMode = "Flat Lines"
- else:
- newobj.ViewObject.DisplayMode = "Wireframe"
- if obj.Shape.Wires[0].isClosed:
- newobj.Closed = True
- newobjlist.append(newobj)
- FreeCAD.ActiveDocument.removeObject(obj.Name)
- if len(newobjlist) == 1: return newobjlist[0]
- return newobjlist
+ '''draftify(objectslist): turns each object of the given list
+ (objectslist can also be a single object) into a Draft parametric
+ wire'''
+ if not isinstance(objectslist,list): objectslist = [objectslist]
+ newobjlist = []
+ for obj in objectslist:
+ if obj.isDerivedFrom('Part::Feature'):
+ for w in obj.Shape.Wires:
+ verts = []
+ edges = fcgeo.sortEdges(w.Edges)
+ for e in edges:
+ verts.append(e.Vertexes[0].Point)
+ if w.isClosed():
+ verts.append(edges[-1].Vertexes[-1].Point)
+ newobj = makeWire(verts)
+ if obj.Shape.Faces:
+ newobj.Closed = True
+ newobj.ViewObject.DisplayMode = "Flat Lines"
+ else:
+ newobj.ViewObject.DisplayMode = "Wireframe"
+ if obj.Shape.Wires[0].isClosed:
+ newobj.Closed = True
+ newobjlist.append(newobj)
+ FreeCAD.ActiveDocument.removeObject(obj.Name)
+ if len(newobjlist) == 1: return newobjlist[0]
+ return newobjlist
def getrgb(color):
- "getRGB(color): returns a rgb value #000000 from a freecad color"
- r = str(hex(int(color[0]*255)))[2:].zfill(2)
- g = str(hex(int(color[1]*255)))[2:].zfill(2)
- b = str(hex(int(color[2]*255)))[2:].zfill(2)
- return "#"+r+g+b
+ "getRGB(color): returns a rgb value #000000 from a freecad color"
+ r = str(hex(int(color[0]*255)))[2:].zfill(2)
+ g = str(hex(int(color[1]*255)))[2:].zfill(2)
+ b = str(hex(int(color[2]*255)))[2:].zfill(2)
+ return "#"+r+g+b
def getSVG(obj,modifier=100,textmodifier=100,linestyle="continuous",fillstyle="shape color",direction=None):
- '''getSVG(object,[modifier],[textmodifier],[linestyle],[fillstyle],[direction]):
- returns a string containing a SVG representation of the given object. the modifier attribute
- specifies a scale factor for linewidths in %, and textmodifier specifies
- a scale factor for texts, in % (both default = 100). You can also supply
- an arbitrary projection vector.'''
- svg = ""
- tmod = ((textmodifier-100)/2)+100
- if tmod == 0: tmod = 0.01
- modifier = 200-modifier
- if modifier == 0: modifier = 0.01
- pmod = (200-textmodifier)/20
- if pmod == 0: pmod = 0.01
- plane = None
- if direction:
- if direction != Vector(0,0,0):
- plane = WorkingPlane.plane()
- plane.alignToPointAndAxis(Vector(0,0,0),fcvec.neg(direction),0)
+ '''getSVG(object,[modifier],[textmodifier],[linestyle],[fillstyle],[direction]):
+ returns a string containing a SVG representation of the given object. the modifier attribute
+ specifies a scale factor for linewidths in %, and textmodifier specifies
+ a scale factor for texts, in % (both default = 100). You can also supply
+ an arbitrary projection vector.'''
+ svg = ""
+ tmod = ((textmodifier-100)/2)+100
+ if tmod == 0: tmod = 0.01
+ modifier = 200-modifier
+ if modifier == 0: modifier = 0.01
+ pmod = (200-textmodifier)/20
+ if pmod == 0: pmod = 0.01
+ plane = None
+ if direction:
+ if direction != Vector(0,0,0):
+ plane = WorkingPlane.plane()
+ plane.alignToPointAndAxis(Vector(0,0,0),fcvec.neg(direction),0)
- def getProj(vec):
- if not plane: return vec
- nx = fcvec.project(vec,plane.u)
- lx = nx.Length
- if abs(nx.getAngle(plane.u)) > 0.1: lx = -lx
- ny = fcvec.project(vec,plane.v)
- ly = ny.Length
- if abs(ny.getAngle(plane.v)) > 0.1: ly = -ly
- return Vector(lx,ly,0)
+ def getProj(vec):
+ if not plane: return vec
+ nx = fcvec.project(vec,plane.u)
+ lx = nx.Length
+ if abs(nx.getAngle(plane.u)) > 0.1: lx = -lx
+ ny = fcvec.project(vec,plane.v)
+ ly = ny.Length
+ if abs(ny.getAngle(plane.v)) > 0.1: ly = -ly
+ return Vector(lx,ly,0)
- def getPath(edges):
- svg ='\n'
- return svg
-
- if getType(obj) == "Dimension":
- p1,p2,p3,p4,tbase,norm,rot = obj.ViewObject.Proxy.calcGeom(obj)
- dimText = getParam("dimPrecision")
- dimText = "%."+str(dimText)+"f"
- p1 = getProj(p1)
- p2 = getProj(p2)
- p3 = getProj(p3)
- p4 = getProj(p4)
- tbase = getProj(tbase)
- svg = '\n'
- svg += '\n'
- svg += '\n'
- svg += ''
- svg += dimText % p3.sub(p2).Length
- svg += '\n\n'
-
- elif getType(obj) == "Annotation":
- "returns an svg representation of a document annotation"
- p = getProj(obj.Position)
- svg = '\n'
- for l in obj.LabelText:
- svg += ''+l+'\n'
- svg += '\n'
-
- elif obj.isDerivedFrom('Part::Feature'):
- if obj.Shape.isNull(): return ''
- color = getrgb(obj.ViewObject.LineColor)
- # setting fill
- if obj.Shape.Faces and (obj.ViewObject.DisplayMode != "Wireframe"):
- if fillstyle == "shape color":
- fill = getrgb(obj.ViewObject.ShapeColor)
- else:
- fill = 'url(#'+hatch+')'
- else:
- fill = 'none'
- # setting linetype
- if linestyle == "dashed":
- lstyle = "0.09,0.05"
- elif linestyle == "dashdotted":
- lstyle = "0.09,0.05,0.02,0.05"
- elif linestyle == "dotted":
- lstyle = "0.02,0.02"
- else:
- lstyle = "none"
- name = obj.Name
- if obj.ViewObject.DisplayMode == "Shaded":
- stroke = "none"
- else:
- stroke = getrgb(obj.ViewObject.LineColor)
- width = obj.ViewObject.LineWidth/modifier
- if len(obj.Shape.Vertexes) > 1:
- wiredEdges = []
- if obj.Shape.Faces:
- for f in obj.Shape.Faces:
- svg += getPath(f.Edges)
- wiredEdges.extend(f.Edges)
- else:
- for w in obj.Shape.Wires:
- svg += getPath(w.Edges)
- wiredEdges.extend(w.Edges)
- if len(wiredEdges) != len(obj.Shape.Edges):
- for e in obj.Shape.Edges:
- if (fcgeo.findEdge(e,wiredEdges) == None):
- svg += getPath([e])
- else:
- cen = getProj(obj.Shape.Edges[0].Curve.Center)
- rad = obj.Shape.Edges[0].Curve.Radius
- svg = '\n'
+ def getPath(edges):
+ svg ='\n'
return svg
+ if getType(obj) == "Dimension":
+ p1,p2,p3,p4,tbase,norm,rot = obj.ViewObject.Proxy.calcGeom(obj)
+ dimText = getParam("dimPrecision")
+ dimText = "%."+str(dimText)+"f"
+ p1 = getProj(p1)
+ p2 = getProj(p2)
+ p3 = getProj(p3)
+ p4 = getProj(p4)
+ tbase = getProj(tbase)
+ svg = '\n'
+ svg += '\n'
+ svg += '\n'
+ svg += ''
+ svg += dimText % p3.sub(p2).Length
+ svg += '\n\n'
+
+ elif getType(obj) == "Annotation":
+ "returns an svg representation of a document annotation"
+ p = getProj(obj.Position)
+ svg = '\n'
+ for l in obj.LabelText:
+ svg += ''+l+'\n'
+ svg += '\n'
+
+ elif obj.isDerivedFrom('Part::Feature'):
+ if obj.Shape.isNull(): return ''
+ color = getrgb(obj.ViewObject.LineColor)
+ # setting fill
+ if obj.Shape.Faces and (obj.ViewObject.DisplayMode != "Wireframe"):
+ if fillstyle == "shape color":
+ fill = getrgb(obj.ViewObject.ShapeColor)
+ else:
+ fill = 'url(#'+hatch+')'
+ else:
+ fill = 'none'
+ # setting linetype
+ if linestyle == "dashed":
+ lstyle = "0.09,0.05"
+ elif linestyle == "dashdotted":
+ lstyle = "0.09,0.05,0.02,0.05"
+ elif linestyle == "dotted":
+ lstyle = "0.02,0.02"
+ else:
+ lstyle = "none"
+ name = obj.Name
+ if obj.ViewObject.DisplayMode == "Shaded":
+ stroke = "none"
+ else:
+ stroke = getrgb(obj.ViewObject.LineColor)
+ width = obj.ViewObject.LineWidth/modifier
+ if len(obj.Shape.Vertexes) > 1:
+ wiredEdges = []
+ if obj.Shape.Faces:
+ for f in obj.Shape.Faces:
+ svg += getPath(f.Edges)
+ wiredEdges.extend(f.Edges)
+ else:
+ for w in obj.Shape.Wires:
+ svg += getPath(w.Edges)
+ wiredEdges.extend(w.Edges)
+ if len(wiredEdges) != len(obj.Shape.Edges):
+ for e in obj.Shape.Edges:
+ if (fcgeo.findEdge(e,wiredEdges) == None):
+ svg += getPath([e])
+ else:
+ cen = getProj(obj.Shape.Edges[0].Curve.Center)
+ rad = obj.Shape.Edges[0].Curve.Radius
+ svg = '\n'
+ return svg
+
def makeDrawingView(obj,page,lwmod=None,tmod=None):
- '''
- makeDrawingView(object,page,[lwmod,tmod]) - adds a View of the given object to the
- given page. lwmod modifies lineweights (in percent), tmod modifies text heights
- (in percent). The Hint scale, X and Y of the page are used.
- '''
- viewobj = FreeCAD.ActiveDocument.addObject("Drawing::FeatureViewPython","View"+obj.Name)
- DrawingView(viewobj)
- page.addObject(viewobj)
- viewobj.Scale = page.ViewObject.HintScale
- viewobj.X = page.ViewObject.HintOffsetX
- viewobj.Y = page.ViewObject.HintOffsetY
- viewobj.Source = obj
- if lwmod: viewobj.LineweightModifier = lwmod
- if tmod: viewobj.TextModifier = tmod
- return viewobj
+ '''
+ makeDrawingView(object,page,[lwmod,tmod]) - adds a View of the given object to the
+ given page. lwmod modifies lineweights (in percent), tmod modifies text heights
+ (in percent). The Hint scale, X and Y of the page are used.
+ '''
+ viewobj = FreeCAD.ActiveDocument.addObject("Drawing::FeatureViewPython","View"+obj.Name)
+ DrawingView(viewobj)
+ page.addObject(viewobj)
+ viewobj.Scale = page.ViewObject.HintScale
+ viewobj.X = page.ViewObject.HintOffsetX
+ viewobj.Y = page.ViewObject.HintOffsetY
+ viewobj.Source = obj
+ if lwmod: viewobj.LineweightModifier = lwmod
+ if tmod: viewobj.TextModifier = tmod
+ return viewobj
def makeShape2DView(baseobj,projectionVector=None):
- '''
- makeShape2DView(object,[projectionVector]) - adds a 2D shape to the document, which is a
- 2D projection of the given object. A specific projection vector can also be given.
- '''
- obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Shape2DView")
- Shape2DView(obj)
- ViewProviderDraft(obj.ViewObject)
- obj.Base = baseobj
- if projectionVector:
- obj.Projection = projectionVector
- select(obj)
- return obj
+ '''
+ makeShape2DView(object,[projectionVector]) - adds a 2D shape to the document, which is a
+ 2D projection of the given object. A specific projection vector can also be given.
+ '''
+ obj = FreeCAD.ActiveDocument.addObject("Part::Part2DObjectPython","Shape2DView")
+ Shape2DView(obj)
+ ViewProviderDraft(obj.ViewObject)
+ obj.Base = baseobj
+ if projectionVector:
+ obj.Projection = projectionVector
+ select(obj)
+ return obj
#---------------------------------------------------------------------------
# Python Features definitions
#---------------------------------------------------------------------------
class ViewProviderDraft:
- "A generic View Provider for Draft objects"
+ "A generic View Provider for Draft objects"
- def __init__(self, obj):
- obj.Proxy = self
+ def __init__(self, obj):
+ obj.Proxy = self
- def attach(self, obj):
- self.Object = obj.Object
- return
+ def attach(self, obj):
+ self.Object = obj.Object
+ return
- def updateData(self, fp, prop):
- return
+ def updateData(self, fp, prop):
+ return
- def getDisplayModes(self,obj):
- modes=[]
- return modes
+ def getDisplayModes(self,obj):
+ modes=[]
+ return modes
- def setDisplayMode(self,mode):
- return mode
+ def setDisplayMode(self,mode):
+ return mode
- def onChanged(self, vp, prop):
- return
+ def onChanged(self, vp, prop):
+ return
- def __getstate__(self):
- return None
+ def __getstate__(self):
+ return None
- def __setstate__(self,state):
- return None
+ def __setstate__(self,state):
+ return None
- def setEdit(self,vp,mode):
- FreeCADGui.runCommand("Draft_Edit")
- return True
+ def setEdit(self,vp,mode):
+ FreeCADGui.runCommand("Draft_Edit")
+ return True
- def unsetEdit(self,vp,mode):
- if FreeCAD.activeDraftCommand:
- FreeCAD.activeDraftCommand.finish()
- return
-
- def getIcon(self):
- return(":/icons/Draft_Draft.svg")
- # return FreeCADGui.draftToolBar.getXPM("Draft_Draft")
+ def unsetEdit(self,vp,mode):
+ if FreeCAD.activeDraftCommand:
+ FreeCAD.activeDraftCommand.finish()
+ return
+
+ def getIcon(self):
+ return(":/icons/Draft_Draft.svg")
class Dimension:
- "The Dimension object"
- def __init__(self, obj):
- obj.addProperty("App::PropertyVector","Start","Base",
- "Startpoint of dimension")
- obj.addProperty("App::PropertyVector","End","Base",
- "Endpoint of dimension")
- obj.addProperty("App::PropertyVector","Dimline","Base",
- "Point through which the dimension line passes")
- obj.addProperty("App::PropertyLink","Base","Base",
- "The base object this dimension is linked to")
- obj.addProperty("App::PropertyIntegerList","LinkedVertices","Base",
- "The indices of the vertices from the base object to measure")
- obj.Start = FreeCAD.Vector(0,0,0)
- obj.End = FreeCAD.Vector(1,0,0)
- obj.Dimline = FreeCAD.Vector(0,1,0)
- obj.Proxy = self
- self.Type = "Dimension"
+ "The Dimension object"
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyVector","Start","Base",
+ "Startpoint of dimension")
+ obj.addProperty("App::PropertyVector","End","Base",
+ "Endpoint of dimension")
+ obj.addProperty("App::PropertyVector","Dimline","Base",
+ "Point through which the dimension line passes")
+ obj.addProperty("App::PropertyLink","Base","Base",
+ "The base object this dimension is linked to")
+ obj.addProperty("App::PropertyIntegerList","LinkedVertices","Base",
+ "The indices of the vertices from the base object to measure")
+ obj.Start = FreeCAD.Vector(0,0,0)
+ obj.End = FreeCAD.Vector(1,0,0)
+ obj.Dimline = FreeCAD.Vector(0,1,0)
+ obj.Proxy = self
+ self.Type = "Dimension"
- def onChanged(self, obj, prop):
- pass
+ def onChanged(self, obj, prop):
+ pass
- def execute(self, obj):
- if obj.ViewObject:
- obj.ViewObject.update()
+ def execute(self, obj):
+ if obj.ViewObject:
+ obj.ViewObject.update()
class ViewProviderDimension:
- "A View Provider for the Dimension object"
- def __init__(self, obj):
- obj.addProperty("App::PropertyLength","FontSize","Base","Font size")
- obj.addProperty("App::PropertyString","FontName","Base","Font name")
- obj.addProperty("App::PropertyLength","LineWidth","Base","Line width")
- obj.addProperty("App::PropertyColor","LineColor","Base","Line color")
- obj.addProperty("App::PropertyLength","ExtLines","Base","Ext lines")
- obj.addProperty("App::PropertyVector","Position","Base","The position of the text. Leave (0,0,0) for automatic position")
- obj.addProperty("App::PropertyString","Override","Base","Text override. Use 'dim' to insert the dimension length")
- obj.Proxy = self
- obj.FontSize=getParam("textheight")
- obj.FontName=getParam("textfont")
- obj.ExtLines=0.3
- obj.Override = ''
+ "A View Provider for the Dimension object"
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyLength","FontSize","Base","Font size")
+ obj.addProperty("App::PropertyString","FontName","Base","Font name")
+ obj.addProperty("App::PropertyLength","LineWidth","Base","Line width")
+ obj.addProperty("App::PropertyColor","LineColor","Base","Line color")
+ obj.addProperty("App::PropertyLength","ExtLines","Base","Ext lines")
+ obj.addProperty("App::PropertyVector","Position","Base","The position of the text. Leave (0,0,0) for automatic position")
+ obj.addProperty("App::PropertyString","Override","Base","Text override. Use 'dim' to insert the dimension length")
+ obj.Proxy = self
+ obj.FontSize=getParam("textheight")
+ obj.FontName=getParam("textfont")
+ obj.ExtLines=0.3
+ obj.Override = ''
- def calcGeom(self,obj):
- p1 = obj.Start
- p4 = obj.End
- base = Part.Line(p1,p4).toShape()
- proj = fcgeo.findDistance(obj.Dimline,base)
- if not proj:
- p2 = p1
- p3 = p4
- else:
- p2 = p1.add(fcvec.neg(proj))
- p3 = p4.add(fcvec.neg(proj))
- dmax = obj.ViewObject.ExtLines
- if dmax and (proj.Length > dmax):
- p1 = p2.add(fcvec.scaleTo(proj,dmax))
- p4 = p3.add(fcvec.scaleTo(proj,dmax))
- midpoint = p2.add(fcvec.scale(p3.sub(p2),0.5))
- if not proj:
- ed = fcgeo.vec(base)
- proj = ed.cross(Vector(0,0,1))
- if not proj: norm = Vector(0,0,1)
- else: norm = fcvec.neg(p3.sub(p2).cross(proj))
- norm.normalize()
- va = FreeCADGui.ActiveDocument.ActiveView.getViewDirection()
- if va.getAngle(norm) < math.pi/2:
- norm = fcvec.neg(norm)
- u = p3.sub(p2)
- u.normalize()
- c = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
- r = c.orientation.getValue()
- ru = Vector(r.multVec(coin.SbVec3f(1,0,0)).getValue())
- if ru.getAngle(u) > math.pi/2: u = fcvec.neg(u)
- v = norm.cross(u)
- offset = fcvec.scaleTo(v,obj.ViewObject.FontSize*.2)
- if obj.ViewObject:
- if hasattr(obj.ViewObject,"DisplayMode"):
- if obj.ViewObject.DisplayMode == "3D":
- offset = fcvec.neg(offset)
- if obj.ViewObject.Position == Vector(0,0,0):
- tbase = midpoint.add(offset)
+ def calcGeom(self,obj):
+ p1 = obj.Start
+ p4 = obj.End
+ base = Part.Line(p1,p4).toShape()
+ proj = fcgeo.findDistance(obj.Dimline,base)
+ if not proj:
+ p2 = p1
+ p3 = p4
+ else:
+ p2 = p1.add(fcvec.neg(proj))
+ p3 = p4.add(fcvec.neg(proj))
+ dmax = obj.ViewObject.ExtLines
+ if dmax and (proj.Length > dmax):
+ p1 = p2.add(fcvec.scaleTo(proj,dmax))
+ p4 = p3.add(fcvec.scaleTo(proj,dmax))
+ midpoint = p2.add(fcvec.scale(p3.sub(p2),0.5))
+ if not proj:
+ ed = fcgeo.vec(base)
+ proj = ed.cross(Vector(0,0,1))
+ if not proj: norm = Vector(0,0,1)
+ else: norm = fcvec.neg(p3.sub(p2).cross(proj))
+ norm.normalize()
+ va = FreeCADGui.ActiveDocument.ActiveView.getViewDirection()
+ if va.getAngle(norm) < math.pi/2:
+ norm = fcvec.neg(norm)
+ u = p3.sub(p2)
+ u.normalize()
+ c = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
+ r = c.orientation.getValue()
+ ru = Vector(r.multVec(coin.SbVec3f(1,0,0)).getValue())
+ if ru.getAngle(u) > math.pi/2: u = fcvec.neg(u)
+ v = norm.cross(u)
+ offset = fcvec.scaleTo(v,obj.ViewObject.FontSize*.2)
+ if obj.ViewObject:
+ if hasattr(obj.ViewObject,"DisplayMode"):
+ if obj.ViewObject.DisplayMode == "3D":
+ offset = fcvec.neg(offset)
+ if obj.ViewObject.Position == Vector(0,0,0):
+ tbase = midpoint.add(offset)
+ else:
+ tbase = obj.ViewObject.Position
+ rot = FreeCAD.Placement(fcvec.getPlaneRotation(u,v,norm)).Rotation.Q
+ return p1,p2,p3,p4,tbase,norm,rot
+
+ def attach(self, obj):
+ self.Object = obj.Object
+ p1,p2,p3,p4,tbase,norm,rot = self.calcGeom(obj.Object)
+ self.color = coin.SoBaseColor()
+ self.color.rgb.setValue(obj.LineColor[0],
+ obj.LineColor[1],
+ obj.LineColor[2])
+ self.font = coin.SoFont()
+ self.font3d = coin.SoFont()
+ self.text = coin.SoAsciiText()
+ self.text3d = coin.SoText2()
+ self.text.justification = self.text3d.justification = coin.SoAsciiText.CENTER
+ self.text.string = self.text3d.string = ''
+ self.textpos = coin.SoTransform()
+ self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z])
+ tm = fcvec.getPlaneRotation(p3.sub(p2),norm)
+ rm = coin.SbRotation()
+ self.textpos.rotation = rm
+ label = coin.SoSeparator()
+ label.addChild(self.textpos)
+ label.addChild(self.color)
+ label.addChild(self.font)
+ label.addChild(self.text)
+ label3d = coin.SoSeparator()
+ label3d.addChild(self.textpos)
+ label3d.addChild(self.color)
+ label3d.addChild(self.font3d)
+ label3d.addChild(self.text3d)
+ self.coord1 = coin.SoCoordinate3()
+ self.coord1.point.setValue((p2.x,p2.y,p2.z))
+ self.coord2 = coin.SoCoordinate3()
+ self.coord2.point.setValue((p3.x,p3.y,p3.z))
+ marks = coin.SoAnnotation()
+ marks.addChild(self.color)
+ marks.addChild(self.coord1)
+ marks.addChild(dimSymbol())
+ marks.addChild(self.coord2)
+ marks.addChild(dimSymbol())
+ self.drawstyle = coin.SoDrawStyle()
+ self.drawstyle.lineWidth = 1
+ self.line = coin.SoLineSet()
+ self.coords = coin.SoCoordinate3()
+ selnode=coin.SoType.fromName("SoFCSelection").createInstance()
+ selnode.documentName.setValue(FreeCAD.ActiveDocument.Name)
+ selnode.objectName.setValue(obj.Object.Name)
+ selnode.subElementName.setValue("Line")
+ selnode.addChild(self.line)
+ self.node = coin.SoGroup()
+ self.node.addChild(self.color)
+ self.node.addChild(self.drawstyle)
+ self.node.addChild(self.coords)
+ self.node.addChild(selnode)
+ self.node.addChild(marks)
+ self.node.addChild(label)
+ self.node3d = coin.SoGroup()
+ self.node3d.addChild(self.color)
+ self.node3d.addChild(self.drawstyle)
+ self.node3d.addChild(self.coords)
+ self.node3d.addChild(selnode)
+ self.node3d.addChild(marks)
+ self.node3d.addChild(label3d)
+ obj.addDisplayMode(self.node,"2D")
+ obj.addDisplayMode(self.node3d,"3D")
+ self.onChanged(obj,"FontSize")
+ self.onChanged(obj,"FontName")
+
+ def updateData(self, obj, prop):
+ text = None
+ if obj.Base and obj.LinkedVertices:
+ if "Shape" in obj.Base.PropertiesList:
+ if len(obj.LinkedVertices) == 3:
+ # arc linked dimension
+ e = obj.Base.Shape.Edges[obj.LinkedVertices[0]]
+ c = e.Curve.Center
+ bray = fcvec.scaleTo(obj.Dimline.sub(c),e.Curve.Radius)
+ if obj.LinkedVertices[1] == 1:
+ v1 = c
+ else:
+ v1 = c.add(fcvec.neg(bray))
+ v2 = c.add(bray)
else:
- tbase = obj.ViewObject.Position
- rot = FreeCAD.Placement(fcvec.getPlaneRotation(u,v,norm)).Rotation.Q
- return p1,p2,p3,p4,tbase,norm,rot
+ # linear linked dimension
+ v1 = obj.Base.Shape.Vertexes[obj.LinkedVertices[0]].Point
+ v2 = obj.Base.Shape.Vertexes[obj.LinkedVertices[1]].Point
+ if v1 != obj.Start: obj.Start = v1
+ if v2 != obj.End: obj.End = v2
+ p1,p2,p3,p4,tbase,norm,rot = self.calcGeom(obj)
+ if 'Override' in obj.ViewObject.PropertiesList:
+ text = str(obj.ViewObject.Override)
+ dtext = getParam("dimPrecision")
+ dtext = "%."+str(dtext)+"f"
+ dtext = (dtext % p3.sub(p2).Length)
+ if text:
+ text = text.replace("dim",dtext)
+ else:
+ text = dtext
+ self.text.string = self.text3d.string = text
+ self.textpos.rotation = coin.SbRotation(rot[0],rot[1],rot[2],rot[3])
+ self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z])
+ if obj.ViewObject.DisplayMode == "2D":
+ self.coords.point.setValues([[p1.x,p1.y,p1.z],
+ [p2.x,p2.y,p2.z],
+ [p3.x,p3.y,p3.z],
+ [p4.x,p4.y,p4.z]])
+ self.line.numVertices.setValues([4])
+ else:
+ ts = (len(text)*obj.ViewObject.FontSize)/4
+ rm = ((p3.sub(p2)).Length/2)-ts
+ p2a = p2.add(fcvec.scaleTo(p3.sub(p2),rm))
+ p2b = p3.add(fcvec.scaleTo(p2.sub(p3),rm))
+ self.coords.point.setValues([[p1.x,p1.y,p1.z],
+ [p2.x,p2.y,p2.z],
+ [p2a.x,p2a.y,p2a.z],
+ [p2b.x,p2b.y,p2b.z],
+ [p3.x,p3.y,p3.z],
+ [p4.x,p4.y,p4.z]])
+ self.line.numVertices.setValues([3,3])
+ self.coord1.point.setValue((p2.x,p2.y,p2.z))
+ self.coord2.point.setValue((p3.x,p3.y,p3.z))
- def attach(self, obj):
- self.Object = obj.Object
- p1,p2,p3,p4,tbase,norm,rot = self.calcGeom(obj.Object)
- self.color = coin.SoBaseColor()
- self.color.rgb.setValue(obj.LineColor[0],
- obj.LineColor[1],
- obj.LineColor[2])
- self.font = coin.SoFont()
- self.font3d = coin.SoFont()
- self.text = coin.SoAsciiText()
- self.text3d = coin.SoText2()
- self.text.justification = self.text3d.justification = coin.SoAsciiText.CENTER
- self.text.string = self.text3d.string = ''
- self.textpos = coin.SoTransform()
- self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z])
- tm = fcvec.getPlaneRotation(p3.sub(p2),norm)
- rm = coin.SbRotation()
- self.textpos.rotation = rm
- label = coin.SoSeparator()
- label.addChild(self.textpos)
- label.addChild(self.color)
- label.addChild(self.font)
- label.addChild(self.text)
- label3d = coin.SoSeparator()
- label3d.addChild(self.textpos)
- label3d.addChild(self.color)
- label3d.addChild(self.font3d)
- label3d.addChild(self.text3d)
- self.coord1 = coin.SoCoordinate3()
- self.coord1.point.setValue((p2.x,p2.y,p2.z))
- self.coord2 = coin.SoCoordinate3()
- self.coord2.point.setValue((p3.x,p3.y,p3.z))
- marks = coin.SoAnnotation()
- marks.addChild(self.color)
- marks.addChild(self.coord1)
- marks.addChild(dimSymbol())
- marks.addChild(self.coord2)
- marks.addChild(dimSymbol())
- self.drawstyle = coin.SoDrawStyle()
- self.drawstyle.lineWidth = 1
- self.line = coin.SoLineSet()
- self.coords = coin.SoCoordinate3()
- selnode=coin.SoType.fromName("SoFCSelection").createInstance()
- selnode.documentName.setValue(FreeCAD.ActiveDocument.Name)
- selnode.objectName.setValue(obj.Object.Name)
- selnode.subElementName.setValue("Line")
- selnode.addChild(self.line)
- self.node = coin.SoGroup()
- self.node.addChild(self.color)
- self.node.addChild(self.drawstyle)
- self.node.addChild(self.coords)
- self.node.addChild(selnode)
- self.node.addChild(marks)
- self.node.addChild(label)
- self.node3d = coin.SoGroup()
- self.node3d.addChild(self.color)
- self.node3d.addChild(self.drawstyle)
- self.node3d.addChild(self.coords)
- self.node3d.addChild(selnode)
- self.node3d.addChild(marks)
- self.node3d.addChild(label3d)
- obj.addDisplayMode(self.node,"2D")
- obj.addDisplayMode(self.node3d,"3D")
- self.onChanged(obj,"FontSize")
- self.onChanged(obj,"FontName")
+ def onChanged(self, vp, prop):
+ if prop == "FontSize":
+ self.font.size = vp.FontSize
+ self.font3d.size = vp.FontSize*100
+ elif prop == "FontName":
+ self.font.name = self.font3d.name = str(vp.FontName)
+ elif prop == "LineColor":
+ c = vp.LineColor
+ self.color.rgb.setValue(c[0],c[1],c[2])
+ elif prop == "LineWidth":
+ self.drawstyle.lineWidth = vp.LineWidth
+ else:
+ self.updateData(vp.Object, None)
- def updateData(self, obj, prop):
- text = None
- if obj.Base and obj.LinkedVertices:
- if "Shape" in obj.Base.PropertiesList:
- if len(obj.LinkedVertices) == 3:
- # arc linked dimension
- e = obj.Base.Shape.Edges[obj.LinkedVertices[0]]
- c = e.Curve.Center
- bray = fcvec.scaleTo(obj.Dimline.sub(c),e.Curve.Radius)
- if obj.LinkedVertices[1] == 1:
- v1 = c
- else:
- v1 = c.add(fcvec.neg(bray))
- v2 = c.add(bray)
- # linear linked dimension
- else:
- v1 = obj.Base.Shape.Vertexes[obj.LinkedVertices[0]].Point
- v2 = obj.Base.Shape.Vertexes[obj.LinkedVertices[1]].Point
- if v1 != obj.Start: obj.Start = v1
- if v2 != obj.End: obj.End = v2
- p1,p2,p3,p4,tbase,norm,rot = self.calcGeom(obj)
- if 'Override' in obj.ViewObject.PropertiesList:
- text = str(obj.ViewObject.Override)
- dtext = getParam("dimPrecision")
- dtext = "%."+str(dtext)+"f"
- dtext = (dtext % p3.sub(p2).Length)
- if text:
- text = text.replace("dim",dtext)
- else:
- text = dtext
- self.text.string = self.text3d.string = text
- self.textpos.rotation = coin.SbRotation(rot[0],rot[1],rot[2],rot[3])
- self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z])
- if obj.ViewObject.DisplayMode == "2D":
- self.coords.point.setValues([[p1.x,p1.y,p1.z],
- [p2.x,p2.y,p2.z],
- [p3.x,p3.y,p3.z],
- [p4.x,p4.y,p4.z]])
- self.line.numVertices.setValues([4])
- else:
- ts = (len(text)*obj.ViewObject.FontSize)/4
- rm = ((p3.sub(p2)).Length/2)-ts
- p2a = p2.add(fcvec.scaleTo(p3.sub(p2),rm))
- p2b = p3.add(fcvec.scaleTo(p2.sub(p3),rm))
- self.coords.point.setValues([[p1.x,p1.y,p1.z],
- [p2.x,p2.y,p2.z],
- [p2a.x,p2a.y,p2a.z],
- [p2b.x,p2b.y,p2b.z],
- [p3.x,p3.y,p3.z],
- [p4.x,p4.y,p4.z]])
- self.line.numVertices.setValues([3,3])
- self.coord1.point.setValue((p2.x,p2.y,p2.z))
- self.coord2.point.setValue((p3.x,p3.y,p3.z))
+ def getDisplayModes(self,obj):
+ modes=[]
+ modes.extend(["2D","3D"])
+ return modes
- def onChanged(self, vp, prop):
- if prop == "FontSize":
- self.font.size = vp.FontSize
- self.font3d.size = vp.FontSize*100
- elif prop == "FontName":
- self.font.name = self.font3d.name = str(vp.FontName)
- elif prop == "LineColor":
- c = vp.LineColor
- self.color.rgb.setValue(c[0],c[1],c[2])
- elif prop == "LineWidth":
- self.drawstyle.lineWidth = vp.LineWidth
- else:
- self.updateData(vp.Object, None)
+ def getDefaultDisplayMode(self):
+ return "2D"
- def getDisplayModes(self,obj):
- modes=[]
- modes.extend(["2D","3D"])
- return modes
+ def getIcon(self):
+ if self.Object.Base:
+ return """
+ /* XPM */
+ static char * dim_xpm[] = {
+ "16 16 6 1",
+ " c None",
+ ". c #000000",
+ "+ c #FFFF00",
+ "@ c #FFFFFF",
+ "$ c #141010",
+ "# c #615BD2",
+ " $$$$$$$$",
+ " $##$$#$$",
+ " . $##$$##$",
+ " .. $##$$##$",
+ " .+. $######$",
+ " .++. $##$$##$",
+ " .+++. .$##$$##$",
+ ".++++. .$######$",
+ " .+++. .$$$$$$$$"
+ " .++. .++. ",
+ " .+. .+. ",
+ " .. .. ",
+ " . . ",
+ " ",
+ " ",
+ " "};
+ """
+ else:
+ return """
+ /* XPM */
+ static char * dim_xpm[] = {
+ "16 16 4 1",
+ " c None",
+ ". c #000000",
+ "+ c #FFFF00",
+ "@ c #FFFFFF",
+ " ",
+ " ",
+ " . . ",
+ " .. .. ",
+ " .+. .+. ",
+ " .++. .++. ",
+ " .+++. .. .+++. ",
+ ".++++. .. .++++.",
+ " .+++. .. .+++. ",
+ " .++. .++. ",
+ " .+. .+. ",
+ " .. .. ",
+ " . . ",
+ " ",
+ " ",
+ " "};
+ """
- def getDefaultDisplayMode(self):
- return "2D"
-
- def getIcon(self):
- if self.Object.Base:
- return """
- /* XPM */
- static char * dim_xpm[] = {
- "16 16 6 1",
- " c None",
- ". c #000000",
- "+ c #FFFF00",
- "@ c #FFFFFF",
- "$ c #141010",
- "# c #615BD2",
- " $$$$$$$$",
- " $##$$#$$",
- " . $##$$##$",
- " .. $##$$##$",
- " .+. $######$",
- " .++. $##$$##$",
- " .+++. .$##$$##$",
- ".++++. .$######$",
- " .+++. .$$$$$$$$"
- " .++. .++. ",
- " .+. .+. ",
- " .. .. ",
- " . . ",
- " ",
- " ",
- " "};
- """
- else:
- return """
- /* XPM */
- static char * dim_xpm[] = {
- "16 16 4 1",
- " c None",
- ". c #000000",
- "+ c #FFFF00",
- "@ c #FFFFFF",
- " ",
- " ",
- " . . ",
- " .. .. ",
- " .+. .+. ",
- " .++. .++. ",
- " .+++. .. .+++. ",
- ".++++. .. .++++.",
- " .+++. .. .+++. ",
- " .++. .++. ",
- " .+. .+. ",
- " .. .. ",
- " . . ",
- " ",
- " ",
- " "};
- """
-
- def __getstate__(self):
- return None
-
- def __setstate__(self,state):
- return None
+ def __getstate__(self):
+ return None
+
+ def __setstate__(self,state):
+ return None
class AngularDimension:
- "The AngularDimension object"
- def __init__(self, obj):
- obj.addProperty("App::PropertyAngle","FirstAngle","Base",
- "Start angle of the dimension")
- obj.addProperty("App::PropertyAngle","LastAngle","Base",
- "End angle of the dimension")
- obj.addProperty("App::PropertyVector","Dimline","Base",
- "Point through which the dimension line passes")
- obj.addProperty("App::PropertyVector","Center","Base",
- "The center point of this dimension")
- obj.FirstAngle = 0
- obj.LastAngle = 90
- obj.Dimline = FreeCAD.Vector(0,1,0)
- obj.Center = FreeCAD.Vector(0,0,0)
- obj.Proxy = self
- self.Type = "AngularDimension"
-
- def onChanged(self, fp, prop):
- pass
+ "The AngularDimension object"
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyAngle","FirstAngle","Base",
+ "Start angle of the dimension")
+ obj.addProperty("App::PropertyAngle","LastAngle","Base",
+ "End angle of the dimension")
+ obj.addProperty("App::PropertyVector","Dimline","Base",
+ "Point through which the dimension line passes")
+ obj.addProperty("App::PropertyVector","Center","Base",
+ "The center point of this dimension")
+ obj.FirstAngle = 0
+ obj.LastAngle = 90
+ obj.Dimline = FreeCAD.Vector(0,1,0)
+ obj.Center = FreeCAD.Vector(0,0,0)
+ obj.Proxy = self
+ self.Type = "AngularDimension"
+
+ def onChanged(self, fp, prop):
+ pass
- def execute(self, fp):
- if fp.ViewObject:
- fp.ViewObject.update()
+ def execute(self, fp):
+ if fp.ViewObject:
+ fp.ViewObject.update()
class ViewProviderAngularDimension:
- "A View Provider for the Angular Dimension object"
- def __init__(self, obj):
- obj.addProperty("App::PropertyLength","FontSize","Base","Font size")
- obj.addProperty("App::PropertyString","FontName","Base","Font name")
- obj.addProperty("App::PropertyLength","LineWidth","Base","Line width")
- obj.addProperty("App::PropertyColor","LineColor","Base","Line color")
- obj.addProperty("App::PropertyVector","Position","Base","The position of the text. Leave (0,0,0) for automatic position")
- obj.addProperty("App::PropertyString","Override","Base","Text override. Use 'dim' to insert the dimension length")
- obj.Proxy = self
- obj.FontSize=getParam("textheight")
- obj.FontName=getParam("textfont")
- obj.Override = ''
+ "A View Provider for the Angular Dimension object"
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyLength","FontSize","Base","Font size")
+ obj.addProperty("App::PropertyString","FontName","Base","Font name")
+ obj.addProperty("App::PropertyLength","LineWidth","Base","Line width")
+ obj.addProperty("App::PropertyColor","LineColor","Base","Line color")
+ obj.addProperty("App::PropertyVector","Position","Base","The position of the text. Leave (0,0,0) for automatic position")
+ obj.addProperty("App::PropertyString","Override","Base","Text override. Use 'dim' to insert the dimension length")
+ obj.Proxy = self
+ obj.FontSize=getParam("textheight")
+ obj.FontName=getParam("textfont")
+ obj.Override = ''
- def attach(self, vobj):
- self.Object = vobj.Object
- self.arc = None
- c,tbase,trot,p2,p3 = self.calcGeom(vobj.Object)
- self.color = coin.SoBaseColor()
- self.color.rgb.setValue(vobj.LineColor[0],
- vobj.LineColor[1],
- vobj.LineColor[2])
- self.font = coin.SoFont()
- self.font3d = coin.SoFont()
- self.text = coin.SoAsciiText()
- self.text3d = coin.SoText2()
- self.text.justification = self.text3d.justification = coin.SoAsciiText.CENTER
- self.text.string = self.text3d.string = ''
- self.textpos = coin.SoTransform()
- self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z])
- self.textpos.rotation = coin.SbRotation()
- label = coin.SoSeparator()
- label.addChild(self.textpos)
- label.addChild(self.color)
- label.addChild(self.font)
- label.addChild(self.text)
- label3d = coin.SoSeparator()
- label3d.addChild(self.textpos)
- label3d.addChild(self.color)
- label3d.addChild(self.font3d)
- label3d.addChild(self.text3d)
- self.coord1 = coin.SoCoordinate3()
- self.coord1.point.setValue((p2.x,p2.y,p2.z))
- self.coord2 = coin.SoCoordinate3()
- self.coord2.point.setValue((p3.x,p3.y,p3.z))
- marks = coin.SoAnnotation()
- marks.addChild(self.color)
- marks.addChild(self.coord1)
- marks.addChild(dimSymbol())
- marks.addChild(self.coord2)
- marks.addChild(dimSymbol())
- self.drawstyle = coin.SoDrawStyle()
- self.drawstyle.lineWidth = 1
- self.coords = coin.SoCoordinate3()
- self.selnode=coin.SoType.fromName("SoFCSelection").createInstance()
- self.selnode.documentName.setValue(FreeCAD.ActiveDocument.Name)
- self.selnode.objectName.setValue(vobj.Object.Name)
- self.selnode.subElementName.setValue("Arc")
- self.node = coin.SoGroup()
- self.node.addChild(self.color)
- self.node.addChild(self.drawstyle)
- self.node.addChild(self.coords)
- self.node.addChild(self.selnode)
- self.node.addChild(marks)
- self.node.addChild(label)
- self.node3d = coin.SoGroup()
- self.node3d.addChild(self.color)
- self.node3d.addChild(self.drawstyle)
- self.node3d.addChild(self.coords)
- self.node3d.addChild(self.selnode)
- self.node3d.addChild(marks)
- self.node3d.addChild(label3d)
- vobj.addDisplayMode(self.node,"2D")
- vobj.addDisplayMode(self.node3d,"3D")
- self.onChanged(vobj,"FontSize")
- self.onChanged(vobj,"FontName")
+ def attach(self, vobj):
+ self.Object = vobj.Object
+ self.arc = None
+ c,tbase,trot,p2,p3 = self.calcGeom(vobj.Object)
+ self.color = coin.SoBaseColor()
+ self.color.rgb.setValue(vobj.LineColor[0],
+ vobj.LineColor[1],
+ vobj.LineColor[2])
+ self.font = coin.SoFont()
+ self.font3d = coin.SoFont()
+ self.text = coin.SoAsciiText()
+ self.text3d = coin.SoText2()
+ self.text.justification = self.text3d.justification = coin.SoAsciiText.CENTER
+ self.text.string = self.text3d.string = ''
+ self.textpos = coin.SoTransform()
+ self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z])
+ self.textpos.rotation = coin.SbRotation()
+ label = coin.SoSeparator()
+ label.addChild(self.textpos)
+ label.addChild(self.color)
+ label.addChild(self.font)
+ label.addChild(self.text)
+ label3d = coin.SoSeparator()
+ label3d.addChild(self.textpos)
+ label3d.addChild(self.color)
+ label3d.addChild(self.font3d)
+ label3d.addChild(self.text3d)
+ self.coord1 = coin.SoCoordinate3()
+ self.coord1.point.setValue((p2.x,p2.y,p2.z))
+ self.coord2 = coin.SoCoordinate3()
+ self.coord2.point.setValue((p3.x,p3.y,p3.z))
+ marks = coin.SoAnnotation()
+ marks.addChild(self.color)
+ marks.addChild(self.coord1)
+ marks.addChild(dimSymbol())
+ marks.addChild(self.coord2)
+ marks.addChild(dimSymbol())
+ self.drawstyle = coin.SoDrawStyle()
+ self.drawstyle.lineWidth = 1
+ self.coords = coin.SoCoordinate3()
+ self.selnode=coin.SoType.fromName("SoFCSelection").createInstance()
+ self.selnode.documentName.setValue(FreeCAD.ActiveDocument.Name)
+ self.selnode.objectName.setValue(vobj.Object.Name)
+ self.selnode.subElementName.setValue("Arc")
+ self.node = coin.SoGroup()
+ self.node.addChild(self.color)
+ self.node.addChild(self.drawstyle)
+ self.node.addChild(self.coords)
+ self.node.addChild(self.selnode)
+ self.node.addChild(marks)
+ self.node.addChild(label)
+ self.node3d = coin.SoGroup()
+ self.node3d.addChild(self.color)
+ self.node3d.addChild(self.drawstyle)
+ self.node3d.addChild(self.coords)
+ self.node3d.addChild(self.selnode)
+ self.node3d.addChild(marks)
+ self.node3d.addChild(label3d)
+ vobj.addDisplayMode(self.node,"2D")
+ vobj.addDisplayMode(self.node3d,"3D")
+ self.onChanged(vobj,"FontSize")
+ self.onChanged(vobj,"FontName")
- def calcGeom(self,obj):
- rad = (obj.Dimline.sub(obj.Center)).Length
- cir = Part.makeCircle(rad,obj.Center,Vector(0,0,1),obj.FirstAngle,obj.LastAngle)
- cp = fcgeo.findMidpoint(cir.Edges[0])
- rv = cp.sub(obj.Center)
- rv = fcvec.scaleTo(rv,rv.Length + obj.ViewObject.FontSize*.2)
- tbase = obj.Center.add(rv)
- trot = fcvec.angle(rv)-math.pi/2
- if (trot > math.pi/2) or (trot < -math.pi/2):
- trot = trot + math.pi
- s = getParam("dimorientation")
- if s == 0:
- if round(trot,precision()) == round(-math.pi/2,precision()):
- trot = math.pi/2
- return cir, tbase, trot, cir.Vertexes[0].Point, cir.Vertexes[-1].Point
+ def calcGeom(self,obj):
+ rad = (obj.Dimline.sub(obj.Center)).Length
+ cir = Part.makeCircle(rad,obj.Center,Vector(0,0,1),obj.FirstAngle,obj.LastAngle)
+ cp = fcgeo.findMidpoint(cir.Edges[0])
+ rv = cp.sub(obj.Center)
+ rv = fcvec.scaleTo(rv,rv.Length + obj.ViewObject.FontSize*.2)
+ tbase = obj.Center.add(rv)
+ trot = fcvec.angle(rv)-math.pi/2
+ if (trot > math.pi/2) or (trot < -math.pi/2):
+ trot = trot + math.pi
+ s = getParam("dimorientation")
+ if s == 0:
+ if round(trot,precision()) == round(-math.pi/2,precision()):
+ trot = math.pi/2
+ return cir, tbase, trot, cir.Vertexes[0].Point, cir.Vertexes[-1].Point
- def updateData(self, obj, prop):
- text = None
- ivob = None
- c,tbase,trot,p2,p3 = self.calcGeom(obj)
- buf=c.writeInventor(2,0.01)
- ivin = coin.SoInput()
- ivin.setBuffer(buf)
- ivob = coin.SoDB.readAll(ivin)
- arc = ivob.getChildren()[1]
- # In case reading from buffer failed
- if ivob and ivob.getNumChildren() > 1:
- arc = ivob.getChild(1).getChild(0)
- arc.removeChild(arc.getChild(0))
- arc.removeChild(arc.getChild(0))
- if self.arc:
- self.selnode.removeChild(self.arc)
- self.arc = arc
- self.selnode.addChild(self.arc)
- if 'Override' in obj.ViewObject.PropertiesList:
- text = str(obj.ViewObject.Override)
- dtext = getParam("dimPrecision")
- dtext = "%."+str(dtext)+"f"
- if obj.LastAngle > obj.FirstAngle:
- dtext = (dtext % (obj.LastAngle-obj.FirstAngle))+'\xb0'
- else:
- dtext = (dtext % ((360-obj.FirstAngle)+obj.LastAngle))+'\xb0'
- if text:
- text = text.replace("dim",dtext)
- else:
- text = dtext
- self.text.string = self.text3d.string = text
- self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z])
- m = FreeCAD.Matrix()
- m.rotateZ(trot)
- tm = FreeCAD.Placement(m).Rotation.Q
- self.textpos.rotation = coin.SbRotation(tm[0],tm[1],tm[2],tm[3])
- self.coord1.point.setValue((p2.x,p2.y,p2.z))
- self.coord2.point.setValue((p3.x,p3.y,p3.z))
+ def updateData(self, obj, prop):
+ text = None
+ ivob = None
+ c,tbase,trot,p2,p3 = self.calcGeom(obj)
+ buf=c.writeInventor(2,0.01)
+ ivin = coin.SoInput()
+ ivin.setBuffer(buf)
+ ivob = coin.SoDB.readAll(ivin)
+ arc = ivob.getChildren()[1]
+ # In case reading from buffer failed
+ if ivob and ivob.getNumChildren() > 1:
+ arc = ivob.getChild(1).getChild(0)
+ arc.removeChild(arc.getChild(0))
+ arc.removeChild(arc.getChild(0))
+ if self.arc:
+ self.selnode.removeChild(self.arc)
+ self.arc = arc
+ self.selnode.addChild(self.arc)
+ if 'Override' in obj.ViewObject.PropertiesList:
+ text = str(obj.ViewObject.Override)
+ dtext = getParam("dimPrecision")
+ dtext = "%."+str(dtext)+"f"
+ if obj.LastAngle > obj.FirstAngle:
+ dtext = (dtext % (obj.LastAngle-obj.FirstAngle))+'\xb0'
+ else:
+ dtext = (dtext % ((360-obj.FirstAngle)+obj.LastAngle))+'\xb0'
+ if text:
+ text = text.replace("dim",dtext)
+ else:
+ text = dtext
+ self.text.string = self.text3d.string = text
+ self.textpos.translation.setValue([tbase.x,tbase.y,tbase.z])
+ m = FreeCAD.Matrix()
+ m.rotateZ(trot)
+ tm = FreeCAD.Placement(m).Rotation.Q
+ self.textpos.rotation = coin.SbRotation(tm[0],tm[1],tm[2],tm[3])
+ self.coord1.point.setValue((p2.x,p2.y,p2.z))
+ self.coord2.point.setValue((p3.x,p3.y,p3.z))
- def onChanged(self, vobj, prop):
- if prop == "FontSize":
- self.font.size = vobj.FontSize
- self.font3d.size = vobj.FontSize*100
- elif prop == "FontName":
- self.font.name = self.font3d.name = str(vobj.FontName)
- elif prop == "LineColor":
- c = vobj.LineColor
- self.color.rgb.setValue(c[0],c[1],c[2])
- elif prop == "LineWidth":
- self.drawstyle.lineWidth = vobj.LineWidth
- elif prop == "DisplayMode":
- pass
- else:
- self.updateData(vobj.Object, None)
+ def onChanged(self, vobj, prop):
+ if prop == "FontSize":
+ self.font.size = vobj.FontSize
+ self.font3d.size = vobj.FontSize*100
+ elif prop == "FontName":
+ self.font.name = self.font3d.name = str(vobj.FontName)
+ elif prop == "LineColor":
+ c = vobj.LineColor
+ self.color.rgb.setValue(c[0],c[1],c[2])
+ elif prop == "LineWidth":
+ self.drawstyle.lineWidth = vobj.LineWidth
+ elif prop == "DisplayMode":
+ pass
+ else:
+ self.updateData(vobj.Object, None)
- def getDisplayModes(self,obj):
- modes=[]
- modes.extend(["2D","3D"])
- return modes
+ def getDisplayModes(self,obj):
+ modes=[]
+ modes.extend(["2D","3D"])
+ return modes
- def getDefaultDisplayMode(self):
- return "2D"
+ def getDefaultDisplayMode(self):
+ return "2D"
- def getIcon(self):
- return """
+ def getIcon(self):
+ return """
/* XPM */
static char * dim_xpm[] = {
"16 16 4 1",
@@ -1676,395 +1675,395 @@ class ViewProviderAngularDimension:
"""
class Rectangle:
- "The Rectangle object"
+ "The Rectangle object"
- def __init__(self, obj):
- obj.addProperty("App::PropertyDistance","Length","Base","Length of the rectangle")
- obj.addProperty("App::PropertyDistance","Height","Base","Height of the rectange")
- obj.Proxy = self
- obj.Length=1
- obj.Height=1
- self.Type = "Rectangle"
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyDistance","Length","Base","Length of the rectangle")
+ obj.addProperty("App::PropertyDistance","Height","Base","Height of the rectange")
+ obj.Proxy = self
+ obj.Length=1
+ obj.Height=1
+ self.Type = "Rectangle"
- def execute(self, fp):
- self.createGeometry(fp)
+ def execute(self, fp):
+ self.createGeometry(fp)
- def onChanged(self, fp, prop):
- if prop in ["Length","Height"]:
- self.createGeometry(fp)
+ def onChanged(self, fp, prop):
+ if prop in ["Length","Height"]:
+ self.createGeometry(fp)
- def createGeometry(self,fp):
- plm = fp.Placement
- p1 = Vector(0,0,0)
- p2 = Vector(p1.x+fp.Length,p1.y,p1.z)
- p3 = Vector(p1.x+fp.Length,p1.y+fp.Height,p1.z)
- p4 = Vector(p1.x,p1.y+fp.Height,p1.z)
- shape = Part.makePolygon([p1,p2,p3,p4,p1])
- shape = Part.Face(shape)
- fp.Shape = shape
- fp.Placement = plm
+ def createGeometry(self,fp):
+ plm = fp.Placement
+ p1 = Vector(0,0,0)
+ p2 = Vector(p1.x+fp.Length,p1.y,p1.z)
+ p3 = Vector(p1.x+fp.Length,p1.y+fp.Height,p1.z)
+ p4 = Vector(p1.x,p1.y+fp.Height,p1.z)
+ shape = Part.makePolygon([p1,p2,p3,p4,p1])
+ shape = Part.Face(shape)
+ fp.Shape = shape
+ fp.Placement = plm
class ViewProviderRectangle(ViewProviderDraft):
- "A View Provider for the Rectangle object"
- def __init__(self, obj):
- ViewProviderDraft.__init__(self,obj)
- obj.addProperty("App::PropertyFile","TextureImage",
- "Base","Uses an image as a texture map")
+ "A View Provider for the Rectangle object"
+ def __init__(self, obj):
+ ViewProviderDraft.__init__(self,obj)
+ obj.addProperty("App::PropertyFile","TextureImage",
+ "Base","Uses an image as a texture map")
- def attach(self,obj):
- self.texture = None
+ def attach(self,obj):
+ self.texture = None
- def onChanged(self, vp, prop):
- if prop == "TextureImage":
- r = vp.RootNode
- if os.path.exists(vp.TextureImage):
- self.texture = coin.SoTexture2()
- self.texture.filename = str(vp.TextureImage)
- r.insertChild(self.texture,1)
- else:
- if self.texture:
- r.removeChild(self.texture)
- self.texture = None
- return
+ def onChanged(self, vp, prop):
+ if prop == "TextureImage":
+ r = vp.RootNode
+ if os.path.exists(vp.TextureImage):
+ self.texture = coin.SoTexture2()
+ self.texture.filename = str(vp.TextureImage)
+ r.insertChild(self.texture,1)
+ else:
+ if self.texture:
+ r.removeChild(self.texture)
+ self.texture = None
+ return
class Circle:
- "The Circle object"
+ "The Circle object"
- def __init__(self, obj):
- obj.addProperty("App::PropertyAngle","FirstAngle","Arc",
- "Start angle of the arc")
- obj.addProperty("App::PropertyAngle","LastAngle","Arc",
- "End angle of the arc (for a full circle, give it same value as First Angle)")
- obj.addProperty("App::PropertyDistance","Radius","Base",
- "Radius of the circle")
- obj.Proxy = self
- self.Type = "Circle"
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyAngle","FirstAngle","Arc",
+ "Start angle of the arc")
+ obj.addProperty("App::PropertyAngle","LastAngle","Arc",
+ "End angle of the arc (for a full circle, give it same value as First Angle)")
+ obj.addProperty("App::PropertyDistance","Radius","Base",
+ "Radius of the circle")
+ obj.Proxy = self
+ self.Type = "Circle"
- def execute(self, fp):
- self.createGeometry(fp)
+ def execute(self, fp):
+ self.createGeometry(fp)
- def onChanged(self, fp, prop):
- if prop in ["Radius","FirstAngle","LastAngle"]:
- self.createGeometry(fp)
+ def onChanged(self, fp, prop):
+ if prop in ["Radius","FirstAngle","LastAngle"]:
+ self.createGeometry(fp)
- def createGeometry(self,fp):
- plm = fp.Placement
- shape = Part.makeCircle(fp.Radius,Vector(0,0,0),
- Vector(0,0,1),fp.FirstAngle,fp.LastAngle)
- if fp.FirstAngle == fp.LastAngle:
- shape = Part.Wire(shape)
- shape = Part.Face(shape)
- fp.Shape = shape
- fp.Placement = plm
+ def createGeometry(self,fp):
+ plm = fp.Placement
+ shape = Part.makeCircle(fp.Radius,Vector(0,0,0),
+ Vector(0,0,1),fp.FirstAngle,fp.LastAngle)
+ if fp.FirstAngle == fp.LastAngle:
+ shape = Part.Wire(shape)
+ shape = Part.Face(shape)
+ fp.Shape = shape
+ fp.Placement = plm
class Wire:
- "The Wire object"
+ "The Wire object"
- def __init__(self, obj):
- obj.addProperty("App::PropertyVectorList","Points","Base",
- "The vertices of the wire")
- obj.addProperty("App::PropertyBool","Closed","Base",
- "If the wire is closed or not")
- obj.addProperty("App::PropertyLink","Base","Base",
- "The base object is the wire is formed from 2 objects")
- obj.addProperty("App::PropertyLink","Tool","Base",
- "The tool object is the wire is formed from 2 objects")
- obj.Proxy = self
- obj.Closed = False
- self.Type = "Wire"
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyVectorList","Points","Base",
+ "The vertices of the wire")
+ obj.addProperty("App::PropertyBool","Closed","Base",
+ "If the wire is closed or not")
+ obj.addProperty("App::PropertyLink","Base","Base",
+ "The base object is the wire is formed from 2 objects")
+ obj.addProperty("App::PropertyLink","Tool","Base",
+ "The tool object is the wire is formed from 2 objects")
+ obj.Proxy = self
+ obj.Closed = False
+ self.Type = "Wire"
- def execute(self, fp):
- self.createGeometry(fp)
+ def execute(self, fp):
+ self.createGeometry(fp)
- def onChanged(self, fp, prop):
- if prop in ["Points","Closed","Base","Tool"]:
- self.createGeometry(fp)
+ def onChanged(self, fp, prop):
+ if prop in ["Points","Closed","Base","Tool"]:
+ self.createGeometry(fp)
- def createGeometry(self,fp):
- plm = fp.Placement
- if fp.Base and (not fp.Tool):
- if fp.Base.isDerivedFrom("Sketcher::SketchObject"):
- shape = fp.Base.Shape.copy()
- if fp.Base.Shape.isClosed():
- shape = Part.Face(shape)
- fp.Shape = shape
- p = []
- for v in shape.Vertexes: p.append(v.Point)
- if fp.Points != p: fp.Points = p
- elif fp.Base and fp.Tool:
- if ('Shape' in fp.Base.PropertiesList) and ('Shape' in fp.Tool.PropertiesList):
- sh1 = fp.Base.Shape.copy()
- sh2 = fp.Tool.Shape.copy()
- shape = sh1.fuse(sh2)
- if fcgeo.isCoplanar(shape.Faces):
- shape = fcgeo.concatenate(shape)
- fp.Shape = shape
- p = []
- for v in shape.Vertexes: p.append(v.Point)
- if fp.Points != p: fp.Points = p
- elif fp.Points:
- if fp.Points[0] == fp.Points[-1]:
- if not fp.Closed: fp.Closed = True
- fp.Points.pop()
- if fp.Closed and (len(fp.Points) > 2):
- shape = Part.makePolygon(fp.Points+[fp.Points[0]])
- shape = Part.Face(shape)
- else:
- edges = []
- pts = fp.Points[1:]
- lp = fp.Points[0]
- for p in pts:
- edges.append(Part.Line(lp,p).toShape())
- lp = p
- shape = Part.Wire(edges)
- fp.Shape = shape
- fp.Placement = plm
+ def createGeometry(self,fp):
+ plm = fp.Placement
+ if fp.Base and (not fp.Tool):
+ if fp.Base.isDerivedFrom("Sketcher::SketchObject"):
+ shape = fp.Base.Shape.copy()
+ if fp.Base.Shape.isClosed():
+ shape = Part.Face(shape)
+ fp.Shape = shape
+ p = []
+ for v in shape.Vertexes: p.append(v.Point)
+ if fp.Points != p: fp.Points = p
+ elif fp.Base and fp.Tool:
+ if ('Shape' in fp.Base.PropertiesList) and ('Shape' in fp.Tool.PropertiesList):
+ sh1 = fp.Base.Shape.copy()
+ sh2 = fp.Tool.Shape.copy()
+ shape = sh1.fuse(sh2)
+ if fcgeo.isCoplanar(shape.Faces):
+ shape = fcgeo.concatenate(shape)
+ fp.Shape = shape
+ p = []
+ for v in shape.Vertexes: p.append(v.Point)
+ if fp.Points != p: fp.Points = p
+ elif fp.Points:
+ if fp.Points[0] == fp.Points[-1]:
+ if not fp.Closed: fp.Closed = True
+ fp.Points.pop()
+ if fp.Closed and (len(fp.Points) > 2):
+ shape = Part.makePolygon(fp.Points+[fp.Points[0]])
+ shape = Part.Face(shape)
+ else:
+ edges = []
+ pts = fp.Points[1:]
+ lp = fp.Points[0]
+ for p in pts:
+ edges.append(Part.Line(lp,p).toShape())
+ lp = p
+ shape = Part.Wire(edges)
+ fp.Shape = shape
+ fp.Placement = plm
class ViewProviderWire(ViewProviderDraft):
- "A View Provider for the Wire object"
- def __init__(self, obj):
- ViewProviderDraft.__init__(self,obj)
- obj.addProperty("App::PropertyBool","EndArrow","Base",
- "Displays a dim symbol at the end of the wire")
+ "A View Provider for the Wire object"
+ def __init__(self, obj):
+ ViewProviderDraft.__init__(self,obj)
+ obj.addProperty("App::PropertyBool","EndArrow","Base",
+ "Displays a dim symbol at the end of the wire")
- def attach(self, obj):
- self.Object = obj.Object
- col = coin.SoBaseColor()
- col.rgb.setValue(obj.LineColor[0],
- obj.LineColor[1],
- obj.LineColor[2])
- self.coords = coin.SoCoordinate3()
- self.pt = coin.SoAnnotation()
- self.pt.addChild(col)
- self.pt.addChild(self.coords)
- self.pt.addChild(dimSymbol())
+ def attach(self, obj):
+ self.Object = obj.Object
+ col = coin.SoBaseColor()
+ col.rgb.setValue(obj.LineColor[0],
+ obj.LineColor[1],
+ obj.LineColor[2])
+ self.coords = coin.SoCoordinate3()
+ self.pt = coin.SoAnnotation()
+ self.pt.addChild(col)
+ self.pt.addChild(self.coords)
+ self.pt.addChild(dimSymbol())
- def updateData(self, obj, prop):
- if prop == "Points":
- if obj.Points:
- p = obj.Points[-1]
- self.coords.point.setValue((p.x,p.y,p.z))
- return
+ def updateData(self, obj, prop):
+ if prop == "Points":
+ if obj.Points:
+ p = obj.Points[-1]
+ self.coords.point.setValue((p.x,p.y,p.z))
+ return
- def onChanged(self, vp, prop):
- if prop == "EndArrow":
- rn = vp.RootNode
- if vp.EndArrow:
- rn.addChild(self.pt)
- else:
- rn.removeChild(self.pt)
- return
+ def onChanged(self, vp, prop):
+ if prop == "EndArrow":
+ rn = vp.RootNode
+ if vp.EndArrow:
+ rn.addChild(self.pt)
+ else:
+ rn.removeChild(self.pt)
+ return
- def claimChildren(self):
- return [self.Object.Base,self.Object.Tool]
+ def claimChildren(self):
+ return [self.Object.Base,self.Object.Tool]
class Polygon:
- "The Polygon object"
+ "The Polygon object"
- def __init__(self, obj):
- obj.addProperty("App::PropertyInteger","FacesNumber","Base","Number of faces")
- obj.addProperty("App::PropertyDistance","Radius","Base","Radius of the control circle")
- obj.addProperty("App::PropertyEnumeration","DrawMode","Base","How the polygon must be drawn from the control circle")
- obj.DrawMode = ['inscribed','circumscribed']
- obj.FacesNumber = 3
- obj.Radius = 1
- obj.Proxy = self
- self.Type = "Polygon"
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyInteger","FacesNumber","Base","Number of faces")
+ obj.addProperty("App::PropertyDistance","Radius","Base","Radius of the control circle")
+ obj.addProperty("App::PropertyEnumeration","DrawMode","Base","How the polygon must be drawn from the control circle")
+ obj.DrawMode = ['inscribed','circumscribed']
+ obj.FacesNumber = 3
+ obj.Radius = 1
+ obj.Proxy = self
+ self.Type = "Polygon"
- def execute(self, fp):
- self.createGeometry(fp)
+ def execute(self, fp):
+ self.createGeometry(fp)
- def onChanged(self, fp, prop):
- if prop in ["FacesNumber","Radius","DrawMode"]:
- self.createGeometry(fp)
+ def onChanged(self, fp, prop):
+ if prop in ["FacesNumber","Radius","DrawMode"]:
+ self.createGeometry(fp)
- def createGeometry(self,fp):
- plm = fp.Placement
- angle = (math.pi*2)/fp.FacesNumber
- if fp.DrawMode == 'inscribed':
- delta = fp.Radius
- else:
- delta = fp.Radius/math.cos(angle/2)
- pts = [Vector(delta,0,0)]
- for i in range(fp.FacesNumber-1):
- ang = (i+1)*angle
- pts.append(Vector(delta*math.cos(ang),delta*math.sin(ang),0))
- pts.append(pts[0])
- shape = Part.makePolygon(pts)
- shape = Part.Face(shape)
- fp.Shape = shape
- fp.Placement = plm
+ def createGeometry(self,fp):
+ plm = fp.Placement
+ angle = (math.pi*2)/fp.FacesNumber
+ if fp.DrawMode == 'inscribed':
+ delta = fp.Radius
+ else:
+ delta = fp.Radius/math.cos(angle/2)
+ pts = [Vector(delta,0,0)]
+ for i in range(fp.FacesNumber-1):
+ ang = (i+1)*angle
+ pts.append(Vector(delta*math.cos(ang),delta*math.sin(ang),0))
+ pts.append(pts[0])
+ shape = Part.makePolygon(pts)
+ shape = Part.Face(shape)
+ fp.Shape = shape
+ fp.Placement = plm
class DrawingView:
- def __init__(self, obj):
- obj.addProperty("App::PropertyVector","Direction","Shape view","Projection direction")
- obj.addProperty("App::PropertyFloat","LinewidthModifier","Drawing view","Modifies the linewidth of the lines inside this object")
- obj.addProperty("App::PropertyFloat","TextModifier","Drawing view","Modifies the size of the texts inside this object")
- obj.addProperty("App::PropertyLink","Source","Base","The linked object")
- obj.addProperty("App::PropertyEnumeration","LineStyle","Drawing view","Line Style")
- obj.addProperty("App::PropertyEnumeration","FillStyle","Drawing view","Shape Fill Style")
- obj.LineStyle = ['continuous','dashed','dashdotted','dotted']
- fills = ['shape color']
- for f in FreeCAD.svgpatterns.keys():
- fills.append(f)
- obj.FillStyle = fills
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyVector","Direction","Shape view","Projection direction")
+ obj.addProperty("App::PropertyFloat","LinewidthModifier","Drawing view","Modifies the linewidth of the lines inside this object")
+ obj.addProperty("App::PropertyFloat","TextModifier","Drawing view","Modifies the size of the texts inside this object")
+ obj.addProperty("App::PropertyLink","Source","Base","The linked object")
+ obj.addProperty("App::PropertyEnumeration","LineStyle","Drawing view","Line Style")
+ obj.addProperty("App::PropertyEnumeration","FillStyle","Drawing view","Shape Fill Style")
+ obj.LineStyle = ['continuous','dashed','dashdotted','dotted']
+ fills = ['shape color']
+ for f in FreeCAD.svgpatterns.keys():
+ fills.append(f)
+ obj.FillStyle = fills
- obj.Proxy = self
- obj.LinewidthModifier = 100
- obj.TextModifier = 100
- self.Type = "DrawingView"
+ obj.Proxy = self
+ obj.LinewidthModifier = 100
+ obj.TextModifier = 100
+ self.Type = "DrawingView"
- def execute(self, obj):
- if obj.Source:
- obj.ViewResult = self.updateSVG(obj)
+ def execute(self, obj):
+ if obj.Source:
+ obj.ViewResult = self.updateSVG(obj)
- def onChanged(self, obj, prop):
- if prop in ["X","Y","Scale","LinewidthModifier","TextModifier","LineStyle","FillStyle","Direction"]:
- obj.ViewResult = self.updateSVG(obj)
+ def onChanged(self, obj, prop):
+ if prop in ["X","Y","Scale","LinewidthModifier","TextModifier","LineStyle","FillStyle","Direction"]:
+ obj.ViewResult = self.updateSVG(obj)
- def updateSVG(self, obj):
- "encapsulates a svg fragment into a transformation node"
- svg = getSVG(obj.Source,obj.LinewidthModifier,obj.TextModifier,obj.LineStyle,obj.FillStyle,obj.Direction)
- result = ''
- result += ''
- result += svg
- result += ''
- return result
+ def updateSVG(self, obj):
+ "encapsulates a svg fragment into a transformation node"
+ svg = getSVG(obj.Source,obj.LinewidthModifier,obj.TextModifier,obj.LineStyle,obj.FillStyle,obj.Direction)
+ result = ''
+ result += ''
+ result += svg
+ result += ''
+ return result
class BSpline:
- "The BSpline object"
+ "The BSpline object"
- def __init__(self, obj):
- obj.addProperty("App::PropertyVectorList","Points","Base",
- "The points of the b-spline")
- obj.addProperty("App::PropertyBool","Closed","Base",
- "If the b-spline is closed or not")
- obj.Proxy = self
- obj.Closed = False
- self.Type = "BSpline"
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyVectorList","Points","Base",
+ "The points of the b-spline")
+ obj.addProperty("App::PropertyBool","Closed","Base",
+ "If the b-spline is closed or not")
+ obj.Proxy = self
+ obj.Closed = False
+ self.Type = "BSpline"
- def execute(self, fp):
- self.createGeometry(fp)
-
- def onChanged(self, fp, prop):
- if prop in ["Points","Closed"]:
- self.createGeometry(fp)
+ def execute(self, fp):
+ self.createGeometry(fp)
+
+ def onChanged(self, fp, prop):
+ if prop in ["Points","Closed"]:
+ self.createGeometry(fp)
- def createGeometry(self,fp):
- plm = fp.Placement
- if fp.Points:
- if fp.Points[0] == fp.Points[-1]:
- if not fp.Closed: fp.Closed = True
- fp.Points.pop()
- if fp.Closed and (len(fp.Points) > 2):
- spline = Part.BSplineCurve()
- spline.interpolate(fp.Points, True)
- # DNC: bug fix: convert to face if closed
- shape = Part.Wire(spline.toShape())
- shape = Part.Face(shape)
- fp.Shape = shape
- else:
- spline = Part.BSplineCurve()
- spline.interpolate(fp.Points, False)
- fp.Shape = spline.toShape()
- fp.Placement = plm
+ def createGeometry(self,fp):
+ plm = fp.Placement
+ if fp.Points:
+ if fp.Points[0] == fp.Points[-1]:
+ if not fp.Closed: fp.Closed = True
+ fp.Points.pop()
+ if fp.Closed and (len(fp.Points) > 2):
+ spline = Part.BSplineCurve()
+ spline.interpolate(fp.Points, True)
+ # DNC: bug fix: convert to face if closed
+ shape = Part.Wire(spline.toShape())
+ shape = Part.Face(shape)
+ fp.Shape = shape
+ else:
+ spline = Part.BSplineCurve()
+ spline.interpolate(fp.Points, False)
+ fp.Shape = spline.toShape()
+ fp.Placement = plm
class ViewProviderBSpline(ViewProviderDraft):
- "A View Provider for the BSPline object"
- def __init__(self, obj):
- ViewProviderDraft.__init__(self,obj)
- obj.addProperty("App::PropertyBool","EndArrow",
- "Base","Displays a dim symbol at the end of the wire")
- col = coin.SoBaseColor()
- col.rgb.setValue(obj.LineColor[0],
- obj.LineColor[1],
- obj.LineColor[2])
- self.coords = coin.SoCoordinate3()
- self.pt = coin.SoAnnotation()
- self.pt.addChild(col)
- self.pt.addChild(self.coords)
- self.pt.addChild(dimSymbol())
+ "A View Provider for the BSPline object"
+ def __init__(self, obj):
+ ViewProviderDraft.__init__(self,obj)
+ obj.addProperty("App::PropertyBool","EndArrow",
+ "Base","Displays a dim symbol at the end of the wire")
+ col = coin.SoBaseColor()
+ col.rgb.setValue(obj.LineColor[0],
+ obj.LineColor[1],
+ obj.LineColor[2])
+ self.coords = coin.SoCoordinate3()
+ self.pt = coin.SoAnnotation()
+ self.pt.addChild(col)
+ self.pt.addChild(self.coords)
+ self.pt.addChild(dimSymbol())
- def updateData(self, obj, prop):
- if prop == "Points":
- if obj.Points:
- p = obj.Points[-1]
- self.coords.point.setValue((p.x,p.y,p.z))
- return
+ def updateData(self, obj, prop):
+ if prop == "Points":
+ if obj.Points:
+ p = obj.Points[-1]
+ self.coords.point.setValue((p.x,p.y,p.z))
+ return
- def onChanged(self, vp, prop):
- if prop == "EndArrow":
- rn = vp.RootNode
- if vp.EndArrow:
- rn.addChild(self.pt)
- else:
- rn.removeChild(self.pt)
- return
+ def onChanged(self, vp, prop):
+ if prop == "EndArrow":
+ rn = vp.RootNode
+ if vp.EndArrow:
+ rn.addChild(self.pt)
+ else:
+ rn.removeChild(self.pt)
+ return
class Block:
- "The Block object"
-
- def __init__(self, obj):
- obj.addProperty("App::PropertyLinkList","Components","Base",
- "The components of this block")
- obj.Proxy = self
- self.Type = "Block"
+ "The Block object"
+
+ def __init__(self, obj):
+ obj.addProperty("App::PropertyLinkList","Components","Base",
+ "The components of this block")
+ obj.Proxy = self
+ self.Type = "Block"
- def execute(self, fp):
- self.createGeometry(fp)
+ def execute(self, fp):
+ self.createGeometry(fp)
- def onChanged(self, fp, prop):
- if prop in ["Components"]:
- self.createGeometry(fp)
+ def onChanged(self, fp, prop):
+ if prop in ["Components"]:
+ self.createGeometry(fp)
- def createGeometry(self,fp):
- plm = fp.Placement
- shps = []
- for c in fp.Components:
- shps.append(c.Shape)
- if shps:
- shape = Part.makeCompound(shps)
- fp.Shape = shape
- fp.Placement = plm
+ def createGeometry(self,fp):
+ plm = fp.Placement
+ shps = []
+ for c in fp.Components:
+ shps.append(c.Shape)
+ if shps:
+ shape = Part.makeCompound(shps)
+ fp.Shape = shape
+ fp.Placement = plm
class ViewProviderBlock(ViewProviderDraft):
- "A View Provider for the Block object"
+ "A View Provider for the Block object"
- def claimChildren(self):
- return self.Object.Components
+ def claimChildren(self):
+ return self.Object.Components
class Shape2DView:
- "The Shape2DView object"
+ "The Shape2DView object"
- def __init__(self,obj):
- obj.addProperty("App::PropertyLink","Base","Base",
- "The base object this 2D view must represent")
- obj.addProperty("App::PropertyVector","Projection","Base",
- "The projection vector of this object")
- obj.Projection = Vector(0,0,-1)
- obj.Proxy = self
- self.Type = "2DShapeView"
+ def __init__(self,obj):
+ obj.addProperty("App::PropertyLink","Base","Base",
+ "The base object this 2D view must represent")
+ obj.addProperty("App::PropertyVector","Projection","Base",
+ "The projection vector of this object")
+ obj.Projection = Vector(0,0,-1)
+ obj.Proxy = self
+ self.Type = "2DShapeView"
- def execute(self,obj):
- self.createGeometry(obj)
+ def execute(self,obj):
+ self.createGeometry(obj)
- def onChanged(self,obj,prop):
- if prop in ["Projection","Base"]:
- print "changing",prop
- self.createGeometry(obj)
+ def onChanged(self,obj,prop):
+ if prop in ["Projection","Base"]:
+ print "changing",prop
+ self.createGeometry(obj)
- def createGeometry(self,obj):
- pl = obj.Placement
- if obj.Base:
- if obj.Base.isDerivedFrom("Part::Feature"):
- [visibleG0,visibleG1,hiddenG0,hiddenG1] = Drawing.project(obj.Base.Shape,obj.Projection)
- print visibleG0.Edges
- if visibleG0:
- obj.Shape = visibleG0
- if not fcgeo.isNull(pl):
- obj.Placement = pl
+ def createGeometry(self,obj):
+ pl = obj.Placement
+ if obj.Base:
+ if obj.Base.isDerivedFrom("Part::Feature"):
+ [visibleG0,visibleG1,hiddenG0,hiddenG1] = Drawing.project(obj.Base.Shape,obj.Projection)
+ print visibleG0.Edges
+ if visibleG0:
+ obj.Shape = visibleG0
+ if not fcgeo.isNull(pl):
+ obj.Placement = pl
diff --git a/src/Mod/Draft/InitGui.py b/src/Mod/Draft/InitGui.py
index cbb537c97c..fd59394b5e 100644
--- a/src/Mod/Draft/InitGui.py
+++ b/src/Mod/Draft/InitGui.py
@@ -29,200 +29,200 @@ import os
class DraftWorkbench (Workbench):
- "the Draft Workbench"
- Icon = """
- /* XPM */
- static char * draft_xpm[] = {
- "14 16 96 2",
- " c None",
- ". c #584605",
- "+ c #513E03",
- "@ c #E6B50D",
- "# c #C29F0E",
- "$ c #6E5004",
- "% c #F7BD0B",
- "& c #8F7008",
- "* c #F3C711",
- "= c #B1950F",
- "- c #785402",
- "; c #946C05",
- "> c #FABF0B",
- ", c #F7C20E",
- "' c #8D740A",
- ") c #F8D115",
- "! c #9F8A0F",
- "~ c #593D00",
- "{ c #FEB304",
- "] c #F3B208",
- "^ c #987407",
- "/ c #FDC70E",
- "( c #EFC311",
- "_ c #8F790C",
- ": c #FBDA18",
- "< c #8B7C0F",
- "[ c #B88203",
- "} c #FEBA08",
- "| c #E7B00A",
- "1 c #A17E09",
- "2 c #FCCE12",
- "3 c #E6C213",
- "4 c #96830E",
- "5 c #FBE11C",
- "6 c #786F0F",
- "7 c #CA9406",
- "8 c #FDC10B",
- "9 c #D8AA0C",
- "0 c #AE8E0C",
- "a c #FCD415",
- "b c #DBBF15",
- "c c #A09012",
- "d c #F9E61F",
- "e c #69650E",
- "f c #4B3702",
- "g c #DAA609",
- "h c #CAA50E",
- "i c #BB9D10",
- "j c #FCDB18",
- "k c #CEB817",
- "l c #AB9E15",
- "m c #F2E821",
- "n c #5E5C0E",
- "o c #503D03",
- "p c #E8B60D",
- "q c #CAAF13",
- "r c #C1B218",
- "s c #B6AE19",
- "t c #EAE625",
- "u c #575723",
- "v c #594605",
- "w c #F1C511",
- "x c #AB9510",
- "y c #D7C018",
- "z c #FBE81F",
- "A c #B3AC18",
- "B c #BCB81D",
- "C c #7F8051",
- "D c #645207",
- "E c #9D8C11",
- "F c #E4D31C",
- "G c #BEB62F",
- "H c #6C6A3F",
- "I c #E1E1E1",
- "J c #73610A",
- "K c #7C720F",
- "L c #A1A084",
- "M c #FFFFFF",
- "N c #565656",
- "O c #887921",
- "P c #988F44",
- "Q c #BFBEB7",
- "R c #EEEEEC",
- "S c #C0C0C0",
- "T c #323232",
- "U c #4D4B39",
- "V c #C7C7C7",
- "W c #FBFBFB",
- "X c #BFBFBF",
- "Y c #141414",
- "Z c #222222",
- "` c #303030",
- " . c #313131",
- ".. c #282828",
- "+. c #121212",
- "@. c #000000",
- " . ",
- " + @ # ",
- " $ % & * = ",
- " - ; > , ' ) ! ",
- "~ { ] ^ / ( _ : < ",
- " [ } | 1 2 3 4 5 6 ",
- " 7 8 9 0 a b c d e ",
- " f g / h i j k l m n ",
- " o p 2 i q 5 r s t u ",
- " v w a x y z A B C ",
- " D ) j E F G H I ",
- " J : 5 K L M M N ",
- " O P Q R M S T ",
- " U V W X Y Z ",
- " ` ...+.",
- " @.@.@.@.@.@.@.@. "};
- """
+ "the Draft Workbench"
+ Icon = """
+ /* XPM */
+ static char * draft_xpm[] = {
+ "14 16 96 2",
+ " c None",
+ ". c #584605",
+ "+ c #513E03",
+ "@ c #E6B50D",
+ "# c #C29F0E",
+ "$ c #6E5004",
+ "% c #F7BD0B",
+ "& c #8F7008",
+ "* c #F3C711",
+ "= c #B1950F",
+ "- c #785402",
+ "; c #946C05",
+ "> c #FABF0B",
+ ", c #F7C20E",
+ "' c #8D740A",
+ ") c #F8D115",
+ "! c #9F8A0F",
+ "~ c #593D00",
+ "{ c #FEB304",
+ "] c #F3B208",
+ "^ c #987407",
+ "/ c #FDC70E",
+ "( c #EFC311",
+ "_ c #8F790C",
+ ": c #FBDA18",
+ "< c #8B7C0F",
+ "[ c #B88203",
+ "} c #FEBA08",
+ "| c #E7B00A",
+ "1 c #A17E09",
+ "2 c #FCCE12",
+ "3 c #E6C213",
+ "4 c #96830E",
+ "5 c #FBE11C",
+ "6 c #786F0F",
+ "7 c #CA9406",
+ "8 c #FDC10B",
+ "9 c #D8AA0C",
+ "0 c #AE8E0C",
+ "a c #FCD415",
+ "b c #DBBF15",
+ "c c #A09012",
+ "d c #F9E61F",
+ "e c #69650E",
+ "f c #4B3702",
+ "g c #DAA609",
+ "h c #CAA50E",
+ "i c #BB9D10",
+ "j c #FCDB18",
+ "k c #CEB817",
+ "l c #AB9E15",
+ "m c #F2E821",
+ "n c #5E5C0E",
+ "o c #503D03",
+ "p c #E8B60D",
+ "q c #CAAF13",
+ "r c #C1B218",
+ "s c #B6AE19",
+ "t c #EAE625",
+ "u c #575723",
+ "v c #594605",
+ "w c #F1C511",
+ "x c #AB9510",
+ "y c #D7C018",
+ "z c #FBE81F",
+ "A c #B3AC18",
+ "B c #BCB81D",
+ "C c #7F8051",
+ "D c #645207",
+ "E c #9D8C11",
+ "F c #E4D31C",
+ "G c #BEB62F",
+ "H c #6C6A3F",
+ "I c #E1E1E1",
+ "J c #73610A",
+ "K c #7C720F",
+ "L c #A1A084",
+ "M c #FFFFFF",
+ "N c #565656",
+ "O c #887921",
+ "P c #988F44",
+ "Q c #BFBEB7",
+ "R c #EEEEEC",
+ "S c #C0C0C0",
+ "T c #323232",
+ "U c #4D4B39",
+ "V c #C7C7C7",
+ "W c #FBFBFB",
+ "X c #BFBFBF",
+ "Y c #141414",
+ "Z c #222222",
+ "` c #303030",
+ " . c #313131",
+ ".. c #282828",
+ "+. c #121212",
+ "@. c #000000",
+ " . ",
+ " + @ # ",
+ " $ % & * = ",
+ " - ; > , ' ) ! ",
+ "~ { ] ^ / ( _ : < ",
+ " [ } | 1 2 3 4 5 6 ",
+ " 7 8 9 0 a b c d e ",
+ " f g / h i j k l m n ",
+ " o p 2 i q 5 r s t u ",
+ " v w a x y z A B C ",
+ " D ) j E F G H I ",
+ " J : 5 K L M M N ",
+ " O P Q R M S T ",
+ " U V W X Y Z ",
+ " ` ...+.",
+ " @.@.@.@.@.@.@.@. "};
+ """
- MenuText = "Draft"
- ToolTip = "The Draft module is used for basic 2D CAD Drafting"
+ MenuText = "Draft"
+ ToolTip = "The Draft module is used for basic 2D CAD Drafting"
- def Initialize(self):
- # run self-tests
- depsOK = False
- try:
- from pivy import coin
- if FreeCADGui.getSoDBVersion() != coin.SoDB.getVersion():
- raise AssertionError("FreeCAD and Pivy use different versions of Coin. This will lead to unexpected behaviour.")
- except AssertionError:
- FreeCAD.Console.PrintWarning("Error: FreeCAD and Pivy use different versions of Coin. This will lead to unexpected behaviour.\n")
- except ImportError:
- FreeCAD.Console.PrintWarning("Error: Pivy not found, Draft workbench will be disabled.\n")
- except:
- FreeCAD.Console.PrintWarning("Error: Unknown error while trying to load Pivy\n")
- else:
- try:
- import PyQt4
- except ImportError:
- FreeCAD.Console.PrintWarning("Error: PyQt4 not found, Draft workbench will be disabled.\n")
- else:
- depsOK = True
+ def Initialize(self):
+ # run self-tests
+ depsOK = False
+ try:
+ from pivy import coin
+ if FreeCADGui.getSoDBVersion() != coin.SoDB.getVersion():
+ raise AssertionError("FreeCAD and Pivy use different versions of Coin. This will lead to unexpected behaviour.")
+ except AssertionError:
+ FreeCAD.Console.PrintWarning("Error: FreeCAD and Pivy use different versions of Coin. This will lead to unexpected behaviour.\n")
+ except ImportError:
+ FreeCAD.Console.PrintWarning("Error: Pivy not found, Draft workbench will be disabled.\n")
+ except:
+ FreeCAD.Console.PrintWarning("Error: Unknown error while trying to load Pivy\n")
+ else:
+ try:
+ import PyQt4
+ except ImportError:
+ FreeCAD.Console.PrintWarning("Error: PyQt4 not found, Draft workbench will be disabled.\n")
+ else:
+ depsOK = True
- if depsOK:
- import Draft_rc
- FreeCADGui.addLanguagePath(":/translations")
- FreeCADGui.addIconPath(":/icons")
- FreeCADGui.addPreferencePage(":/ui/userprefs-base.ui","Draft")
- FreeCADGui.addPreferencePage(":/ui/userprefs-import.ui","Draft")
- else:
- return
- Log ('Loading Draft GUI...\n')
- try:
- import draftTools,draftGui,macros
- self.appendMenu(["&Macro","Installed Macros"],macros.macrosList)
- except:
- pass
- self.cmdList = ["Draft_Line","Draft_Wire","Draft_Circle","Draft_Arc",
- "Draft_Polygon","Draft_Rectangle", "Draft_Text",
- "Draft_Dimension", "Draft_BSpline"]
- self.modList = ["Draft_Move","Draft_Rotate","Draft_Offset",
- "Draft_Trimex", "Draft_Upgrade", "Draft_Downgrade", "Draft_Scale",
- "Draft_Drawing","Draft_Edit","Draft_WireToBSpline","Draft_AddPoint",
- "Draft_DelPoint","Draft_Shape2DView"]
- self.treecmdList = ["Draft_ApplyStyle","Draft_ToggleDisplayMode","Draft_AddToGroup","Draft_SelectGroup"]
- self.lineList = ["Draft_UndoLine","Draft_FinishLine","Draft_CloseLine"]
- self.appendToolbar("Draft tools",self.cmdList+self.modList)
- self.appendMenu("Draft",self.cmdList+self.modList)
- self.appendMenu(["Draft","Display options"],self.treecmdList)
- self.appendMenu(["Draft","Wire tools"],self.lineList)
+ if depsOK:
+ import Draft_rc
+ FreeCADGui.addLanguagePath(":/translations")
+ FreeCADGui.addIconPath(":/icons")
+ FreeCADGui.addPreferencePage(":/ui/userprefs-base.ui","Draft")
+ FreeCADGui.addPreferencePage(":/ui/userprefs-import.ui","Draft")
+ else:
+ return
+ Log ('Loading Draft GUI...\n')
+ try:
+ import draftTools,draftGui,macros
+ self.appendMenu(["&Macro","Installed Macros"],macros.macrosList)
+ except:
+ pass
+ self.cmdList = ["Draft_Line","Draft_Wire","Draft_Circle","Draft_Arc",
+ "Draft_Polygon","Draft_Rectangle", "Draft_Text",
+ "Draft_Dimension", "Draft_BSpline"]
+ self.modList = ["Draft_Move","Draft_Rotate","Draft_Offset",
+ "Draft_Trimex", "Draft_Upgrade", "Draft_Downgrade", "Draft_Scale",
+ "Draft_Drawing","Draft_Edit","Draft_WireToBSpline","Draft_AddPoint",
+ "Draft_DelPoint","Draft_Shape2DView"]
+ self.treecmdList = ["Draft_ApplyStyle","Draft_ToggleDisplayMode","Draft_AddToGroup","Draft_SelectGroup"]
+ self.lineList = ["Draft_UndoLine","Draft_FinishLine","Draft_CloseLine"]
+ self.appendToolbar("Draft tools",self.cmdList+self.modList)
+ self.appendMenu("Draft",self.cmdList+self.modList)
+ self.appendMenu(["Draft","Display options"],self.treecmdList)
+ self.appendMenu(["Draft","Wire tools"],self.lineList)
- def Activated(self):
- FreeCADGui.draftToolBar.Activated()
+ def Activated(self):
+ FreeCADGui.draftToolBar.Activated()
- def Deactivated(self):
- FreeCADGui.draftToolBar.Deactivated()
+ def Deactivated(self):
+ FreeCADGui.draftToolBar.Deactivated()
- def ContextMenu(self, recipient):
- if (recipient == "View"):
- if (FreeCAD.activeDraftCommand == None):
- if (FreeCADGui.Selection.getSelection() != []):
- self.appendContextMenu("Draft",self.cmdList+self.modList)
- self.appendContextMenu("Display options",self.treecmdList)
- else:
- self.appendContextMenu("Draft",self.cmdList)
- else:
- if (FreeCAD.activeDraftCommand.featureName == "Line"):
- self.appendContextMenu("",self.lineList)
+ def ContextMenu(self, recipient):
+ if (recipient == "View"):
+ if (FreeCAD.activeDraftCommand == None):
+ if (FreeCADGui.Selection.getSelection() != []):
+ self.appendContextMenu("Draft",self.cmdList+self.modList)
+ self.appendContextMenu("Display options",self.treecmdList)
else:
- if (FreeCADGui.Selection.getSelection() != []):
- self.appendContextMenu("Display options",self.treecmdList)
+ self.appendContextMenu("Draft",self.cmdList)
+ else:
+ if (FreeCAD.activeDraftCommand.featureName == "Line"):
+ self.appendContextMenu("",self.lineList)
+ else:
+ if (FreeCADGui.Selection.getSelection() != []):
+ self.appendContextMenu("Display options",self.treecmdList)
- def GetClassName(self):
- return "Gui::PythonWorkbench"
+ def GetClassName(self):
+ return "Gui::PythonWorkbench"
FreeCADGui.addWorkbench(DraftWorkbench)
App.addImportType("Autodesk DXF (*.dxf)","importDXF")
diff --git a/src/Mod/Draft/draftGui.py b/src/Mod/Draft/draftGui.py
index e366af55a0..c809987198 100644
--- a/src/Mod/Draft/draftGui.py
+++ b/src/Mod/Draft/draftGui.py
@@ -33,63 +33,63 @@ Report to Draft.py for info
import FreeCAD, FreeCADGui, os, Draft
try:
- from PyQt4 import QtCore,QtGui,QtSvg
+ from PyQt4 import QtCore,QtGui,QtSvg
except:
- FreeCAD.Console.PrintMessage("Error: Python-qt4 package must be installed on your system to use the Draft module.")
+ FreeCAD.Console.PrintMessage("Error: Python-qt4 package must be installed on your system to use the Draft module.")
def getMainWindow():
- "returns the main window"
- # using QtGui.qApp.activeWindow() isn't very reliable because if another
- # widget than the mainwindow is active (e.g. a dialog) the wrong widget is
- # returned
- toplevel = QtGui.qApp.topLevelWidgets()
- for i in toplevel:
- if i.metaObject().className() == "Gui::MainWindow":
- return i
- raise Exception("No main window found")
+ "returns the main window"
+ # using QtGui.qApp.activeWindow() isn't very reliable because if another
+ # widget than the mainwindow is active (e.g. a dialog) the wrong widget is
+ # returned
+ toplevel = QtGui.qApp.topLevelWidgets()
+ for i in toplevel:
+ if i.metaObject().className() == "Gui::MainWindow":
+ return i
+ raise Exception("No main window found")
class todo:
- ''' static todo class, delays execution of functions. Use todo.delay
- to schedule geometry manipulation that would crash coin if done in the
- event callback'''
+ ''' static todo class, delays execution of functions. Use todo.delay
+ to schedule geometry manipulation that would crash coin if done in the
+ event callback'''
- '''List of (function, argument) pairs to be executed by
- QtCore.QTimer.singleShot(0,doTodo).'''
- itinerary = []
- commitlist = []
+ '''List of (function, argument) pairs to be executed by
+ QtCore.QTimer.singleShot(0,doTodo).'''
+ itinerary = []
+ commitlist = []
+
+ @staticmethod
+ def doTasks():
+ # print "debug: doing delayed tasks: commitlist: ",todo.commitlist," itinerary: ",todo.itinerary
+ for f, arg in todo.itinerary:
+ try:
+ # print "debug: executing",f
+ f(arg)
+ except:
+ wrn = "[Draft.todo] Unexpected error:" + sys.exc_info()[0]
+ FreeCAD.Console.PrintWarning (wrn)
+ todo.itinerary = []
+ if todo.commitlist:
+ for name,func in todo.commitlist:
+ # print "debug: committing ",str(name)
+ name = str(name)
+ FreeCAD.ActiveDocument.openTransaction(name)
+ func()
+ FreeCAD.ActiveDocument.commitTransaction()
+ todo.commitlist = []
- @staticmethod
- def doTasks():
- # print "debug: doing delayed tasks: commitlist: ",todo.commitlist," itinerary: ",todo.itinerary
- for f, arg in todo.itinerary:
- try:
- # print "debug: executing",f
- f(arg)
- except:
- wrn = "[Draft.todo] Unexpected error:" + sys.exc_info()[0]
- FreeCAD.Console.PrintWarning (wrn)
- todo.itinerary = []
- if todo.commitlist:
- for name,func in todo.commitlist:
- # print "debug: committing ",str(name)
- name = str(name)
- FreeCAD.ActiveDocument.openTransaction(name)
- func()
- FreeCAD.ActiveDocument.commitTransaction()
- todo.commitlist = []
+ @staticmethod
+ def delay (f, arg):
+ # print "debug: delaying",f
+ if todo.itinerary == []:
+ QtCore.QTimer.singleShot(0, todo.doTasks)
+ todo.itinerary.append((f,arg))
- @staticmethod
- def delay (f, arg):
- # print "debug: delaying",f
- if todo.itinerary == []:
- QtCore.QTimer.singleShot(0, todo.doTasks)
- todo.itinerary.append((f,arg))
-
- @staticmethod
- def delayCommit (cl):
- # print "debug: delaying commit",cl
- QtCore.QTimer.singleShot(0, todo.doTasks)
- todo.commitlist = cl
+ @staticmethod
+ def delayCommit (cl):
+ # print "debug: delaying commit",cl
+ QtCore.QTimer.singleShot(0, todo.doTasks)
+ todo.commitlist = cl
def translate(context,text):
"convenience function for Qt translator"
@@ -101,955 +101,954 @@ def translate(context,text):
#---------------------------------------------------------------------------
class DraftDockWidget(QtGui.QWidget):
- "custom Widget that emits a resized() signal when resized"
- def __init__(self,parent = None):
- QtGui.QDockWidget.__init__(self,parent)
- def resizeEvent(self,event):
- self.emit(QtCore.SIGNAL("resized()"))
- def changeEvent(self, event):
- if event.type() == QtCore.QEvent.LanguageChange:
- self.emit(QtCore.SIGNAL("retranslate()"))
- else:
- QtGui.QWidget.changeEvent(self,event)
+ "custom Widget that emits a resized() signal when resized"
+ def __init__(self,parent = None):
+ QtGui.QDockWidget.__init__(self,parent)
+ def resizeEvent(self,event):
+ self.emit(QtCore.SIGNAL("resized()"))
+ def changeEvent(self, event):
+ if event.type() == QtCore.QEvent.LanguageChange:
+ self.emit(QtCore.SIGNAL("retranslate()"))
+ else:
+ QtGui.QWidget.changeEvent(self,event)
class DraftLineEdit(QtGui.QLineEdit):
- "custom QLineEdit widget that has the power to catch Escape keypress"
- def __init__(self, parent=None):
- QtGui.QLineEdit.__init__(self, parent)
- def keyPressEvent(self, event):
- if event.key() == QtCore.Qt.Key_Escape:
- self.emit(QtCore.SIGNAL("escaped()"))
- elif event.key() == QtCore.Qt.Key_Up:
- self.emit(QtCore.SIGNAL("up()"))
- elif event.key() == QtCore.Qt.Key_Down:
- self.emit(QtCore.SIGNAL("down()"))
- elif (event.key() == QtCore.Qt.Key_Z) and QtCore.Qt.ControlModifier:
- self.emit(QtCore.SIGNAL("undo()"))
- else:
- QtGui.QLineEdit.keyPressEvent(self, event)
+ "custom QLineEdit widget that has the power to catch Escape keypress"
+ def __init__(self, parent=None):
+ QtGui.QLineEdit.__init__(self, parent)
+ def keyPressEvent(self, event):
+ if event.key() == QtCore.Qt.Key_Escape:
+ self.emit(QtCore.SIGNAL("escaped()"))
+ elif event.key() == QtCore.Qt.Key_Up:
+ self.emit(QtCore.SIGNAL("up()"))
+ elif event.key() == QtCore.Qt.Key_Down:
+ self.emit(QtCore.SIGNAL("down()"))
+ elif (event.key() == QtCore.Qt.Key_Z) and QtCore.Qt.ControlModifier:
+ self.emit(QtCore.SIGNAL("undo()"))
+ else:
+ QtGui.QLineEdit.keyPressEvent(self, event)
class DraftTaskPanel:
def __init__(self,widget):
- self.form = widget
+ self.form = widget
def accept(self):
- if FreeCAD.activeDraftCommand:
- FreeCAD.activeDraftCommand.finish()
- return True
+ if FreeCAD.activeDraftCommand:
+ FreeCAD.activeDraftCommand.finish()
+ return True
def reject(self):
- if FreeCAD.activeDraftCommand:
- FreeCAD.activeDraftCommand.finish()
- return True
+ if FreeCAD.activeDraftCommand:
+ FreeCAD.activeDraftCommand.finish()
+ return True
class DraftToolBar:
- "main draft Toolbar"
- def __init__(self):
- self.tray = None
- self.sourceCmd = None
- self.taskmode = Draft.getParam("UiMode")
- self.paramcolor = Draft.getParam("color")>>8
- self.color = QtGui.QColor(self.paramcolor)
- self.facecolor = QtGui.QColor(204,204,204)
- self.linewidth = Draft.getParam("linewidth")
- self.fontsize = Draft.getParam("textheight")
- self.paramconstr = Draft.getParam("constructioncolor")>>8
- self.constrMode = False
- self.continueMode = False
- self.state = None
- self.textbuffer = []
- self.crossedViews = []
-
- if self.taskmode:
- # only a dummy widget, since widgets are created on demand
- self.baseWidget = QtGui.QWidget()
- else:
- # create the draft Toolbar
- self.draftWidget = QtGui.QDockWidget()
- self.baseWidget = DraftDockWidget()
- self.draftWidget.setObjectName("draftToolbar")
- self.draftWidget.setTitleBarWidget(self.baseWidget)
- self.draftWidget.setWindowTitle(translate("draft", "draft Command Bar"))
- self.mw = getMainWindow()
- self.mw.addDockWidget(QtCore.Qt.TopDockWidgetArea,self.draftWidget)
- self.draftWidget.setVisible(False)
- self.draftWidget.toggleViewAction().setVisible(False)
- self.mw = getMainWindow()
- self.baseWidget.setObjectName("draftToolbar")
- self.layout = QtGui.QHBoxLayout(self.baseWidget)
- self.layout.setObjectName("layout")
- self.toptray = self.layout
- self.bottomtray = self.layout
- self.setupToolBar()
- self.setupTray()
- self.setupStyle()
- self.retranslateUi(self.baseWidget)
+ "main draft Toolbar"
+ def __init__(self):
+ self.tray = None
+ self.sourceCmd = None
+ self.taskmode = Draft.getParam("UiMode")
+ self.paramcolor = Draft.getParam("color")>>8
+ self.color = QtGui.QColor(self.paramcolor)
+ self.facecolor = QtGui.QColor(204,204,204)
+ self.linewidth = Draft.getParam("linewidth")
+ self.fontsize = Draft.getParam("textheight")
+ self.paramconstr = Draft.getParam("constructioncolor")>>8
+ self.constrMode = False
+ self.continueMode = False
+ self.state = None
+ self.textbuffer = []
+ self.crossedViews = []
+
+ if self.taskmode:
+ # only a dummy widget, since widgets are created on demand
+ self.baseWidget = QtGui.QWidget()
+ else:
+ # create the draft Toolbar
+ self.draftWidget = QtGui.QDockWidget()
+ self.baseWidget = DraftDockWidget()
+ self.draftWidget.setObjectName("draftToolbar")
+ self.draftWidget.setTitleBarWidget(self.baseWidget)
+ self.draftWidget.setWindowTitle(translate("draft", "draft Command Bar"))
+ self.mw = getMainWindow()
+ self.mw.addDockWidget(QtCore.Qt.TopDockWidgetArea,self.draftWidget)
+ self.draftWidget.setVisible(False)
+ self.draftWidget.toggleViewAction().setVisible(False)
+ self.mw = getMainWindow()
+ self.baseWidget.setObjectName("draftToolbar")
+ self.layout = QtGui.QHBoxLayout(self.baseWidget)
+ self.layout.setObjectName("layout")
+ self.toptray = self.layout
+ self.bottomtray = self.layout
+ self.setupToolBar()
+ self.setupTray()
+ self.setupStyle()
+ self.retranslateUi(self.baseWidget)
#---------------------------------------------------------------------------
# General UI setup
#---------------------------------------------------------------------------
- def _pushbutton (self,name, layout, hide=True, icon=None, width=66, checkable=False):
- button = QtGui.QPushButton(self.baseWidget)
- button.setObjectName(name)
- button.setMaximumSize(QtCore.QSize(width,26))
- if hide:
- button.hide()
- if icon:
- button.setIcon(QtGui.QIcon(':/icons/'+icon+'.svg'))
- button.setIconSize(QtCore.QSize(16, 16))
- if checkable:
- button.setCheckable(True)
- button.setChecked(False)
- layout.addWidget(button)
- return button
+ def _pushbutton (self,name, layout, hide=True, icon=None, width=66, checkable=False):
+ button = QtGui.QPushButton(self.baseWidget)
+ button.setObjectName(name)
+ button.setMaximumSize(QtCore.QSize(width,26))
+ if hide:
+ button.hide()
+ if icon:
+ button.setIcon(QtGui.QIcon(':/icons/'+icon+'.svg'))
+ button.setIconSize(QtCore.QSize(16, 16))
+ if checkable:
+ button.setCheckable(True)
+ button.setChecked(False)
+ layout.addWidget(button)
+ return button
- def _label (self,name, layout, hide=True):
- label = QtGui.QLabel(self.baseWidget)
- label.setObjectName(name)
- if hide: label.hide()
- layout.addWidget(label)
- return label
+ def _label (self,name, layout, hide=True):
+ label = QtGui.QLabel(self.baseWidget)
+ label.setObjectName(name)
+ if hide: label.hide()
+ layout.addWidget(label)
+ return label
- def _lineedit (self,name, layout, hide=True, width=None):
- lineedit = DraftLineEdit(self.baseWidget)
- lineedit.setObjectName(name)
- if hide: lineedit.hide()
- if not width: width = 800
- lineedit.setMaximumSize(QtCore.QSize(width,22))
- layout.addWidget(lineedit)
- return lineedit
+ def _lineedit (self,name, layout, hide=True, width=None):
+ lineedit = DraftLineEdit(self.baseWidget)
+ lineedit.setObjectName(name)
+ if hide: lineedit.hide()
+ if not width: width = 800
+ lineedit.setMaximumSize(QtCore.QSize(width,22))
+ layout.addWidget(lineedit)
+ return lineedit
- def _spinbox (self,name, layout, val=None, vmax=None, hide=True, double=False, size=None):
- if double:
- sbox = QtGui.QDoubleSpinBox(self.baseWidget)
- sbox.setDecimals(2)
- else:
- sbox = QtGui.QSpinBox(self.baseWidget)
- sbox.setObjectName(name)
- if val: sbox.setValue(val)
- if vmax: sbox.setMaximum(vmax)
- if size: sbox.setMaximumSize(QtCore.QSize(size[0],size[1]))
- if hide: sbox.hide()
- layout.addWidget(sbox)
- return sbox
+ def _spinbox (self,name, layout, val=None, vmax=None, hide=True, double=False, size=None):
+ if double:
+ sbox = QtGui.QDoubleSpinBox(self.baseWidget)
+ sbox.setDecimals(2)
+ else:
+ sbox = QtGui.QSpinBox(self.baseWidget)
+ sbox.setObjectName(name)
+ if val: sbox.setValue(val)
+ if vmax: sbox.setMaximum(vmax)
+ if size: sbox.setMaximumSize(QtCore.QSize(size[0],size[1]))
+ if hide: sbox.hide()
+ layout.addWidget(sbox)
+ return sbox
- def _checkbox (self,name, layout, checked=True, hide=True):
- chk = QtGui.QCheckBox(self.baseWidget)
- chk.setChecked(checked)
- chk.setObjectName(name)
- if hide: chk.hide()
- layout.addWidget(chk)
- return chk
+ def _checkbox (self,name, layout, checked=True, hide=True):
+ chk = QtGui.QCheckBox(self.baseWidget)
+ chk.setChecked(checked)
+ chk.setObjectName(name)
+ if hide: chk.hide()
+ layout.addWidget(chk)
+ return chk
- def setupToolBar(self,task=False):
- "sets the draft toolbar up"
+ def setupToolBar(self,task=False):
+ "sets the draft toolbar up"
+
+ # command
- # command
+ self.promptlabel = self._label("promptlabel", self.layout, hide=task)
+ self.cmdlabel = self._label("cmdlabel", self.layout, hide=task)
+ boldtxt = QtGui.QFont()
+ boldtxt.setWeight(75)
+ boldtxt.setBold(True)
+ self.cmdlabel.setFont(boldtxt)
- self.promptlabel = self._label("promptlabel", self.layout, hide=task)
- self.cmdlabel = self._label("cmdlabel", self.layout, hide=task)
- boldtxt = QtGui.QFont()
- boldtxt.setWeight(75)
- boldtxt.setBold(True)
- self.cmdlabel.setFont(boldtxt)
+ # subcommands
- # subcommands
+ self.addButton = self._pushbutton("addButton", self.layout, icon="Draft_AddPoint", width=22, checkable=True)
+ self.delButton = self._pushbutton("delButton", self.layout, icon="Draft_DelPoint", width=22, checkable=True)
- self.addButton = self._pushbutton("addButton", self.layout, icon="Draft_AddPoint", width=22, checkable=True)
- self.delButton = self._pushbutton("delButton", self.layout, icon="Draft_DelPoint", width=22, checkable=True)
+ # point
- # point
+ xl = QtGui.QHBoxLayout()
+ yl = QtGui.QHBoxLayout()
+ zl = QtGui.QHBoxLayout()
+ self.layout.addLayout(xl)
+ self.layout.addLayout(yl)
+ self.layout.addLayout(zl)
+ self.labelx = self._label("labelx", xl)
+ self.xValue = self._lineedit("xValue", xl, width=60)
+ self.xValue.setText("0.00")
+ self.labely = self._label("labely", yl)
+ self.yValue = self._lineedit("yValue", yl, width=60)
+ self.yValue.setText("0.00")
+ self.labelz = self._label("labelz", zl)
+ self.zValue = self._lineedit("zValue", zl, width=60)
+ self.zValue.setText("0.00")
+ self.textValue = self._lineedit("textValue", self.layout)
- xl = QtGui.QHBoxLayout()
- yl = QtGui.QHBoxLayout()
- zl = QtGui.QHBoxLayout()
- self.layout.addLayout(xl)
- self.layout.addLayout(yl)
- self.layout.addLayout(zl)
- self.labelx = self._label("labelx", xl)
- self.xValue = self._lineedit("xValue", xl, width=60)
- self.xValue.setText("0.00")
- self.labely = self._label("labely", yl)
- self.yValue = self._lineedit("yValue", yl, width=60)
- self.yValue.setText("0.00")
- self.labelz = self._label("labelz", zl)
- self.zValue = self._lineedit("zValue", zl, width=60)
- self.zValue.setText("0.00")
- self.textValue = self._lineedit("textValue", self.layout)
+ # options
- # options
+ self.numFaces = self._spinbox("numFaces", self.layout, 3)
+ self.offsetLabel = self._label("offsetlabel", self.layout)
+ self.offsetValue = self._lineedit("offsetValue", self.layout, width=60)
+ self.offsetValue.setText("0.00")
+ self.labelRadius = self._label("labelRadius", self.layout)
+ self.radiusValue = self._lineedit("radiusValue", self.layout, width=60)
+ self.radiusValue.setText("0.00")
+ self.isRelative = self._checkbox("isRelative",self.layout,checked=True)
+ self.hasFill = self._checkbox("hasFill",self.layout,checked=Draft.getParam("fillmode"))
+ self.continueCmd = self._checkbox("continueCmd",self.layout,checked=False)
+ self.occOffset = self._checkbox("occOffset",self.layout,checked=False)
+ self.undoButton = self._pushbutton("undoButton", self.layout, icon='Draft_Rotate')
+ self.finishButton = self._pushbutton("finishButton", self.layout, icon='Draft_Finish')
+ self.closeButton = self._pushbutton("closeButton", self.layout, icon='Draft_Lock')
+ self.wipeButton = self._pushbutton("wipeButton", self.layout, icon='Draft_Wipe')
+ self.xyButton = self._pushbutton("xyButton", self.layout)
+ self.xzButton = self._pushbutton("xzButton", self.layout)
+ self.yzButton = self._pushbutton("yzButton", self.layout)
+ self.currentViewButton = self._pushbutton("view", self.layout)
+ self.resetPlaneButton = self._pushbutton("none", self.layout)
+ self.isCopy = self._checkbox("isCopy",self.layout,checked=False)
- self.numFaces = self._spinbox("numFaces", self.layout, 3)
- self.offsetLabel = self._label("offsetlabel", self.layout)
- self.offsetValue = self._lineedit("offsetValue", self.layout, width=60)
- self.offsetValue.setText("0.00")
- self.labelRadius = self._label("labelRadius", self.layout)
- self.radiusValue = self._lineedit("radiusValue", self.layout, width=60)
- self.radiusValue.setText("0.00")
- self.isRelative = self._checkbox("isRelative",self.layout,checked=True)
- self.hasFill = self._checkbox("hasFill",self.layout,checked=Draft.getParam("fillmode"))
- self.continueCmd = self._checkbox("continueCmd",self.layout,checked=False)
- self.occOffset = self._checkbox("occOffset",self.layout,checked=False)
- self.undoButton = self._pushbutton("undoButton", self.layout, icon='Draft_Rotate')
- self.finishButton = self._pushbutton("finishButton", self.layout, icon='Draft_Finish')
- self.closeButton = self._pushbutton("closeButton", self.layout, icon='Draft_Lock')
- self.wipeButton = self._pushbutton("wipeButton", self.layout, icon='Draft_Wipe')
- self.xyButton = self._pushbutton("xyButton", self.layout)
- self.xzButton = self._pushbutton("xzButton", self.layout)
- self.yzButton = self._pushbutton("yzButton", self.layout)
- self.currentViewButton = self._pushbutton("view", self.layout)
- self.resetPlaneButton = self._pushbutton("none", self.layout)
- self.isCopy = self._checkbox("isCopy",self.layout,checked=False)
+ # spacer
- # spacer
+ spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding,
+ QtGui.QSizePolicy.Minimum)
+ self.layout.addItem(spacerItem)
+
+ QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("returnPressed()"),self.checkx)
+ QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("returnPressed()"),self.checky)
+ QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
+ QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
+ QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
+ QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
+ QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
+ QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
+ QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("returnPressed()"),self.sendText)
+ QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("escaped()"),self.finish)
+ QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("down()"),self.sendText)
+ QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("up()"),self.lineUp)
+ QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("returnPressed()"),self.xValue.setFocus)
+ QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("returnPressed()"),self.xValue.selectAll)
+ QtCore.QObject.connect(self.offsetValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
+ QtCore.QObject.connect(self.offsetValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
+ QtCore.QObject.connect(self.addButton,QtCore.SIGNAL("toggled(bool)"),self.setAddMode)
+ QtCore.QObject.connect(self.delButton,QtCore.SIGNAL("toggled(bool)"),self.setDelMode)
+ QtCore.QObject.connect(self.finishButton,QtCore.SIGNAL("pressed()"),self.finish)
+ QtCore.QObject.connect(self.closeButton,QtCore.SIGNAL("pressed()"),self.closeLine)
+ QtCore.QObject.connect(self.wipeButton,QtCore.SIGNAL("pressed()"),self.wipeLine)
+ QtCore.QObject.connect(self.undoButton,QtCore.SIGNAL("pressed()"),self.undoSegment)
+ QtCore.QObject.connect(self.xyButton,QtCore.SIGNAL("clicked()"),self.selectXY)
+ QtCore.QObject.connect(self.xzButton,QtCore.SIGNAL("clicked()"),self.selectXZ)
+ QtCore.QObject.connect(self.yzButton,QtCore.SIGNAL("clicked()"),self.selectYZ)
+ QtCore.QObject.connect(self.continueCmd,QtCore.SIGNAL("stateChanged(int)"),self.setContinue)
+ QtCore.QObject.connect(self.currentViewButton,QtCore.SIGNAL("clicked()"),self.selectCurrentView)
+ QtCore.QObject.connect(self.resetPlaneButton,QtCore.SIGNAL("clicked()"),self.selectResetPlane)
+ QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("escaped()"),self.finish)
+ QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("undo()"),self.undoSegment)
+ QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("escaped()"),self.finish)
+ QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("undo()"),self.undoSegment)
+ QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("escaped()"),self.finish)
+ QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("undo()"),self.undoSegment)
+ QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("escaped()"),self.finish)
+ QtCore.QObject.connect(self.baseWidget,QtCore.SIGNAL("resized()"),self.relocate)
+ QtCore.QObject.connect(self.baseWidget,QtCore.SIGNAL("retranslate()"),self.retranslateUi)
- spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding,
- QtGui.QSizePolicy.Minimum)
- self.layout.addItem(spacerItem)
+ def setupTray(self):
+ "sets draft tray buttons up"
- QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("returnPressed()"),self.checkx)
- QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("returnPressed()"),self.checky)
- QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
- QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
- QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
- QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
- QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
- QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
- QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("returnPressed()"),self.sendText)
- QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("escaped()"),self.finish)
- QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("down()"),self.sendText)
- QtCore.QObject.connect(self.textValue,QtCore.SIGNAL("up()"),self.lineUp)
- QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("returnPressed()"),self.xValue.setFocus)
- QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("returnPressed()"),self.xValue.selectAll)
- QtCore.QObject.connect(self.offsetValue,QtCore.SIGNAL("textEdited(QString)"),self.checkSpecialChars)
- QtCore.QObject.connect(self.offsetValue,QtCore.SIGNAL("returnPressed()"),self.validatePoint)
- QtCore.QObject.connect(self.addButton,QtCore.SIGNAL("toggled(bool)"),self.setAddMode)
- QtCore.QObject.connect(self.delButton,QtCore.SIGNAL("toggled(bool)"),self.setDelMode)
- QtCore.QObject.connect(self.finishButton,QtCore.SIGNAL("pressed()"),self.finish)
- QtCore.QObject.connect(self.closeButton,QtCore.SIGNAL("pressed()"),self.closeLine)
- QtCore.QObject.connect(self.wipeButton,QtCore.SIGNAL("pressed()"),self.wipeLine)
- QtCore.QObject.connect(self.undoButton,QtCore.SIGNAL("pressed()"),self.undoSegment)
- QtCore.QObject.connect(self.xyButton,QtCore.SIGNAL("clicked()"),self.selectXY)
- QtCore.QObject.connect(self.xzButton,QtCore.SIGNAL("clicked()"),self.selectXZ)
- QtCore.QObject.connect(self.yzButton,QtCore.SIGNAL("clicked()"),self.selectYZ)
- QtCore.QObject.connect(self.continueCmd,QtCore.SIGNAL("stateChanged(int)"),self.setContinue)
- QtCore.QObject.connect(self.currentViewButton,QtCore.SIGNAL("clicked()"),self.selectCurrentView)
- QtCore.QObject.connect(self.resetPlaneButton,QtCore.SIGNAL("clicked()"),self.selectResetPlane)
- QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("escaped()"),self.finish)
- QtCore.QObject.connect(self.xValue,QtCore.SIGNAL("undo()"),self.undoSegment)
- QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("escaped()"),self.finish)
- QtCore.QObject.connect(self.yValue,QtCore.SIGNAL("undo()"),self.undoSegment)
- QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("escaped()"),self.finish)
- QtCore.QObject.connect(self.zValue,QtCore.SIGNAL("undo()"),self.undoSegment)
- QtCore.QObject.connect(self.radiusValue,QtCore.SIGNAL("escaped()"),self.finish)
- QtCore.QObject.connect(self.baseWidget,QtCore.SIGNAL("resized()"),self.relocate)
- QtCore.QObject.connect(self.baseWidget,QtCore.SIGNAL("retranslate()"),self.retranslateUi)
+ self.wplabel = self._pushbutton("wplabel", self.toptray, icon='Draft_SelectPlane',hide=False,width=120)
+ defaultWP = Draft.getParam("defaultWP")
+ if defaultWP == 1:
+ self.wplabel.setText("Top")
+ elif defaultWP == 2:
+ self.wplabel.setText("Front")
+ elif defaultWP == 3:
+ self.wplabel.setText("Side")
+ else:
+ self.wplabel.setText("None")
+ self.constrButton = self._pushbutton("constrButton", self.toptray, hide=False, icon='Draft_Construction',width=22, checkable=True)
+ self.constrColor = QtGui.QColor(self.paramconstr)
+ self.colorButton = self._pushbutton("colorButton",self.bottomtray, hide=False,width=22)
+ self.colorPix = QtGui.QPixmap(16,16)
+ self.colorPix.fill(self.color)
+ self.colorButton.setIcon(QtGui.QIcon(self.colorPix))
+ self.facecolorButton = self._pushbutton("facecolorButton",self.bottomtray, hide=False,width=22)
+ self.facecolorPix = QtGui.QPixmap(16,16)
+ self.facecolorPix.fill(self.facecolor)
+ self.facecolorButton.setIcon(QtGui.QIcon(self.facecolorPix))
+ self.widthButton = self._spinbox("widthButton", self.bottomtray, val=self.linewidth,hide=False,size=(50,22))
+ self.widthButton.setSuffix("px")
+ self.fontsizeButton = self._spinbox("fontsizeButton",self.bottomtray, val=self.fontsize,hide=False,double=True,size=(50,22))
+ self.applyButton = self._pushbutton("applyButton", self.toptray, hide=False, icon='Draft_Apply',width=22)
- def setupTray(self):
- "sets draft tray buttons up"
+ QtCore.QObject.connect(self.wplabel,QtCore.SIGNAL("pressed()"),self.selectplane)
+ QtCore.QObject.connect(self.colorButton,QtCore.SIGNAL("pressed()"),self.getcol)
+ QtCore.QObject.connect(self.facecolorButton,QtCore.SIGNAL("pressed()"),self.getfacecol)
+ QtCore.QObject.connect(self.widthButton,QtCore.SIGNAL("valueChanged(int)"),self.setwidth)
+ QtCore.QObject.connect(self.fontsizeButton,QtCore.SIGNAL("valueChanged(double)"),self.setfontsize)
+ QtCore.QObject.connect(self.applyButton,QtCore.SIGNAL("pressed()"),self.apply)
+ QtCore.QObject.connect(self.constrButton,QtCore.SIGNAL("toggled(bool)"),self.toggleConstrMode)
- self.wplabel = self._pushbutton("wplabel", self.toptray, icon='Draft_SelectPlane',hide=False,width=120)
- defaultWP = Draft.getParam("defaultWP")
- if defaultWP == 1:
- self.wplabel.setText("Top")
- elif defaultWP == 2:
- self.wplabel.setText("Front")
- elif defaultWP == 3:
- self.wplabel.setText("Side")
- else:
- self.wplabel.setText("None")
- self.constrButton = self._pushbutton("constrButton", self.toptray, hide=False, icon='Draft_Construction',width=22, checkable=True)
- self.constrColor = QtGui.QColor(self.paramconstr)
- self.colorButton = self._pushbutton("colorButton",self.bottomtray, hide=False,width=22)
- self.colorPix = QtGui.QPixmap(16,16)
- self.colorPix.fill(self.color)
- self.colorButton.setIcon(QtGui.QIcon(self.colorPix))
- self.facecolorButton = self._pushbutton("facecolorButton",self.bottomtray, hide=False,width=22)
- self.facecolorPix = QtGui.QPixmap(16,16)
- self.facecolorPix.fill(self.facecolor)
- self.facecolorButton.setIcon(QtGui.QIcon(self.facecolorPix))
- self.widthButton = self._spinbox("widthButton", self.bottomtray, val=self.linewidth,hide=False,size=(50,22))
- self.widthButton.setSuffix("px")
- self.fontsizeButton = self._spinbox("fontsizeButton",self.bottomtray, val=self.fontsize,hide=False,double=True,size=(50,22))
- self.applyButton = self._pushbutton("applyButton", self.toptray, hide=False, icon='Draft_Apply',width=22)
-
- QtCore.QObject.connect(self.wplabel,QtCore.SIGNAL("pressed()"),self.selectplane)
- QtCore.QObject.connect(self.colorButton,QtCore.SIGNAL("pressed()"),self.getcol)
- QtCore.QObject.connect(self.facecolorButton,QtCore.SIGNAL("pressed()"),self.getfacecol)
- QtCore.QObject.connect(self.widthButton,QtCore.SIGNAL("valueChanged(int)"),self.setwidth)
- QtCore.QObject.connect(self.fontsizeButton,QtCore.SIGNAL("valueChanged(double)"),self.setfontsize)
- QtCore.QObject.connect(self.applyButton,QtCore.SIGNAL("pressed()"),self.apply)
- QtCore.QObject.connect(self.constrButton,QtCore.SIGNAL("toggled(bool)"),self.toggleConstrMode)
-
- def setupStyle(self):
- style = "#constrButton:Checked {background-color: "
- style += self.getDefaultColor("constr",rgb=True)+" } "
- style += "#addButton:Checked, #delButton:checked {"
- style += "background-color: rgb(20,100,250) }"
- self.baseWidget.setStyleSheet(style)
+ def setupStyle(self):
+ style = "#constrButton:Checked {background-color: "
+ style += self.getDefaultColor("constr",rgb=True)+" } "
+ style += "#addButton:Checked, #delButton:checked {"
+ style += "background-color: rgb(20,100,250) }"
+ self.baseWidget.setStyleSheet(style)
#---------------------------------------------------------------------------
# language tools
#---------------------------------------------------------------------------
- def retranslateUi(self, widget=None):
- self.promptlabel.setText(translate("draft", "active command:"))
- self.cmdlabel.setText(translate("draft", "None"))
- self.cmdlabel.setToolTip(translate("draft", "Active Draft command"))
- self.xValue.setToolTip(translate("draft", "X coordinate of next point"))
- self.labelx.setText(translate("draft", "X"))
- self.labely.setText(translate("draft", "Y"))
- self.labelz.setText(translate("draft", "Z"))
- self.yValue.setToolTip(translate("draft", "Y coordinate of next point"))
- self.zValue.setToolTip(translate("draft", "Z coordinate of next point"))
- self.labelRadius.setText(translate("draft", "Radius"))
- self.radiusValue.setToolTip(translate("draft", "Radius of Circle"))
- self.isRelative.setText(translate("draft", "&Relative"))
- self.isRelative.setToolTip(translate("draft", "Coordinates relative to last point or absolute (SPACE)"))
- self.hasFill.setText(translate("draft", "F&illed"))
- self.hasFill.setToolTip(translate("draft", "Check this if the object should appear as filled, otherwise it will appear as wireframe (i)"))
- self.finishButton.setText(translate("draft", "&Finish"))
- self.finishButton.setToolTip(translate("draft", "Finishes the current drawing or editing operation (F)"))
- self.continueCmd.setToolTip(translate("draft", "If checked, command will not finish until you press the command button again"))
- self.continueCmd.setText(translate("draft", "&Continue"))
- self.occOffset.setToolTip(translate("draft", "If checked, an OCC-style offset will be performed instead of the classic offset"))
- self.occOffset.setText(translate("draft", "&OCC-style offset"))
- self.addButton.setToolTip(translate("draft", "Add points to the current object"))
- self.delButton.setToolTip(translate("draft", "Remove points from the current object"))
- self.undoButton.setText(translate("draft", "&Undo"))
- self.undoButton.setToolTip(translate("draft", "Undo the last segment (CTRL+Z)"))
- self.closeButton.setText(translate("draft", "&Close"))
- self.closeButton.setToolTip(translate("draft", "Finishes and closes the current line (C)"))
- self.wipeButton.setText(translate("draft", "&Wipe"))
- self.wipeButton.setToolTip(translate("draft", "Wipes the existing segments of this line and starts again from the last point (W)"))
- self.numFaces.setToolTip(translate("draft", "Number of sides"))
- self.offsetLabel.setText(translate("draft", "Offset"))
- self.xyButton.setText(translate("draft", "XY"))
- self.xyButton.setToolTip(translate("draft", "Select XY plane"))
- self.xzButton.setText(translate("draft", "XZ"))
- self.xzButton.setToolTip(translate("draft", "Select XZ plane"))
- self.yzButton.setText(translate("draft", "YZ"))
- self.yzButton.setToolTip(translate("draft", "Select YZ plane"))
- self.currentViewButton.setText(translate("draft", "View"))
- self.currentViewButton.setToolTip(translate("draft", "Select plane perpendicular to the current view"))
- self.resetPlaneButton.setText(translate("draft", "None"))
- self.resetPlaneButton.setToolTip(translate("draft", "Do not project points to a drawing plane"))
- self.isCopy.setText(translate("draft", "&Copy"))
- self.isCopy.setToolTip(translate("draft", "If checked, objects will be copied instead of moved (C)"))
- if (not self.taskmode) or self.tray:
- self.colorButton.setToolTip(translate("draft", "Line Color"))
- self.facecolorButton.setToolTip(translate("draft", "Face Color"))
- self.widthButton.setToolTip(translate("draft", "Line Width"))
- self.fontsizeButton.setToolTip(translate("draft", "Font Size"))
- self.applyButton.setToolTip(translate("draft", "Apply to selected objects"))
- self.constrButton.setToolTip(translate("draft", "Toggles Construction Mode"))
+ def retranslateUi(self, widget=None):
+ self.promptlabel.setText(translate("draft", "active command:"))
+ self.cmdlabel.setText(translate("draft", "None"))
+ self.cmdlabel.setToolTip(translate("draft", "Active Draft command"))
+ self.xValue.setToolTip(translate("draft", "X coordinate of next point"))
+ self.labelx.setText(translate("draft", "X"))
+ self.labely.setText(translate("draft", "Y"))
+ self.labelz.setText(translate("draft", "Z"))
+ self.yValue.setToolTip(translate("draft", "Y coordinate of next point"))
+ self.zValue.setToolTip(translate("draft", "Z coordinate of next point"))
+ self.labelRadius.setText(translate("draft", "Radius"))
+ self.radiusValue.setToolTip(translate("draft", "Radius of Circle"))
+ self.isRelative.setText(translate("draft", "&Relative"))
+ self.isRelative.setToolTip(translate("draft", "Coordinates relative to last point or absolute (SPACE)"))
+ self.hasFill.setText(translate("draft", "F&illed"))
+ self.hasFill.setToolTip(translate("draft", "Check this if the object should appear as filled, otherwise it will appear as wireframe (i)"))
+ self.finishButton.setText(translate("draft", "&Finish"))
+ self.finishButton.setToolTip(translate("draft", "Finishes the current drawing or editing operation (F)"))
+ self.continueCmd.setToolTip(translate("draft", "If checked, command will not finish until you press the command button again"))
+ self.continueCmd.setText(translate("draft", "&Continue"))
+ self.occOffset.setToolTip(translate("draft", "If checked, an OCC-style offset will be performed instead of the classic offset"))
+ self.occOffset.setText(translate("draft", "&OCC-style offset"))
+ self.addButton.setToolTip(translate("draft", "Add points to the current object"))
+ self.delButton.setToolTip(translate("draft", "Remove points from the current object"))
+ self.undoButton.setText(translate("draft", "&Undo"))
+ self.undoButton.setToolTip(translate("draft", "Undo the last segment (CTRL+Z)"))
+ self.closeButton.setText(translate("draft", "&Close"))
+ self.closeButton.setToolTip(translate("draft", "Finishes and closes the current line (C)"))
+ self.wipeButton.setText(translate("draft", "&Wipe"))
+ self.wipeButton.setToolTip(translate("draft", "Wipes the existing segments of this line and starts again from the last point (W)"))
+ self.numFaces.setToolTip(translate("draft", "Number of sides"))
+ self.offsetLabel.setText(translate("draft", "Offset"))
+ self.xyButton.setText(translate("draft", "XY"))
+ self.xyButton.setToolTip(translate("draft", "Select XY plane"))
+ self.xzButton.setText(translate("draft", "XZ"))
+ self.xzButton.setToolTip(translate("draft", "Select XZ plane"))
+ self.yzButton.setText(translate("draft", "YZ"))
+ self.yzButton.setToolTip(translate("draft", "Select YZ plane"))
+ self.currentViewButton.setText(translate("draft", "View"))
+ self.currentViewButton.setToolTip(translate("draft", "Select plane perpendicular to the current view"))
+ self.resetPlaneButton.setText(translate("draft", "None"))
+ self.resetPlaneButton.setToolTip(translate("draft", "Do not project points to a drawing plane"))
+ self.isCopy.setText(translate("draft", "&Copy"))
+ self.isCopy.setToolTip(translate("draft", "If checked, objects will be copied instead of moved (C)"))
+ if (not self.taskmode) or self.tray:
+ self.colorButton.setToolTip(translate("draft", "Line Color"))
+ self.facecolorButton.setToolTip(translate("draft", "Face Color"))
+ self.widthButton.setToolTip(translate("draft", "Line Width"))
+ self.fontsizeButton.setToolTip(translate("draft", "Font Size"))
+ self.applyButton.setToolTip(translate("draft", "Apply to selected objects"))
+ self.constrButton.setToolTip(translate("draft", "Toggles Construction Mode"))
#---------------------------------------------------------------------------
# Interface modes
#---------------------------------------------------------------------------
- def taskUi(self,title):
- if self.taskmode:
- FreeCADGui.Control.closeDialog()
- self.baseWidget = QtGui.QWidget()
- self.setTitle(title)
- self.layout = QtGui.QVBoxLayout(self.baseWidget)
- self.setupToolBar(task=True)
- self.retranslateUi(self.baseWidget)
- self.panel = DraftTaskPanel(self.baseWidget)
- FreeCADGui.Control.showDialog(self.panel)
- else:
- self.setTitle(title)
+ def taskUi(self,title):
+ if self.taskmode:
+ FreeCADGui.Control.closeDialog()
+ self.baseWidget = QtGui.QWidget()
+ self.setTitle(title)
+ self.layout = QtGui.QVBoxLayout(self.baseWidget)
+ self.setupToolBar(task=True)
+ self.retranslateUi(self.baseWidget)
+ self.panel = DraftTaskPanel(self.baseWidget)
+ FreeCADGui.Control.showDialog(self.panel)
+ else:
+ self.setTitle(title)
- def selectPlaneUi(self):
- self.taskUi(translate("draft", "Select Plane"))
- self.xyButton.show()
- self.xzButton.show()
- self.yzButton.show()
- self.currentViewButton.show()
- self.resetPlaneButton.show()
- self.offsetLabel.show()
- self.offsetValue.show()
+ def selectPlaneUi(self):
+ self.taskUi(translate("draft", "Select Plane"))
+ self.xyButton.show()
+ self.xzButton.show()
+ self.yzButton.show()
+ self.currentViewButton.show()
+ self.resetPlaneButton.show()
+ self.offsetLabel.show()
+ self.offsetValue.show()
- def lineUi(self):
- self.pointUi(translate("draft", "Line"))
- self.xValue.setEnabled(True)
- self.yValue.setEnabled(True)
- self.isRelative.show()
- self.hasFill.show()
- self.finishButton.show()
- self.closeButton.show()
- self.wipeButton.show()
- self.undoButton.show()
- self.continueCmd.show()
+ def lineUi(self):
+ self.pointUi(translate("draft", "Line"))
+ self.xValue.setEnabled(True)
+ self.yValue.setEnabled(True)
+ self.isRelative.show()
+ self.hasFill.show()
+ self.finishButton.show()
+ self.closeButton.show()
+ self.wipeButton.show()
+ self.undoButton.show()
+ self.continueCmd.show()
- def circleUi(self):
- self.pointUi(translate("draft", "Circle"))
- self.continueCmd.show()
- self.labelx.setText(translate("draft", "Center X"))
- self.hasFill.show()
+ def circleUi(self):
+ self.pointUi(translate("draft", "Circle"))
+ self.continueCmd.show()
+ self.labelx.setText(translate("draft", "Center X"))
+ self.hasFill.show()
- def arcUi(self):
- self.pointUi(translate("draft", "Arc"))
- self.labelx.setText(translate("draft", "Center X"))
- self.continueCmd.show()
+ def arcUi(self):
+ self.pointUi(translate("draft", "Arc"))
+ self.labelx.setText(translate("draft", "Center X"))
+ self.continueCmd.show()
- def pointUi(self,title=translate("draft","Point")):
- self.taskUi(title)
- self.xValue.setEnabled(True)
- self.yValue.setEnabled(True)
- self.labelx.setText(translate("draft", "X"))
- self.labelx.show()
- self.labely.show()
- self.labelz.show()
- self.xValue.show()
- self.yValue.show()
- self.zValue.show()
- self.xValue.setFocus()
- self.xValue.selectAll()
+ def pointUi(self,title=translate("draft","Point")):
+ self.taskUi(title)
+ self.xValue.setEnabled(True)
+ self.yValue.setEnabled(True)
+ self.labelx.setText(translate("draft", "X"))
+ self.labelx.show()
+ self.labely.show()
+ self.labelz.show()
+ self.xValue.show()
+ self.yValue.show()
+ self.zValue.show()
+ self.xValue.setFocus()
+ self.xValue.selectAll()
- def offsetUi(self):
- self.taskUi(translate("draft","Offset"))
- self.radiusUi()
- self.isCopy.show()
- self.occOffset.show()
- self.labelRadius.setText(translate("draft","Distance"))
- self.radiusValue.setFocus()
- self.radiusValue.selectAll()
+ def offsetUi(self):
+ self.taskUi(translate("draft","Offset"))
+ self.radiusUi()
+ self.isCopy.show()
+ self.occOffset.show()
+ self.labelRadius.setText(translate("draft","Distance"))
+ self.radiusValue.setFocus()
+ self.radiusValue.selectAll()
- def offUi(self):
- if self.taskmode:
- FreeCADGui.Control.closeDialog()
- self.baseWidget = QtGui.QWidget()
- print "UI turned off"
- else:
- self.setTitle(translate("draft", "None"))
- self.labelx.setText(translate("draft", "X"))
- self.labelx.hide()
- self.labely.hide()
- self.labelz.hide()
- self.xValue.hide()
- self.yValue.hide()
- self.zValue.hide()
- self.numFaces.hide()
- self.isRelative.hide()
- self.hasFill.hide()
- self.finishButton.hide()
- self.addButton.hide()
- self.delButton.hide()
- self.undoButton.hide()
- self.closeButton.hide()
- self.wipeButton.hide()
- self.xyButton.hide()
- self.xzButton.hide()
- self.yzButton.hide()
- self.currentViewButton.hide()
- self.resetPlaneButton.hide()
- self.offsetLabel.hide()
- self.offsetValue.hide()
- self.labelRadius.hide()
- self.radiusValue.hide()
- self.isCopy.hide()
- self.textValue.hide()
- self.continueCmd.hide()
- self.occOffset.hide()
+ def offUi(self):
+ if self.taskmode:
+ FreeCADGui.Control.closeDialog()
+ self.baseWidget = QtGui.QWidget()
+ # print "UI turned off"
+ else:
+ self.setTitle(translate("draft", "None"))
+ self.labelx.setText(translate("draft", "X"))
+ self.labelx.hide()
+ self.labely.hide()
+ self.labelz.hide()
+ self.xValue.hide()
+ self.yValue.hide()
+ self.zValue.hide()
+ self.numFaces.hide()
+ self.isRelative.hide()
+ self.hasFill.hide()
+ self.finishButton.hide()
+ self.addButton.hide()
+ self.delButton.hide()
+ self.undoButton.hide()
+ self.closeButton.hide()
+ self.wipeButton.hide()
+ self.xyButton.hide()
+ self.xzButton.hide()
+ self.yzButton.hide()
+ self.currentViewButton.hide()
+ self.resetPlaneButton.hide()
+ self.offsetLabel.hide()
+ self.offsetValue.hide()
+ self.labelRadius.hide()
+ self.radiusValue.hide()
+ self.isCopy.hide()
+ self.textValue.hide()
+ self.continueCmd.hide()
+ self.occOffset.hide()
- def radiusUi(self):
- self.labelx.hide()
- self.labely.hide()
- self.labelz.hide()
- self.xValue.hide()
- self.yValue.hide()
- self.zValue.hide()
- self.labelRadius.setText(translate("draft", "Radius"))
- self.labelRadius.show()
- self.radiusValue.show()
+ def radiusUi(self):
+ self.labelx.hide()
+ self.labely.hide()
+ self.labelz.hide()
+ self.xValue.hide()
+ self.yValue.hide()
+ self.zValue.hide()
+ self.labelRadius.setText(translate("draft", "Radius"))
+ self.labelRadius.show()
+ self.radiusValue.show()
- def textUi(self):
- self.labelx.hide()
- self.labely.hide()
- self.labelz.hide()
- self.xValue.hide()
- self.yValue.hide()
- self.zValue.hide()
- self.textValue.show()
- self.textValue.setText('')
- self.textValue.setFocus()
- self.textbuffer=[]
- self.textline=0
- self.continueCmd.show()
+ def textUi(self):
+ self.labelx.hide()
+ self.labely.hide()
+ self.labelz.hide()
+ self.xValue.hide()
+ self.yValue.hide()
+ self.zValue.hide()
+ self.textValue.show()
+ self.textValue.setText('')
+ self.textValue.setFocus()
+ self.textbuffer=[]
+ self.textline=0
+ self.continueCmd.show()
+
+ def switchUi(self,store=True):
+ if store:
+ self.state = []
+ self.state.append(self.labelx.isVisible())
+ self.state.append(self.labely.isVisible())
+ self.state.append(self.labelz.isVisible())
+ self.state.append(self.xValue.isVisible())
+ self.state.append(self.yValue.isVisible())
+ self.state.append(self.zValue.isVisible())
+ self.labelx.hide()
+ self.labely.hide()
+ self.labelz.hide()
+ self.xValue.hide()
+ self.yValue.hide()
+ self.zValue.hide()
+ else:
+ if self.state:
+ if self.state[0]:self.labelx.show()
+ if self.state[1]:self.labely.show()
+ if self.state[2]:self.labelz.show()
+ if self.state[3]:self.xValue.show()
+ if self.state[4]:self.yValue.show()
+ if self.state[5]:self.zValue.show()
+ self.state = None
- def switchUi(self,store=True):
- if store:
- self.state = []
- self.state.append(self.labelx.isVisible())
- self.state.append(self.labely.isVisible())
- self.state.append(self.labelz.isVisible())
- self.state.append(self.xValue.isVisible())
- self.state.append(self.yValue.isVisible())
- self.state.append(self.zValue.isVisible())
- self.labelx.hide()
- self.labely.hide()
- self.labelz.hide()
- self.xValue.hide()
- self.yValue.hide()
- self.zValue.hide()
- else:
- if self.state:
- if self.state[0]:self.labelx.show()
- if self.state[1]:self.labely.show()
- if self.state[2]:self.labelz.show()
- if self.state[3]:self.xValue.show()
- if self.state[4]:self.yValue.show()
- if self.state[5]:self.zValue.show()
- self.state = None
+ def setTitle(self,title):
+ if self.taskmode:
+ self.baseWidget.setWindowTitle(title)
+ else:
+ self.cmdlabel.setText(title)
- def setTitle(self,title):
- if self.taskmode:
- self.baseWidget.setWindowTitle(title)
- else:
- self.cmdlabel.setText(title)
+ def selectUi(self):
+ self.labelx.setText(translate("draft", "Pick Object"))
+ self.labelx.show()
- def selectUi(self):
- self.labelx.setText(translate("draft", "Pick Object"))
- self.labelx.show()
+ def editUi(self):
+ self.taskUi(translate("draft", "Edit"))
+ self.labelx.hide()
+ self.labely.hide()
+ self.labelz.hide()
+ self.xValue.hide()
+ self.yValue.hide()
+ self.zValue.hide()
+ self.numFaces.hide()
+ self.isRelative.hide()
+ self.hasFill.hide()
+ self.addButton.show()
+ self.delButton.show()
+ self.finishButton.show()
+ self.closeButton.show()
- def editUi(self):
- self.taskUi(translate("draft", "Edit"))
- self.labelx.hide()
- self.labely.hide()
- self.labelz.hide()
- self.xValue.hide()
- self.yValue.hide()
- self.zValue.hide()
- self.numFaces.hide()
- self.isRelative.hide()
- self.hasFill.hide()
- self.addButton.show()
- self.delButton.show()
- self.finishButton.show()
- self.closeButton.show()
+ def extUi(self):
+ self.hasFill.show()
+ self.continueCmd.show()
- def extUi(self):
- self.hasFill.show()
- self.continueCmd.show()
+ def modUi(self):
+ self.isCopy.show()
+ self.continueCmd.show()
- def modUi(self):
- self.isCopy.show()
- self.continueCmd.show()
-
- def relocate(self):
- "relocates the right-aligned buttons depending on the toolbar size"
- if self.baseWidget.geometry().width() < 400:
- self.layout.setDirection(QtGui.QBoxLayout.TopToBottom)
- else:
- self.layout.setDirection(QtGui.QBoxLayout.LeftToRight)
+ def relocate(self):
+ "relocates the right-aligned buttons depending on the toolbar size"
+ if self.baseWidget.geometry().width() < 400:
+ self.layout.setDirection(QtGui.QBoxLayout.TopToBottom)
+ else:
+ self.layout.setDirection(QtGui.QBoxLayout.LeftToRight)
#---------------------------------------------------------------------------
# Processing functions
#---------------------------------------------------------------------------
- def getcol(self):
- "opens a color picker dialog"
- self.color=QtGui.QColorDialog.getColor()
- self.colorPix.fill(self.color)
- self.colorButton.setIcon(QtGui.QIcon(self.colorPix))
- if Draft.getParam("saveonexit"):
- Draft.setParam("color",self.color.rgb()<<8)
- r = float(self.color.red()/255.0)
- g = float(self.color.green()/255.0)
- b = float(self.color.blue()/255.0)
- col = (r,g,b,0.0)
- for i in FreeCADGui.Selection.getSelection():
- if (i.Type == "App::Annotation"):
- i.ViewObject.TextColor=col
- else:
- if "LineColor" in i.ViewObject.PropertiesList:
- i.ViewObject.LineColor = col
- if "PointColor" in i.ViewObject.PropertiesList:
- i.ViewObject.PointColor = col
+ def getcol(self):
+ "opens a color picker dialog"
+ self.color=QtGui.QColorDialog.getColor()
+ self.colorPix.fill(self.color)
+ self.colorButton.setIcon(QtGui.QIcon(self.colorPix))
+ if Draft.getParam("saveonexit"):
+ Draft.setParam("color",self.color.rgb()<<8)
+ r = float(self.color.red()/255.0)
+ g = float(self.color.green()/255.0)
+ b = float(self.color.blue()/255.0)
+ col = (r,g,b,0.0)
+ for i in FreeCADGui.Selection.getSelection():
+ if (i.Type == "App::Annotation"):
+ i.ViewObject.TextColor=col
+ else:
+ if "LineColor" in i.ViewObject.PropertiesList:
+ i.ViewObject.LineColor = col
+ if "PointColor" in i.ViewObject.PropertiesList:
+ i.ViewObject.PointColor = col
- def getfacecol(self):
- "opens a color picker dialog"
- self.facecolor=QtGui.QColorDialog.getColor()
- self.facecolorPix.fill(self.facecolor)
- self.facecolorButton.setIcon(QtGui.QIcon(self.facecolorPix))
- r = float(self.facecolor.red()/255.0)
- g = float(self.facecolor.green()/255.0)
- b = float(self.facecolor.blue()/255.0)
- col = (r,g,b,0.0)
- for i in FreeCADGui.Selection.getSelection():
- if "ShapeColor" in i.ViewObject.PropertiesList:
- i.ViewObject.ShapeColor = col
+ def getfacecol(self):
+ "opens a color picker dialog"
+ self.facecolor=QtGui.QColorDialog.getColor()
+ self.facecolorPix.fill(self.facecolor)
+ self.facecolorButton.setIcon(QtGui.QIcon(self.facecolorPix))
+ r = float(self.facecolor.red()/255.0)
+ g = float(self.facecolor.green()/255.0)
+ b = float(self.facecolor.blue()/255.0)
+ col = (r,g,b,0.0)
+ for i in FreeCADGui.Selection.getSelection():
+ if "ShapeColor" in i.ViewObject.PropertiesList:
+ i.ViewObject.ShapeColor = col
- def setwidth(self,val):
- self.linewidth = float(val)
- if Draft.getParam("saveonexit"):
- Draft.setParam("linewidth",int(val))
- for i in FreeCADGui.Selection.getSelection():
- if "LineWidth" in i.ViewObject.PropertiesList:
- i.ViewObject.LineWidth = float(val)
+ def setwidth(self,val):
+ self.linewidth = float(val)
+ if Draft.getParam("saveonexit"):
+ Draft.setParam("linewidth",int(val))
+ for i in FreeCADGui.Selection.getSelection():
+ if "LineWidth" in i.ViewObject.PropertiesList:
+ i.ViewObject.LineWidth = float(val)
- def setfontsize(self,val):
- self.fontsize = float(val)
- if Draft.getParam("saveonexit"):
- Draft.setParam("textheight",float(val))
- for i in FreeCADGui.Selection.getSelection():
- if "FontSize" in i.ViewObject.PropertiesList:
- i.ViewObject.FontSize = float(val)
+ def setfontsize(self,val):
+ self.fontsize = float(val)
+ if Draft.getParam("saveonexit"):
+ Draft.setParam("textheight",float(val))
+ for i in FreeCADGui.Selection.getSelection():
+ if "FontSize" in i.ViewObject.PropertiesList:
+ i.ViewObject.FontSize = float(val)
- def setContinue(self,val):
- self.continueMode = bool(val)
+ def setContinue(self,val):
+ self.continueMode = bool(val)
- def apply(self):
- for i in FreeCADGui.Selection.getSelection():
- Draft.formatObject(i)
+ def apply(self):
+ for i in FreeCADGui.Selection.getSelection():
+ Draft.formatObject(i)
- def checkx(self):
- if self.yValue.isEnabled():
- self.yValue.setFocus()
- self.yValue.selectAll()
+ def checkx(self):
+ if self.yValue.isEnabled():
+ self.yValue.setFocus()
+ self.yValue.selectAll()
+ else:
+ self.checky()
+
+ def checky(self):
+ if self.zValue.isEnabled():
+ self.zValue.setFocus()
+ self.zValue.selectAll()
+ else:
+ self.validatePoint()
+
+ def validatePoint(self):
+ "function for checking and sending numbers entered manually"
+ if self.sourceCmd != None:
+ if (self.labelRadius.isVisible()):
+ try:
+ rad=float(self.radiusValue.text())
+ except ValueError:
+ pass
else:
- self.checky()
-
- def checky(self):
- if self.zValue.isEnabled():
- self.zValue.setFocus()
- self.zValue.selectAll()
+ self.sourceCmd.numericRadius(rad)
+ elif (self.offsetLabel.isVisible()):
+ try:
+ offset=float(self.offsetValue.text())
+ except ValueError:
+ pass
else:
- self.validatePoint()
+ self.sourceCmd.offsetHandler(offset)
+ else:
+ try:
+ numx=float(self.xValue.text())
+ numy=float(self.yValue.text())
+ numz=float(self.zValue.text())
+ except ValueError:
+ pass
+ else:
+ if self.isRelative.isVisible() and self.isRelative.isChecked():
+ if self.sourceCmd.node:
+ if self.sourceCmd.featureName == "Rectangle":
+ last = self.sourceCmd.node[0]
+ else:
+ last = self.sourceCmd.node[-1]
+ numx = last.x + numx
+ numy = last.y + numy
+ numz = last.z + numz
+ if FreeCAD.DraftWorkingPlane:
+ v = FreeCAD.Vector(numx,numy,numz)
+ v = FreeCAD.DraftWorkingPlane.getGlobalCoords(v)
+ numx = v.x
+ numy = v.y
+ numz = v.z
+ self.sourceCmd.numericInput(numx,numy,numz)
- def validatePoint(self):
- "function for checking and sending numbers entered manually"
- if self.sourceCmd != None:
- if (self.labelRadius.isVisible()):
- try:
- rad=float(self.radiusValue.text())
- except ValueError:
- pass
- else:
- self.sourceCmd.numericRadius(rad)
- elif (self.offsetLabel.isVisible()):
- try:
- offset=float(self.offsetValue.text())
- except ValueError:
- pass
- else:
- self.sourceCmd.offsetHandler(offset)
- else:
- try:
- numx=float(self.xValue.text())
- numy=float(self.yValue.text())
- numz=float(self.zValue.text())
- except ValueError:
- pass
- else:
- if self.isRelative.isVisible() and self.isRelative.isChecked():
- if self.sourceCmd.node:
- if self.sourceCmd.featureName == "Rectangle":
- last = self.sourceCmd.node[0]
- else:
- last = self.sourceCmd.node[-1]
- numx = last.x + numx
- numy = last.y + numy
- numz = last.z + numz
- if FreeCAD.DraftWorkingPlane:
- v = FreeCAD.Vector(numx,numy,numz)
- v = FreeCAD.DraftWorkingPlane.getGlobalCoords(v)
- numx = v.x
- numy = v.y
- numz = v.z
- self.sourceCmd.numericInput(numx,numy,numz)
+ def finish(self):
+ "finish button action"
+ self.sourceCmd.finish(False)
- def finish(self):
- "finish button action"
- self.sourceCmd.finish(False)
+ def closeLine(self):
+ "close button action"
+ self.sourceCmd.finish(True)
- def closeLine(self):
- "close button action"
- self.sourceCmd.finish(True)
+ def wipeLine(self):
+ "wipes existing segments of a line"
+ self.sourceCmd.wipe()
- def wipeLine(self):
- "wipes existing segments of a line"
- self.sourceCmd.wipe()
+ def selectXY(self):
+ self.sourceCmd.selectHandler("XY")
- def selectXY(self):
- self.sourceCmd.selectHandler("XY")
+ def selectXZ(self):
+ self.sourceCmd.selectHandler("XZ")
- def selectXZ(self):
- self.sourceCmd.selectHandler("XZ")
+ def selectYZ(self):
+ self.sourceCmd.selectHandler("YZ")
- def selectYZ(self):
- self.sourceCmd.selectHandler("YZ")
+ def selectCurrentView(self):
+ self.sourceCmd.selectHandler("currentView")
- def selectCurrentView(self):
- self.sourceCmd.selectHandler("currentView")
+ def selectResetPlane(self):
+ self.sourceCmd.selectHandler("reset")
- def selectResetPlane(self):
- self.sourceCmd.selectHandler("reset")
+ def undoSegment(self):
+ "undo last line segment"
+ self.sourceCmd.undolast()
- def undoSegment(self):
- "undo last line segment"
- self.sourceCmd.undolast()
-
- def checkSpecialChars(self,txt):
- '''
- checks for special characters in the entered coords that mut be
- treated as shortcuts
- '''
- spec = False
- if txt.endsWith(" ") or txt.endsWith("r"):
- self.isRelative.setChecked(not self.isRelative.isChecked())
- spec = True
- elif txt.endsWith("i"):
- if self.hasFill.isVisible():
- self.hasFill.setChecked(not self.hasFill.isChecked())
- spec = True
- elif txt.endsWith("f"):
- if self.finishButton.isVisible():
- self.finish()
- spec = True
- elif txt.endsWith("w"):
- self.wipeLine()
- elif txt.endsWith("c"):
- if self.closeButton.isVisible():
- self.closeLine()
- elif self.isCopy.isVisible():
- self.isCopy.setChecked(not self.isCopy.isChecked())
- elif self.continueCmd.isVisible():
- self.continueCmd.setChecked(not self.continueCmd.isChecked())
- spec = True
- if spec and (not self.taskmode):
- for i in [self.xValue,self.yValue,self.zValue]:
- if (i.text() == txt): i.setText("")
+ def checkSpecialChars(self,txt):
+ '''
+ checks for special characters in the entered coords that mut be
+ treated as shortcuts
+ '''
+ spec = False
+ if txt.endsWith(" ") or txt.endsWith("r"):
+ self.isRelative.setChecked(not self.isRelative.isChecked())
+ spec = True
+ elif txt.endsWith("i"):
+ if self.hasFill.isVisible():
+ self.hasFill.setChecked(not self.hasFill.isChecked())
+ spec = True
+ elif txt.endsWith("f"):
+ if self.finishButton.isVisible():
+ self.finish()
+ spec = True
+ elif txt.endsWith("w"):
+ self.wipeLine()
+ elif txt.endsWith("c"):
+ if self.closeButton.isVisible():
+ self.closeLine()
+ elif self.isCopy.isVisible():
+ self.isCopy.setChecked(not self.isCopy.isChecked())
+ elif self.continueCmd.isVisible():
+ self.continueCmd.setChecked(not self.continueCmd.isChecked())
+ spec = True
+ if spec and (not self.taskmode):
+ for i in [self.xValue,self.yValue,self.zValue]:
+ if (i.text() == txt): i.setText("")
- def sendText(self):
- '''
- this function sends the entered text to the active draft command
- if enter has been pressed twice. Otherwise it blanks the line.
- '''
- if self.textline == len(self.textbuffer):
- if self.textline:
- if not self.textValue.text():
- self.sourceCmd.text=self.textbuffer
- self.sourceCmd.createObject()
- self.textbuffer.append(self.textValue.text())
- self.textline += 1
- self.textValue.setText('')
- elif self.textline < len(self.textbuffer):
- self.textbuffer[self.textline] = self.textValue.text()
- self.textline += 1
- if self.textline < len(self.textbuffer):
- self.textValue.setText(self.textbuffer[self.textline])
- else:
- self.textValue.setText('')
+ def sendText(self):
+ '''
+ this function sends the entered text to the active draft command
+ if enter has been pressed twice. Otherwise it blanks the line.
+ '''
+ if self.textline == len(self.textbuffer):
+ if self.textline:
+ if not self.textValue.text():
+ self.sourceCmd.text=self.textbuffer
+ self.sourceCmd.createObject()
+ self.textbuffer.append(self.textValue.text())
+ self.textline += 1
+ self.textValue.setText('')
+ elif self.textline < len(self.textbuffer):
+ self.textbuffer[self.textline] = self.textValue.text()
+ self.textline += 1
+ if self.textline < len(self.textbuffer):
+ self.textValue.setText(self.textbuffer[self.textline])
+ else:
+ self.textValue.setText('')
- def lineUp(self):
- "displays previous line in text editor"
- if self.textline:
- if self.textline == len(self.textbuffer):
- self.textbuffer.append(self.textValue.text())
- self.textline -= 1
- if self.textValue.text():
- self.textValue.setText(self.textbuffer[self.textline])
- elif self.textline < len(self.textbuffer):
- self.textbuffer[self.textline] = self.textValue.text()
- self.textline -= 1
- self.textValue.setText(self.textbuffer[self.textline])
+ def lineUp(self):
+ "displays previous line in text editor"
+ if self.textline:
+ if self.textline == len(self.textbuffer):
+ self.textbuffer.append(self.textValue.text())
+ self.textline -= 1
+ if self.textValue.text():
+ self.textValue.setText(self.textbuffer[self.textline])
+ elif self.textline < len(self.textbuffer):
+ self.textbuffer[self.textline] = self.textValue.text()
+ self.textline -= 1
+ self.textValue.setText(self.textbuffer[self.textline])
- def displayPoint(self, point, last=None, plane=None):
- "this function displays the passed coords in the x, y, and z widgets"
- dp = point
- if self.isRelative.isChecked() and (last != None):
- if plane:
- dp = plane.getLocalCoords(FreeCAD.Vector(point.x-last.x, point.y-last.y, point.z-last.z))
- else:
- dp = FreeCAD.Vector(point.x-last.x, point.y-last.y, point.z-last.z)
- self.xValue.setText("%.2f" % dp.x)
- self.yValue.setText("%.2f" % dp.y)
- if self.zValue.isEnabled(): self.zValue.setText("%.2f" % dp.z)
- if self.xValue.isEnabled():
- self.xValue.setFocus()
- self.xValue.selectAll()
- else:
- self.yValue.setFocus()
- self.yValue.selectAll()
+ def displayPoint(self, point, last=None, plane=None):
+ "this function displays the passed coords in the x, y, and z widgets"
+ dp = point
+ if self.isRelative.isChecked() and (last != None):
+ if plane:
+ dp = plane.getLocalCoords(FreeCAD.Vector(point.x-last.x, point.y-last.y, point.z-last.z))
+ else:
+ dp = FreeCAD.Vector(point.x-last.x, point.y-last.y, point.z-last.z)
+ self.xValue.setText("%.2f" % dp.x)
+ self.yValue.setText("%.2f" % dp.y)
+ if self.zValue.isEnabled(): self.zValue.setText("%.2f" % dp.z)
+ if self.xValue.isEnabled():
+ self.xValue.setFocus()
+ self.xValue.selectAll()
+ else:
+ self.yValue.setFocus()
+ self.yValue.selectAll()
- def getDefaultColor(self,type,rgb=False):
- "gets color from the preferences or toolbar"
- if type == "snap":
- color = Draft.getParam("snapcolor")
- r = ((color>>24)&0xFF)/255
- g = ((color>>16)&0xFF)/255
- b = ((color>>8)&0xFF)/255
- elif type == "ui":
- r = float(self.color.red()/255.0)
- g = float(self.color.green()/255.0)
- b = float(self.color.blue()/255.0)
- elif type == "face":
- r = float(self.facecolor.red()/255.0)
- g = float(self.facecolor.green()/255.0)
- b = float(self.facecolor.blue()/255.0)
- elif type == "constr":
- color = QtGui.QColor(Draft.getParam("constructioncolor")>>8)
- r = color.red()/255.0
- g = color.green()/255.0
- b = color.blue()/255.0
- else: print "draft: error: couldn't get a color for ",type," type."
- if rgb:
- return("rgb("+str(int(r*255))+","+str(int(g*255))+","+str(int(b*255))+")")
- else:
- return (r,g,b)
+ def getDefaultColor(self,type,rgb=False):
+ "gets color from the preferences or toolbar"
+ if type == "snap":
+ color = Draft.getParam("snapcolor")
+ r = ((color>>24)&0xFF)/255
+ g = ((color>>16)&0xFF)/255
+ b = ((color>>8)&0xFF)/255
+ elif type == "ui":
+ r = float(self.color.red()/255.0)
+ g = float(self.color.green()/255.0)
+ b = float(self.color.blue()/255.0)
+ elif type == "face":
+ r = float(self.facecolor.red()/255.0)
+ g = float(self.facecolor.green()/255.0)
+ b = float(self.facecolor.blue()/255.0)
+ elif type == "constr":
+ color = QtGui.QColor(Draft.getParam("constructioncolor")>>8)
+ r = color.red()/255.0
+ g = color.green()/255.0
+ b = color.blue()/255.0
+ else: print "draft: error: couldn't get a color for ",type," type."
+ if rgb:
+ return("rgb("+str(int(r*255))+","+str(int(g*255))+","+str(int(b*255))+")")
+ else:
+ return (r,g,b)
- def cross(self,on=True):
- if on:
- if not self.crossedViews:
- mw = getMainWindow()
- self.crossedViews = mw.findChildren(QtGui.QFrame,"SoQtWidgetName")
- for w in self.crossedViews:
- w.setCursor(QtCore.Qt.CrossCursor)
- else:
- for w in self.crossedViews:
- w.unsetCursor()
- self.crossedViews = []
+ def cross(self,on=True):
+ if on:
+ if not self.crossedViews:
+ mw = getMainWindow()
+ self.crossedViews = mw.findChildren(QtGui.QFrame,"SoQtWidgetName")
+ for w in self.crossedViews:
+ w.setCursor(QtCore.Qt.CrossCursor)
+ else:
+ for w in self.crossedViews:
+ w.unsetCursor()
+ self.crossedViews = []
- def toggleConstrMode(self,checked):
- self.baseWidget.setStyleSheet("#constrButton:Checked {background-color: "+self.getDefaultColor("constr",rgb=True)+" }")
- self.constrMode = checked
+ def toggleConstrMode(self,checked):
+ self.baseWidget.setStyleSheet("#constrButton:Checked {background-color: "+self.getDefaultColor("constr",rgb=True)+" }")
+ self.constrMode = checked
- def isConstructionMode(self):
- if self.tray or (not self.taskmode):
- return self.constrButton.isChecked()
- else:
- return False
+ def isConstructionMode(self):
+ if self.tray or (not self.taskmode):
+ return self.constrButton.isChecked()
+ else:
+ return False
- def drawPage(self):
- self.sourceCmd.draw()
+ def drawPage(self):
+ self.sourceCmd.draw()
- def changePage(self,index):
- pagename = str(self.pageBox.itemText(index))
- vobj = FreeCADGui.ActiveDocument.getObject(pagename)
- if vobj:
- self.scaleBox.setEditText(str(vobj.HintScale))
- self.marginXValue.setValue(float(vobj.HintOffsetX))
- self.marginYValue.setValue(float(vobj.HintOffsetY))
+ def changePage(self,index):
+ pagename = str(self.pageBox.itemText(index))
+ vobj = FreeCADGui.ActiveDocument.getObject(pagename)
+ if vobj:
+ self.scaleBox.setEditText(str(vobj.HintScale))
+ self.marginXValue.setValue(float(vobj.HintOffsetX))
+ self.marginYValue.setValue(float(vobj.HintOffsetY))
- def selectplane(self):
- FreeCADGui.runCommand("Draft_SelectPlane")
+ def selectplane(self):
+ FreeCADGui.runCommand("Draft_SelectPlane")
- def popupMenu(self,mlist):
- "pops up a menu filled with the given list"
- self.groupmenu = QtGui.QMenu()
- for i in mlist:
- self.groupmenu.addAction(i)
- pos = getMainWindow().cursor().pos()
- self.groupmenu.popup(pos)
- QtCore.QObject.connect(self.groupmenu,QtCore.SIGNAL("triggered(QAction *)"),self.popupTriggered)
+ def popupMenu(self,mlist):
+ "pops up a menu filled with the given list"
+ self.groupmenu = QtGui.QMenu()
+ for i in mlist:
+ self.groupmenu.addAction(i)
+ pos = getMainWindow().cursor().pos()
+ self.groupmenu.popup(pos)
+ QtCore.QObject.connect(self.groupmenu,QtCore.SIGNAL("triggered(QAction *)"),self.popupTriggered)
- def popupTriggered(self,action):
- self.sourceCmd.proceed(str(action.text()))
+ def popupTriggered(self,action):
+ self.sourceCmd.proceed(str(action.text()))
- def setAddMode(self,bool):
- if self.addButton.isChecked():
- self.delButton.setChecked(False)
+ def setAddMode(self,bool):
+ if self.addButton.isChecked():
+ self.delButton.setChecked(False)
- def setDelMode(self,bool):
- if self.delButton.isChecked():
- self.addButton.setChecked(False)
+ def setDelMode(self,bool):
+ if self.delButton.isChecked():
+ self.addButton.setChecked(False)
- def setRadiusValue(self,val):
- self.radiusValue.setText("%.2f" % val)
- self.radiusValue.setFocus()
- self.radiusValue.selectAll()
+ def setRadiusValue(self,val):
+ self.radiusValue.setText("%.2f" % val)
+ self.radiusValue.setFocus()
+ self.radiusValue.selectAll()
- def show(self):
- if not self.taskmode:
- self.draftWidget.setVisible(True)
+ def show(self):
+ if not self.taskmode:
+ self.draftWidget.setVisible(True)
- def hide(self):
- if not self.taskmode:
- self.draftWidget.setVisible(False)
+ def hide(self):
+ if not self.taskmode:
+ self.draftWidget.setVisible(False)
- def getXPM(self,iconname,size=16):
- i = QtGui.QIcon(":/icons/"+iconname+".svg")
- p = i.pixmap(size,size)
- a = QtCore.QByteArray()
- b = QtCore.QBuffer(a)
- b.open(QtCore.QIODevice.WriteOnly)
- p.save(b,"XPM")
- b.close()
- return str(a)
+ def getXPM(self,iconname,size=16):
+ i = QtGui.QIcon(":/icons/"+iconname+".svg")
+ p = i.pixmap(size,size)
+ a = QtCore.QByteArray()
+ b = QtCore.QBuffer(a)
+ b.open(QtCore.QIODevice.WriteOnly)
+ p.save(b,"XPM")
+ b.close()
+ return str(a)
#---------------------------------------------------------------------------
# TaskView operations
#---------------------------------------------------------------------------
- def setWatchers(self):
- print "adding draft widgets to taskview..."
- class DraftCreateWatcher:
- def __init__(self):
- self.commands = ["Draft_Line","Draft_Wire",
- "Draft_Rectangle","Draft_Arc",
- "Draft_Circle","Draft_BSpline",
- "Draft_Text","Draft_Dimension"]
- self.title = "Create objects"
- def shouldShow(self):
- return (FreeCAD.ActiveDocument != None) and (not FreeCADGui.Selection.getSelection())
+ def setWatchers(self):
+ print "adding draft widgets to taskview..."
+ class DraftCreateWatcher:
+ def __init__(self):
+ self.commands = ["Draft_Line","Draft_Wire",
+ "Draft_Rectangle","Draft_Arc",
+ "Draft_Circle","Draft_BSpline",
+ "Draft_Text","Draft_Dimension"]
+ self.title = "Create objects"
+ def shouldShow(self):
+ return (FreeCAD.ActiveDocument != None) and (not FreeCADGui.Selection.getSelection())
- class DraftModifyWatcher:
- def __init__(self):
- self.commands = ["Draft_Move","Draft_Rotate",
- "Draft_Scale","Draft_Offset",
- "Draft_Trimex","Draft_Upgrade",
- "Draft_Downgrade","Draft_Edit",
- "Draft_Drawing"]
- self.title = "Modify objects"
- def shouldShow(self):
- return (FreeCAD.ActiveDocument != None) and (FreeCADGui.Selection.getSelection() != [])
+ class DraftModifyWatcher:
+ def __init__(self):
+ self.commands = ["Draft_Move","Draft_Rotate",
+ "Draft_Scale","Draft_Offset",
+ "Draft_Trimex","Draft_Upgrade",
+ "Draft_Downgrade","Draft_Edit",
+ "Draft_Drawing"]
+ self.title = "Modify objects"
+ def shouldShow(self):
+ return (FreeCAD.ActiveDocument != None) and (FreeCADGui.Selection.getSelection() != [])
- class DraftTrayWatcher:
- def __init__(self,traywidget):
- self.form = traywidget
- self.widgets = [self.form]
- def shouldShow(self):
- return True
+ class DraftTrayWatcher:
+ def __init__(self,traywidget):
+ self.form = traywidget
+ self.widgets = [self.form]
+ def shouldShow(self):
+ return True
- print "setting tray"
- self.traywidget = QtGui.QWidget()
- self.tray = QtGui.QVBoxLayout(self.traywidget)
- self.tray.setObjectName("traylayout")
- self.toptray = QtGui.QHBoxLayout()
- self.bottomtray = QtGui.QHBoxLayout()
- self.tray.addLayout(self.toptray)
- self.tray.addLayout(self.bottomtray)
- self.setupTray()
- self.setupStyle()
- w = DraftTrayWatcher(self.traywidget)
- FreeCADGui.Control.addTaskWatcher([w,DraftCreateWatcher(),DraftModifyWatcher()])
+ print "setting tray"
+ self.traywidget = QtGui.QWidget()
+ self.tray = QtGui.QVBoxLayout(self.traywidget)
+ self.tray.setObjectName("traylayout")
+ self.toptray = QtGui.QHBoxLayout()
+ self.bottomtray = QtGui.QHBoxLayout()
+ self.tray.addLayout(self.toptray)
+ self.tray.addLayout(self.bottomtray)
+ self.setupTray()
+ self.setupStyle()
+ w = DraftTrayWatcher(self.traywidget)
+ FreeCADGui.Control.addTaskWatcher([w,DraftCreateWatcher(),DraftModifyWatcher()])
- def changeEvent(self, event):
- if event.type() == QtCore.QEvent.LanguageChange:
- print "Language changed!"
- self.ui.retranslateUi(self)
+ def changeEvent(self, event):
+ if event.type() == QtCore.QEvent.LanguageChange:
+ print "Language changed!"
+ self.ui.retranslateUi(self)
- def Activated(self):
- if self.taskmode:
- self.setWatchers()
- else:
- self.draftWidget.setVisible(True)
- self.draftWidget.toggleViewAction().setVisible(True)
-
- def Deactivated(self):
- if (FreeCAD.activeDraftCommand != None):
- FreeCAD.activeDraftCommand.finish()
- if self.taskmode:
- FreeCADGui.Control.clearTaskWatcher()
- self.tray = None
- else:
- self.draftWidget.setVisible(False)
- self.draftWidget.toggleViewAction().setVisible(False)
+ def Activated(self):
+ if self.taskmode:
+ self.setWatchers()
+ else:
+ self.draftWidget.setVisible(True)
+ self.draftWidget.toggleViewAction().setVisible(True)
+ def Deactivated(self):
+ if (FreeCAD.activeDraftCommand != None):
+ FreeCAD.activeDraftCommand.finish()
+ if self.taskmode:
+ FreeCADGui.Control.clearTaskWatcher()
+ self.tray = None
+ else:
+ self.draftWidget.setVisible(False)
+ self.draftWidget.toggleViewAction().setVisible(False)
if not hasattr(FreeCADGui,"draftToolBar"):
- FreeCADGui.draftToolBar = DraftToolBar()
+ FreeCADGui.draftToolBar = DraftToolBar()
diff --git a/src/Mod/Draft/draftTools.py b/src/Mod/Draft/draftTools.py
index 34273d6657..65c6c7eea4 100755
--- a/src/Mod/Draft/draftTools.py
+++ b/src/Mod/Draft/draftTools.py
@@ -44,28 +44,28 @@ from pivy import coin
FreeCADGui.updateLocale()
def translate(context,text):
- "convenience function for Qt translator"
- return QtGui.QApplication.translate(context, text, None, QtGui.QApplication.UnicodeUTF8).toUtf8()
+ "convenience function for Qt translator"
+ return QtGui.QApplication.translate(context, text, None, QtGui.QApplication.UnicodeUTF8).toUtf8()
def msg(text=None,mode=None):
- "prints the given message on the FreeCAD status bar"
- if not text: FreeCAD.Console.PrintMessage("")
+ "prints the given message on the FreeCAD status bar"
+ if not text: FreeCAD.Console.PrintMessage("")
+ else:
+ if mode == 'warning':
+ FreeCAD.Console.PrintWarning(text)
+ elif mode == 'error':
+ FreeCAD.Console.PrintError(text)
else:
- if mode == 'warning':
- FreeCAD.Console.PrintWarning(text)
- elif mode == 'error':
- FreeCAD.Console.PrintError(text)
- else:
- FreeCAD.Console.PrintMessage(text)
+ FreeCAD.Console.PrintMessage(text)
# loads the fill patterns
FreeCAD.svgpatterns = importSVG.getContents(Draft_rc.qt_resource_data,'pattern',True)
altpat = Draft.getParam("patternFile")
if os.path.isdir(altpat):
- for f in os.listdir(altpat):
- if '.svg' in f:
- p = importSVG.getContents(altpat+os.sep+f,'pattern')
- if p: FreeCAD.svgpatterns[p[0]]=p[1]
+ for f in os.listdir(altpat):
+ if '.svg' in f:
+ p = importSVG.getContents(altpat+os.sep+f,'pattern')
+ if p: FreeCAD.svgpatterns[p[0]]=p[1]
# sets the default working plane
plane = WorkingPlane.plane()
@@ -84,640 +84,628 @@ MODCONSTRAIN = MODS[Draft.getParam("modconstrain")]
MODSNAP = MODS[Draft.getParam("modsnap")]
MODALT = MODS[Draft.getParam("modalt")]
-#---------------------------------------------------------------------------
-# Global state
-#---------------------------------------------------------------------------
-
-''' plane selection code used to look like this:
- if self.ui.lockedz:
- self.axis = Vector(0,0,1)
- self.xVec = Vector(1,0,0)
- self.upVec = Vector(0,1,0)
- else:
- self.axis = fcvec.neg(self.view.getViewDirection())
- rot = self.view.getCameraNode().orientation.getValue()
- self.upVec = Vector(rot.multVec(coin.SbVec3f((0,1,0))).getValue())
- self.xVec = fcvec.rotate(self.upVec,math.pi/2,fcvec.neg(self.axis))
-'''
-
-
#---------------------------------------------------------------------------
# Snapping stuff
#---------------------------------------------------------------------------
def snapPoint(target,point,cursor,ctrl=False):
- '''
- Snap function used by the Draft tools
-
- Currently has two modes: passive and active. Pressing CTRL while
- clicking puts you in active mode:
-
- - In passive mode (an open circle appears), your point is
- snapped to the nearest point on any underlying geometry.
-
- - In active mode (ctrl pressed, a filled circle appears), your point
- can currently be snapped to the following points:
- - Nodes and midpoints of all Part shapes
- - Nodes and midpoints of lines/wires
- - Centers and quadrant points of circles
- - Endpoints of arcs
- - Intersection between line, wires segments, arcs and circles
- - When constrained (SHIFT pressed), Intersections between
- constraining axis and lines/wires
- '''
+ '''
+ Snap function used by the Draft tools
+
+ Currently has two modes: passive and active. Pressing CTRL while
+ clicking puts you in active mode:
+
+ - In passive mode (an open circle appears), your point is
+ snapped to the nearest point on any underlying geometry.
+
+ - In active mode (ctrl pressed, a filled circle appears), your point
+ can currently be snapped to the following points:
+ - Nodes and midpoints of all Part shapes
+ - Nodes and midpoints of lines/wires
+ - Centers and quadrant points of circles
+ - Endpoints of arcs
+ - Intersection between line, wires segments, arcs and circles
+ - When constrained (SHIFT pressed), Intersections between
+ constraining axis and lines/wires
+ '''
- def getConstrainedPoint(edge,last,constrain):
- "check for constrained snappoint"
- p1 = edge.Vertexes[0].Point
- p2 = edge.Vertexes[-1].Point
- ar = []
- if (constrain == 0):
- if ((last.y > p1.y) and (last.y < p2.y) or (last.y > p2.y) and (last.y < p1.y)):
- pc = (last.y-p1.y)/(p2.y-p1.y)
- cp = (Vector(p1.x+pc*(p2.x-p1.x),p1.y+pc*(p2.y-p1.y),p1.z+pc*(p2.z-p1.z)))
- ar.append([cp,1,cp]) # constrainpoint
- if (constrain == 1):
- if ((last.x > p1.x) and (last.x < p2.x) or (last.x > p2.x) and (last.x < p1.x)):
- pc = (last.x-p1.x)/(p2.x-p1.x)
- cp = (Vector(p1.x+pc*(p2.x-p1.x),p1.y+pc*(p2.y-p1.y),p1.z+pc*(p2.z-p1.z)))
- ar.append([cp,1,cp]) # constrainpoint
- return ar
+ def getConstrainedPoint(edge,last,constrain):
+ "check for constrained snappoint"
+ p1 = edge.Vertexes[0].Point
+ p2 = edge.Vertexes[-1].Point
+ ar = []
+ if (constrain == 0):
+ if ((last.y > p1.y) and (last.y < p2.y) or (last.y > p2.y) and (last.y < p1.y)):
+ pc = (last.y-p1.y)/(p2.y-p1.y)
+ cp = (Vector(p1.x+pc*(p2.x-p1.x),p1.y+pc*(p2.y-p1.y),p1.z+pc*(p2.z-p1.z)))
+ ar.append([cp,1,cp]) # constrainpoint
+ if (constrain == 1):
+ if ((last.x > p1.x) and (last.x < p2.x) or (last.x > p2.x) and (last.x < p1.x)):
+ pc = (last.x-p1.x)/(p2.x-p1.x)
+ cp = (Vector(p1.x+pc*(p2.x-p1.x),p1.y+pc*(p2.y-p1.y),p1.z+pc*(p2.z-p1.z)))
+ ar.append([cp,1,cp]) # constrainpoint
+ return ar
- def getPassivePoint(info):
- "returns a passive snap point"
- cur = Vector(info['x'],info['y'],info['z'])
- return [cur,2,cur]
+ def getPassivePoint(info):
+ "returns a passive snap point"
+ cur = Vector(info['x'],info['y'],info['z'])
+ return [cur,2,cur]
- def getScreenDist(dist,cursor):
- "returns a 3D distance from a screen pixels distance"
- p1 = FreeCADGui.ActiveDocument.ActiveView.getPoint(cursor)
- p2 = FreeCADGui.ActiveDocument.ActiveView.getPoint((cursor[0]+dist,cursor[1]))
- return (p2.sub(p1)).Length
+ def getScreenDist(dist,cursor):
+ "returns a 3D distance from a screen pixels distance"
+ p1 = FreeCADGui.ActiveDocument.ActiveView.getPoint(cursor)
+ p2 = FreeCADGui.ActiveDocument.ActiveView.getPoint((cursor[0]+dist,cursor[1]))
+ return (p2.sub(p1)).Length
- def getGridSnap(target,point):
- "returns a grid snap point if available"
- if target.grid:
- return target.grid.getClosestNode(point)
- return None
+ def getGridSnap(target,point):
+ "returns a grid snap point if available"
+ if target.grid:
+ return target.grid.getClosestNode(point)
+ return None
- def getPerpendicular(edge,last):
- "returns a point on an edge, perpendicular to the given point"
- dv = last.sub(edge.Vertexes[0].Point)
- nv = fcvec.project(dv,fcgeo.vec(edge))
- np = (edge.Vertexes[0].Point).add(nv)
- return np
+ def getPerpendicular(edge,last):
+ "returns a point on an edge, perpendicular to the given point"
+ dv = last.sub(edge.Vertexes[0].Point)
+ nv = fcvec.project(dv,fcgeo.vec(edge))
+ np = (edge.Vertexes[0].Point).add(nv)
+ return np
- # checking if alwaySnap setting is on
- extractrl = False
- if Draft.getParam("alwaysSnap"):
- extractrl = ctrl
- ctrl = True
+ # checking if alwaySnap setting is on
+ extractrl = False
+ if Draft.getParam("alwaysSnap"):
+ extractrl = ctrl
+ ctrl = True
- # setting Radius
- radius = getScreenDist(Draft.getParam("snapRange"),cursor)
+ # setting Radius
+ radius = getScreenDist(Draft.getParam("snapRange"),cursor)
- # checking if parallel to one of the edges of the last objects
- target.snap.off()
- target.extsnap.off()
- if (len(target.node) > 0):
- for o in [lastObj[1],lastObj[0]]:
- if o:
- ob = target.doc.getObject(o)
- if ob:
- edges = ob.Shape.Edges
- if len(edges)<10:
- for e in edges:
- if isinstance(e.Curve,Part.Line):
- last = target.node[len(target.node)-1]
- de = Part.Line(last,last.add(fcgeo.vec(e))).toShape()
- np = getPerpendicular(e,point)
- if (np.sub(point)).Length < radius:
- target.snap.coords.point.setValue((np.x,np.y,np.z))
- target.snap.setMarker("circle")
- target.snap.on()
- target.extsnap.p1(e.Vertexes[0].Point)
- target.extsnap.p2(np)
- target.extsnap.on()
- point = np
- else:
- last = target.node[len(target.node)-1]
- de = Part.Line(last,last.add(fcgeo.vec(e))).toShape()
- np = getPerpendicular(de,point)
- if (np.sub(point)).Length < radius:
- target.snap.coords.point.setValue((np.x,np.y,np.z))
- target.snap.setMarker("circle")
- target.snap.on()
- point = np
+ # checking if parallel to one of the edges of the last objects
+ target.snap.off()
+ target.extsnap.off()
+ if (len(target.node) > 0):
+ for o in [lastObj[1],lastObj[0]]:
+ if o:
+ ob = target.doc.getObject(o)
+ if ob:
+ edges = ob.Shape.Edges
+ if len(edges)<10:
+ for e in edges:
+ if isinstance(e.Curve,Part.Line):
+ last = target.node[len(target.node)-1]
+ de = Part.Line(last,last.add(fcgeo.vec(e))).toShape()
+ np = getPerpendicular(e,point)
+ if (np.sub(point)).Length < radius:
+ target.snap.coords.point.setValue((np.x,np.y,np.z))
+ target.snap.setMarker("circle")
+ target.snap.on()
+ target.extsnap.p1(e.Vertexes[0].Point)
+ target.extsnap.p2(np)
+ target.extsnap.on()
+ point = np
+ else:
+ last = target.node[len(target.node)-1]
+ de = Part.Line(last,last.add(fcgeo.vec(e))).toShape()
+ np = getPerpendicular(de,point)
+ if (np.sub(point)).Length < radius:
+ target.snap.coords.point.setValue((np.x,np.y,np.z))
+ target.snap.setMarker("circle")
+ target.snap.on()
+ point = np
- # check if we snapped to something
- snapped=target.view.getObjectInfo((cursor[0],cursor[1]))
+ # check if we snapped to something
+ snapped=target.view.getObjectInfo((cursor[0],cursor[1]))
- if (snapped == None):
- gpt = getGridSnap(target,point)
- if gpt:
- if radius != 0:
- dv = point.sub(gpt)
- if dv.Length <= radius:
- target.snap.coords.point.setValue((gpt.x,gpt.y,gpt.z))
- target.snap.setMarker("point")
- target.snap.on()
- return gpt
- return point
- else:
- obj = target.doc.getObject(snapped['Object'])
- if hasattr(obj.ViewObject,"Selectable"):
+ if (snapped == None):
+ # nothing has been snapped, check fro grid snap
+ gpt = getGridSnap(target,point)
+ if gpt:
+ if radius != 0:
+ dv = point.sub(gpt)
+ if dv.Length <= radius:
+ target.snap.coords.point.setValue((gpt.x,gpt.y,gpt.z))
+ target.snap.setMarker("point")
+ target.snap.on()
+ return gpt
+ return point
+ else:
+ # we have something to snap
+ obj = target.doc.getObject(snapped['Object'])
+ if hasattr(obj.ViewObject,"Selectable"):
if not obj.ViewObject.Selectable:
return point
- if not ctrl:
+ if not ctrl:
# are we in passive snap?
snapArray = [getPassivePoint(snapped)]
- else:
- snapArray = []
- comp = snapped['Component']
- if obj.isDerivedFrom("Part::Feature"):
- if "Edge" in comp:
- intedges = []
- if lastObj[0]:
- lo = target.doc.getObject(lastObj[0])
- if lo:
- if lo.isDerivedFrom("Part::Feature"):
- intedges = lo.Shape.Edges
+ else:
+ snapArray = []
+ comp = snapped['Component']
+ if obj.isDerivedFrom("Part::Feature"):
+ if "Edge" in comp:
+ # get the stored objects to calculate intersections
+ intedges = []
+ if lastObj[0]:
+ lo = target.doc.getObject(lastObj[0])
+ if lo:
+ if lo.isDerivedFrom("Part::Feature"):
+ intedges = lo.Shape.Edges
- nr = int(comp[4:])-1
- edge = obj.Shape.Edges[nr]
- for v in edge.Vertexes:
- snapArray.append([v.Point,0,v.Point])
- if isinstance(edge.Curve,Part.Line):
- midpoint = fcgeo.findMidpoint(edge)
- snapArray.append([midpoint,1,midpoint])
- if (len(target.node) > 0):
- last = target.node[len(target.node)-1]
- snapArray.extend(getConstrainedPoint(edge,last,target.constrain))
- np = getPerpendicular(edge,last)
- snapArray.append([np,1,np])
+ nr = int(comp[4:])-1
+ edge = obj.Shape.Edges[nr]
+ for v in edge.Vertexes:
+ snapArray.append([v.Point,0,v.Point])
+ if isinstance(edge.Curve,Part.Line):
+ # the edge is a line
+ midpoint = fcgeo.findMidpoint(edge)
+ snapArray.append([midpoint,1,midpoint])
+ if (len(target.node) > 0):
+ last = target.node[len(target.node)-1]
+ snapArray.extend(getConstrainedPoint(edge,last,target.constrain))
+ np = getPerpendicular(edge,last)
+ snapArray.append([np,1,np])
- elif isinstance (edge.Curve,Part.Circle):
- rad = edge.Curve.Radius
- pos = edge.Curve.Center
- for i in [0,30,45,60,90,120,135,150,180,210,225,240,270,300,315,330]:
- ang = math.radians(i)
- cur = Vector(math.sin(ang)*rad+pos.x,math.cos(ang)*rad+pos.y,pos.z)
- snapArray.append([cur,1,cur])
- for i in [15,37.5,52.5,75,105,127.5,142.5,165,195,217.5,232.5,255,285,307.5,322.5,345]:
- ang = math.radians(i)
- cur = Vector(math.sin(ang)*rad+pos.x,math.cos(ang)*rad+pos.y,pos.z)
- snapArray.append([cur,0,pos])
+ elif isinstance (edge.Curve,Part.Circle):
+ # the edge is an arc
+ rad = edge.Curve.Radius
+ pos = edge.Curve.Center
+ for i in [0,30,45,60,90,120,135,150,180,210,225,240,270,300,315,330]:
+ ang = math.radians(i)
+ cur = Vector(math.sin(ang)*rad+pos.x,math.cos(ang)*rad+pos.y,pos.z)
+ snapArray.append([cur,1,cur])
+ for i in [15,37.5,52.5,75,105,127.5,142.5,165,195,217.5,232.5,255,285,307.5,322.5,345]:
+ ang = math.radians(i)
+ cur = Vector(math.sin(ang)*rad+pos.x,math.cos(ang)*rad+pos.y,pos.z)
+ snapArray.append([cur,0,pos])
- for e in intedges:
- pt = fcgeo.findIntersection(e,edge)
- if pt:
- for p in pt:
- snapArray.append([p,3,p])
- elif ("Vertex" in comp):
- p = Vector(snapped['x'],snapped['y'],snapped['z'])
- snapArray.append([p,0,p])
- elif (comp == ''):
- # workaround for the new view provider
- p = Vector(snapped['x'],snapped['y'],snapped['z'])
- snapArray.append([p,2,p])
- else:
- snapArray = [getPassivePoint(snapped)]
- elif Draft.getType(obj) == "Dimension":
- for pt in [obj.Start,obj.End,obj.Dimline]:
- snapArray.append([pt,0,pt])
- elif Draft.getType(obj) == "Mesh":
- for v in obj.Mesh.Points:
- snapArray.append([v.Vector,0,v.Vector])
- if not lastObj[0]:
- lastObj[0] = obj.Name
- lastObj[1] = obj.Name
- if (lastObj[1] != obj.Name):
- lastObj[0] = lastObj[1]
- lastObj[1] = obj.Name
+ for e in intedges:
+ # get the intersection points
+ pt = fcgeo.findIntersection(e,edge)
+ if pt:
+ for p in pt:
+ snapArray.append([p,3,p])
+ elif "Vertex" in comp:
+ # directly snapped to a vertex
+ p = Vector(snapped['x'],snapped['y'],snapped['z'])
+ snapArray.append([p,0,p])
+ elif comp == '':
+ # workaround for the new view provider
+ p = Vector(snapped['x'],snapped['y'],snapped['z'])
+ snapArray.append([p,2,p])
+ else:
+ snapArray = [getPassivePoint(snapped)]
+ elif Draft.getType(obj) == "Dimension":
+ for pt in [obj.Start,obj.End,obj.Dimline]:
+ snapArray.append([pt,0,pt])
+ elif Draft.getType(obj) == "Mesh":
+ for v in obj.Mesh.Points:
+ snapArray.append([v.Vector,0,v.Vector])
+ if not lastObj[0]:
+ lastObj[0] = obj.Name
+ lastObj[1] = obj.Name
+ if (lastObj[1] != obj.Name):
+ lastObj[0] = lastObj[1]
+ lastObj[1] = obj.Name
- # calculating shortest distance
- shortest = 1000000000000000000
- spt = Vector(snapped['x'],snapped['y'],snapped['z'])
- newpoint = [Vector(0,0,0),0,Vector(0,0,0)]
- for pt in snapArray:
- if pt[0] == None: print "snapPoint: debug 'i[0]' is 'None'"
- di = pt[0].sub(spt)
- if di.Length < shortest:
- shortest = di.Length
- newpoint = pt
- if radius != 0:
- dv = point.sub(newpoint[2])
- if (not extractrl) and (dv.Length > radius):
- newpoint = getPassivePoint(snapped)
- target.snap.coords.point.setValue((newpoint[2].x,newpoint[2].y,newpoint[2].z))
- if (newpoint[1] == 1):
- target.snap.setMarker("square")
- elif (newpoint[1] == 0):
- target.snap.setMarker("point")
- elif (newpoint[1] == 3):
- target.snap.setMarker("square")
- else:
- target.snap.setMarker("circle")
- target.snap.on()
- return newpoint[2]
+ # calculating shortest distance
+ shortest = 1000000000000000000
+ spt = Vector(snapped['x'],snapped['y'],snapped['z'])
+ newpoint = [Vector(0,0,0),0,Vector(0,0,0)]
+ for pt in snapArray:
+ if pt[0] == None: print "snapPoint: debug 'i[0]' is 'None'"
+ di = pt[0].sub(spt)
+ if di.Length < shortest:
+ shortest = di.Length
+ newpoint = pt
+ if radius != 0:
+ dv = point.sub(newpoint[2])
+ if (not extractrl) and (dv.Length > radius):
+ newpoint = getPassivePoint(snapped)
+ target.snap.coords.point.setValue((newpoint[2].x,newpoint[2].y,newpoint[2].z))
+ if (newpoint[1] == 1):
+ target.snap.setMarker("square")
+ elif (newpoint[1] == 0):
+ target.snap.setMarker("point")
+ elif (newpoint[1] == 3):
+ target.snap.setMarker("square")
+ else:
+ target.snap.setMarker("circle")
+ target.snap.on()
+ return newpoint[2]
def constrainPoint (target,pt,mobile=False,sym=False):
- '''
- Constrain function used by the Draft tools
- On commands that need to enter several points (currently only line/wire),
- you can constrain the next point to be picked to the last drawn point by
- pressing SHIFT. The vertical or horizontal constraining depends on the
- position of your mouse in relation to last point at the moment you press
- SHIFT. if mobile=True, mobile behaviour applies. If sym=True, x alway = y
- '''
- point = Vector(pt)
- if len(target.node) > 0:
- last = target.node[-1]
- dvec = point.sub(last)
- affinity = plane.getClosestAxis(dvec)
- if ((target.constrain == None) or mobile):
- if affinity == "x":
- dv = fcvec.project(dvec,plane.u)
- point = last.add(dv)
- if sym:
- l = dv.Length
- if dv.getAngle(plane.u) > 1:
- l = -l
- point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
- target.constrain = 0 #x direction
- target.ui.xValue.setEnabled(True)
- target.ui.yValue.setEnabled(False)
- target.ui.zValue.setEnabled(False)
- target.ui.xValue.setFocus()
- elif affinity == "y":
- dv = fcvec.project(dvec,plane.v)
- point = last.add(dv)
- if sym:
- l = dv.Length
- if dv.getAngle(plane.v) > 1:
- l = -l
- point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
- target.constrain = 1 #y direction
- target.ui.xValue.setEnabled(False)
- target.ui.yValue.setEnabled(True)
- target.ui.zValue.setEnabled(False)
- target.ui.yValue.setFocus()
- elif affinity == "z":
- dv = fcvec.project(dvec,plane.axis)
- point = last.add(dv)
- if sym:
- l = dv.Length
- if dv.getAngle(plane.axis) > 1:
- l = -l
- point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
- target.constrain = 2 #z direction
- target.ui.xValue.setEnabled(False)
- target.ui.yValue.setEnabled(False)
- target.ui.zValue.setEnabled(True)
- target.ui.zValue.setFocus()
- else: target.constrain = 3
- elif (target.constrain == 0):
- dv = fcvec.project(dvec,plane.u)
- point = last.add(dv)
- if sym:
- l = dv.Length
- if dv.getAngle(plane.u) > 1:
- l = -l
- point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
- elif (target.constrain == 1):
- dv = fcvec.project(dvec,plane.v)
- point = last.add(dv)
- if sym:
- l = dv.Length
- if dv.getAngle(plane.u) > 1:
- l = -l
- point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
- elif (target.constrain == 2):
- dv = fcvec.project(dvec,plane.axis)
- point = last.add(dv)
- if sym:
- l = dv.Length
- if dv.getAngle(plane.u) > 1:
- l = -l
- point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
- return point
+ '''
+ Constrain function used by the Draft tools
+ On commands that need to enter several points (currently only line/wire),
+ you can constrain the next point to be picked to the last drawn point by
+ pressing SHIFT. The vertical or horizontal constraining depends on the
+ position of your mouse in relation to last point at the moment you press
+ SHIFT. if mobile=True, mobile behaviour applies. If sym=True, x alway = y
+ '''
+ point = Vector(pt)
+ if len(target.node) > 0:
+ last = target.node[-1]
+ dvec = point.sub(last)
+ affinity = plane.getClosestAxis(dvec)
+ if ((target.constrain == None) or mobile):
+ if affinity == "x":
+ dv = fcvec.project(dvec,plane.u)
+ point = last.add(dv)
+ if sym:
+ l = dv.Length
+ if dv.getAngle(plane.u) > 1:
+ l = -l
+ point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
+ target.constrain = 0 #x direction
+ target.ui.xValue.setEnabled(True)
+ target.ui.yValue.setEnabled(False)
+ target.ui.zValue.setEnabled(False)
+ target.ui.xValue.setFocus()
+ elif affinity == "y":
+ dv = fcvec.project(dvec,plane.v)
+ point = last.add(dv)
+ if sym:
+ l = dv.Length
+ if dv.getAngle(plane.v) > 1:
+ l = -l
+ point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
+ target.constrain = 1 #y direction
+ target.ui.xValue.setEnabled(False)
+ target.ui.yValue.setEnabled(True)
+ target.ui.zValue.setEnabled(False)
+ target.ui.yValue.setFocus()
+ elif affinity == "z":
+ dv = fcvec.project(dvec,plane.axis)
+ point = last.add(dv)
+ if sym:
+ l = dv.Length
+ if dv.getAngle(plane.axis) > 1:
+ l = -l
+ point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
+ target.constrain = 2 #z direction
+ target.ui.xValue.setEnabled(False)
+ target.ui.yValue.setEnabled(False)
+ target.ui.zValue.setEnabled(True)
+ target.ui.zValue.setFocus()
+ else: target.constrain = 3
+ elif (target.constrain == 0):
+ dv = fcvec.project(dvec,plane.u)
+ point = last.add(dv)
+ if sym:
+ l = dv.Length
+ if dv.getAngle(plane.u) > 1:
+ l = -l
+ point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
+ elif (target.constrain == 1):
+ dv = fcvec.project(dvec,plane.v)
+ point = last.add(dv)
+ if sym:
+ l = dv.Length
+ if dv.getAngle(plane.u) > 1:
+ l = -l
+ point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
+ elif (target.constrain == 2):
+ dv = fcvec.project(dvec,plane.axis)
+ point = last.add(dv)
+ if sym:
+ l = dv.Length
+ if dv.getAngle(plane.u) > 1:
+ l = -l
+ point = last.add(plane.getGlobalCoords(Vector(l,l,l)))
+ return point
def selectObject(arg):
- '''this is a scene even handler, to be called from the Draft tools
- when they need to select an object'''
- if (arg["Type"] == "SoKeyboardEvent"):
- if (arg["Key"] == "ESCAPE"):
- FreeCAD.activeDraftCommand.finish()
- #TODO : this part raises a coin3D warning about scene traversal, to be fixed.
- if (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- cursor = arg["Position"]
- snapped = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo((cursor[0],cursor[1]))
- if snapped:
- obj = FreeCAD.ActiveDocument.getObject(snapped['Object'])
- FreeCADGui.Selection.addSelection(obj)
- FreeCAD.activeDraftCommand.component=snapped['Component']
- FreeCAD.activeDraftCommand.proceed()
-
+ '''this is a scene even handler, to be called from the Draft tools
+ when they need to select an object'''
+ if (arg["Type"] == "SoKeyboardEvent"):
+ if (arg["Key"] == "ESCAPE"):
+ FreeCAD.activeDraftCommand.finish()
+ # TODO : this part raises a coin3D warning about scene traversal, to be fixed.
+ if (arg["Type"] == "SoMouseButtonEvent"):
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ cursor = arg["Position"]
+ snapped = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo((cursor[0],cursor[1]))
+ if snapped:
+ obj = FreeCAD.ActiveDocument.getObject(snapped['Object'])
+ FreeCADGui.Selection.addSelection(obj)
+ FreeCAD.activeDraftCommand.component=snapped['Component']
+ FreeCAD.activeDraftCommand.proceed()
def getPoint(target,args,mobile=False,sym=False,workingplane=True):
- '''
- Function used by the Draft Tools.
- returns a constrained 3d point and its original point.
- if mobile=True, the constraining occurs from the location of
- mouse cursor when Shift is pressed, otherwise from last entered
- point. If sym=True, x and y values stay always equal. If workingplane=False,
- the point wont be projected on the Working Plane.
- '''
- ui = FreeCADGui.draftToolBar
- view = FreeCADGui.ActiveDocument.ActiveView
- point = view.getPoint(args["Position"][0],args["Position"][1])
- point = snapPoint(target,point,args["Position"],hasMod(args,MODSNAP))
+ '''
+ Function used by the Draft Tools.
+ returns a constrained 3d point and its original point.
+ if mobile=True, the constraining occurs from the location of
+ mouse cursor when Shift is pressed, otherwise from last entered
+ point. If sym=True, x and y values stay always equal. If workingplane=False,
+ the point wont be projected on the Working Plane.
+ '''
+ ui = FreeCADGui.draftToolBar
+ view = FreeCADGui.ActiveDocument.ActiveView
+ point = view.getPoint(args["Position"][0],args["Position"][1])
+ point = snapPoint(target,point,args["Position"],hasMod(args,MODSNAP))
- if (not plane.weak) and workingplane:
- # working plane was explicitely selected - project onto it
- viewDirection = view.getViewDirection()
- if FreeCADGui.ActiveDocument.ActiveView.getCameraType() == "Perspective":
- camera = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
- p = camera.getField("position").getValue()
- # view is from camera to point:
- viewDirection = point.sub(Vector(p[0],p[1],p[2]))
- # if we are not snapping to anything, project along view axis,
- # otherwise perpendicularly
- if view.getObjectInfo((args["Position"][0],args["Position"][1])):
- pass
- # point = plane.projectPoint(point)
- else:
- point = plane.projectPoint(point, viewDirection)
- ctrlPoint = Vector(point.x,point.y,point.z)
- if (hasMod(args,MODCONSTRAIN)): # constraining
- if mobile and (target.constrain == None):
- target.node.append(point)
- point = constrainPoint(target,point,mobile=mobile,sym=sym)
- else:
- target.constrain = None
- ui.xValue.setEnabled(True)
- ui.yValue.setEnabled(True)
- ui.zValue.setEnabled(True)
- if target.node:
- if target.featureName == "Rectangle":
- ui.displayPoint(point, target.node[0], plane=plane)
- else:
- ui.displayPoint(point, target.node[-1], plane=plane)
- else: ui.displayPoint(point, plane=plane)
- return point,ctrlPoint
+ if (not plane.weak) and workingplane:
+ # working plane was explicitely selected - project onto it
+ viewDirection = view.getViewDirection()
+ if FreeCADGui.ActiveDocument.ActiveView.getCameraType() == "Perspective":
+ camera = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
+ p = camera.getField("position").getValue()
+ # view is from camera to point:
+ viewDirection = point.sub(Vector(p[0],p[1],p[2]))
+ # if we are not snapping to anything, project along view axis,
+ # otherwise perpendicularly
+ if view.getObjectInfo((args["Position"][0],args["Position"][1])):
+ pass
+ # point = plane.projectPoint(point)
+ else:
+ point = plane.projectPoint(point, viewDirection)
+ ctrlPoint = Vector(point.x,point.y,point.z)
+ if (hasMod(args,MODCONSTRAIN)): # constraining
+ if mobile and (target.constrain == None):
+ target.node.append(point)
+ point = constrainPoint(target,point,mobile=mobile,sym=sym)
+ else:
+ target.constrain = None
+ ui.xValue.setEnabled(True)
+ ui.yValue.setEnabled(True)
+ ui.zValue.setEnabled(True)
+ if target.node:
+ if target.featureName == "Rectangle":
+ ui.displayPoint(point, target.node[0], plane=plane)
+ else:
+ ui.displayPoint(point, target.node[-1], plane=plane)
+ else: ui.displayPoint(point, plane=plane)
+ return point,ctrlPoint
def getSupport(args):
- "returns the supporting object and sets the working plane"
- snapped = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo((args["Position"][0],args["Position"][1]))
- if not snapped: return None
- obj = None
- plane.save()
- try:
- obj = FreeCAD.ActiveDocument.getObject(snapped['Object'])
- shape = obj.Shape
- component = getattr(shape,snapped["Component"])
- if plane.alignToFace(component, 0) \
- or plane.alignToCurve(component, 0):
- self.display(plane.axis)
- except:
- pass
- return obj
+ "returns the supporting object and sets the working plane"
+ snapped = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo((args["Position"][0],args["Position"][1]))
+ if not snapped: return None
+ obj = None
+ plane.save()
+ try:
+ obj = FreeCAD.ActiveDocument.getObject(snapped['Object'])
+ shape = obj.Shape
+ component = getattr(shape,snapped["Component"])
+ if plane.alignToFace(component, 0) \
+ or plane.alignToCurve(component, 0):
+ self.display(plane.axis)
+ except:
+ pass
+ return obj
def hasMod(args,mod):
- "checks if args has a specific modifier"
- if mod == "shift":
- return args["ShiftDown"]
- elif mod == "ctrl":
- return args["CtrlDown"]
- elif mod == "alt":
- return args["AltDown"]
+ "checks if args has a specific modifier"
+ if mod == "shift":
+ return args["ShiftDown"]
+ elif mod == "ctrl":
+ return args["CtrlDown"]
+ elif mod == "alt":
+ return args["AltDown"]
def setMod(args,mod,state):
- "sets a specific modifier state in args"
- if mod == "shift":
- args["ShiftDown"] = state
- elif mod == "ctrl":
- args["CtrlDown"] = state
- elif mod == "alt":
- args["AltDown"] = state
-
+ "sets a specific modifier state in args"
+ if mod == "shift":
+ args["ShiftDown"] = state
+ elif mod == "ctrl":
+ args["CtrlDown"] = state
+ elif mod == "alt":
+ args["AltDown"] = state
#---------------------------------------------------------------------------
# Trackers
#---------------------------------------------------------------------------
class Tracker:
- "A generic Draft Tracker, to be used by other specific trackers"
- def __init__(self,dotted=False,scolor=None,swidth=None,children=[],ontop=False):
- self.ontop = ontop
- color = coin.SoBaseColor()
- color.rgb = scolor or FreeCADGui.draftToolBar.getDefaultColor("ui")
- drawstyle = coin.SoDrawStyle()
- if swidth:
- drawstyle.lineWidth = swidth
- if dotted:
- drawstyle.style = coin.SoDrawStyle.LINES
- drawstyle.lineWeight = 3
- drawstyle.linePattern = 0x0f0f #0xaa
- node = coin.SoSeparator()
- for c in [drawstyle, color] + children:
- node.addChild(c)
- self.switch = coin.SoSwitch() # this is the on/off switch
- self.switch.addChild(node)
- self.switch.whichChild = -1
- self.Visible = False
- todo.delay(self._insertSwitch, self.switch)
+ "A generic Draft Tracker, to be used by other specific trackers"
+ def __init__(self,dotted=False,scolor=None,swidth=None,children=[],ontop=False):
+ self.ontop = ontop
+ color = coin.SoBaseColor()
+ color.rgb = scolor or FreeCADGui.draftToolBar.getDefaultColor("ui")
+ drawstyle = coin.SoDrawStyle()
+ if swidth:
+ drawstyle.lineWidth = swidth
+ if dotted:
+ drawstyle.style = coin.SoDrawStyle.LINES
+ drawstyle.lineWeight = 3
+ drawstyle.linePattern = 0x0f0f #0xaa
+ node = coin.SoSeparator()
+ for c in [drawstyle, color] + children:
+ node.addChild(c)
+ self.switch = coin.SoSwitch() # this is the on/off switch
+ self.switch.addChild(node)
+ self.switch.whichChild = -1
+ self.Visible = False
+ todo.delay(self._insertSwitch, self.switch)
- def finalize(self):
- todo.delay(self._removeSwitch, self.switch)
- self.switch = None
+ def finalize(self):
+ todo.delay(self._removeSwitch, self.switch)
+ self.switch = None
- def _insertSwitch(self, switch):
- '''insert self.switch into the scene graph. Must not be called
- from an event handler (or other scene graph traversal).'''
- sg=FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
- if self.ontop:
- sg.insertChild(switch,0)
- else:
- sg.addChild(switch)
+ def _insertSwitch(self, switch):
+ '''insert self.switch into the scene graph. Must not be called
+ from an event handler (or other scene graph traversal).'''
+ sg=FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
+ if self.ontop:
+ sg.insertChild(switch,0)
+ else:
+ sg.addChild(switch)
- def _removeSwitch(self, switch):
- '''remove self.switch from the scene graph. As with _insertSwitch,
- must not be called during scene graph traversal).'''
- sg=FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
- sg.removeChild(switch)
+ def _removeSwitch(self, switch):
+ '''remove self.switch from the scene graph. As with _insertSwitch,
+ must not be called during scene graph traversal).'''
+ sg=FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
+ sg.removeChild(switch)
- def on(self):
- self.switch.whichChild = 0
- self.Visible = True
+ def on(self):
+ self.switch.whichChild = 0
+ self.Visible = True
- def off(self):
- self.switch.whichChild = -1
- self.Visible = False
+ def off(self):
+ self.switch.whichChild = -1
+ self.Visible = False
class snapTracker(Tracker):
- "A Snap Mark tracker, used by tools that support snapping"
- def __init__(self):
- color = coin.SoBaseColor()
- color.rgb = FreeCADGui.draftToolBar.getDefaultColor("snap")
- self.marker = coin.SoMarkerSet() # this is the marker symbol
- self.marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_9_9
- self.coords = coin.SoCoordinate3() # this is the coordinate
- self.coords.point.setValue((0,0,0))
- node = coin.SoAnnotation()
- node.addChild(self.coords)
- node.addChild(color)
- node.addChild(self.marker)
- Tracker.__init__(self,children=[node])
+ "A Snap Mark tracker, used by tools that support snapping"
+ def __init__(self):
+ color = coin.SoBaseColor()
+ color.rgb = FreeCADGui.draftToolBar.getDefaultColor("snap")
+ self.marker = coin.SoMarkerSet() # this is the marker symbol
+ self.marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_9_9
+ self.coords = coin.SoCoordinate3() # this is the coordinate
+ self.coords.point.setValue((0,0,0))
+ node = coin.SoAnnotation()
+ node.addChild(self.coords)
+ node.addChild(color)
+ node.addChild(self.marker)
+ Tracker.__init__(self,children=[node])
- def setMarker(self,style):
- if (style == "point"):
- self.marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_9_9
- elif (style == "square"):
- self.marker.markerIndex = coin.SoMarkerSet.DIAMOND_FILLED_9_9
- elif (style == "circle"):
- self.marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_9_9
+ def setMarker(self,style):
+ if (style == "point"):
+ self.marker.markerIndex = coin.SoMarkerSet.CIRCLE_FILLED_9_9
+ elif (style == "square"):
+ self.marker.markerIndex = coin.SoMarkerSet.DIAMOND_FILLED_9_9
+ elif (style == "circle"):
+ self.marker.markerIndex = coin.SoMarkerSet.CIRCLE_LINE_9_9
class lineTracker(Tracker):
- "A Line tracker, used by the tools that need to draw temporary lines"
- def __init__(self,dotted=False,scolor=None,swidth=None):
- line = coin.SoLineSet()
- line.numVertices.setValue(2)
- self.coords = coin.SoCoordinate3() # this is the coordinate
- self.coords.point.setValues(0,2,[[0,0,0],[1,0,0]])
- Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line])
+ "A Line tracker, used by the tools that need to draw temporary lines"
+ def __init__(self,dotted=False,scolor=None,swidth=None):
+ line = coin.SoLineSet()
+ line.numVertices.setValue(2)
+ self.coords = coin.SoCoordinate3() # this is the coordinate
+ self.coords.point.setValues(0,2,[[0,0,0],[1,0,0]])
+ Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line])
- def p1(self,point=None):
- "sets or gets the first point of the line"
- if point:
- self.coords.point.set1Value(0,point.x,point.y,point.z)
- else:
- return Vector(self.coords.point.getValues()[0].getValue())
+ def p1(self,point=None):
+ "sets or gets the first point of the line"
+ if point:
+ self.coords.point.set1Value(0,point.x,point.y,point.z)
+ else:
+ return Vector(self.coords.point.getValues()[0].getValue())
- def p2(self,point=None):
- "sets or gets the second point of the line"
- if point:
- self.coords.point.set1Value(1,point.x,point.y,point.z)
- else:
- return Vector(self.coords.point.getValues()[-1].getValue())
+ def p2(self,point=None):
+ "sets or gets the second point of the line"
+ if point:
+ self.coords.point.set1Value(1,point.x,point.y,point.z)
+ else:
+ return Vector(self.coords.point.getValues()[-1].getValue())
- def getLength(self):
- "returns the length of the line"
- p1 = Vector(self.coords.point.getValues()[0].getValue())
- p2 = Vector(self.coords.point.getValues()[-1].getValue())
- return (p2.sub(p1)).Length
+ def getLength(self):
+ "returns the length of the line"
+ p1 = Vector(self.coords.point.getValues()[0].getValue())
+ p2 = Vector(self.coords.point.getValues()[-1].getValue())
+ return (p2.sub(p1)).Length
class rectangleTracker(Tracker):
- "A Rectangle tracker, used by the rectangle tool"
- def __init__(self,dotted=False,scolor=None,swidth=None):
- self.origin = Vector(0,0,0)
- line = coin.SoLineSet()
- line.numVertices.setValue(5)
- self.coords = coin.SoCoordinate3() # this is the coordinate
- self.coords.point.setValues(0,50,[[0,0,0],[2,0,0],[2,2,0],[0,2,0],[0,0,0]])
- Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line])
- self.u = plane.u
- self.v = plane.v
+ "A Rectangle tracker, used by the rectangle tool"
+ def __init__(self,dotted=False,scolor=None,swidth=None):
+ self.origin = Vector(0,0,0)
+ line = coin.SoLineSet()
+ line.numVertices.setValue(5)
+ self.coords = coin.SoCoordinate3() # this is the coordinate
+ self.coords.point.setValues(0,50,[[0,0,0],[2,0,0],[2,2,0],[0,2,0],[0,0,0]])
+ Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line])
+ self.u = plane.u
+ self.v = plane.v
- def setorigin(self,point):
- "sets the base point of the rectangle"
- self.coords.point.set1Value(0,point.x,point.y,point.z)
- self.coords.point.set1Value(4,point.x,point.y,point.z)
- self.origin = point
+ def setorigin(self,point):
+ "sets the base point of the rectangle"
+ self.coords.point.set1Value(0,point.x,point.y,point.z)
+ self.coords.point.set1Value(4,point.x,point.y,point.z)
+ self.origin = point
- def update(self,point):
- "sets the opposite (diagonal) point of the rectangle"
- diagonal = point.sub(self.origin)
- inpoint1 = self.origin.add(fcvec.project(diagonal,self.v))
- inpoint2 = self.origin.add(fcvec.project(diagonal,self.u))
- self.coords.point.set1Value(1,inpoint1.x,inpoint1.y,inpoint1.z)
- self.coords.point.set1Value(2,point.x,point.y,point.z)
- self.coords.point.set1Value(3,inpoint2.x,inpoint2.y,inpoint2.z)
+ def update(self,point):
+ "sets the opposite (diagonal) point of the rectangle"
+ diagonal = point.sub(self.origin)
+ inpoint1 = self.origin.add(fcvec.project(diagonal,self.v))
+ inpoint2 = self.origin.add(fcvec.project(diagonal,self.u))
+ self.coords.point.set1Value(1,inpoint1.x,inpoint1.y,inpoint1.z)
+ self.coords.point.set1Value(2,point.x,point.y,point.z)
+ self.coords.point.set1Value(3,inpoint2.x,inpoint2.y,inpoint2.z)
- def setPlane(self,u,v=None):
- '''sets given (u,v) vectors as working plane. You can give only u
- and v will be deduced automatically given current workplane'''
- self.u = u
- if v:
- self.v = v
- else:
- norm = plane.u.cross(plane.v)
- self.v = self.u.cross(norm)
+ def setPlane(self,u,v=None):
+ '''sets given (u,v) vectors as working plane. You can give only u
+ and v will be deduced automatically given current workplane'''
+ self.u = u
+ if v:
+ self.v = v
+ else:
+ norm = plane.u.cross(plane.v)
+ self.v = self.u.cross(norm)
- def p1(self,point=None):
- "sets or gets the base point of the rectangle"
- if point:
- self.setorigin(point)
- else:
- return Vector(self.coords.point.getValues()[0].getValue())
+ def p1(self,point=None):
+ "sets or gets the base point of the rectangle"
+ if point:
+ self.setorigin(point)
+ else:
+ return Vector(self.coords.point.getValues()[0].getValue())
- def p2(self):
- "gets the second point (on u axis) of the rectangle"
- return Vector(self.coords.point.getValues()[3].getValue())
+ def p2(self):
+ "gets the second point (on u axis) of the rectangle"
+ return Vector(self.coords.point.getValues()[3].getValue())
- def p3(self,point=None):
- "sets or gets the opposite (diagonal) point of the rectangle"
- if point:
- self.update(point)
- else:
- return Vector(self.coords.point.getValues()[2].getValue())
+ def p3(self,point=None):
+ "sets or gets the opposite (diagonal) point of the rectangle"
+ if point:
+ self.update(point)
+ else:
+ return Vector(self.coords.point.getValues()[2].getValue())
- def p4(self):
- "gets the fourth point (on v axis) of the rectangle"
- return Vector(self.coords.point.getValues()[1].getValue())
+ def p4(self):
+ "gets the fourth point (on v axis) of the rectangle"
+ return Vector(self.coords.point.getValues()[1].getValue())
- def getSize(self):
- "returns (length,width) of the rectangle"
- p1 = Vector(self.coords.point.getValues()[0].getValue())
- p2 = Vector(self.coords.point.getValues()[2].getValue())
- diag = p2.sub(p1)
- return ((fcvec.project(diag,self.u)).Length,(fcvec.project(diag,self.v)).Length)
+ def getSize(self):
+ "returns (length,width) of the rectangle"
+ p1 = Vector(self.coords.point.getValues()[0].getValue())
+ p2 = Vector(self.coords.point.getValues()[2].getValue())
+ diag = p2.sub(p1)
+ return ((fcvec.project(diag,self.u)).Length,(fcvec.project(diag,self.v)).Length)
- def getNormal(self):
- "returns the normal of the rectangle"
- return (self.u.cross(self.v)).normalize()
+ def getNormal(self):
+ "returns the normal of the rectangle"
+ return (self.u.cross(self.v)).normalize()
class dimTracker(Tracker):
- "A Dimension tracker, used by the dimension tool"
- def __init__(self,dotted=False,scolor=None,swidth=None):
- line = coin.SoLineSet()
- line.numVertices.setValue(4)
- self.coords = coin.SoCoordinate3() # this is the coordinate
- self.coords.point.setValues(0,4,[[0,0,0],[0,0,0],[0,0,0],[0,0,0]])
- Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line])
- self.p1 = self.p2 = self.p3 = None
+ "A Dimension tracker, used by the dimension tool"
+ def __init__(self,dotted=False,scolor=None,swidth=None):
+ line = coin.SoLineSet()
+ line.numVertices.setValue(4)
+ self.coords = coin.SoCoordinate3() # this is the coordinate
+ self.coords.point.setValues(0,4,[[0,0,0],[0,0,0],[0,0,0],[0,0,0]])
+ Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line])
+ self.p1 = self.p2 = self.p3 = None
- def update(self,pts):
- if len(pts) == 1:
- self.p3 = pts[0]
- else:
- self.p1 = pts[0]
- self.p2 = pts[1]
- if len(pts) > 2:
- self.p3 = pts[2]
- self.calc()
+ def update(self,pts):
+ if len(pts) == 1:
+ self.p3 = pts[0]
+ else:
+ self.p1 = pts[0]
+ self.p2 = pts[1]
+ if len(pts) > 2:
+ self.p3 = pts[2]
+ self.calc()
- def calc(self):
- if (self.p1 != None) and (self.p2 != None):
- points = [fcvec.tup(self.p1,True),fcvec.tup(self.p2,True),\
- fcvec.tup(self.p1,True),fcvec.tup(self.p2,True)]
- if self.p3 != None:
- p1 = self.p1
- p4 = self.p2
- if fcvec.equals(p1,p4):
- proj = None
- else:
- base = Part.Line(p1,p4).toShape()
- proj = fcgeo.findDistance(self.p3,base)
- if not proj:
- p2 = p1
- p3 = p4
- else:
- p2 = p1.add(fcvec.neg(proj))
- p3 = p4.add(fcvec.neg(proj))
- points = [fcvec.tup(p1),fcvec.tup(p2),fcvec.tup(p3),fcvec.tup(p4)]
- self.coords.point.setValues(0,4,points)
+ def calc(self):
+ if (self.p1 != None) and (self.p2 != None):
+ points = [fcvec.tup(self.p1,True),fcvec.tup(self.p2,True),\
+ fcvec.tup(self.p1,True),fcvec.tup(self.p2,True)]
+ if self.p3 != None:
+ p1 = self.p1
+ p4 = self.p2
+ if fcvec.equals(p1,p4):
+ proj = None
+ else:
+ base = Part.Line(p1,p4).toShape()
+ proj = fcgeo.findDistance(self.p3,base)
+ if not proj:
+ p2 = p1
+ p3 = p4
+ else:
+ p2 = p1.add(fcvec.neg(proj))
+ p3 = p4.add(fcvec.neg(proj))
+ points = [fcvec.tup(p1),fcvec.tup(p2),fcvec.tup(p3),fcvec.tup(p4)]
+ self.coords.point.setValues(0,4,points)
class bsplineTracker(Tracker):
"A bspline tracker"
@@ -740,16 +728,16 @@ class bsplineTracker(Tracker):
c = Part.BSplineCurve()
# DNC: allows to close the curve by placing ends close to each other
if ( len(self.points) >= 3 ) and ( (self.points[0] - self.points[-1]).Length < Draft.tolerance() ):
- # YVH: Added a try to bypass some hazardous situations
- try:
- c.interpolate(self.points[:-1], True)
- except:
- pass
+ # YVH: Added a try to bypass some hazardous situations
+ try:
+ c.interpolate(self.points[:-1], True)
+ except:
+ pass
elif self.points:
- try:
- c.interpolate(self.points, False)
- except:
- pass
+ try:
+ c.interpolate(self.points, False)
+ except:
+ pass
c = c.toShape()
buf=c.writeInventor(2,0.01)
#fp=open("spline.iv","w")
@@ -768,325 +756,325 @@ class bsplineTracker(Tracker):
FreeCAD.Console.PrintWarning("bsplineTracker.recompute() failed to read-in Inventor string\n")
class arcTracker(Tracker):
- "An arc tracker"
- def __init__(self,dotted=False,scolor=None,swidth=None,start=0,end=math.pi*2):
- self.circle = None
- self.startangle = math.degrees(start)
- self.endangle = math.degrees(end)
- self.trans = coin.SoTransform()
- self.trans.translation.setValue([0,0,0])
- self.sep = coin.SoSeparator()
- self.recompute()
- Tracker.__init__(self,dotted,scolor,swidth,[self.trans, self.sep])
+ "An arc tracker"
+ def __init__(self,dotted=False,scolor=None,swidth=None,start=0,end=math.pi*2):
+ self.circle = None
+ self.startangle = math.degrees(start)
+ self.endangle = math.degrees(end)
+ self.trans = coin.SoTransform()
+ self.trans.translation.setValue([0,0,0])
+ self.sep = coin.SoSeparator()
+ self.recompute()
+ Tracker.__init__(self,dotted,scolor,swidth,[self.trans, self.sep])
- def setCenter(self,cen):
- "sets the center point"
- self.trans.translation.setValue([cen.x,cen.y,cen.z])
+ def setCenter(self,cen):
+ "sets the center point"
+ self.trans.translation.setValue([cen.x,cen.y,cen.z])
- def setRadius(self,rad):
- "sets the radius"
- self.trans.scaleFactor.setValue([rad,rad,rad])
+ def setRadius(self,rad):
+ "sets the radius"
+ self.trans.scaleFactor.setValue([rad,rad,rad])
- def getRadius(self):
- "returns the current radius"
- return self.trans.scaleFactor.getValue()[0]
+ def getRadius(self):
+ "returns the current radius"
+ return self.trans.scaleFactor.getValue()[0]
- def setStartAngle(self,ang):
- "sets the start angle"
- self.startangle = math.degrees(ang)
- self.recompute()
+ def setStartAngle(self,ang):
+ "sets the start angle"
+ self.startangle = math.degrees(ang)
+ self.recompute()
- def setEndAngle(self,ang):
- "sets the end angle"
- self.endangle = math.degrees(ang)
- self.recompute()
+ def setEndAngle(self,ang):
+ "sets the end angle"
+ self.endangle = math.degrees(ang)
+ self.recompute()
- def getAngle(self,pt):
- "returns the angle of a given vector"
- c = self.trans.translation.getValue()
- center = Vector(c[0],c[1],c[2])
- base = plane.u
- rad = pt.sub(center)
- return(fcvec.angle(rad,base,plane.axis))
+ def getAngle(self,pt):
+ "returns the angle of a given vector"
+ c = self.trans.translation.getValue()
+ center = Vector(c[0],c[1],c[2])
+ base = plane.u
+ rad = pt.sub(center)
+ return(fcvec.angle(rad,base,plane.axis))
- def getAngles(self):
- "returns the start and end angles"
- return(self.startangle,self.endangle)
+ def getAngles(self):
+ "returns the start and end angles"
+ return(self.startangle,self.endangle)
- def setStartPoint(self,pt):
- "sets the start angle from a point"
- self.setStartAngle(-self.getAngle(pt))
+ def setStartPoint(self,pt):
+ "sets the start angle from a point"
+ self.setStartAngle(-self.getAngle(pt))
- def setEndPoint(self,pt):
- "sets the end angle from a point"
- self.setEndAngle(self.getAngle(pt))
+ def setEndPoint(self,pt):
+ "sets the end angle from a point"
+ self.setEndAngle(self.getAngle(pt))
- def setApertureAngle(self,ang):
- "sets the end angle by giving the aperture angle"
- ap = math.degrees(ang)
- self.endangle = self.startangle + ap
- self.recompute()
+ def setApertureAngle(self,ang):
+ "sets the end angle by giving the aperture angle"
+ ap = math.degrees(ang)
+ self.endangle = self.startangle + ap
+ self.recompute()
- def recompute(self):
- if self.circle: self.sep.removeChild(self.circle)
- self.circle = None
- if self.endangle < self.startangle:
- c = Part.makeCircle(1,Vector(0,0,0),plane.axis,self.endangle,self.startangle)
- else:
- c = Part.makeCircle(1,Vector(0,0,0),plane.axis,self.startangle,self.endangle)
- buf=c.writeInventor(2,0.01)
- ivin = coin.SoInput()
- ivin.setBuffer(buf)
- ivob = coin.SoDB.readAll(ivin)
- # In case reading from buffer failed
- if ivob and ivob.getNumChildren() > 1:
- self.circle = ivob.getChild(1).getChild(0)
- self.circle.removeChild(self.circle.getChild(0))
- self.circle.removeChild(self.circle.getChild(0))
- self.sep.addChild(self.circle)
- else:
- FreeCAD.Console.PrintWarning("arcTracker.recompute() failed to read-in Inventor string\n")
+ def recompute(self):
+ if self.circle: self.sep.removeChild(self.circle)
+ self.circle = None
+ if self.endangle < self.startangle:
+ c = Part.makeCircle(1,Vector(0,0,0),plane.axis,self.endangle,self.startangle)
+ else:
+ c = Part.makeCircle(1,Vector(0,0,0),plane.axis,self.startangle,self.endangle)
+ buf=c.writeInventor(2,0.01)
+ ivin = coin.SoInput()
+ ivin.setBuffer(buf)
+ ivob = coin.SoDB.readAll(ivin)
+ # In case reading from buffer failed
+ if ivob and ivob.getNumChildren() > 1:
+ self.circle = ivob.getChild(1).getChild(0)
+ self.circle.removeChild(self.circle.getChild(0))
+ self.circle.removeChild(self.circle.getChild(0))
+ self.sep.addChild(self.circle)
+ else:
+ FreeCAD.Console.PrintWarning("arcTracker.recompute() failed to read-in Inventor string\n")
class ghostTracker(Tracker):
- '''A Ghost tracker, that allows to copy whole object representations.
- You can pass it an object or a list of objects, or a shape.'''
- def __init__(self,sel):
- self.trans = coin.SoTransform()
- self.trans.translation.setValue([0,0,0])
- self.children = [self.trans]
- self.ivsep = coin.SoSeparator()
- try:
- if isinstance(sel,Part.Shape):
- ivin = coin.SoInput()
- ivin.setBuffer(sel.writeInventor())
- ivob = coin.SoDB.readAll(ivin)
- self.ivsep.addChild(ivob.getChildren()[1])
- else:
- if not isinstance(sel,list):
- sel = [sel]
- for obj in sel:
- self.ivsep.addChild(obj.ViewObject.RootNode.copy())
- except:
- print "draft: Couldn't create ghost"
- self.children.append(self.ivsep)
- Tracker.__init__(self,children=self.children)
+ '''A Ghost tracker, that allows to copy whole object representations.
+ You can pass it an object or a list of objects, or a shape.'''
+ def __init__(self,sel):
+ self.trans = coin.SoTransform()
+ self.trans.translation.setValue([0,0,0])
+ self.children = [self.trans]
+ self.ivsep = coin.SoSeparator()
+ try:
+ if isinstance(sel,Part.Shape):
+ ivin = coin.SoInput()
+ ivin.setBuffer(sel.writeInventor())
+ ivob = coin.SoDB.readAll(ivin)
+ self.ivsep.addChild(ivob.getChildren()[1])
+ else:
+ if not isinstance(sel,list):
+ sel = [sel]
+ for obj in sel:
+ self.ivsep.addChild(obj.ViewObject.RootNode.copy())
+ except:
+ print "draft: Couldn't create ghost"
+ self.children.append(self.ivsep)
+ Tracker.__init__(self,children=self.children)
- def update(self,obj):
- obj.ViewObject.show()
- self.finalize()
- self.ivsep = coin.SoSeparator()
- self.ivsep.addChild(obj.ViewObject.RootNode.copy())
- Tracker.__init__(self,children=[self.ivsep])
- self.on()
- obj.ViewObject.hide()
+ def update(self,obj):
+ obj.ViewObject.show()
+ self.finalize()
+ self.ivsep = coin.SoSeparator()
+ self.ivsep.addChild(obj.ViewObject.RootNode.copy())
+ Tracker.__init__(self,children=[self.ivsep])
+ self.on()
+ obj.ViewObject.hide()
class editTracker(Tracker):
- "A node edit tracker"
- def __init__(self,pos=Vector(0,0,0),name="None",idx=0,objcol=None):
- color = coin.SoBaseColor()
- if objcol:
- color.rgb = objcol[:3]
- else:
- color.rgb = FreeCADGui.draftToolBar.getDefaultColor("snap")
- self.marker = coin.SoMarkerSet() # this is the marker symbol
- self.marker.markerIndex = coin.SoMarkerSet.SQUARE_FILLED_9_9
- self.coords = coin.SoCoordinate3() # this is the coordinate
- self.coords.point.setValue((pos.x,pos.y,pos.z))
- selnode = coin.SoType.fromName("SoFCSelection").createInstance()
- selnode.documentName.setValue(FreeCAD.ActiveDocument.Name)
- selnode.objectName.setValue(name)
- selnode.subElementName.setValue("EditNode"+str(idx))
- node = coin.SoAnnotation()
- selnode.addChild(self.coords)
- selnode.addChild(color)
- selnode.addChild(self.marker)
- node.addChild(selnode)
- Tracker.__init__(self,children=[node],ontop=True)
- self.on()
+ "A node edit tracker"
+ def __init__(self,pos=Vector(0,0,0),name="None",idx=0,objcol=None):
+ color = coin.SoBaseColor()
+ if objcol:
+ color.rgb = objcol[:3]
+ else:
+ color.rgb = FreeCADGui.draftToolBar.getDefaultColor("snap")
+ self.marker = coin.SoMarkerSet() # this is the marker symbol
+ self.marker.markerIndex = coin.SoMarkerSet.SQUARE_FILLED_9_9
+ self.coords = coin.SoCoordinate3() # this is the coordinate
+ self.coords.point.setValue((pos.x,pos.y,pos.z))
+ selnode = coin.SoType.fromName("SoFCSelection").createInstance()
+ selnode.documentName.setValue(FreeCAD.ActiveDocument.Name)
+ selnode.objectName.setValue(name)
+ selnode.subElementName.setValue("EditNode"+str(idx))
+ node = coin.SoAnnotation()
+ selnode.addChild(self.coords)
+ selnode.addChild(color)
+ selnode.addChild(self.marker)
+ node.addChild(selnode)
+ Tracker.__init__(self,children=[node],ontop=True)
+ self.on()
- def set(self,pos):
- self.coords.point.setValue((pos.x,pos.y,pos.z))
+ def set(self,pos):
+ self.coords.point.setValue((pos.x,pos.y,pos.z))
- def get(self):
- p = self.coords.point.getValues()[0]
- return Vector(p[0],p[1],p[2])
+ def get(self):
+ p = self.coords.point.getValues()[0]
+ return Vector(p[0],p[1],p[2])
- def move(self,delta):
- self.set(self.get().add(delta))
+ def move(self,delta):
+ self.set(self.get().add(delta))
class PlaneTracker(Tracker):
- "A working plane tracker"
- def __init__(self):
- # getting screen distance
- p1 = FreeCADGui.ActiveDocument.ActiveView.getPoint((100,100))
- p2 = FreeCADGui.ActiveDocument.ActiveView.getPoint((110,100))
- bl = (p2.sub(p1)).Length * (Draft.getParam("snapRange")/2)
- self.trans = coin.SoTransform()
- self.trans.translation.setValue([0,0,0])
- m1 = coin.SoMaterial()
- m1.transparency.setValue(0.8)
- m1.diffuseColor.setValue([0.4,0.4,0.6])
- c1 = coin.SoCoordinate3()
- c1.point.setValues([[-bl,-bl,0],[bl,-bl,0],[bl,bl,0],[-bl,bl,0]])
- f = coin.SoIndexedFaceSet()
- f.coordIndex.setValues([0,1,2,3])
- m2 = coin.SoMaterial()
- m2.transparency.setValue(0.7)
- m2.diffuseColor.setValue([0.2,0.2,0.3])
- c2 = coin.SoCoordinate3()
- c2.point.setValues([[0,bl,0],[0,0,0],[bl,0,0],[-.05*bl,.95*bl,0],[0,bl,0],
- [.05*bl,.95*bl,0],[.95*bl,.05*bl,0],[bl,0,0],[.95*bl,-.05*bl,0]])
- l = coin.SoLineSet()
- l.numVertices.setValues([3,3,3])
- s = coin.SoSeparator()
- s.addChild(self.trans)
- s.addChild(m1)
- s.addChild(c1)
- s.addChild(f)
- s.addChild(m2)
- s.addChild(c2)
- s.addChild(l)
- Tracker.__init__(self,children=[s])
+ "A working plane tracker"
+ def __init__(self):
+ # getting screen distance
+ p1 = FreeCADGui.ActiveDocument.ActiveView.getPoint((100,100))
+ p2 = FreeCADGui.ActiveDocument.ActiveView.getPoint((110,100))
+ bl = (p2.sub(p1)).Length * (Draft.getParam("snapRange")/2)
+ self.trans = coin.SoTransform()
+ self.trans.translation.setValue([0,0,0])
+ m1 = coin.SoMaterial()
+ m1.transparency.setValue(0.8)
+ m1.diffuseColor.setValue([0.4,0.4,0.6])
+ c1 = coin.SoCoordinate3()
+ c1.point.setValues([[-bl,-bl,0],[bl,-bl,0],[bl,bl,0],[-bl,bl,0]])
+ f = coin.SoIndexedFaceSet()
+ f.coordIndex.setValues([0,1,2,3])
+ m2 = coin.SoMaterial()
+ m2.transparency.setValue(0.7)
+ m2.diffuseColor.setValue([0.2,0.2,0.3])
+ c2 = coin.SoCoordinate3()
+ c2.point.setValues([[0,bl,0],[0,0,0],[bl,0,0],[-.05*bl,.95*bl,0],[0,bl,0],
+ [.05*bl,.95*bl,0],[.95*bl,.05*bl,0],[bl,0,0],[.95*bl,-.05*bl,0]])
+ l = coin.SoLineSet()
+ l.numVertices.setValues([3,3,3])
+ s = coin.SoSeparator()
+ s.addChild(self.trans)
+ s.addChild(m1)
+ s.addChild(c1)
+ s.addChild(f)
+ s.addChild(m2)
+ s.addChild(c2)
+ s.addChild(l)
+ Tracker.__init__(self,children=[s])
- def set(self,pos=None):
- if pos:
- Q = plane.getRotation().Rotation.Q
- else:
- plm = plane.getPlacement()
- Q = plm.Rotation.Q
- pos = plm.Base
- self.trans.translation.setValue([pos.x,pos.y,pos.z])
- self.trans.rotation.setValue([Q[0],Q[1],Q[2],Q[3]])
- self.on()
+ def set(self,pos=None):
+ if pos:
+ Q = plane.getRotation().Rotation.Q
+ else:
+ plm = plane.getPlacement()
+ Q = plm.Rotation.Q
+ pos = plm.Base
+ self.trans.translation.setValue([pos.x,pos.y,pos.z])
+ self.trans.rotation.setValue([Q[0],Q[1],Q[2],Q[3]])
+ self.on()
class wireTracker(Tracker):
- "A wire tracker"
- def __init__(self,wire):
- self.line = coin.SoLineSet()
- self.closed = fcgeo.isReallyClosed(wire)
- if self.closed:
- self.line.numVertices.setValue(len(wire.Vertexes)+1)
- else:
- self.line.numVertices.setValue(len(wire.Vertexes))
- self.coords = coin.SoCoordinate3()
- self.update(wire)
- Tracker.__init__(self,children=[self.coords,self.line])
+ "A wire tracker"
+ def __init__(self,wire):
+ self.line = coin.SoLineSet()
+ self.closed = fcgeo.isReallyClosed(wire)
+ if self.closed:
+ self.line.numVertices.setValue(len(wire.Vertexes)+1)
+ else:
+ self.line.numVertices.setValue(len(wire.Vertexes))
+ self.coords = coin.SoCoordinate3()
+ self.update(wire)
+ Tracker.__init__(self,children=[self.coords,self.line])
- def update(self,wire):
- if wire:
- self.line.numVertices.setValue(len(wire.Vertexes))
- for i in range(len(wire.Vertexes)):
- p=wire.Vertexes[i].Point
- self.coords.point.set1Value(i,[p.x,p.y,p.z])
- if self.closed:
- t = len(wire.Vertexes)
- p = wire.Vertexes[0].Point
- self.coords.point.set1Value(t,[p.x,p.y,p.z])
+ def update(self,wire):
+ if wire:
+ self.line.numVertices.setValue(len(wire.Vertexes))
+ for i in range(len(wire.Vertexes)):
+ p=wire.Vertexes[i].Point
+ self.coords.point.set1Value(i,[p.x,p.y,p.z])
+ if self.closed:
+ t = len(wire.Vertexes)
+ p = wire.Vertexes[0].Point
+ self.coords.point.set1Value(t,[p.x,p.y,p.z])
class gridTracker(Tracker):
- "A grid tracker"
- def __init__(self):
- # self.space = 1
- self.space = Draft.getParam("gridSpacing")
- # self.mainlines = 10
- self.mainlines = Draft.getParam("gridEvery")
- self.numlines = 100
- col = [0.2,0.2,0.3]
-
- self.trans = coin.SoTransform()
- self.trans.translation.setValue([0,0,0])
+ "A grid tracker"
+ def __init__(self):
+ # self.space = 1
+ self.space = Draft.getParam("gridSpacing")
+ # self.mainlines = 10
+ self.mainlines = Draft.getParam("gridEvery")
+ self.numlines = 100
+ col = [0.2,0.2,0.3]
+
+ self.trans = coin.SoTransform()
+ self.trans.translation.setValue([0,0,0])
- bound = (self.numlines/2)*self.space
- pts = []
- mpts = []
- for i in range(self.numlines+1):
- curr = -bound + i*self.space
- z = 0
- if i/float(self.mainlines) == i/self.mainlines:
- mpts.extend([[-bound,curr,z],[bound,curr,z]])
- mpts.extend([[curr,-bound,z],[curr,bound,z]])
- else:
- pts.extend([[-bound,curr,z],[bound,curr,z]])
- pts.extend([[curr,-bound,z],[curr,bound,z]])
- idx = []
- midx = []
- for p in range(0,len(pts),2):
- idx.append(2)
- for mp in range(0,len(mpts),2):
- midx.append(2)
+ bound = (self.numlines/2)*self.space
+ pts = []
+ mpts = []
+ for i in range(self.numlines+1):
+ curr = -bound + i*self.space
+ z = 0
+ if i/float(self.mainlines) == i/self.mainlines:
+ mpts.extend([[-bound,curr,z],[bound,curr,z]])
+ mpts.extend([[curr,-bound,z],[curr,bound,z]])
+ else:
+ pts.extend([[-bound,curr,z],[bound,curr,z]])
+ pts.extend([[curr,-bound,z],[curr,bound,z]])
+ idx = []
+ midx = []
+ for p in range(0,len(pts),2):
+ idx.append(2)
+ for mp in range(0,len(mpts),2):
+ midx.append(2)
- mat1 = coin.SoMaterial()
- mat1.transparency.setValue(0.7)
- mat1.diffuseColor.setValue(col)
- self.coords1 = coin.SoCoordinate3()
- self.coords1.point.setValues(pts)
- lines1 = coin.SoLineSet()
- lines1.numVertices.setValues(idx)
- mat2 = coin.SoMaterial()
- mat2.transparency.setValue(0.3)
- mat2.diffuseColor.setValue(col)
- self.coords2 = coin.SoCoordinate3()
- self.coords2.point.setValues(mpts)
- lines2 = coin.SoLineSet()
- lines2.numVertices.setValues(midx)
- s = coin.SoSeparator()
- s.addChild(self.trans)
- s.addChild(mat1)
- s.addChild(self.coords1)
- s.addChild(lines1)
- s.addChild(mat2)
- s.addChild(self.coords2)
- s.addChild(lines2)
- Tracker.__init__(self,children=[s])
- self.update()
+ mat1 = coin.SoMaterial()
+ mat1.transparency.setValue(0.7)
+ mat1.diffuseColor.setValue(col)
+ self.coords1 = coin.SoCoordinate3()
+ self.coords1.point.setValues(pts)
+ lines1 = coin.SoLineSet()
+ lines1.numVertices.setValues(idx)
+ mat2 = coin.SoMaterial()
+ mat2.transparency.setValue(0.3)
+ mat2.diffuseColor.setValue(col)
+ self.coords2 = coin.SoCoordinate3()
+ self.coords2.point.setValues(mpts)
+ lines2 = coin.SoLineSet()
+ lines2.numVertices.setValues(midx)
+ s = coin.SoSeparator()
+ s.addChild(self.trans)
+ s.addChild(mat1)
+ s.addChild(self.coords1)
+ s.addChild(lines1)
+ s.addChild(mat2)
+ s.addChild(self.coords2)
+ s.addChild(lines2)
+ Tracker.__init__(self,children=[s])
+ self.update()
- def update(self):
- bound = (self.numlines/2)*self.space
- pts = []
- mpts = []
- for i in range(self.numlines+1):
- curr = -bound + i*self.space
- if i/float(self.mainlines) == i/self.mainlines:
- mpts.extend([[-bound,curr,0],[bound,curr,0]])
- mpts.extend([[curr,-bound,0],[curr,bound,0]])
- else:
- pts.extend([[-bound,curr,0],[bound,curr,0]])
- pts.extend([[curr,-bound,0],[curr,bound,0]])
- self.coords1.point.setValues(pts)
- self.coords2.point.setValues(mpts)
+ def update(self):
+ bound = (self.numlines/2)*self.space
+ pts = []
+ mpts = []
+ for i in range(self.numlines+1):
+ curr = -bound + i*self.space
+ if i/float(self.mainlines) == i/self.mainlines:
+ mpts.extend([[-bound,curr,0],[bound,curr,0]])
+ mpts.extend([[curr,-bound,0],[curr,bound,0]])
+ else:
+ pts.extend([[-bound,curr,0],[bound,curr,0]])
+ pts.extend([[curr,-bound,0],[curr,bound,0]])
+ self.coords1.point.setValues(pts)
+ self.coords2.point.setValues(mpts)
- def setSpacing(self,space):
- self.space = space
- self.update()
+ def setSpacing(self,space):
+ self.space = space
+ self.update()
- def setMainlines(self,ml):
- self.mainlines = ml
- self.update()
+ def setMainlines(self,ml):
+ self.mainlines = ml
+ self.update()
- def set(self):
- Q = plane.getRotation().Rotation.Q
- self.trans.rotation.setValue([Q[0],Q[1],Q[2],Q[3]])
- self.on()
+ def set(self):
+ Q = plane.getRotation().Rotation.Q
+ self.trans.rotation.setValue([Q[0],Q[1],Q[2],Q[3]])
+ self.on()
- def getClosestNode(self,point):
- "returns the closest node from the given point"
- # get the 2D coords.
- point = plane.projectPoint(point)
- u = fcvec.project(point,plane.u)
- lu = u.Length
- if u.getAngle(plane.u) > 1.5:
- lu = -lu
- v = fcvec.project(point,plane.v)
- lv = v.Length
- if v.getAngle(plane.v) > 1.5:
- lv = -lv
- # print "u = ",u," v = ",v
- # find nearest grid node
- pu = (round(lu/self.space,0))*self.space
- pv = (round(lv/self.space,0))*self.space
- rot = FreeCAD.Rotation()
- rot.Q = self.trans.rotation.getValue().getValue()
- return rot.multVec(Vector(pu,pv,0))
+ def getClosestNode(self,point):
+ "returns the closest node from the given point"
+ # get the 2D coords.
+ point = plane.projectPoint(point)
+ u = fcvec.project(point,plane.u)
+ lu = u.Length
+ if u.getAngle(plane.u) > 1.5:
+ lu = -lu
+ v = fcvec.project(point,plane.v)
+ lv = v.Length
+ if v.getAngle(plane.v) > 1.5:
+ lv = -lv
+ # print "u = ",u," v = ",v
+ # find nearest grid node
+ pu = (round(lu/self.space,0))*self.space
+ pv = (round(lv/self.space,0))*self.space
+ rot = FreeCAD.Rotation()
+ rot.Q = self.trans.rotation.getValue().getValue()
+ return rot.multVec(Vector(pu,pv,0))
#---------------------------------------------------------------------------
@@ -1094,107 +1082,107 @@ class gridTracker(Tracker):
#---------------------------------------------------------------------------
class SelectPlane:
- "The Draft_SelectPlane FreeCAD command definition"
+ "The Draft_SelectPlane FreeCAD command definition"
- def GetResources(self):
- return {'Pixmap' : 'Draft_SelectPlane',
- 'Accel' : "W, P",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_SelectPlane", "SelectPlane"),
- 'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_SelectPlane", "Select a working plane for geometry creation")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_SelectPlane',
+ 'Accel' : "W, P",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_SelectPlane", "SelectPlane"),
+ 'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_SelectPlane", "Select a working plane for geometry creation")}
- def IsActive(self):
- if FreeCADGui.ActiveDocument:
- return True
- else:
- return False
+ def IsActive(self):
+ if FreeCADGui.ActiveDocument:
+ return True
+ else:
+ return False
- def Activated(self):
- if FreeCAD.activeDraftCommand:
- FreeCAD.activeDraftCommand.finish()
- self.offset = 0
- self.ui = None
- self.call = None
- self.doc = FreeCAD.ActiveDocument
- if self.doc:
- FreeCAD.activeDraftCommand = self
- self.view = FreeCADGui.ActiveDocument.ActiveView
- self.ui = FreeCADGui.draftToolBar
- self.ui.selectPlaneUi()
- msg(translate("draft", "Pick a face to define the drawing plane\n"))
- self.ui.sourceCmd = self
- if plane.alignToSelection(self.offset):
- FreeCADGui.Selection.clearSelection()
- self.display(plane.axis)
- self.finish()
- else:
- self.call = self.view.addEventCallback("SoEvent", self.action)
+ def Activated(self):
+ if FreeCAD.activeDraftCommand:
+ FreeCAD.activeDraftCommand.finish()
+ self.offset = 0
+ self.ui = None
+ self.call = None
+ self.doc = FreeCAD.ActiveDocument
+ if self.doc:
+ FreeCAD.activeDraftCommand = self
+ self.view = FreeCADGui.ActiveDocument.ActiveView
+ self.ui = FreeCADGui.draftToolBar
+ self.ui.selectPlaneUi()
+ msg(translate("draft", "Pick a face to define the drawing plane\n"))
+ self.ui.sourceCmd = self
+ if plane.alignToSelection(self.offset):
+ FreeCADGui.Selection.clearSelection()
+ self.display(plane.axis)
+ self.finish()
+ else:
+ self.call = self.view.addEventCallback("SoEvent", self.action)
- def action(self, arg):
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if arg["Type"] == "SoMouseButtonEvent":
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- cursor = arg["Position"]
- doc = FreeCADGui.ActiveDocument
- info = doc.ActiveView.getObjectInfo((cursor[0],cursor[1]))
- if info:
- try:
- shape = doc.getObject(info["Object"]).Object.Shape
- component = getattr(shape, info["Component"])
- if plane.alignToFace(component, self.offset) \
- or plane.alignToCurve(component, self.offset):
- self.display(plane.axis)
- self.finish()
- except:
- pass
+ def action(self, arg):
+ if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
+ self.finish()
+ if arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ cursor = arg["Position"]
+ doc = FreeCADGui.ActiveDocument
+ info = doc.ActiveView.getObjectInfo((cursor[0],cursor[1]))
+ if info:
+ try:
+ shape = doc.getObject(info["Object"]).Object.Shape
+ component = getattr(shape, info["Component"])
+ if plane.alignToFace(component, self.offset) \
+ or plane.alignToCurve(component, self.offset):
+ self.display(plane.axis)
+ self.finish()
+ except:
+ pass
- def selectHandler(self, arg):
- try:
- self.offset = float(self.ui.offsetValue.text())
- except:
- self.offset = 0
- if arg == "XY":
- plane.alignToPointAndAxis(Vector(0,0,0), Vector(0,0,1), self.offset)
- self.display('top')
- self.finish()
- elif arg == "XZ":
- plane.alignToPointAndAxis(Vector(0,0,0), Vector(0,-1,0), self.offset)
- self.display('front')
- self.finish()
- elif arg == "YZ":
- plane.alignToPointAndAxis(Vector(0,0,0), Vector(1,0,0), self.offset)
- self.display('side')
- self.finish()
- elif arg == "currentView":
- viewDirection = fcvec.neg(self.view.getViewDirection())
- plane.alignToPointAndAxis(Vector(0,0,0), viewDirection, self.offset)
- self.display(viewDirection)
- self.finish()
- elif arg == "reset":
- plane.reset()
- self.display('None')
- self.finish()
+ def selectHandler(self, arg):
+ try:
+ self.offset = float(self.ui.offsetValue.text())
+ except:
+ self.offset = 0
+ if arg == "XY":
+ plane.alignToPointAndAxis(Vector(0,0,0), Vector(0,0,1), self.offset)
+ self.display('top')
+ self.finish()
+ elif arg == "XZ":
+ plane.alignToPointAndAxis(Vector(0,0,0), Vector(0,-1,0), self.offset)
+ self.display('front')
+ self.finish()
+ elif arg == "YZ":
+ plane.alignToPointAndAxis(Vector(0,0,0), Vector(1,0,0), self.offset)
+ self.display('side')
+ self.finish()
+ elif arg == "currentView":
+ viewDirection = fcvec.neg(self.view.getViewDirection())
+ plane.alignToPointAndAxis(Vector(0,0,0), viewDirection, self.offset)
+ self.display(viewDirection)
+ self.finish()
+ elif arg == "reset":
+ plane.reset()
+ self.display('None')
+ self.finish()
- def offsetHandler(self, arg):
- self.offset = arg
+ def offsetHandler(self, arg):
+ self.offset = arg
- def display(self,arg):
- if self.offset:
- if self.offset > 0: suffix = ' + '+str(self.offset)
- else: suffix = ' - '+str(self.offset)
- else: suffix = ''
- if type(arg).__name__ == 'str':
- self.ui.wplabel.setText(arg+suffix)
- elif type(arg).__name__ == 'Vector':
- plv = 'd('+str(arg.x)+','+str(arg.y)+','+str(arg.z)+')'
- self.ui.wplabel.setText(plv+suffix)
+ def display(self,arg):
+ if self.offset:
+ if self.offset > 0: suffix = ' + '+str(self.offset)
+ else: suffix = ' - '+str(self.offset)
+ else: suffix = ''
+ if type(arg).__name__ == 'str':
+ self.ui.wplabel.setText(arg+suffix)
+ elif type(arg).__name__ == 'Vector':
+ plv = 'd('+str(arg.x)+','+str(arg.y)+','+str(arg.z)+')'
+ self.ui.wplabel.setText(plv+suffix)
- def finish(self):
- if self.call:
- self.view.removeEventCallback("SoEvent",self.call)
- FreeCAD.activeDraftCommand = None
- if self.ui:
- self.ui.offUi()
+ def finish(self):
+ if self.call:
+ self.view.removeEventCallback("SoEvent",self.call)
+ FreeCAD.activeDraftCommand = None
+ if self.ui:
+ self.ui.offUi()
#---------------------------------------------------------------------------
@@ -1202,1289 +1190,1333 @@ class SelectPlane:
#---------------------------------------------------------------------------
class Creator:
- "A generic Draft Creator Tool used by creation tools such as line or arc"
- def __init__(self):
- self.commitList = []
+ "A generic Draft Creator Tool used by creation tools such as line or arc"
+
+ def __init__(self):
+ self.commitList = []
- def Activated(self,name="None"):
- if FreeCAD.activeDraftCommand:
- FreeCAD.activeDraftCommand.finish()
- self.ui = None
- self.call = None
- self.doc = None
- self.support = None
- self.commitList = []
- self.doc = FreeCAD.ActiveDocument
- self.view = FreeCADGui.ActiveDocument.ActiveView
- self.featureName = name
- if not self.doc:
- self.finish()
- else:
- FreeCAD.activeDraftCommand = self
- self.ui = FreeCADGui.draftToolBar
- self.ui.cross(True)
- self.ui.sourceCmd = self
- self.ui.setTitle(name)
- self.ui.show()
- rot = self.view.getCameraNode().getField("orientation").getValue()
- upv = Vector(rot.multVec(coin.SbVec3f(0,1,0)).getValue())
- plane.setup(fcvec.neg(self.view.getViewDirection()), Vector(0,0,0), upv)
- self.node = []
- self.pos = []
- self.constrain = None
- self.obj = None
- self.snap = snapTracker()
- self.extsnap = lineTracker(dotted=True)
- self.planetrack = PlaneTracker()
- if Draft.getParam("grid"):
- self.grid = gridTracker()
- self.grid.set()
- else:
- self.grid = None
+ def Activated(self,name="None"):
+ if FreeCAD.activeDraftCommand:
+ FreeCAD.activeDraftCommand.finish()
+ self.ui = None
+ self.call = None
+ self.doc = None
+ self.support = None
+ self.commitList = []
+ self.doc = FreeCAD.ActiveDocument
+ self.view = FreeCADGui.ActiveDocument.ActiveView
+ self.featureName = name
+ if not self.doc:
+ self.finish()
+ else:
+ FreeCAD.activeDraftCommand = self
+ self.ui = FreeCADGui.draftToolBar
+ self.ui.cross(True)
+ self.ui.sourceCmd = self
+ self.ui.setTitle(name)
+ self.ui.show()
+ rot = self.view.getCameraNode().getField("orientation").getValue()
+ upv = Vector(rot.multVec(coin.SbVec3f(0,1,0)).getValue())
+ plane.setup(fcvec.neg(self.view.getViewDirection()), Vector(0,0,0), upv)
+ self.node = []
+ self.pos = []
+ self.constrain = None
+ self.obj = None
+ self.snap = snapTracker()
+ self.extsnap = lineTracker(dotted=True)
+ self.planetrack = PlaneTracker()
+ if Draft.getParam("grid"):
+ self.grid = gridTracker()
+ self.grid.set()
+ else:
+ self.grid = None
+ def IsActive(self):
+ if FreeCADGui.ActiveDocument:
+ return True
+ else:
+ return False
- def IsActive(self):
- if FreeCADGui.ActiveDocument:
- return True
- else:
- return False
+ def finish(self):
+ self.snap.finalize()
+ self.extsnap.finalize()
+ self.node=[]
+ self.planetrack.finalize()
+ if self.grid: self.grid.finalize()
+ if self.support: plane.restore()
+ FreeCAD.activeDraftCommand = None
+ if self.ui:
+ self.ui.offUi()
+ self.ui.cross(False)
+ self.ui.sourceCmd = None
+ msg("")
+ if self.call:
+ self.view.removeEventCallback("SoEvent",self.call)
+ self.call = None
+ if self.commitList:
+ todo.delayCommit(self.commitList)
+ self.commitList = []
- def finish(self):
- self.snap.finalize()
- self.extsnap.finalize()
- self.node=[]
- self.planetrack.finalize()
- if self.grid: self.grid.finalize()
- if self.support: plane.restore()
- FreeCAD.activeDraftCommand = None
- if self.ui:
- self.ui.offUi()
- self.ui.cross(False)
- self.ui.sourceCmd = None
- msg("")
- if self.call:
- self.view.removeEventCallback("SoEvent",self.call)
- self.call = None
- if self.commitList:
- todo.delayCommit(self.commitList)
- self.commitList = []
-
- def commit(self,name,func):
- "stores partial actions to be committed to the FreeCAD document"
- self.commitList.append((name,func))
+ def commit(self,name,func):
+ "stores partial actions to be committed to the FreeCAD document"
+ self.commitList.append((name,func))
class Line(Creator):
- "The Line FreeCAD command definition"
+ "The Line FreeCAD command definition"
- def __init__(self, wiremode=False):
- self.isWire = wiremode
+ def __init__(self, wiremode=False):
+ self.isWire = wiremode
- def GetResources(self):
- return {'Pixmap' : 'Draft_Line',
- 'Accel' : "L,I",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Line", "Line"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Line", "Creates a 2-point line. CTRL to snap, SHIFT to constrain")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Line',
+ 'Accel' : "L,I",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Line", "Line"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Line", "Creates a 2-point line. CTRL to snap, SHIFT to constrain")}
- def Activated(self,name="Line"):
- Creator.Activated(self,name)
- if self.doc:
- self.obj = None
- self.ui.lineUi()
- self.linetrack = lineTracker()
- self.constraintrack = lineTracker(dotted=True)
- self.obj=self.doc.addObject("Part::Feature",self.featureName)
- # self.obj.ViewObject.Selectable = False
- Draft.formatObject(self.obj)
- if not Draft.getParam("UiMode"): self.makeDumbTask()
- self.call = self.view.addEventCallback("SoEvent",self.action)
- msg(translate("draft", "Pick first point:\n"))
+ def Activated(self,name="Line"):
+ Creator.Activated(self,name)
+ if self.doc:
+ self.obj = None
+ self.ui.lineUi()
+ self.linetrack = lineTracker()
+ self.constraintrack = lineTracker(dotted=True)
+ self.obj=self.doc.addObject("Part::Feature",self.featureName)
+ # self.obj.ViewObject.Selectable = False
+ Draft.formatObject(self.obj)
+ if not Draft.getParam("UiMode"): self.makeDumbTask()
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ msg(translate("draft", "Pick first point:\n"))
- def makeDumbTask(self):
- "create a dumb taskdialog to prevent deleting the temp object"
- class TaskPanel:
- def __init__(self):
- pass
- def getStandardButtons(self):
- return 0
- panel = TaskPanel()
- FreeCADGui.Control.showDialog(panel)
+ def makeDumbTask(self):
+ "create a dumb taskdialog to prevent deleting the temp object"
+ class TaskPanel:
+ def __init__(self):
+ pass
+ def getStandardButtons(self):
+ return 0
+ panel = TaskPanel()
+ FreeCADGui.Control.showDialog(panel)
- def finish(self,closed=False,cont=False):
- "terminates the operation and closes the poly if asked"
- if not Draft.getParam("UiMode"):
- FreeCADGui.Control.closeDialog()
- if self.obj:
- old = self.obj.Name
- todo.delay(self.doc.removeObject,old)
- self.obj = None
- if (len(self.node) > 1):
- self.commit(translate("draft","Create Wire"),partial(Draft.makeWire,self.node,closed,face=self.ui.hasFill.isChecked(),support=self.support))
- if self.ui:
- self.linetrack.finalize()
- self.constraintrack.finalize()
- Creator.finish(self)
- if cont and self.ui:
- if self.ui.continueMode:
- self.Activated()
+ def finish(self,closed=False,cont=False):
+ "terminates the operation and closes the poly if asked"
+ if not Draft.getParam("UiMode"):
+ FreeCADGui.Control.closeDialog()
+ if self.obj:
+ old = self.obj.Name
+ todo.delay(self.doc.removeObject,old)
+ self.obj = None
+ if (len(self.node) > 1):
+ self.commit(translate("draft","Create Wire"),
+ partial(Draft.makeWire,self.node,closed,
+ face=self.ui.hasFill.isChecked(),support=self.support))
+ if self.ui:
+ self.linetrack.finalize()
+ self.constraintrack.finalize()
+ Creator.finish(self)
+ if cont and self.ui:
+ if self.ui.continueMode:
+ self.Activated()
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"): #mouse movement detection
- point,ctrlPoint = getPoint(self,arg)
- self.ui.cross(True)
- self.linetrack.p2(point)
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- elif (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- if (arg["Position"] == self.pos):
- self.finish(False,cont=True)
- else:
- if not self.node: self.support = getSupport(arg)
- point,ctrlPoint = getPoint(self,arg)
- self.pos = arg["Position"]
- self.node.append(point)
- self.linetrack.p1(point)
- self.drawSegment(point)
- if (not self.isWire and len(self.node) == 2):
- self.finish(False,cont=True)
- if (len(self.node) > 2):
- # DNC: allows to close the curve
- # by placing ends close to each other
- # with tol = Draft tolerance
- # old code has been to insensitive
- # if fcvec.equals(point,self.node[0]):
- if ((point-self.node[0]).Length < Draft.tolerance()):
- self.undolast()
- self.finish(True,cont=True)
- msg(translate("draft", "Wire has been closed\n"))
-
- def undolast(self):
- "undoes last line segment"
- if (len(self.node) > 1):
- self.node.pop()
- last = self.node[len(self.node)-1]
- self.linetrack.p1(last)
- if self.obj.Shape.Edges:
- edges = self.obj.Shape.Edges
- if len(edges) > 1:
- edges.pop()
- newshape = Part.Wire(edges)
- else:
- newshape = Part.Shape()
- self.obj.Shape = newshape
- # DNC: report on removal
- msg(translate("draft", "Last point has been removed\n"))
-
- def drawSegment(self,point):
- "draws a new segment"
- if (len(self.node) == 1):
- self.linetrack.on()
- msg(translate("draft", "Pick next point:\n"))
- self.planetrack.set(self.node[0])
- elif (len(self.node) == 2):
- last = self.node[len(self.node)-2]
- newseg = Part.Line(last,point).toShape()
- self.obj.Shape = newseg
- self.obj.ViewObject.Visibility = True
- if self.isWire:
- msg(translate("draft", "Pick next point, or (F)inish or (C)lose:\n"))
- else:
- currentshape = self.obj.Shape
- last = self.node[len(self.node)-2]
- newseg = Part.Line(last,point).toShape()
- newshape=currentshape.fuse(newseg)
- self.obj.Shape = newshape
- msg(translate("draft", "Pick next point, or (F)inish or (C)lose:\n"))
-
- def wipe(self):
- "removes all previous segments and starts from last point"
- if len(self.node) > 1:
- print "nullifying"
- #self.obj.Shape.nullify()
- self.obj.ViewObject.Visibility = False
- self.node = [self.node[-1]]
- print "setting trackers"
- self.linetrack.p1(self.node[0])
- self.planetrack.set(self.node[0])
- msg(translate("draft", "Pick next point:\n"))
- print "done"
-
- def numericInput(self,numx,numy,numz):
- "this function gets called by the toolbar when valid x, y, and z have been entered there"
- point = Vector(numx,numy,numz)
- self.node.append(point)
- self.linetrack.p1(point)
- self.drawSegment(point)
- if (not self.isWire and len(self.node) == 2):
- self.finish(False,cont=True)
- if self.ui.xValue.isEnabled():
- self.ui.xValue.setFocus()
- self.ui.xValue.selectAll()
- elif self.ui.yValue.isEnabled():
- self.ui.yValue.setFocus()
- self.ui.yValue.selectAll()
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event": #mouse movement detection
+ point,ctrlPoint = getPoint(self,arg)
+ self.ui.cross(True)
+ self.linetrack.p2(point)
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else:
+ self.constraintrack.off()
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ if (arg["Position"] == self.pos):
+ self.finish(False,cont=True)
else:
- self.ui.zValue.setFocus()
- self.ui.zValue.selectAll()
+ if not self.node: self.support = getSupport(arg)
+ point,ctrlPoint = getPoint(self,arg)
+ self.pos = arg["Position"]
+ self.node.append(point)
+ self.linetrack.p1(point)
+ self.drawSegment(point)
+ if (not self.isWire and len(self.node) == 2):
+ self.finish(False,cont=True)
+ if (len(self.node) > 2):
+ # DNC: allows to close the curve
+ # by placing ends close to each other
+ # with tol = Draft tolerance
+ # old code has been to insensitive
+ # if fcvec.equals(point,self.node[0]):
+ if ((point-self.node[0]).Length < Draft.tolerance()):
+ self.undolast()
+ self.finish(True,cont=True)
+ msg(translate("draft", "Wire has been closed\n"))
+ def undolast(self):
+ "undoes last line segment"
+ if (len(self.node) > 1):
+ self.node.pop()
+ last = self.node[len(self.node)-1]
+ self.linetrack.p1(last)
+ if self.obj.Shape.Edges:
+ edges = self.obj.Shape.Edges
+ if len(edges) > 1:
+ edges.pop()
+ newshape = Part.Wire(edges)
+ else:
+ newshape = Part.Shape()
+ self.obj.Shape = newshape
+ # DNC: report on removal
+ msg(translate("draft", "Last point has been removed\n"))
+
+ def drawSegment(self,point):
+ "draws a new segment"
+ if (len(self.node) == 1):
+ self.linetrack.on()
+ msg(translate("draft", "Pick next point:\n"))
+ self.planetrack.set(self.node[0])
+ elif (len(self.node) == 2):
+ last = self.node[len(self.node)-2]
+ newseg = Part.Line(last,point).toShape()
+ self.obj.Shape = newseg
+ self.obj.ViewObject.Visibility = True
+ if self.isWire:
+ msg(translate("draft", "Pick next point, or (F)inish or (C)lose:\n"))
+ else:
+ currentshape = self.obj.Shape
+ last = self.node[len(self.node)-2]
+ newseg = Part.Line(last,point).toShape()
+ newshape=currentshape.fuse(newseg)
+ self.obj.Shape = newshape
+ msg(translate("draft", "Pick next point, or (F)inish or (C)lose:\n"))
+
+ def wipe(self):
+ "removes all previous segments and starts from last point"
+ if len(self.node) > 1:
+ print "nullifying"
+ # self.obj.Shape.nullify() - for some reason this fails
+ self.obj.ViewObject.Visibility = False
+ self.node = [self.node[-1]]
+ print "setting trackers"
+ self.linetrack.p1(self.node[0])
+ self.planetrack.set(self.node[0])
+ msg(translate("draft", "Pick next point:\n"))
+ print "done"
+
+ def numericInput(self,numx,numy,numz):
+ "this function gets called by the toolbar when valid x, y, and z have been entered there"
+ point = Vector(numx,numy,numz)
+ self.node.append(point)
+ self.linetrack.p1(point)
+ self.drawSegment(point)
+ if (not self.isWire and len(self.node) == 2):
+ self.finish(False,cont=True)
+ if self.ui.xValue.isEnabled():
+ self.ui.xValue.setFocus()
+ self.ui.xValue.selectAll()
+ elif self.ui.yValue.isEnabled():
+ self.ui.yValue.setFocus()
+ self.ui.yValue.selectAll()
+ else:
+ self.ui.zValue.setFocus()
+ self.ui.zValue.selectAll()
+
+
class Wire(Line):
- "a FreeCAD command for creating a wire"
- def __init__(self):
- Line.__init__(self,wiremode=True)
- def GetResources(self):
- return {'Pixmap' : 'Draft_Wire',
- 'Accel' : "W, I",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Wire", "Wire"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Wire", "Creates a multiple-point wire. CTRL to snap, SHIFT to constrain")}
+ "a FreeCAD command for creating a wire"
+ def __init__(self):
+ Line.__init__(self,wiremode=True)
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Wire',
+ 'Accel' : "W, I",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Wire", "Wire"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Wire", "Creates a multiple-point wire. CTRL to snap, SHIFT to constrain")}
+
class BSpline(Line):
- "a FreeCAD command for creating a b-spline"
- def __init__(self):
- Line.__init__(self,wiremode=True)
+ "a FreeCAD command for creating a b-spline"
+
+ def __init__(self):
+ Line.__init__(self,wiremode=True)
- def GetResources(self):
- return {'Pixmap' : 'Draft_BSpline',
- 'Accel' : "B, S",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_BSpline", "B-Spline"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_BSpline", "Creates a multiple-point b-spline. CTRL to snap, SHIFT to constrain")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_BSpline',
+ 'Accel' : "B, S",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_BSpline", "B-Spline"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_BSpline", "Creates a multiple-point b-spline. CTRL to snap, SHIFT to constrain")}
- def Activated(self):
- Line.Activated(self,"BSpline")
- if self.doc:
- self.bsplinetrack = bsplineTracker()
+ def Activated(self):
+ Line.Activated(self,"BSpline")
+ if self.doc:
+ self.bsplinetrack = bsplineTracker()
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"): #mouse movement detection
- point,ctrlPoint = getPoint(self,arg)
- self.ui.cross(True)
- self.bsplinetrack.update(self.node + [point])
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- elif (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- if (arg["Position"] == self.pos):
- self.finish(False,cont=True)
- else:
- if not self.node: self.support = getSupport(arg)
- point,ctrlPoint = getPoint(self,arg)
- self.pos = arg["Position"]
- self.node.append(point)
- self.drawUpdate(point)
- if (not self.isWire and len(self.node) == 2):
- self.finish(False,cont=True)
- if (len(self.node) > 2):
- # DNC: allows to close the curve
- # by placing ends close to each other
- # with tol = Draft tolerance
- # old code has been to insensitive
- if ((point-self.node[0]).Length < Draft.tolerance()):
- self.undolast()
- self.finish(True,cont=True)
- msg(translate("draft", "Spline has been closed\n"))
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event": #mouse movement detection
+ point,ctrlPoint = getPoint(self,arg)
+ self.ui.cross(True)
+ self.bsplinetrack.update(self.node + [point])
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else: self.constraintrack.off()
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ if (arg["Position"] == self.pos):
+ self.finish(False,cont=True)
+ else:
+ if not self.node: self.support = getSupport(arg)
+ point,ctrlPoint = getPoint(self,arg)
+ self.pos = arg["Position"]
+ self.node.append(point)
+ self.drawUpdate(point)
+ if (not self.isWire and len(self.node) == 2):
+ self.finish(False,cont=True)
+ if (len(self.node) > 2):
+ # DNC: allows to close the curve
+ # by placing ends close to each other
+ # with tol = Draft tolerance
+ # old code has been to insensitive
+ if ((point-self.node[0]).Length < Draft.tolerance()):
+ self.undolast()
+ self.finish(True,cont=True)
+ msg(translate("draft", "Spline has been closed\n"))
- def undolast(self):
- "undoes last line segment"
- if (len(self.node) > 1):
- self.node.pop()
- self.bsplinetrack.update(self.node)
- spline = Part.BSplineCurve()
- spline.interpolate(self.node, False)
- self.obj.Shape = spline.toShape()
- msg(translate("draft", "Last point has been removed\n"))
+ def undolast(self):
+ "undoes last line segment"
+ if (len(self.node) > 1):
+ self.node.pop()
+ self.bsplinetrack.update(self.node)
+ spline = Part.BSplineCurve()
+ spline.interpolate(self.node, False)
+ self.obj.Shape = spline.toShape()
+ msg(translate("draft", "Last point has been removed\n"))
- def drawUpdate(self,point):
- if (len(self.node) == 1):
- self.bsplinetrack.on()
- self.planetrack.set(self.node[0])
- msg(translate("draft", "Pick next point:\n"))
- else:
- spline = Part.BSplineCurve()
- spline.interpolate(self.node, False)
- self.obj.Shape = spline.toShape()
- msg(translate("draft", "Pick next point, or (F)inish or (C)lose:\n"))
+ def drawUpdate(self,point):
+ if (len(self.node) == 1):
+ self.bsplinetrack.on()
+ self.planetrack.set(self.node[0])
+ msg(translate("draft", "Pick next point:\n"))
+ else:
+ spline = Part.BSplineCurve()
+ spline.interpolate(self.node, False)
+ self.obj.Shape = spline.toShape()
+ msg(translate("draft", "Pick next point, or (F)inish or (C)lose:\n"))
- def finish(self,closed=False,cont=False):
- "terminates the operation and closes the poly if asked"
- if not Draft.getParam("UiMode"):
- FreeCADGui.Control.closeDialog()
- if (len(self.node) > 1):
- old = self.obj.Name
- self.doc.removeObject(old)
- self.commit(translate("draft","Create BSpline"),partial(Draft.makeBSpline,self.node,closed,face=self.ui.hasFill.isChecked(),support=self.support))
- if self.ui:
+ def finish(self,closed=False,cont=False):
+ "terminates the operation and closes the poly if asked"
+ if not Draft.getParam("UiMode"):
+ FreeCADGui.Control.closeDialog()
+ if (len(self.node) > 1):
+ old = self.obj.Name
+ self.doc.removeObject(old)
+ self.commit(translate("draft","Create BSpline"),
+ partial(Draft.makeBSpline,self.node,closed,
+ face=self.ui.hasFill.isChecked(),support=self.support))
+ if self.ui:
self.bsplinetrack.finalize()
self.constraintrack.finalize()
- Creator.finish(self)
- if cont and self.ui:
- if self.ui.continueMode:
- self.Activated()
+ Creator.finish(self)
+ if cont and self.ui:
+ if self.ui.continueMode:
+ self.Activated()
+
class FinishLine:
- "a FreeCAD command to finish any running Line drawing operation"
- def Activated(self):
- if (FreeCAD.activeDraftCommand != None):
- if (FreeCAD.activeDraftCommand.featureName == "Line"):
- FreeCAD.activeDraftCommand.finish(False)
- def GetResources(self):
- return {'Pixmap' : 'Draft_Finish',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_FinishLine", "Finish line"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_FinishLine", "Finishes a line without closing it")}
- def IsActive(self):
- if FreeCAD.activeDraftCommand:
- if FreeCAD.activeDraftCommand.featureName == "Line":
- return True
- return False
-
+ "a FreeCAD command to finish any running Line drawing operation"
+
+ def Activated(self):
+ if (FreeCAD.activeDraftCommand != None):
+ if (FreeCAD.activeDraftCommand.featureName == "Line"):
+ FreeCAD.activeDraftCommand.finish(False)
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Finish',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_FinishLine", "Finish line"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_FinishLine", "Finishes a line without closing it")}
+ def IsActive(self):
+ if FreeCAD.activeDraftCommand:
+ if FreeCAD.activeDraftCommand.featureName == "Line":
+ return True
+ return False
+
+
class CloseLine:
- "a FreeCAD command to close any running Line drawing operation"
- def Activated(self):
- if (FreeCAD.activeDraftCommand != None):
- if (FreeCAD.activeDraftCommand.featureName == "Line"):
- FreeCAD.activeDraftCommand.finish(True)
- def GetResources(self):
- return {'Pixmap' : 'Draft_Lock',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_CloseLine", "Close Line"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_CloseLine", "Closes the line being drawn")}
- def IsActive(self):
- if FreeCAD.activeDraftCommand:
- if FreeCAD.activeDraftCommand.featureName == "Line":
- return True
- return False
+ "a FreeCAD command to close any running Line drawing operation"
+
+ def Activated(self):
+ if (FreeCAD.activeDraftCommand != None):
+ if (FreeCAD.activeDraftCommand.featureName == "Line"):
+ FreeCAD.activeDraftCommand.finish(True)
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Lock',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_CloseLine", "Close Line"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_CloseLine", "Closes the line being drawn")}
+
+ def IsActive(self):
+ if FreeCAD.activeDraftCommand:
+ if FreeCAD.activeDraftCommand.featureName == "Line":
+ return True
+ return False
class UndoLine:
- "a FreeCAD command to undo last drawn segment of a line"
- def Activated(self):
- if (FreeCAD.activeDraftCommand != None):
- if (FreeCAD.activeDraftCommand.featureName == "Line"):
- FreeCAD.activeDraftCommand.undolast()
- def GetResources(self):
- return {'Pixmap' : 'Draft_Rotate',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_UndoLine", "Undo last segment"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_UndoLine", "Undoes the last drawn segment of the line being drawn")}
- def IsActive(self):
- if FreeCAD.activeDraftCommand:
- if FreeCAD.activeDraftCommand.featureName == "Line":
- return True
- return False
-
+ "a FreeCAD command to undo last drawn segment of a line"
+
+ def Activated(self):
+ if (FreeCAD.activeDraftCommand != None):
+ if (FreeCAD.activeDraftCommand.featureName == "Line"):
+ FreeCAD.activeDraftCommand.undolast()
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Rotate',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_UndoLine", "Undo last segment"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_UndoLine", "Undoes the last drawn segment of the line being drawn")}
+
+ def IsActive(self):
+ if FreeCAD.activeDraftCommand:
+ if FreeCAD.activeDraftCommand.featureName == "Line":
+ return True
+ return False
+
+
class Rectangle(Creator):
- "the Draft_Rectangle FreeCAD command definition"
+ "the Draft_Rectangle FreeCAD command definition"
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Rectangle',
+ 'Accel' : "R, E",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Rectangle", "Rectangle"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Rectangle", "Creates a 2-point rectangle. CTRL to snap")}
- def GetResources(self):
- return {'Pixmap' : 'Draft_Rectangle',
- 'Accel' : "R, E",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Rectangle", "Rectangle"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Rectangle", "Creates a 2-point rectangle. CTRL to snap")}
+ def Activated(self):
+ Creator.Activated(self,"Rectangle")
+ if self.ui:
+ self.refpoint = None
+ self.ui.pointUi()
+ self.ui.extUi()
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ self.rect = rectangleTracker()
+ msg(translate("draft", "Pick first point:\n"))
- def Activated(self):
- Creator.Activated(self,"Rectangle")
- if self.ui:
- self.refpoint = None
- self.ui.pointUi()
- self.ui.extUi()
- self.call = self.view.addEventCallback("SoEvent",self.action)
- self.rect = rectangleTracker()
- msg(translate("draft", "Pick first point:\n"))
+ def finish(self,closed=False,cont=False):
+ "terminates the operation and closes the poly if asked"
+ Creator.finish(self)
+ if self.ui:
+ self.rect.off()
+ self.rect.finalize()
+ if cont and self.ui:
+ if self.ui.continueMode:
+ self.Activated()
- def finish(self,closed=False,cont=False):
- "terminates the operation and closes the poly if asked"
- Creator.finish(self)
- if self.ui:
- self.rect.off()
- self.rect.finalize()
- if cont and self.ui:
- if self.ui.continueMode:
- self.Activated()
+ def createObject(self):
+ "creates the final object in the current doc"
+ p1 = self.node[0]
+ p3 = self.node[-1]
+ diagonal = p3.sub(p1)
+ p2 = p1.add(fcvec.project(diagonal, plane.v))
+ p4 = p1.add(fcvec.project(diagonal, plane.u))
+ length = p4.sub(p1).Length
+ if abs(fcvec.angle(p4.sub(p1),plane.u,plane.axis)) > 1: length = -length
+ height = p2.sub(p1).Length
+ if abs(fcvec.angle(p2.sub(p1),plane.v,plane.axis)) > 1: height = -height
+ p = plane.getRotation()
+ p.move(p1)
+ self.commit(translate("draft","Create Rectangle"),
+ partial(Draft.makeRectangle,length,height,
+ p,self.ui.hasFill.isChecked(),support=self.support))
+ self.finish(cont=True)
- def createObject(self):
- "creates the final object in the current doc"
- p1 = self.node[0]
- p3 = self.node[-1]
- diagonal = p3.sub(p1)
- p2 = p1.add(fcvec.project(diagonal, plane.v))
- p4 = p1.add(fcvec.project(diagonal, plane.u))
- length = p4.sub(p1).Length
- if abs(fcvec.angle(p4.sub(p1),plane.u,plane.axis)) > 1: length = -length
- height = p2.sub(p1).Length
- if abs(fcvec.angle(p2.sub(p1),plane.v,plane.axis)) > 1: height = -height
- p = plane.getRotation()
- p.move(p1)
- self.commit(translate("draft","Create Rectangle"),partial(Draft.makeRectangle,length,height,p,self.ui.hasFill.isChecked(),support=self.support))
- self.finish(cont=True)
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event": #mouse movement detection
+ point,ctrlPoint = getPoint(self,arg,mobile=True)
+ self.rect.update(point)
+ self.ui.cross(True)
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ if (arg["Position"] == self.pos):
+ self.finish()
+ else:
+ if not self.node: self.support = getSupport(arg)
+ point,ctrlPoint = getPoint(self,arg)
+ self.appendPoint(point)
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"): #mouse movement detection
- point,ctrlPoint = getPoint(self,arg,mobile=True)
- self.rect.update(point)
- self.ui.cross(True)
- elif (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- if (arg["Position"] == self.pos):
- self.finish()
- else:
- if not self.node: self.support = getSupport(arg)
- point,ctrlPoint = getPoint(self,arg)
- self.appendPoint(point)
+ def numericInput(self,numx,numy,numz):
+ "this function gets called by the toolbar when valid x, y, and z have been entered there"
+ point = Vector(numx,numy,numz)
+ self.appendPoint(point)
- def numericInput(self,numx,numy,numz):
- "this function gets called by the toolbar when valid x, y, and z have been entered there"
- point = Vector(numx,numy,numz)
- self.appendPoint(point)
-
- def appendPoint(self,point):
- self.node.append(point)
- if (len(self.node) > 1):
- self.rect.update(point)
- self.createObject()
- else:
- msg(translate("draft", "Pick opposite point:\n"))
- self.ui.isRelative.show()
- self.rect.setorigin(point)
- self.rect.on()
- self.planetrack.set(point)
+ def appendPoint(self,point):
+ self.node.append(point)
+ if (len(self.node) > 1):
+ self.rect.update(point)
+ self.createObject()
+ else:
+ msg(translate("draft", "Pick opposite point:\n"))
+ self.ui.isRelative.show()
+ self.rect.setorigin(point)
+ self.rect.on()
+ self.planetrack.set(point)
class Arc(Creator):
- "the Draft_Arc FreeCAD command definition"
+ "the Draft_Arc FreeCAD command definition"
- def __init__(self):
- self.closedCircle=False
- self.featureName = "Arc"
+ def __init__(self):
+ self.closedCircle=False
+ self.featureName = "Arc"
- def GetResources(self):
- return {'Pixmap' : 'Draft_Arc',
- 'Accel' : "A, R",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Arc", "Arc"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Arc", "Creates an arc. CTRL to snap, SHIFT to constrain")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Arc',
+ 'Accel' : "A, R",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Arc", "Arc"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Arc", "Creates an arc. CTRL to snap, SHIFT to constrain")}
- def Activated(self):
- Creator.Activated(self,self.featureName)
- if self.ui:
- self.step = 0
- self.center = None
- self.rad = None
- self.angle = 0 # angle inscribed by arc
- self.tangents = []
- self.tanpoints = []
- if self.featureName == "Arc": self.ui.arcUi()
- else: self.ui.circleUi()
- self.altdown = False
- self.ui.sourceCmd = self
- self.linetrack = lineTracker(dotted=True)
- self.constraintrack = lineTracker(dotted=True)
- self.arctrack = arcTracker()
- self.call = self.view.addEventCallback("SoEvent",self.action)
- msg(translate("draft", "Pick center point:\n"))
+ def Activated(self):
+ Creator.Activated(self,self.featureName)
+ if self.ui:
+ self.step = 0
+ self.center = None
+ self.rad = None
+ self.angle = 0 # angle inscribed by arc
+ self.tangents = []
+ self.tanpoints = []
+ if self.featureName == "Arc": self.ui.arcUi()
+ else: self.ui.circleUi()
+ self.altdown = False
+ self.ui.sourceCmd = self
+ self.linetrack = lineTracker(dotted=True)
+ self.constraintrack = lineTracker(dotted=True)
+ self.arctrack = arcTracker()
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ msg(translate("draft", "Pick center point:\n"))
- def finish(self,closed=False,cont=False):
- "finishes the arc"
- Creator.finish(self)
- if self.ui:
- self.linetrack.finalize()
- self.constraintrack.finalize()
- self.arctrack.finalize()
- self.doc.recompute()
- if cont and self.ui:
- if self.ui.continueMode:
- self.Activated()
+ def finish(self,closed=False,cont=False):
+ "finishes the arc"
+ Creator.finish(self)
+ if self.ui:
+ self.linetrack.finalize()
+ self.constraintrack.finalize()
+ self.arctrack.finalize()
+ self.doc.recompute()
+ if cont and self.ui:
+ if self.ui.continueMode:
+ self.Activated()
- def updateAngle(self, angle):
- # previous absolute angle
- lastangle = self.firstangle + self.angle
- if lastangle <= -2*math.pi: lastangle += 2*math.pi
- if lastangle >= 2*math.pi: lastangle -= 2*math.pi
- # compute delta = change in angle:
- d0 = angle-lastangle
- d1 = d0 + 2*math.pi
- d2 = d0 - 2*math.pi
- if abs(d0) < min(abs(d1), abs(d2)):
- delta = d0
- elif abs(d1) < abs(d2):
- delta = d1
- else:
- delta = d2
- newangle = self.angle + delta
- # normalize angle, preserving direction
- if newangle >= 2*math.pi: newangle -= 2*math.pi
- if newangle <= -2*math.pi: newangle += 2*math.pi
- self.angle = newangle
+ def updateAngle(self, angle):
+ # previous absolute angle
+ lastangle = self.firstangle + self.angle
+ if lastangle <= -2*math.pi: lastangle += 2*math.pi
+ if lastangle >= 2*math.pi: lastangle -= 2*math.pi
+ # compute delta = change in angle:
+ d0 = angle-lastangle
+ d1 = d0 + 2*math.pi
+ d2 = d0 - 2*math.pi
+ if abs(d0) < min(abs(d1), abs(d2)):
+ delta = d0
+ elif abs(d1) < abs(d2):
+ delta = d1
+ else:
+ delta = d2
+ newangle = self.angle + delta
+ # normalize angle, preserving direction
+ if newangle >= 2*math.pi: newangle -= 2*math.pi
+ if newangle <= -2*math.pi: newangle += 2*math.pi
+ self.angle = newangle
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"):
- point,ctrlPoint = getPoint(self,arg)
- # this is to make sure radius is what you see on screen
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event":
+ point,ctrlPoint = getPoint(self,arg)
+ # this is to make sure radius is what you see on screen
+ self.ui.cross(True)
+ if self.center and fcvec.dist(point,self.center) > 0:
+ viewdelta = fcvec.project(point.sub(self.center), plane.axis)
+ if not fcvec.isNull(viewdelta):
+ point = point.add(fcvec.neg(viewdelta))
+ if (self.step == 0): # choose center
+ if hasMod(arg,MODALT):
+ if not self.altdown:
+ self.ui.cross(False)
+ self.altdown = True
+ self.ui.switchUi(True)
+ else:
+ if self.altdown:
+ self.ui.cross(True)
+ self.altdown = False
+ self.ui.switchUi(False)
+ elif (self.step == 1): # choose radius
+ if len(self.tangents) == 2:
+ cir = fcgeo.circleFrom2tan1pt(self.tangents[0], self.tangents[1], point)
+ self.center = fcgeo.findClosestCircle(point,cir).Center
+ self.arctrack.setCenter(self.center)
+ elif self.tangents and self.tanpoints:
+ cir = fcgeo.circleFrom1tan2pt(self.tangents[0], self.tanpoints[0], point)
+ self.center = fcgeo.findClosestCircle(point,cir).Center
+ self.arctrack.setCenter(self.center)
+ if hasMod(arg,MODALT):
+ if not self.altdown:
+ self.ui.cross(False)
+ self.altdown = True
+ snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
+ if snapped:
+ ob = self.doc.getObject(snapped['Object'])
+ num = int(snapped['Component'].lstrip('Edge'))-1
+ ed = ob.Shape.Edges[num]
+ if len(self.tangents) == 2:
+ cir = fcgeo.circleFrom3tan(self.tangents[0], self.tangents[1], ed)
+ cl = fcgeo.findClosestCircle(point,cir)
+ self.center = cl.Center
+ self.rad = cl.Radius
+ self.arctrack.setCenter(self.center)
+ else:
+ self.rad = self.center.add(fcgeo.findDistance(self.center,ed).sub(self.center)).Length
+ else:
+ self.rad = fcvec.dist(point,self.center)
+ else:
+ if self.altdown:
self.ui.cross(True)
- if self.center and fcvec.dist(point,self.center) > 0:
- viewdelta = fcvec.project(point.sub(self.center), plane.axis)
- if not fcvec.isNull(viewdelta):
- point = point.add(fcvec.neg(viewdelta))
- if (self.step == 0): # choose center
- if hasMod(arg,MODALT):
- if not self.altdown:
- self.ui.cross(False)
- self.altdown = True
- self.ui.switchUi(True)
- else:
- if self.altdown:
- self.ui.cross(True)
- self.altdown = False
- self.ui.switchUi(False)
- elif (self.step == 1): # choose radius
- if len(self.tangents) == 2:
- cir = fcgeo.circleFrom2tan1pt(self.tangents[0], self.tangents[1], point)
- self.center = fcgeo.findClosestCircle(point,cir).Center
- self.arctrack.setCenter(self.center)
- elif self.tangents and self.tanpoints:
- cir = fcgeo.circleFrom1tan2pt(self.tangents[0], self.tanpoints[0], point)
- self.center = fcgeo.findClosestCircle(point,cir).Center
- self.arctrack.setCenter(self.center)
- if hasMod(arg,MODALT):
- if not self.altdown:
- self.ui.cross(False)
- self.altdown = True
- snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
- if snapped:
- ob = self.doc.getObject(snapped['Object'])
- num = int(snapped['Component'].lstrip('Edge'))-1
- ed = ob.Shape.Edges[num]
- if len(self.tangents) == 2:
- cir = fcgeo.circleFrom3tan(self.tangents[0], self.tangents[1], ed)
- cl = fcgeo.findClosestCircle(point,cir)
- self.center = cl.Center
- self.rad = cl.Radius
- self.arctrack.setCenter(self.center)
- else:
- self.rad = self.center.add(fcgeo.findDistance(self.center,ed).sub(self.center)).Length
- else:
- self.rad = fcvec.dist(point,self.center)
- else:
- if self.altdown:
- self.ui.cross(True)
- self.altdown = False
- self.rad = fcvec.dist(point,self.center)
- self.ui.setRadiusValue(self.rad)
- self.arctrack.setRadius(self.rad)
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- self.linetrack.p1(self.center)
- self.linetrack.p2(point)
- self.linetrack.on()
- elif (self.step == 2): # choose first angle
- currentrad = fcvec.dist(point,self.center)
- if currentrad != 0:
- angle = fcvec.angle(plane.u, point.sub(self.center), plane.axis)
- else: angle = 0
- self.linetrack.p2(fcvec.scaleTo(point.sub(self.center),self.rad).add(self.center))
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- self.ui.setRadiusValue(math.degrees(angle))
- self.firstangle = angle
- else: # choose second angle
- currentrad = fcvec.dist(point,self.center)
- if currentrad != 0:
- angle = fcvec.angle(plane.u, point.sub(self.center), plane.axis)
- else: angle = 0
- self.linetrack.p2(fcvec.scaleTo(point.sub(self.center),self.rad).add(self.center))
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- self.ui.setRadiusValue(math.degrees(angle))
- self.updateAngle(angle)
- self.arctrack.setApertureAngle(self.angle)
+ self.altdown = False
+ self.rad = fcvec.dist(point,self.center)
+ self.ui.setRadiusValue(self.rad)
+ self.arctrack.setRadius(self.rad)
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else:
+ self.constraintrack.off()
+ self.linetrack.p1(self.center)
+ self.linetrack.p2(point)
+ self.linetrack.on()
+ elif (self.step == 2): # choose first angle
+ currentrad = fcvec.dist(point,self.center)
+ if currentrad != 0:
+ angle = fcvec.angle(plane.u, point.sub(self.center), plane.axis)
+ else: angle = 0
+ self.linetrack.p2(fcvec.scaleTo(point.sub(self.center),self.rad).add(self.center))
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else:
+ self.constraintrack.off()
+ self.ui.setRadiusValue(math.degrees(angle))
+ self.firstangle = angle
+ else: # choose second angle
+ currentrad = fcvec.dist(point,self.center)
+ if currentrad != 0:
+ angle = fcvec.angle(plane.u, point.sub(self.center), plane.axis)
+ else: angle = 0
+ self.linetrack.p2(fcvec.scaleTo(point.sub(self.center),self.rad).add(self.center))
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else:
+ self.constraintrack.off()
+ self.ui.setRadiusValue(math.degrees(angle))
+ self.updateAngle(angle)
+ self.arctrack.setApertureAngle(self.angle)
- if (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- point,ctrlPoint = getPoint(self,arg)
- # this is to make sure radius is what you see on screen
- if self.center and fcvec.dist(point,self.center) > 0:
- viewdelta = fcvec.project(point.sub(self.center), plane.axis)
- if not fcvec.isNull(viewdelta):
- point = point.add(fcvec.neg(viewdelta))
- if (self.step == 0): # choose center
- self.support = getSupport(arg)
- if hasMod(arg,MODALT):
- snapped=self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
- if snapped:
- ob = self.doc.getObject(snapped['Object'])
- num = int(snapped['Component'].lstrip('Edge'))-1
- ed = ob.Shape.Edges[num]
- self.tangents.append(ed)
- if len(self.tangents) == 2:
- self.arctrack.on()
- self.ui.radiusUi()
- self.step = 1
- self.linetrack.on()
- msg(translate("draft", "Pick radius:\n"))
- else:
- if len(self.tangents) == 1:
- self.tanpoints.append(point)
- else:
- self.center = point
- self.node = [point]
- self.arctrack.setCenter(self.center)
- self.linetrack.p1(self.center)
- self.linetrack.p2(self.view.getPoint(arg["Position"][0],arg["Position"][1]))
- self.arctrack.on()
- self.ui.radiusUi()
- self.step = 1
- self.linetrack.on()
- msg(translate("draft", "Pick radius:\n"))
- self.planetrack.set(point)
-
- elif (self.step == 1): # choose radius
- if self.closedCircle:
- self.ui.cross(False)
- self.drawArc()
- else:
- self.ui.labelRadius.setText("Start angle")
- self.linetrack.p1(self.center)
- self.linetrack.on()
- self.step = 2
- msg(translate("draft", "Pick start angle:\n"))
- elif (self.step == 2): # choose first angle
- self.ui.labelRadius.setText("Aperture")
- self.step = 3
- # scale center->point vector for proper display
- u = fcvec.scaleTo(point.sub(self.center), self.rad)
- self.arctrack.setStartAngle(self.firstangle)
- msg(translate("draft", "Pick aperture:\n"))
- else: # choose second angle
- self.step = 4
- self.drawArc()
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ point,ctrlPoint = getPoint(self,arg)
+ # this is to make sure radius is what you see on screen
+ if self.center and fcvec.dist(point,self.center) > 0:
+ viewdelta = fcvec.project(point.sub(self.center), plane.axis)
+ if not fcvec.isNull(viewdelta):
+ point = point.add(fcvec.neg(viewdelta))
+ if (self.step == 0): # choose center
+ self.support = getSupport(arg)
+ if hasMod(arg,MODALT):
+ snapped=self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
+ if snapped:
+ ob = self.doc.getObject(snapped['Object'])
+ num = int(snapped['Component'].lstrip('Edge'))-1
+ ed = ob.Shape.Edges[num]
+ self.tangents.append(ed)
+ if len(self.tangents) == 2:
+ self.arctrack.on()
+ self.ui.radiusUi()
+ self.step = 1
+ self.linetrack.on()
+ msg(translate("draft", "Pick radius:\n"))
+ else:
+ if len(self.tangents) == 1:
+ self.tanpoints.append(point)
+ else:
+ self.center = point
+ self.node = [point]
+ self.arctrack.setCenter(self.center)
+ self.linetrack.p1(self.center)
+ self.linetrack.p2(self.view.getPoint(arg["Position"][0],arg["Position"][1]))
+ self.arctrack.on()
+ self.ui.radiusUi()
+ self.step = 1
+ self.linetrack.on()
+ msg(translate("draft", "Pick radius:\n"))
+ self.planetrack.set(point)
+ elif (self.step == 1): # choose radius
+ if self.closedCircle:
+ self.ui.cross(False)
+ self.drawArc()
+ else:
+ self.ui.labelRadius.setText("Start angle")
+ self.linetrack.p1(self.center)
+ self.linetrack.on()
+ self.step = 2
+ msg(translate("draft", "Pick start angle:\n"))
+ elif (self.step == 2): # choose first angle
+ self.ui.labelRadius.setText("Aperture")
+ self.step = 3
+ # scale center->point vector for proper display
+ u = fcvec.scaleTo(point.sub(self.center), self.rad)
+ self.arctrack.setStartAngle(self.firstangle)
+ msg(translate("draft", "Pick aperture:\n"))
+ else: # choose second angle
+ self.step = 4
+ self.drawArc()
- def drawArc(self):
- "actually draws the FreeCAD object"
- p = plane.getRotation()
- p.move(self.center)
- if self.closedCircle:
- self.commit(translate("draft","Create Circle"),partial(Draft.makeCircle,self.rad,p,self.ui.hasFill.isChecked(),support=self.support))
- else:
- sta = math.degrees(self.firstangle)
- end = math.degrees(self.firstangle+self.angle)
- print "debug:",sta, end
- if end < sta: sta,end = end,sta
- self.commit(translate("draft","Create Arc"),partial(Draft.makeCircle,self.rad,p,self.ui.hasFill.isChecked(),sta,end,support=self.support))
- self.finish(cont=True)
+ def drawArc(self):
+ "actually draws the FreeCAD object"
+ p = plane.getRotation()
+ p.move(self.center)
+ if self.closedCircle:
+ self.commit(translate("draft","Create Circle"),
+ partial(Draft.makeCircle,self.rad,p,
+ self.ui.hasFill.isChecked(),support=self.support))
+ else:
+ sta = math.degrees(self.firstangle)
+ end = math.degrees(self.firstangle+self.angle)
+ print "debug:",sta, end
+ if end < sta: sta,end = end,sta
+ self.commit(translate("draft","Create Arc"),
+ partial(Draft.makeCircle,self.rad,p,self.ui.hasFill.isChecked(),
+ sta,end,support=self.support))
+ self.finish(cont=True)
- def numericInput(self,numx,numy,numz):
- "this function gets called by the toolbar when valid x, y, and z have been entered there"
- self.center = Vector(numx,numy,numz)
- self.node = [self.center]
- self.arctrack.setCenter(self.center)
- self.arctrack.on()
- self.ui.radiusUi()
- self.step = 1
+ def numericInput(self,numx,numy,numz):
+ "this function gets called by the toolbar when valid x, y, and z have been entered there"
+ self.center = Vector(numx,numy,numz)
+ self.node = [self.center]
+ self.arctrack.setCenter(self.center)
+ self.arctrack.on()
+ self.ui.radiusUi()
+ self.step = 1
+ self.ui.radiusValue.setFocus()
+ msg(translate("draft", "Pick radius:\n"))
+
+ def numericRadius(self,rad):
+ "this function gets called by the toolbar when valid radius have been entered there"
+ if (self.step == 1):
+ self.rad = rad
+ if len(self.tangents) == 2:
+ cir = fcgeo.circleFrom2tan1rad(self.tangents[0], self.tangents[1], rad)
+ if self.center:
+ self.center = fcgeo.findClosestCircle(self.center,cir).Center
+ else:
+ self.center = cir[-1].Center
+ elif self.tangents and self.tanpoints:
+ cir = fcgeo.circleFrom1tan1pt1rad(self.tangents[0],self.tanpoints[0],rad)
+ if self.center:
+ self.center = fcgeo.findClosestCircle(self.center,cir).Center
+ else:
+ self.center = cir[-1].Center
+ if self.closedCircle:
+ self.drawArc()
+ else:
+ self.step = 2
+ self.arctrack.setCenter(self.center)
+ self.ui.labelRadius.setText("Start angle")
+ self.linetrack.p1(self.center)
+ self.linetrack.on()
+ self.ui.radiusValue.setText("")
self.ui.radiusValue.setFocus()
- msg(translate("draft", "Pick radius:\n"))
-
- def numericRadius(self,rad):
- "this function gets called by the toolbar when valid radius have been entered there"
- if (self.step == 1):
- self.rad = rad
- if len(self.tangents) == 2:
- cir = fcgeo.circleFrom2tan1rad(self.tangents[0], self.tangents[1], rad)
- if self.center:
- self.center = fcgeo.findClosestCircle(self.center,cir).Center
- else:
- self.center = cir[-1].Center
- elif self.tangents and self.tanpoints:
- cir = fcgeo.circleFrom1tan1pt1rad(self.tangents[0],self.tanpoints[0],rad)
- if self.center:
- self.center = fcgeo.findClosestCircle(self.center,cir).Center
- else:
- self.center = cir[-1].Center
- if self.closedCircle:
- self.drawArc()
- else:
- self.step = 2
- self.arctrack.setCenter(self.center)
- self.ui.labelRadius.setText("Start angle")
- self.linetrack.p1(self.center)
- self.linetrack.on()
- self.ui.radiusValue.setText("")
- self.ui.radiusValue.setFocus()
- msg(translate("draft", "Pick start angle:\n"))
- elif (self.step == 2):
- self.ui.labelRadius.setText("Aperture")
- self.firstangle = math.radians(rad)
- if fcvec.equals(plane.axis, Vector(1,0,0)): u = Vector(0,self.rad,0)
- else: u = fcvec.scaleTo(Vector(1,0,0).cross(plane.axis), self.rad)
- urotated = fcvec.rotate(u, math.radians(rad), plane.axis)
- self.arctrack.setStartAngle(self.firstangle)
- self.step = 3
- self.ui.radiusValue.setText("")
- self.ui.radiusValue.setFocus()
- msg(translate("draft", "Aperture angle:\n"))
- else:
- self.updateAngle(rad)
- self.angle = math.radians(rad)
- self.step = 4
- self.drawArc()
-
+ msg(translate("draft", "Pick start angle:\n"))
+ elif (self.step == 2):
+ self.ui.labelRadius.setText("Aperture")
+ self.firstangle = math.radians(rad)
+ if fcvec.equals(plane.axis, Vector(1,0,0)): u = Vector(0,self.rad,0)
+ else: u = fcvec.scaleTo(Vector(1,0,0).cross(plane.axis), self.rad)
+ urotated = fcvec.rotate(u, math.radians(rad), plane.axis)
+ self.arctrack.setStartAngle(self.firstangle)
+ self.step = 3
+ self.ui.radiusValue.setText("")
+ self.ui.radiusValue.setFocus()
+ msg(translate("draft", "Aperture angle:\n"))
+ else:
+ self.updateAngle(rad)
+ self.angle = math.radians(rad)
+ self.step = 4
+ self.drawArc()
+
class Circle(Arc):
- "The Draft_Circle FreeCAD command definition"
+ "The Draft_Circle FreeCAD command definition"
- def __init__(self):
- self.closedCircle=True
- self.featureName = "Circle"
-
- def GetResources(self):
- return {'Pixmap' : 'Draft_Circle',
- 'Accel' : "C, I",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Circle", "Circle"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Circle", "Creates a circle. CTRL to snap, ALT to select tangent objects")}
+ def __init__(self):
+ self.closedCircle=True
+ self.featureName = "Circle"
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Circle',
+ 'Accel' : "C, I",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Circle", "Circle"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Circle", "Creates a circle. CTRL to snap, ALT to select tangent objects")}
class Polygon(Creator):
- "the Draft_Polygon FreeCAD command definition"
+ "the Draft_Polygon FreeCAD command definition"
- def GetResources(self):
- return {'Pixmap' : 'Draft_Polygon',
- 'Accel' : "P, G",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Polygon", "Polygon"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Polygon", "Creates a regular polygon. CTRL to snap, SHIFT to constrain")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Polygon',
+ 'Accel' : "P, G",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Polygon", "Polygon"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Polygon", "Creates a regular polygon. CTRL to snap, SHIFT to constrain")}
- def Activated(self):
- Creator.Activated(self,"Polygon")
- if self.ui:
- self.step = 0
- self.center = None
- self.rad = None
- self.tangents = []
- self.tanpoints = []
- self.ui.pointUi()
- self.ui.extUi()
- self.ui.numFaces.show()
- self.altdown = False
- self.ui.sourceCmd = self
- self.linetrack = lineTracker(dotted=True)
- self.constraintrack = lineTracker(dotted=True)
- self.arctrack = arcTracker()
- self.call = self.view.addEventCallback("SoEvent",self.action)
- msg(translate("draft", "Pick center point:\n"))
+ def Activated(self):
+ Creator.Activated(self,"Polygon")
+ if self.ui:
+ self.step = 0
+ self.center = None
+ self.rad = None
+ self.tangents = []
+ self.tanpoints = []
+ self.ui.pointUi()
+ self.ui.extUi()
+ self.ui.numFaces.show()
+ self.altdown = False
+ self.ui.sourceCmd = self
+ self.linetrack = lineTracker(dotted=True)
+ self.constraintrack = lineTracker(dotted=True)
+ self.arctrack = arcTracker()
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ msg(translate("draft", "Pick center point:\n"))
- def finish(self,closed=False,cont=False):
- "finishes the arc"
- Creator.finish(self)
- if self.ui:
- self.linetrack.finalize()
- self.constraintrack.finalize()
- self.arctrack.finalize()
- self.doc.recompute()
- if cont and self.ui:
- if self.ui.continueMode:
- self.Activated()
+ def finish(self,closed=False,cont=False):
+ "finishes the arc"
+ Creator.finish(self)
+ if self.ui:
+ self.linetrack.finalize()
+ self.constraintrack.finalize()
+ self.arctrack.finalize()
+ self.doc.recompute()
+ if cont and self.ui:
+ if self.ui.continueMode:
+ self.Activated()
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"):
- point,ctrlPoint = getPoint(self,arg)
- # this is to make sure radius is what you see on screen
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event":
+ point,ctrlPoint = getPoint(self,arg)
+ # this is to make sure radius is what you see on screen
+ self.ui.cross(True)
+ if self.center and fcvec.dist(point,self.center) > 0:
+ viewdelta = fcvec.project(point.sub(self.center), plane.axis)
+ if not fcvec.isNull(viewdelta):
+ point = point.add(fcvec.neg(viewdelta))
+ if (self.step == 0): # choose center
+ if hasMod(arg,MODALT):
+ if not self.altdown:
+ self.ui.cross(False)
+ self.altdown = True
+ self.ui.switchUi(True)
+ else:
+ if self.altdown:
self.ui.cross(True)
- if self.center and fcvec.dist(point,self.center) > 0:
- viewdelta = fcvec.project(point.sub(self.center), plane.axis)
- if not fcvec.isNull(viewdelta):
- point = point.add(fcvec.neg(viewdelta))
- if (self.step == 0): # choose center
- if hasMod(arg,MODALT):
- if not self.altdown:
- self.ui.cross(False)
- self.altdown = True
- self.ui.switchUi(True)
- else:
- if self.altdown:
- self.ui.cross(True)
- self.altdown = False
- self.ui.switchUi(False)
- else: # choose radius
- if len(self.tangents) == 2:
- cir = fcgeo.circleFrom2tan1pt(self.tangents[0], self.tangents[1], point)
- self.center = fcgeo.findClosestCircle(point,cir).Center
- self.arctrack.setCenter(self.center)
- elif self.tangents and self.tanpoints:
- cir = fcgeo.circleFrom1tan2pt(self.tangents[0], self.tanpoints[0], point)
- self.center = fcgeo.findClosestCircle(point,cir).Center
- self.arctrack.setCenter(self.center)
- if hasMod(arg,MODALT):
- if not self.altdown:
- self.ui.cross(False)
- self.altdown = True
- snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
- if snapped:
- ob = self.doc.getObject(snapped['Object'])
- num = int(snapped['Component'].lstrip('Edge'))-1
- ed = ob.Shape.Edges[num]
- if len(self.tangents) == 2:
- cir = fcgeo.circleFrom3tan(self.tangents[0], self.tangents[1], ed)
- cl = fcgeo.findClosestCircle(point,cir)
- self.center = cl.Center
- self.rad = cl.Radius
- self.arctrack.setCenter(self.center)
- else:
- self.rad = self.center.add(fcgeo.findDistance(self.center,ed).sub(self.center)).Length
- else:
- self.rad = fcvec.dist(point,self.center)
- else:
- if self.altdown:
- self.ui.cross(True)
- self.altdown = False
- self.rad = fcvec.dist(point,self.center)
- self.ui.setRadiusValue(self.rad)
- self.arctrack.setRadius(self.rad)
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- self.linetrack.p1(self.center)
- self.linetrack.p2(point)
- self.linetrack.on()
-
- if (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- point,ctrlPoint = getPoint(self,arg)
- # this is to make sure radius is what you see on screen
- if self.center and fcvec.dist(point,self.center) > 0:
- viewdelta = fcvec.project(point.sub(self.center), plane.axis)
- if not fcvec.isNull(viewdelta):
- point = point.add(fcvec.neg(viewdelta))
- if (self.step == 0): # choose center
- if not self.node: self.support = getSupport(arg)
- if hasMod(arg,MODALT):
- snapped=self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
- if snapped:
- ob = self.doc.getObject(snapped['Object'])
- num = int(snapped['Component'].lstrip('Edge'))-1
- ed = ob.Shape.Edges[num]
- self.tangents.append(ed)
- if len(self.tangents) == 2:
- self.arctrack.on()
- self.ui.radiusUi()
- self.step = 1
- self.linetrack.on()
- msg(translate("draft", "Pick radius:\n"))
- else:
- if len(self.tangents) == 1:
- self.tanpoints.append(point)
- else:
- self.center = point
- self.node = [point]
- self.arctrack.setCenter(self.center)
- self.linetrack.p1(self.center)
- self.linetrack.p2(self.view.getPoint(arg["Position"][0],arg["Position"][1]))
- self.arctrack.on()
- self.ui.radiusUi()
- self.step = 1
- self.linetrack.on()
- msg(translate("draft", "Pick radius:\n"))
- self.planetrack.set(point)
- elif (self.step == 1): # choose radius
- self.ui.cross(False)
- self.drawPolygon()
-
- def drawPolygon(self):
- "actually draws the FreeCAD object"
- p = plane.getRotation()
- p.move(self.center)
- self.commit(translate("draft","Create Polygon"),partial(Draft.makePolygon,self.ui.numFaces.value(),self.rad,True,p,face=self.ui.hasFill.isChecked(),support=self.support))
- self.finish(cont=True)
-
- def numericInput(self,numx,numy,numz):
- "this function gets called by the toolbar when valid x, y, and z have been entered there"
- self.center = Vector(numx,numy,numz)
- self.node = [self.center]
- self.arctrack.setCenter(self.center)
- self.arctrack.on()
- self.ui.radiusUi()
- self.step = 1
- self.ui.radiusValue.setFocus()
- msg(translate("draft", "Pick radius:\n"))
-
- def numericRadius(self,rad):
- "this function gets called by the toolbar when valid radius have been entered there"
- self.rad = rad
+ self.altdown = False
+ self.ui.switchUi(False)
+ else: # choose radius
if len(self.tangents) == 2:
- cir = fcgeo.circleFrom2tan1rad(self.tangents[0], self.tangents[1], rad)
- if self.center:
- self.center = fcgeo.findClosestCircle(self.center,cir).Center
- else:
- self.center = cir[-1].Center
+ cir = fcgeo.circleFrom2tan1pt(self.tangents[0], self.tangents[1], point)
+ self.center = fcgeo.findClosestCircle(point,cir).Center
+ self.arctrack.setCenter(self.center)
elif self.tangents and self.tanpoints:
- cir = fcgeo.circleFrom1tan1pt1rad(self.tangents[0],self.tanpoints[0],rad)
- if self.center:
- self.center = fcgeo.findClosestCircle(self.center,cir).Center
+ cir = fcgeo.circleFrom1tan2pt(self.tangents[0], self.tanpoints[0], point)
+ self.center = fcgeo.findClosestCircle(point,cir).Center
+ self.arctrack.setCenter(self.center)
+ if hasMod(arg,MODALT):
+ if not self.altdown:
+ self.ui.cross(False)
+ self.altdown = True
+ snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
+ if snapped:
+ ob = self.doc.getObject(snapped['Object'])
+ num = int(snapped['Component'].lstrip('Edge'))-1
+ ed = ob.Shape.Edges[num]
+ if len(self.tangents) == 2:
+ cir = fcgeo.circleFrom3tan(self.tangents[0], self.tangents[1], ed)
+ cl = fcgeo.findClosestCircle(point,cir)
+ self.center = cl.Center
+ self.rad = cl.Radius
+ self.arctrack.setCenter(self.center)
else:
- self.center = cir[-1].Center
- self.drawPolygon()
+ self.rad = self.center.add(fcgeo.findDistance(self.center,ed).sub(self.center)).Length
+ else:
+ self.rad = fcvec.dist(point,self.center)
+ else:
+ if self.altdown:
+ self.ui.cross(True)
+ self.altdown = False
+ self.rad = fcvec.dist(point,self.center)
+ self.ui.setRadiusValue(self.rad)
+ self.arctrack.setRadius(self.rad)
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else: self.constraintrack.off()
+ self.linetrack.p1(self.center)
+ self.linetrack.p2(point)
+ self.linetrack.on()
+
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ point,ctrlPoint = getPoint(self,arg)
+ # this is to make sure radius is what you see on screen
+ if self.center and fcvec.dist(point,self.center) > 0:
+ viewdelta = fcvec.project(point.sub(self.center), plane.axis)
+ if not fcvec.isNull(viewdelta):
+ point = point.add(fcvec.neg(viewdelta))
+ if (self.step == 0): # choose center
+ if not self.node: self.support = getSupport(arg)
+ if hasMod(arg,MODALT):
+ snapped=self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
+ if snapped:
+ ob = self.doc.getObject(snapped['Object'])
+ num = int(snapped['Component'].lstrip('Edge'))-1
+ ed = ob.Shape.Edges[num]
+ self.tangents.append(ed)
+ if len(self.tangents) == 2:
+ self.arctrack.on()
+ self.ui.radiusUi()
+ self.step = 1
+ self.linetrack.on()
+ msg(translate("draft", "Pick radius:\n"))
+ else:
+ if len(self.tangents) == 1:
+ self.tanpoints.append(point)
+ else:
+ self.center = point
+ self.node = [point]
+ self.arctrack.setCenter(self.center)
+ self.linetrack.p1(self.center)
+ self.linetrack.p2(self.view.getPoint(arg["Position"][0],arg["Position"][1]))
+ self.arctrack.on()
+ self.ui.radiusUi()
+ self.step = 1
+ self.linetrack.on()
+ msg(translate("draft", "Pick radius:\n"))
+ self.planetrack.set(point)
+ elif (self.step == 1): # choose radius
+ self.ui.cross(False)
+ self.drawPolygon()
+
+ def drawPolygon(self):
+ "actually draws the FreeCAD object"
+ p = plane.getRotation()
+ p.move(self.center)
+ self.commit(translate("draft","Create Polygon"),
+ partial(Draft.makePolygon,self.ui.numFaces.value(),self.rad,
+ True,p,face=self.ui.hasFill.isChecked(),support=self.support))
+ self.finish(cont=True)
+
+ def numericInput(self,numx,numy,numz):
+ "this function gets called by the toolbar when valid x, y, and z have been entered there"
+ self.center = Vector(numx,numy,numz)
+ self.node = [self.center]
+ self.arctrack.setCenter(self.center)
+ self.arctrack.on()
+ self.ui.radiusUi()
+ self.step = 1
+ self.ui.radiusValue.setFocus()
+ msg(translate("draft", "Pick radius:\n"))
+
+ def numericRadius(self,rad):
+ "this function gets called by the toolbar when valid radius have been entered there"
+ self.rad = rad
+ if len(self.tangents) == 2:
+ cir = fcgeo.circleFrom2tan1rad(self.tangents[0], self.tangents[1], rad)
+ if self.center:
+ self.center = fcgeo.findClosestCircle(self.center,cir).Center
+ else:
+ self.center = cir[-1].Center
+ elif self.tangents and self.tanpoints:
+ cir = fcgeo.circleFrom1tan1pt1rad(self.tangents[0],self.tanpoints[0],rad)
+ if self.center:
+ self.center = fcgeo.findClosestCircle(self.center,cir).Center
+ else:
+ self.center = cir[-1].Center
+ self.drawPolygon()
+
class Text(Creator):
- '''
- This class creates an annotation feature.
- '''
+ "This class creates an annotation feature."
- def GetResources(self):
- return {'Pixmap' : 'Draft_Text',
- 'Accel' : "T, E",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Text", "Text"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Text", "Creates an annotation. CTRL to snap")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Text',
+ 'Accel' : "T, E",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Text", "Text"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Text", "Creates an annotation. CTRL to snap")}
- def Activated(self):
- Creator.Activated(self,"Text")
- if self.ui:
- self.dialog = None
- self.text = ''
- self.ui.sourceCmd = self
- self.ui.pointUi()
- self.call = self.view.addEventCallback("SoEvent",self.action)
- self.ui.xValue.setFocus()
- self.ui.xValue.selectAll()
- msg(translate("draft", "Pick location point:\n"))
- FreeCADGui.draftToolBar.show()
+ def Activated(self):
+ Creator.Activated(self,"Text")
+ if self.ui:
+ self.dialog = None
+ self.text = ''
+ self.ui.sourceCmd = self
+ self.ui.pointUi()
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ self.ui.xValue.setFocus()
+ self.ui.xValue.selectAll()
+ msg(translate("draft", "Pick location point:\n"))
+ FreeCADGui.draftToolBar.show()
- def finish(self,closed=False,cont=False):
- "terminates the operation"
- Creator.finish(self)
- if self.ui:
- del self.dialog
- if cont and self.ui:
- if self.ui.continueMode:
- self.Activated()
+ def finish(self,closed=False,cont=False):
+ "terminates the operation"
+ Creator.finish(self)
+ if self.ui:
+ del self.dialog
+ if cont and self.ui:
+ if self.ui.continueMode:
+ self.Activated()
- def createObject(self):
- "creates an object in the current doc"
- self.commit(translate("draft","Create Text"),partial(Draft.makeText,self.text,self.node[0]))
- self.finish(cont=True)
+ def createObject(self):
+ "creates an object in the current doc"
+ self.commit(translate("draft","Create Text"),
+ partial(Draft.makeText,self.text,self.node[0]))
+ self.finish(cont=True)
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"): #mouse movement detection
- point,ctrlPoint = getPoint(self,arg)
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event": #mouse movement detection
+ point,ctrlPoint = getPoint(self,arg)
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ point,dtrlPoint = getPoint(self,arg)
+ self.node.append(point)
+ self.ui.textUi()
+ self.ui.textValue.setFocus()
+ self.ui.cross(False)
- elif (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- point,dtrlPoint = getPoint(self,arg)
- self.node.append(point)
- self.ui.textUi()
- self.ui.textValue.setFocus()
- self.ui.cross(False)
+ def numericInput(self,numx,numy,numz):
+ '''this function gets called by the toolbar when valid
+ x, y, and z have been entered there'''
+ point = Vector(numx,numy,numz)
+ self.node.append(point)
+ self.ui.textUi()
+ self.ui.textValue.setFocus()
+ self.ui.cross(False)
- def numericInput(self,numx,numy,numz):
- "this function gets called by the toolbar when valid x, y, and z have been entered there"
- point = Vector(numx,numy,numz)
- self.node.append(point)
- self.ui.textUi()
- self.ui.textValue.setFocus()
- self.ui.cross(False)
-
-class Dimension(Creator):
- "The Draft_Dimension FreeCAD command definition"
- def __init__(self):
- self.max=2
- self.cont = None
- self.dir = None
+class Dimension(Creator):
+ "The Draft_Dimension FreeCAD command definition"
+
+ def __init__(self):
+ self.max=2
+ self.cont = None
+ self.dir = None
- def GetResources(self):
- return {'Pixmap' : 'Draft_Dimension',
- 'Accel' : "D, I",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Dimension", "Dimension"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Dimension", "Creates a dimension. CTRL to snap, SHIFT to constrain, ALT to select a segment")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Dimension',
+ 'Accel' : "D, I",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Dimension", "Dimension"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Dimension", "Creates a dimension. CTRL to snap, SHIFT to constrain, ALT to select a segment")}
- def Activated(self):
- if self.cont:
- self.finish()
- elif self.hasMeasures():
- Creator.Activated(self,"Dimension")
- self.dimtrack = dimTracker()
- self.arctrack = arcTracker()
- self.constraintrack = lineTracker(dotted=True)
- self.createOnMeasures()
- self.finish()
- else:
- Creator.Activated(self,"Dimension")
- if self.ui:
- self.ui.pointUi()
- self.ui.continueCmd.show()
- self.altdown = False
- self.call = self.view.addEventCallback("SoEvent",self.action)
- self.dimtrack = dimTracker()
- self.arctrack = arcTracker()
- self.link = None
- self.edges = []
- self.pts = []
- self.angledata = None
- self.indices = []
- self.center = None
- self.arcmode = False
- self.point2 = None
- self.constraintrack = lineTracker(dotted=True)
- msg(translate("draft", "Pick first point:\n"))
- FreeCADGui.draftToolBar.show()
-
- def hasMeasures(self):
- "checks if only measurements objects are selected"
- sel = FreeCADGui.Selection.getSelection()
- if not sel:
- return False
- for o in sel:
- if not o.isDerivedFrom("App::MeasureDistance"):
- return False
- return True
-
- def finish(self,closed=False):
- "terminates the operation"
- self.cont = None
- self.dir = None
- Creator.finish(self)
- if self.ui:
- self.dimtrack.finalize()
- self.arctrack.finalize()
- self.constraintrack.finalize()
-
- def createOnMeasures(self):
- for o in FreeCADGui.Selection.getSelection():
- p1 = o.P1
- p2 = o.P2
- pt = o.ViewObject.RootNode.getChildren()[1].getChildren()[0].getChildren()[0].getChildren()[3]
- p3 = Vector(pt.point.getValues()[2].getValue())
- self.commit(translate("draft","Create Dimension"),partial(Draft.makeDimension,p1,p2,p3))
- self.commit(translate("draft","Delete Measurement"),partial(FreeCAD.ActiveDocument.removeObject,o.Name))
-
- def createObject(self):
- "creates an object in the current doc"
- if self.angledata:
- self.commit(translate("draft","Create Dimension"),partial(Draft.makeAngularDimension,self.center,self.angledata,self.node[-1]))
- elif self.link and (not self.arcmode):
- self.commit(translate("draft","Create Dimension"),partial(Draft.makeDimension,self.link[0],self.link[1],self.link[2],self.node[2]))
- elif self.arcmode:
- self.commit(translate("draft","Create Dimension"),partial(Draft.makeDimension,self.link[0],self.link[1],self.arcmode,self.node[2]))
- else:
- self.commit(translate("draft","Create Dimension"),partial(Draft.makeDimension,self.node[0],self.node[1],self.node[2]))
- if self.ui.continueMode:
- self.cont = self.node[2]
- if not self.dir:
- if self.link:
- v1 = self.link[0].Shape.Vertexes[self.link[1]].Point
- v2 = self.link[0].Shape.Vertexes[self.link[2]].Point
- self.dir = v2.sub(v1)
- else:
- self.dir = self.node[1].sub(self.node[0])
- self.node = [self.node[1]]
+ def Activated(self):
+ if self.cont:
+ self.finish()
+ elif self.hasMeasures():
+ Creator.Activated(self,"Dimension")
+ self.dimtrack = dimTracker()
+ self.arctrack = arcTracker()
+ self.constraintrack = lineTracker(dotted=True)
+ self.createOnMeasures()
+ self.finish()
+ else:
+ Creator.Activated(self,"Dimension")
+ if self.ui:
+ self.ui.pointUi()
+ self.ui.continueCmd.show()
+ self.altdown = False
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ self.dimtrack = dimTracker()
+ self.arctrack = arcTracker()
self.link = None
+ self.edges = []
+ self.pts = []
+ self.angledata = None
+ self.indices = []
+ self.center = None
+ self.arcmode = False
+ self.point2 = None
+ self.constraintrack = lineTracker(dotted=True)
+ msg(translate("draft", "Pick first point:\n"))
+ FreeCADGui.draftToolBar.show()
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"): #mouse movement detection
- shift = hasMod(arg,MODCONSTRAIN)
- if self.arcmode or self.point2:
- setMod(arg,MODCONSTRAIN,False)
- point,ctrlPoint = getPoint(self,arg)
- self.ui.cross(True)
- if hasMod(arg,MODALT) and (len(self.node)<3):
- self.ui.cross(False)
- self.dimtrack.off()
- if not self.altdown:
- self.altdown = True
- self.ui.switchUi(True)
- snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
- if snapped:
- ob = self.doc.getObject(snapped['Object'])
- if "Edge" in snapped['Component']:
- num = int(snapped['Component'].lstrip('Edge'))-1
- ed = ob.Shape.Edges[num]
- v1 = ed.Vertexes[0].Point
- v2 = ed.Vertexes[-1].Point
- self.dimtrack.update([v1,v2,self.cont])
- else:
- self.ui.cross(True)
- if self.node and (len(self.edges) < 2):
- self.dimtrack.on()
- if len(self.edges) == 2:
- # angular dimension
- self.dimtrack.off()
- r = point.sub(self.center)
- self.arctrack.setRadius(r.Length)
- a = self.arctrack.getAngle(point)
- pair = fcgeo.getBoundaryAngles(a,self.pts)
- if not (pair[0] < a < pair[1]):
- self.angledata = [4*math.pi-pair[0],2*math.pi-pair[1]]
- else:
- self.angledata = [2*math.pi-pair[0],2*math.pi-pair[1]]
- self.arctrack.setStartAngle(self.angledata[0])
- self.arctrack.setEndAngle(self.angledata[1])
- if self.altdown:
- self.altdown = False
- self.ui.switchUi(False)
- if self.dir:
- point = self.node[0].add(fcvec.project(point.sub(self.node[0]),self.dir))
- if len(self.node) == 2:
- if self.arcmode and self.edges:
- cen = self.edges[0].Curve.Center
- rad = self.edges[0].Curve.Radius
- baseray = point.sub(cen)
- v2 = fcvec.scaleTo(baseray,rad)
- v1 = fcvec.neg(v2)
- if shift:
- self.node = [cen,cen.add(v2)]
- self.arcmode = "radius"
- else:
- self.node = [cen.add(v1),cen.add(v2)]
- self.arcmode = "diameter"
- self.dimtrack.update(self.node)
- # Draw constraint tracker line.
- if shift and (not self.arcmode):
- if len(self.node) == 2:
- if not self.point2:
- self.point2 = self.node[1]
- else:
- self.node[1] = self.point2
- a=abs(point.sub(self.node[0]).getAngle(plane.u))
- if (a > math.pi/4) and (a <= 0.75*math.pi):
- self.node[1] = Vector(self.node[0].x,self.node[1].y,self.node[0].z)
- else:
- self.node[1] = Vector(self.node[1].x,self.node[0].y,self.node[0].z)
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else:
- if self.point2:
- self.node[1] = self.point2
- self.point2 = None
- self.constraintrack.off()
- # update the dimline
- if self.node and (not self.arcmode):
- self.dimtrack.update(self.node+[point]+[self.cont])
- elif (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- point,ctrlPoint = getPoint(self,arg)
- if not self.node: self.support = getSupport(arg)
- if hasMod(arg,MODALT) and (len(self.node)<3):
- snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
- if snapped:
- ob = self.doc.getObject(snapped['Object'])
- if 'Edge' in snapped['Component']:
- num = int(snapped['Component'].lstrip('Edge'))-1
- ed = ob.Shape.Edges[num]
- v1 = ed.Vertexes[0].Point
- v2 = ed.Vertexes[-1].Point
- i1 = i2 = None
- for i in range(len(ob.Shape.Vertexes)):
- if v1 == ob.Shape.Vertexes[i].Point:
- i1 = i
- if v2 == ob.Shape.Vertexes[i].Point:
- i2 = i
- if (i1 != None) and (i2 != None):
- self.indices.append(num)
- if not self.edges:
- # nothing snapped yet, we treat it as normal edge-snapped dimension
- self.node = [v1,v2]
- self.link = [ob,i1,i2]
- self.edges.append(ed)
- if isinstance(ed.Curve,Part.Circle):
- # snapped edge is an arc
- self.arcmode = "diameter"
- self.link = [ob,num]
- else:
- # there is already a snapped edge, so we start angular dimension
- self.edges.append(ed)
- self.node.extend([v1,v2]) # self.node now has the 4 endpoints
- c = fcgeo.findIntersection(self.node[0],
- self.node[1],
- self.node[2],
- self.node[3],
- True,True)
- if c:
- self.center = c[0]
- self.arctrack.setCenter(self.center)
- self.arctrack.on()
- for e in self.edges:
- for v in e.Vertexes:
- self.pts.append(self.arctrack.getAngle(v.Point))
- self.link = [self.link[0],ob]
- else:
- msg(translate("draft", "Edges don't intersect!\n"))
- self.finish()
-
- self.dimtrack.on()
- else:
- if self.dir:
- point = self.node[0].add(fcvec.project(point.sub(self.node[0]),self.dir))
- self.node.append(point)
- self.dimtrack.update(self.node)
- if (len(self.node) == 2):
- self.point2 = self.node[1]
- if (len(self.node) == 1):
- self.dimtrack.on()
- self.planetrack.set(self.node[0])
- elif (len(self.node) == 2) and self.cont:
- self.node.append(self.cont)
- self.createObject()
- if not self.cont: self.finish()
- elif (len(self.node) == 3):
- # for unlinked arc mode:
- #if self.arcmode:
- # v = self.node[1].sub(self.node[0])
- # v = fcvec.scale(v,0.5)
- # cen = self.node[0].add(v)
- # self.node = [self.node[0],self.node[1],cen]
- self.createObject()
- if not self.cont: self.finish()
- elif self.angledata:
- self.node.append(point)
- self.createObject()
- self.finish()
+ def hasMeasures(self):
+ "checks if only measurements objects are selected"
+ sel = FreeCADGui.Selection.getSelection()
+ if not sel:
+ return False
+ for o in sel:
+ if not o.isDerivedFrom("App::MeasureDistance"):
+ return False
+ return True
- def numericInput(self,numx,numy,numz):
- "this function gets called by the toolbar when valid x, y, and z have been entered there"
- point = Vector(numx,numy,numz)
- self.node.append(point)
- self.dimtrack.update(self.node)
- if (len(self.node) == 1):
- self.dimtrack.on()
- elif (len(self.node) == 3):
- self.createObject()
- if not self.cont: self.finish()
+ def finish(self,closed=False):
+ "terminates the operation"
+ self.cont = None
+ self.dir = None
+ Creator.finish(self)
+ if self.ui:
+ self.dimtrack.finalize()
+ self.arctrack.finalize()
+ self.constraintrack.finalize()
+ def createOnMeasures(self):
+ for o in FreeCADGui.Selection.getSelection():
+ p1 = o.P1
+ p2 = o.P2
+ pt = o.ViewObject.RootNode.getChildren()[1].getChildren()[0].getChildren()[0].getChildren()[3]
+ p3 = Vector(pt.point.getValues()[2].getValue())
+ self.commit(translate("draft","Create Dimension"),
+ partial(Draft.makeDimension,p1,p2,p3))
+ self.commit(translate("draft","Delete Measurement"),
+ partial(FreeCAD.ActiveDocument.removeObject,o.Name))
+
+ def createObject(self):
+ "creates an object in the current doc"
+ if self.angledata:
+ self.commit(translate("draft","Create Dimension"),
+ partial(Draft.makeAngularDimension,self.center,
+ self.angledata,self.node[-1]))
+ elif self.link and (not self.arcmode):
+ self.commit(translate("draft","Create Dimension"),
+ partial(Draft.makeDimension,self.link[0],self.link[1],
+ self.link[2],self.node[2]))
+ elif self.arcmode:
+ self.commit(translate("draft","Create Dimension"),
+ partial(Draft.makeDimension,self.link[0],self.link[1],
+ self.arcmode,self.node[2]))
+ else:
+ self.commit(translate("draft","Create Dimension"),
+ partial(Draft.makeDimension,self.node[0],self.node[1],
+ self.node[2]))
+ if self.ui.continueMode:
+ self.cont = self.node[2]
+ if not self.dir:
+ if self.link:
+ v1 = self.link[0].Shape.Vertexes[self.link[1]].Point
+ v2 = self.link[0].Shape.Vertexes[self.link[2]].Point
+ self.dir = v2.sub(v1)
+ else:
+ self.dir = self.node[1].sub(self.node[0])
+ self.node = [self.node[1]]
+ self.link = None
+
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event": #mouse movement detection
+ shift = hasMod(arg,MODCONSTRAIN)
+ if self.arcmode or self.point2:
+ setMod(arg,MODCONSTRAIN,False)
+ point,ctrlPoint = getPoint(self,arg)
+ self.ui.cross(True)
+ if hasMod(arg,MODALT) and (len(self.node)<3):
+ self.ui.cross(False)
+ self.dimtrack.off()
+ if not self.altdown:
+ self.altdown = True
+ self.ui.switchUi(True)
+ snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
+ if snapped:
+ ob = self.doc.getObject(snapped['Object'])
+ if "Edge" in snapped['Component']:
+ num = int(snapped['Component'].lstrip('Edge'))-1
+ ed = ob.Shape.Edges[num]
+ v1 = ed.Vertexes[0].Point
+ v2 = ed.Vertexes[-1].Point
+ self.dimtrack.update([v1,v2,self.cont])
+ else:
+ self.ui.cross(True)
+ if self.node and (len(self.edges) < 2):
+ self.dimtrack.on()
+ if len(self.edges) == 2:
+ # angular dimension
+ self.dimtrack.off()
+ r = point.sub(self.center)
+ self.arctrack.setRadius(r.Length)
+ a = self.arctrack.getAngle(point)
+ pair = fcgeo.getBoundaryAngles(a,self.pts)
+ if not (pair[0] < a < pair[1]):
+ self.angledata = [4*math.pi-pair[0],2*math.pi-pair[1]]
+ else:
+ self.angledata = [2*math.pi-pair[0],2*math.pi-pair[1]]
+ self.arctrack.setStartAngle(self.angledata[0])
+ self.arctrack.setEndAngle(self.angledata[1])
+ if self.altdown:
+ self.altdown = False
+ self.ui.switchUi(False)
+ if self.dir:
+ point = self.node[0].add(fcvec.project(point.sub(self.node[0]),self.dir))
+ if len(self.node) == 2:
+ if self.arcmode and self.edges:
+ cen = self.edges[0].Curve.Center
+ rad = self.edges[0].Curve.Radius
+ baseray = point.sub(cen)
+ v2 = fcvec.scaleTo(baseray,rad)
+ v1 = fcvec.neg(v2)
+ if shift:
+ self.node = [cen,cen.add(v2)]
+ self.arcmode = "radius"
+ else:
+ self.node = [cen.add(v1),cen.add(v2)]
+ self.arcmode = "diameter"
+ self.dimtrack.update(self.node)
+ # Draw constraint tracker line.
+ if shift and (not self.arcmode):
+ if len(self.node) == 2:
+ if not self.point2:
+ self.point2 = self.node[1]
+ else:
+ self.node[1] = self.point2
+ a=abs(point.sub(self.node[0]).getAngle(plane.u))
+ if (a > math.pi/4) and (a <= 0.75*math.pi):
+ self.node[1] = Vector(self.node[0].x,self.node[1].y,self.node[0].z)
+ else:
+ self.node[1] = Vector(self.node[1].x,self.node[0].y,self.node[0].z)
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else:
+ if self.point2:
+ self.node[1] = self.point2
+ self.point2 = None
+ self.constraintrack.off()
+ # update the dimline
+ if self.node and (not self.arcmode):
+ self.dimtrack.update(self.node+[point]+[self.cont])
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ point,ctrlPoint = getPoint(self,arg)
+ if not self.node: self.support = getSupport(arg)
+ if hasMod(arg,MODALT) and (len(self.node)<3):
+ snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
+ if snapped:
+ ob = self.doc.getObject(snapped['Object'])
+ if 'Edge' in snapped['Component']:
+ num = int(snapped['Component'].lstrip('Edge'))-1
+ ed = ob.Shape.Edges[num]
+ v1 = ed.Vertexes[0].Point
+ v2 = ed.Vertexes[-1].Point
+ i1 = i2 = None
+ for i in range(len(ob.Shape.Vertexes)):
+ if v1 == ob.Shape.Vertexes[i].Point:
+ i1 = i
+ if v2 == ob.Shape.Vertexes[i].Point:
+ i2 = i
+ if (i1 != None) and (i2 != None):
+ self.indices.append(num)
+ if not self.edges:
+ # nothing snapped yet, we treat it as normal edge-snapped dimension
+ self.node = [v1,v2]
+ self.link = [ob,i1,i2]
+ self.edges.append(ed)
+ if isinstance(ed.Curve,Part.Circle):
+ # snapped edge is an arc
+ self.arcmode = "diameter"
+ self.link = [ob,num]
+ else:
+ # there is already a snapped edge, so we start angular dimension
+ self.edges.append(ed)
+ self.node.extend([v1,v2]) # self.node now has the 4 endpoints
+ c = fcgeo.findIntersection(self.node[0],
+ self.node[1],
+ self.node[2],
+ self.node[3],
+ True,True)
+ if c:
+ self.center = c[0]
+ self.arctrack.setCenter(self.center)
+ self.arctrack.on()
+ for e in self.edges:
+ for v in e.Vertexes:
+ self.pts.append(self.arctrack.getAngle(v.Point))
+ self.link = [self.link[0],ob]
+ else:
+ msg(translate("draft", "Edges don't intersect!\n"))
+ self.finish()
+ self.dimtrack.on()
+ else:
+ if self.dir:
+ point = self.node[0].add(fcvec.project(point.sub(self.node[0]),self.dir))
+ self.node.append(point)
+ self.dimtrack.update(self.node)
+ if (len(self.node) == 2):
+ self.point2 = self.node[1]
+ if (len(self.node) == 1):
+ self.dimtrack.on()
+ self.planetrack.set(self.node[0])
+ elif (len(self.node) == 2) and self.cont:
+ self.node.append(self.cont)
+ self.createObject()
+ if not self.cont: self.finish()
+ elif (len(self.node) == 3):
+ # for unlinked arc mode:
+ # if self.arcmode:
+ # v = self.node[1].sub(self.node[0])
+ # v = fcvec.scale(v,0.5)
+ # cen = self.node[0].add(v)
+ # self.node = [self.node[0],self.node[1],cen]
+ self.createObject()
+ if not self.cont: self.finish()
+ elif self.angledata:
+ self.node.append(point)
+ self.createObject()
+ self.finish()
+
+ def numericInput(self,numx,numy,numz):
+ "this function gets called by the toolbar when valid x, y, and z have been entered there"
+ point = Vector(numx,numy,numz)
+ self.node.append(point)
+ self.dimtrack.update(self.node)
+ if (len(self.node) == 1):
+ self.dimtrack.on()
+ elif (len(self.node) == 3):
+ self.createObject()
+ if not self.cont: self.finish()
#---------------------------------------------------------------------------
@@ -2492,1855 +2524,1922 @@ class Dimension(Creator):
#---------------------------------------------------------------------------
class Modifier:
- "A generic Modifier Tool, used by modification tools such as move"
- def __init__(self):
- self.commitList = []
+ "A generic Modifier Tool, used by modification tools such as move"
+
+ def __init__(self):
+ self.commitList = []
+
+ def Activated(self,name="None"):
+ if FreeCAD.activeDraftCommand:
+ FreeCAD.activeDraftCommand.finish()
+ self.ui = None
+ self.call = None
+ self.commitList = []
+ self.doc = FreeCAD.ActiveDocument
+ if not self.doc:
+ self.finish()
+ else:
+ FreeCAD.activeDraftCommand = self
+ self.view = FreeCADGui.ActiveDocument.ActiveView
+ self.ui = FreeCADGui.draftToolBar
+ FreeCADGui.draftToolBar.show()
+ rot = self.view.getCameraNode().getField("orientation").getValue()
+ upv = Vector(rot.multVec(coin.SbVec3f(0,1,0)).getValue())
+ plane.setup(fcvec.neg(self.view.getViewDirection()), Vector(0,0,0), upv)
+ self.node = []
+ self.ui.sourceCmd = self
+ self.constrain = None
+ self.obj = None
+ self.extendedCopy = False
+ self.ui.setTitle(name)
+ self.featureName = name
+ self.snap = snapTracker()
+ self.extsnap = lineTracker(dotted=True)
+ self.planetrack = PlaneTracker()
+ if Draft.getParam("grid"):
+ self.grid = gridTracker()
+ self.grid.set()
+ else:
+ self.grid = None
- def Activated(self,name="None"):
- if FreeCAD.activeDraftCommand:
- FreeCAD.activeDraftCommand.finish()
- self.ui = None
- self.call = None
- self.commitList = []
- self.doc = FreeCAD.ActiveDocument
- if not self.doc:
- self.finish()
- else:
- FreeCAD.activeDraftCommand = self
- self.view = FreeCADGui.ActiveDocument.ActiveView
- self.ui = FreeCADGui.draftToolBar
- FreeCADGui.draftToolBar.show()
- rot = self.view.getCameraNode().getField("orientation").getValue()
- upv = Vector(rot.multVec(coin.SbVec3f(0,1,0)).getValue())
- plane.setup(fcvec.neg(self.view.getViewDirection()), Vector(0,0,0), upv)
- self.node = []
- self.ui.sourceCmd = self
- self.constrain = None
- self.obj = None
- self.extendedCopy = False
- self.ui.setTitle(name)
- self.featureName = name
- self.snap = snapTracker()
- self.extsnap = lineTracker(dotted=True)
- self.planetrack = PlaneTracker()
- if Draft.getParam("grid"):
- self.grid = gridTracker()
- self.grid.set()
- else:
- self.grid = None
-
- def IsActive(self):
- if FreeCADGui.ActiveDocument:
- return True
- else:
- return False
+ def IsActive(self):
+ if FreeCADGui.ActiveDocument:
+ return True
+ else:
+ return False
- def finish(self):
- self.node = []
- self.snap.finalize()
- self.extsnap.finalize()
- FreeCAD.activeDraftCommand = None
- if self.ui:
- self.ui.offUi()
- self.ui.sourceCmd=None
- self.ui.cross(False)
- msg("")
- self.planetrack.finalize()
- if self.grid: self.grid.finalize()
- if self.call:
- self.view.removeEventCallback("SoEvent",self.call)
- self.call = None
- if self.commitList:
- todo.delayCommit(self.commitList)
- self.commitList = []
+ def finish(self):
+ self.node = []
+ self.snap.finalize()
+ self.extsnap.finalize()
+ FreeCAD.activeDraftCommand = None
+ if self.ui:
+ self.ui.offUi()
+ self.ui.sourceCmd=None
+ self.ui.cross(False)
+ msg("")
+ self.planetrack.finalize()
+ if self.grid: self.grid.finalize()
+ if self.call:
+ self.view.removeEventCallback("SoEvent",self.call)
+ self.call = None
+ if self.commitList:
+ todo.delayCommit(self.commitList)
+ self.commitList = []
+
+ def commit(self,name,func):
+ "stores partial actions to be committed to the FreeCAD document"
+ # print "committing"
+ self.commitList.append((name,func))
+
- def commit(self,name,func):
- "stores partial actions to be committed to the FreeCAD document"
- # print "committing"
- self.commitList.append((name,func))
-
class Move(Modifier):
- "The Draft_Move FreeCAD command definition"
+ "The Draft_Move FreeCAD command definition"
- def GetResources(self):
- return {'Pixmap' : 'Draft_Move',
- 'Accel' : "M, V",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Move", "Move"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Move", "Moves the selected objects between 2 points. CTRL to snap, SHIFT to constrain, ALT to copy")}
-
- def Activated(self):
- Modifier.Activated(self,"Move")
- if self.ui:
- if not Draft.getSelection():
- self.ghost = None
- self.linetrack = None
- self.constraintrack = None
- self.ui.selectUi()
- msg(translate("draft", "Select an object to move\n"))
- self.call = self.view.addEventCallback("SoEvent",selectObject)
- else:
- self.proceed()
-
- def proceed(self):
- if self.call: self.view.removeEventCallback("SoEvent",self.call)
- self.sel = Draft.getSelection()
- self.sel = Draft.getGroupContents(self.sel)
- self.ui.pointUi()
- self.ui.modUi()
- self.ui.xValue.setFocus()
- self.ui.xValue.selectAll()
- self.linetrack = lineTracker()
- self.constraintrack = lineTracker(dotted=True)
- self.ghost = ghostTracker(self.sel)
- self.call = self.view.addEventCallback("SoEvent",self.action)
- msg(translate("draft", "Pick start point:\n"))
- self.ui.cross(True)
-
- def finish(self,closed=False,cont=False):
- if self.ui:
- self.ghost.finalize()
- self.linetrack.finalize()
- self.constraintrack.finalize()
- Modifier.finish(self)
- if cont and self.ui:
- if self.ui.continueMode:
- FreeCADGui.Selection.clearSelection()
- self.Activated()
-
- def move(self,delta,copy=False):
- "moving the real shapes"
- if copy:
- self.commit(translate("draft","Copy"),partial(Draft.move,self.sel,delta,copy))
- else:
- self.commit(translate("draft","Move"),partial(Draft.move,self.sel,delta,copy))
- self.doc.recompute()
-
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"): #mouse movement detection
- point,ctrlPoint = getPoint(self,arg)
- self.linetrack.p2(point)
- self.ui.cross(True)
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- if (len(self.node) > 0):
- last = self.node[len(self.node)-1]
- delta = point.sub(last)
- self.ghost.trans.translation.setValue([delta.x,delta.y,delta.z])
- if self.extendedCopy:
- if not hasMod(arg,MODALT): self.finish()
- if (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- point,ctrlPoint = getPoint(self,arg)
- if (self.node == []):
- self.node.append(point)
- self.ui.isRelative.show()
- self.linetrack.on()
- self.ghost.on()
- self.linetrack.p1(point)
- msg(translate("draft", "Pick end point:\n"))
- self.planetrack.set(point)
- else:
- last = self.node[0]
- if self.ui.isCopy.isChecked() or hasMod(arg,MODALT):
- self.move(point.sub(last),True)
- else:
- self.move(point.sub(last))
- if hasMod(arg,MODALT):
- self.extendedCopy = True
- else:
- self.finish(cont=True)
-
- def numericInput(self,numx,numy,numz):
- "this function gets called by the toolbar when valid x, y, and z have been entered there"
- point = Vector(numx,numy,numz)
- if not self.node:
- self.node.append(point)
- self.ui.isRelative.show()
- self.ui.isCopy.show()
- self.linetrack.p1(point)
- self.linetrack.on()
- self.ghost.on()
- msg(translate("draft", "Pick end point:\n"))
- else:
- last = self.node[-1]
- if self.ui.isCopy.isChecked():
- self.move(point.sub(last),True)
- else:
- self.move(point.sub(last))
- self.finish()
-
-
-class ApplyStyle(Modifier):
- "The Draft_ApplyStyle FreeCA command definition"
-
- def GetResources(self):
- return {'Pixmap' : 'Draft_Apply',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ApplyStyle", "Apply Current Style"),
- 'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_ApplyStyle", "Applies current line width and color to selected objects")}
-
- def IsActive(self):
- if Draft.getSelection():
- return True
- else:
- return False
-
- def Activated(self):
- Modifier.Activated(self)
- if self.ui:
- self.sel = Draft.getSelection()
- if (len(self.sel)>0):
- for ob in self.sel:
- if (ob.Type == "App::DocumentObjectGroup"):
- self.formatGroup(ob)
- else:
- self.commit(translate("draft","Change Style"),partial(Draft.formatObject,ob))
-
- def formatGroup(self,grpob):
- for ob in grpob.Group:
- if (ob.Type == "App::DocumentObjectGroup"):
- self.formatGroup(ob)
- else:
- self.commit(translate("draft","Change Style"),partial(Draft.formatObject,ob))
-
-
-class Rotate(Modifier):
- "The Draft_Rotate FreeCAD command definition"
-
- def GetResources(self):
- return {'Pixmap' : 'Draft_Rotate',
- 'Accel' : "R, O",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Rotate", "Rotate"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Rotate", "Rotates the selected objects. CTRL to snap, SHIFT to constrain, ALT creates a copy")}
-
- def Activated(self):
- Modifier.Activated(self,"Rotate")
- if self.ui:
- if not Draft.getSelection():
- self.ghost = None
- self.linetrack = None
- self.arctrack = None
- self.constraintrack = None
- self.ui.selectUi()
- msg(translate("draft", "Select an object to rotate\n"))
- self.call = self.view.addEventCallback("SoEvent",selectObject)
- else:
- self.proceed()
-
- def proceed(self):
- if self.call: self.view.removeEventCallback("SoEvent",self.call)
- self.sel = Draft.getSelection()
- self.sel = Draft.getGroupContents(self.sel)
- self.step = 0
- self.center = None
- self.ui.arcUi()
- self.ui.isCopy.show()
- self.ui.setTitle("Rotate")
- self.linetrack = lineTracker()
- self.constraintrack = lineTracker(dotted=True)
- self.arctrack = arcTracker()
- self.ghost = ghostTracker(self.sel)
- self.call = self.view.addEventCallback("SoEvent",self.action)
- msg(translate("draft", "Pick rotation center:\n"))
- self.ui.cross(True)
-
- def finish(self,closed=False,cont=False):
- "finishes the arc"
- Modifier.finish(self)
- if self.ui:
- self.linetrack.finalize()
- self.constraintrack.finalize()
- self.arctrack.finalize()
- self.ghost.finalize()
- self.doc.recompute()
- if cont and self.ui:
- if self.ui.continueMode:
- FreeCADGui.Selection.clearSelection()
- self.Activated()
-
- def rot (self,angle,copy=False):
- "rotating the real shapes"
- if copy:
- self.commit(translate("draft","Copy"),partial(Draft.rotate,self.sel,math.degrees(angle),self.center,plane.axis,copy))
- else:
- self.commit(translate("draft","Rotate"),partial(Draft.rotate,self.sel,math.degrees(angle),self.center,plane.axis,copy))
-
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"):
- point,ctrlPoint = getPoint(self,arg)
- self.ui.cross(True)
- # this is to make sure radius is what you see on screen
- if self.center and fcvec.dist(point,self.center):
- viewdelta = fcvec.project(point.sub(self.center), plane.axis)
- if not fcvec.isNull(viewdelta):
- point = point.add(fcvec.neg(viewdelta))
- if self.extendedCopy:
- if not hasMod(arg,MODALT):
- self.step = 3
- self.finish()
- if (self.step == 0):
- pass
- elif (self.step == 1):
- currentrad = fcvec.dist(point,self.center)
- if (currentrad != 0):
- angle = fcvec.angle(plane.u, point.sub(self.center), plane.axis)
- else: angle = 0
- self.linetrack.p2(point)
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- self.ui.radiusValue.setText("%.2f" % math.degrees(angle))
- self.firstangle = angle
- self.ui.radiusValue.setFocus()
- self.ui.radiusValue.selectAll()
- elif (self.step == 2):
- currentrad = fcvec.dist(point,self.center)
- if (currentrad != 0):
- angle = fcvec.angle(plane.u, point.sub(self.center), plane.axis)
- else: angle = 0
- if (angle < self.firstangle):
- sweep = (2*math.pi-self.firstangle)+angle
- else:
- sweep = angle - self.firstangle
- self.arctrack.setApertureAngle(sweep)
- self.ghost.trans.rotation.setValue(coin.SbVec3f(fcvec.tup(plane.axis)),sweep)
- self.linetrack.p2(point)
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- self.ui.radiusValue.setText("%.2f" % math.degrees(sweep))
- self.ui.radiusValue.setFocus()
- self.ui.radiusValue.selectAll()
-
- if (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- point,ctrlPoint = getPoint(self,arg)
- if self.center and fcvec.dist(point,self.center):
- viewdelta = fcvec.project(point.sub(self.center), plane.axis)
- if not fcvec.isNull(viewdelta): point = point.add(fcvec.neg(viewdelta))
- if (self.step == 0):
- self.center = point
- self.node = [point]
- self.ui.radiusUi()
- self.ui.hasFill.hide()
- self.ui.labelRadius.setText("Base angle")
- self.linetrack.p1(self.center)
- self.arctrack.setCenter(self.center)
- self.ghost.trans.center.setValue(self.center.x,self.center.y,self.center.z)
- self.linetrack.on()
- self.step = 1
- msg(translate("draft", "Pick base angle:\n"))
- self.planetrack.set(point)
- elif (self.step == 1):
- self.ui.labelRadius.setText("Rotation")
- self.rad = fcvec.dist(point,self.center)
- self.arctrack.on()
- self.arctrack.setStartPoint(point)
- self.ghost.on()
- self.step = 2
- msg(translate("draft", "Pick rotation angle:\n"))
- else:
- currentrad = fcvec.dist(point,self.center)
- angle = point.sub(self.center).getAngle(plane.u)
- if fcvec.project(point.sub(self.center), plane.v).getAngle(plane.v) > 1:
- angle = -angle
- if (angle < self.firstangle):
- sweep = (2*math.pi-self.firstangle)+angle
- else:
- sweep = angle - self.firstangle
- if self.ui.isCopy.isChecked() or hasMod(arg,MODALT):
- self.rot(sweep,True)
- else:
- self.rot(sweep)
- if hasMod(arg,MODALT):
- self.extendedCopy = True
- else:
- self.finish(cont=True)
-
- def numericInput(self,numx,numy,numz):
- "this function gets called by the toolbar when valid x, y, and z have been entered there"
- self.center = Vector(numx,numy,numz)
- self.node = [self.center]
- self.arctrack.setCenter(self.center)
- self.ghost.trans.center.setValue(self.center.x,self.center.y,self.center.z)
- self.linetrack.p1(self.center)
- #self.arctrack.on()
- self.linetrack.on()
- self.ui.radiusUi()
- self.ui.hasFill.hide()
- self.ui.labelRadius.setText("Base angle")
- self.step = 1
- msg(translate("draft", "Pick base angle:\n"))
-
- def numericRadius(self,rad):
- "this function gets called by the toolbar when valid radius have been entered there"
- if (self.step == 1):
- self.ui.labelRadius.setText("Rotation")
- self.firstangle = math.radians(rad)
- self.arctrack.setStartAngle(self.firstangle)
- self.arctrack.on()
- self.ghost.on()
- self.step = 2
- msg(translate("draft", "Pick rotation angle:\n"))
- else:
- self.rot(math.radians(rad),self.ui.isCopy.isChecked())
- self.finish(cont=True)
-
-
-class Offset(Modifier):
- "The Draft_Offset FreeCAD command definition"
-
- def GetResources(self):
- return {'Pixmap' : 'Draft_Offset',
- 'Accel' : "O, S",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Offset", "Offset"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Offset", "Offsets the active object. CTRL to snap, SHIFT to constrain, ALT to copy")}
-
- def Activated(self):
- self.running = False
- Modifier.Activated(self,"Offset")
- if self.ui:
- if not Draft.getSelection():
- self.ghost = None
- self.linetrack = None
- self.arctrack = None
- self.constraintrack = None
- self.ui.selectUi()
- msg(translate("draft", "Select an object to offset\n"))
- self.call = self.view.addEventCallback("SoEvent",selectObject)
- elif len(Draft.getSelection()) > 1:
- msg(translate("draft", "Offset only works on one object at a time\n"),"warning")
- else:
- self.proceed()
-
- def proceed(self):
- if self.call: self.view.removeEventCallback("SoEvent",self.call)
- self.sel = Draft.getSelection()[0]
- if not self.sel.isDerivedFrom("Part::Feature"):
- msg(translate("draft", "Cannot offset this object type\n"),"warning")
- self.finish()
- else:
- self.step = 0
- self.dvec = None
- self.constrainSeg = None
- self.ui.offsetUi()
- self.linetrack = lineTracker()
- self.constraintrack = lineTracker(dotted=True)
- self.faces = False
- self.shape = self.sel.Shape
- self.mode = None
- if Draft.getType(self.sel) in ["Circle","Arc"]:
- self.ghost = arcTracker()
- self.mode = "Circle"
- self.center = self.shape.Edges[0].Curve.Center
- self.ghost.setCenter(self.center)
- self.ghost.setStartAngle(math.radians(self.sel.FirstAngle))
- self.ghost.setEndAngle(math.radians(self.sel.LastAngle))
- else:
- self.ghost = wireTracker(self.shape)
- self.mode = "Wire"
- self.call = self.view.addEventCallback("SoEvent",self.action)
- msg(translate("draft", "Pick distance:\n"))
- self.ui.cross(True)
- self.planetrack.set(self.shape.Vertexes[0].Point)
- self.running = True
-
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"):
- self.ui.cross(True)
- point,ctrlPoint = getPoint(self,arg)
- if hasMod(arg,MODCONSTRAIN) and self.constrainSeg:
- dist = fcgeo.findPerpendicular(point,self.shape,self.constrainSeg[1])
- e = self.shape.Edges[self.constrainSeg[1]]
- self.constraintrack.p1(e.Vertexes[0].Point)
- self.constraintrack.p2(point.add(dist[0]))
- self.constraintrack.on()
- else:
- dist = fcgeo.findPerpendicular(point,self.shape.Edges)
- self.constraintrack.off()
- if dist:
- self.ghost.on()
- if self.mode == "Wire":
- d = fcvec.neg(dist[0])
- v1 = fcgeo.getTangent(self.shape.Edges[0],point)
- v2 = fcgeo.getTangent(self.shape.Edges[dist[1]],point)
- a = -fcvec.angle(v1,v2)
- self.dvec = fcvec.rotate(d,a,plane.axis)
- self.ghost.update(fcgeo.offsetWire(self.shape,self.dvec,occ=self.ui.occOffset.isChecked()))
- elif self.mode == "Circle":
- self.dvec = point.sub(self.center).Length
- self.ghost.setRadius(self.dvec)
- self.constrainSeg = dist
- self.linetrack.on()
- self.linetrack.p1(point)
- self.linetrack.p2(point.add(dist[0]))
- self.ui.radiusValue.setText("%.2f" % dist[0].Length)
- else:
- self.dvec = None
- self.ghost.off()
- self.constrainSeg = None
- self.linetrack.off()
- self.ui.radiusValue.setText("off")
- self.ui.radiusValue.setFocus()
- self.ui.radiusValue.selectAll()
- if self.extendedCopy:
- if not hasMod(arg,MODALT): self.finish()
- if (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- copymode = False
- occmode = self.ui.occOffset.isChecked()
- if hasMod(arg,MODALT) or self.ui.isCopy.isChecked(): copymode = True
- if self.dvec:
- self.commit(translate("draft","Offset"),partial(Draft.offset,self.sel,self.dvec,copymode,occ=occmode))
- if hasMod(arg,MODALT):
- self.extendedCopy = True
- else:
- self.finish()
-
- def finish(self,closed=False):
- Modifier.finish(self)
- if self.ui and self.running:
- self.linetrack.finalize()
- self.constraintrack.finalize()
- self.ghost.finalize()
-
- def numericRadius(self,rad):
- "this function gets called by the toolbar when valid radius have been entered there"
- if self.dvec:
- self.dvec.normalize()
- self.dvec.multiply(rad)
- copymode = False
- occmode = self.ui.occOffset.isChecked()
- if self.ui.isCopy.isChecked(): copymode = True
- self.commit(translate("draft","Offset"),partial(Draft.offset,self.sel,self.dvec,copymode,occ=occmode))
- self.finish()
-
-class Upgrade(Modifier):
- '''The Draft_Upgrade FreeCAD command definition.
- This class upgrades selected objects in different ways,
- following this list (in order):
- - if there are more than one faces, the faces are merged (union)
- - if there is only one face, nothing is done
- - if there are closed wires, they are transformed in a face
- - otherwise join all edges into a wire (closed if applicable)
- - if nothing of the above is possible, a Compound is created
- '''
-
- def GetResources(self):
- return {'Pixmap' : 'Draft_Upgrade',
- 'Accel' : "U, P",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Upgrade", "Upgrade"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Upgrade", "Joins the selected objects into one, or converts closed wires to filled faces, or unite faces")}
-
- def Activated(self):
- Modifier.Activated(self,"Upgrade")
- if self.ui:
- if not Draft.getSelection():
- self.ui.selectUi()
- msg(translate("draft", "Select an object to upgrade\n"))
- self.call = self.view.addEventCallback("SoEvent",selectObject)
- else:
- self.proceed()
-
- def compound(self):
- #shapeslist = []
- #for ob in self.sel: shapeslist.append(ob.Shape)
- #newob = self.doc.addObject("Part::Feature","Compound")
- #newob.Shape = Part.makeCompound(shapeslist)
- newob = Draft.makeBlock(self.sel)
- self.nodelete = True
- return newob
-
- def proceed(self):
- if self.call: self.view.removeEventCallback("SoEvent",self.call)
- self.sel = Draft.getSelection()
- newob = None
- self.nodelete = False
- edges = []
- wires = []
- openwires = []
- faces = []
- groups = []
- curves = []
- facewires = []
- # determining what we have in our selection
- for ob in self.sel:
- if ob.Type == "App::DocumentObjectGroup":
- groups.append(ob)
- else:
- if ob.Shape.ShapeType == 'Edge': openwires.append(ob.Shape)
- for f in ob.Shape.Faces:
- faces.append(f)
- facewires.extend(f.Wires)
- for w in ob.Shape.Wires:
- if w.isClosed():
- wires.append(w)
- else:
- openwires.append(w)
- for e in ob.Shape.Edges:
- if not isinstance(e.Curve,Part.Line):
- curves.append(e)
- lastob = ob
- # print "objects:",self.sel," edges:",edges," wires:",wires," openwires:",openwires," faces:",faces," groups:",groups," curves:",curves," facewires:",facewires
- # applying transformation
- self.doc.openTransaction("Upgrade")
- if groups:
- # if we have a group: turn each closed wire inside into a face
- msg(translate("draft", "Found groups: closing each open object inside\n"))
- for grp in groups:
- for ob in grp.Group:
- if not ob.Shape.Faces:
- for w in ob.Shape.Wires:
- newob = Draft.makeWire(w,closed=w.isClosed())
- self.sel.append(ob)
- grp.addObject(newob)
- elif faces and (len(wires)+len(openwires)==len(facewires)):
- if (len(self.sel) == 1) and (len(faces) > 1):
- # we have a shell: we try to make a solid
- sol = Part.makeSolid(self.sel[0].Shape)
- if sol.isClosed():
- msg(translate("draft", "Found 1 solidificable object: solidifying it\n"))
- newob = self.doc.addObject("Part::Feature","Solid")
- newob.Shape = sol
- Draft.formatObject(newob,lastob)
-
- elif (len(self.sel) == 2) and (not curves):
- # we have exactly 2 objects: we fuse them
- msg(translate("draft", "Found 2 objects: fusing them\n"))
- newob = Draft.fuse(self.sel[0],self.sel[1])
- self.nodelete = True
- elif (len(self.sel) > 2) and (len(faces) > 10):
- # we have many separate faces: we try to make a shell
- sh = Part.makeShell(faces)
- newob = self.doc.addObject("Part::Feature","Shell")
- newob.Shape = sh
- Draft.formatObject(newob,lastob)
- elif (len(self.sel) > 2) or (len(faces) > 1):
- # more than 2 objects or faces: we try the draft way: make one face out of them
- u = faces.pop(0)
- for f in faces:
- u = u.fuse(f)
- if fcgeo.isCoplanar(faces):
- if self.sel[0].ViewObject.DisplayMode == "Wireframe":
- f = False
- else:
- f = True
- u = fcgeo.concatenate(u)
- if not curves:
- msg(translate("draft", "Found several objects or faces: making a parametric face\n"))
- newob = Draft.makeWire(u.Wires[0],closed=True,face=f)
- Draft.formatObject(newob,lastob)
- else:
- # if not possible, we do a non-parametric union
- msg(translate("draft", "Found objects containing curves: fusing them\n"))
- newob = self.doc.addObject("Part::Feature","Union")
- newob.Shape = u
- Draft.formatObject(newob,lastob)
- else:
- # if not possible, we do a non-parametric union
- msg(translate("draft", "Found several objects: fusing them\n"))
- # if we have a solid, make sure we really return a solid
- if (len(u.Faces) > 1) and u.isClosed():
- u = Part.makeSolid(u)
- newob = self.doc.addObject("Part::Feature","Union")
- newob.Shape = u
- Draft.formatObject(newob,lastob)
- elif len(self.sel) == 1:
- # only one object: if not parametric, we "draftify" it
- self.nodelete = True
- if (not curves) and (Draft.getType(self.sel[0]) == "Part"):
- msg(translate("draft", "Found 1 non-parametric objects: draftifying it\n"))
- Draft.draftify(self.sel[0])
-
- elif wires and (not faces) and (not openwires):
- if (len(self.sel) == 1) and self.sel[0].isDerivedFrom("Sketcher::SketchObject") and (not curves):
- msg(translate("draft", "Found 1 closed sketch object: making a face from it\n"))
- newob = Draft.makeWire(self.sel[0].Shape,closed=True)
- newob.Base = self.sel[0]
- self.sel[0].ViewObject.Visibility = False
- self.nodelete = True
- else:
- # only closed wires
- for w in wires:
- f = Part.Face(w)
- faces.append(f)
- for f in faces:
- if not curves:
- newob = Draft.makeWire(f.Wire,closed=True)
- else:
- # if there are curved segments, we do a non-parametric face
- msg(translate("draft", "Found closed wires: making faces\n"))
- newob = self.doc.addObject("Part::Feature","Face")
- newob.Shape = f
- Draft.formatObject(newob,lastob)
- elif (len(openwires) == 1) and (not faces) and (not wires):
- # special case, we have only one open wire. We close it!"
- p0 = openwires[0].Vertexes[0].Point
- p1 = openwires[0].Vertexes[-1].Point
- edges = openwires[0].Edges
- edges.append(Part.Line(p1,p0).toShape())
- w = Part.Wire(fcgeo.sortEdges(edges))
- msg(translate("draft", "Found 1 open wire: closing it\n"))
- if not curves:
- newob = Draft.makeWire(w,closed=True)
- else:
- # if not possible, we do a non-parametric union
- newob = self.doc.addObject("Part::Feature","Wire")
- newob.Shape = w
- Draft.formatObject(newob,lastob)
- elif openwires and (not wires) and (not faces):
- # only open wires and edges: we try to join their edges
- for ob in self.sel:
- for e in ob.Shape.Edges:
- edges.append(e)
- newob = None
- nedges = fcgeo.sortEdges(edges[:])
- # for e in nedges: print "debug: ",e.Curve,e.Vertexes[0].Point,e.Vertexes[-1].Point
- w = Part.Wire(nedges)
- if len(w.Edges) == len(edges):
- msg(translate("draft", "Found several edges: wiring them\n"))
- if not curves:
- newob = Draft.makeWire(w)
- else:
- newob = self.doc.addObject("Part::Feature","Wire")
- newob.Shape = w
- Draft.formatObject(newob,lastob)
- if not newob:
- print "no new object found"
- msg(translate("draft", "Found several non-connected edges: making compound\n"))
- newob = self.compound()
- Draft.formatObject(newob,lastob)
- else:
- msg(translate("draft", "Found several non-treatable objects: making compound\n"))
- newob = self.compound()
- Draft.formatObject(newob,lastob)
- if not self.nodelete:
- for ob in self.sel:
- if not ob.Type == "App::DocumentObjectGroup":
- self.doc.removeObject(ob.Name)
- self.doc.commitTransaction()
- if newob: Draft.select(newob)
- Modifier.finish(self)
-
-class Downgrade(Modifier):
- '''
- The Draft_Downgrade FreeCAD command definition.
- This class downgrades selected objects in different ways,
- following this list (in order):
- - if there are more than one faces, the subsequent
- faces are subtracted from the first one
- - if there is only one face, it gets converted to a wire
- - otherwise wires are exploded into single edges
- '''
-
- def GetResources(self):
- return {'Pixmap' : 'Draft_Downgrade',
- 'Accel' : "D, N",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Downgrade", "Downgrade"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Downgrade", "Explodes the selected objects into simpler objects, or subtract faces")}
-
- def Activated(self):
- Modifier.Activated(self,"Downgrade")
- if self.ui:
- if not Draft.getSelection():
- self.ui.selectUi()
- msg(translate("draft", "Select an object to upgrade\n"))
- self.call = self.view.addEventCallback("SoEvent",selectObject)
- else:
- self.proceed()
-
-
- def proceed(self):
- self.sel = Draft.getSelection()
- edges = []
- faces = []
- for ob in self.sel:
- for f in ob.Shape.Faces:
- faces.append(f)
- for ob in self.sel:
- for e in ob.Shape.Edges:
- edges.append(e)
- lastob = ob
- # applying transformation
- self.doc.openTransaction("Downgrade")
- if (len(self.sel) == 1) and (Draft.getType(self.sel[0]) == "Block"):
- # a block, we explode it
- pl = self.sel[0].Placement
- newob = []
- for ob in self.sel[0].Components:
- ob.ViewObject.Visibility = True
- ob.Placement = ob.Placement.multiply(pl)
- newob.append(ob)
- self.doc.removeObject(self.sel[0].Name)
- elif (len(self.sel) == 1) and (self.sel[0].isDerivedFrom("Part::Feature")) and ("Base" in self.sel[0].PropertiesList):
- # special case, we have one parametric object: we "de-parametrize" it
- msg(translate("draft", "Found 1 parametric object: breaking its dependencies\n"))
- Draft.shapify(self.sel[0])
- elif len(self.sel) == 2:
- # we have only 2 objects: cut 2nd from 1st
- msg(translate("draft", "Found 2 objects: subtracting them\n"))
- newob = Draft.cut(self.sel[0],self.sel[1])
- elif (len(faces) > 1):
- if len(self.sel) == 1:
- # one object with several faces: split it
- for f in faces:
- msg(translate("draft", "Found several faces: splitting them\n"))
- newob = self.doc.addObject("Part::Feature","Face")
- newob.Shape = f
- Draft.formatObject(newob,self.sel[0])
- self.doc.removeObject(ob.Name)
- else:
- # several objects: remove all the faces from the first one
- msg(translate("draft", "Found several objects: subtracting them from the first one\n"))
- u = faces.pop(0)
- for f in faces:
- u = u.cut(f)
- newob = self.doc.addObject("Part::Feature","Subtraction")
- newob.Shape = u
- for ob in self.sel:
- Draft.formatObject(newob,ob)
- self.doc.removeObject(ob.Name)
- elif (len(faces) > 0):
- # only one face: we extract its wires
- msg(translate("draft", "Found 1 face: extracting its wires\n"))
- for w in faces[0].Wires:
- newob = self.doc.addObject("Part::Feature","Wire")
- newob.Shape = w
- Draft.formatObject(newob,lastob)
- for ob in self.sel:
- self.doc.removeObject(ob.Name)
- else:
- # no faces: split wire into single edges
- msg(translate("draft", "Found only wires: extracting their edges\n"))
- for ob in self.sel:
- for e in edges:
- newob = self.doc.addObject("Part::Feature","Edge")
- newob.Shape = e
- Draft.formatObject(newob,ob)
- self.doc.removeObject(ob.Name)
- self.doc.commitTransaction()
- Draft.select(newob)
- Modifier.finish(self)
-
-
-class Trimex(Modifier):
- ''' The Draft_Trimex FreeCAD command definition.
- This tool trims or extends lines, wires and arcs,
- or extrudes single faces. SHIFT constrains to the last point
- or extrudes in direction to the face normal.'''
-
- def GetResources(self):
- return {'Pixmap' : 'Draft_Trimex',
- 'Accel' : "T, R",
- 'MenuText' : QtCore.QT_TRANSLATE_NOOP("Draft_Trimex", "Trimex"),
- 'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_Trimex", "Trims or extends the selected object, or extrudes single faces. CTRL snaps, SHIFT constrains to current segment or to normal, ALT inverts")}
-
- def Activated(self):
- Modifier.Activated(self,"Trimex")
- self.edges = []
- self.placement = None
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Move',
+ 'Accel' : "M, V",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Move", "Move"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Move", "Moves the selected objects between 2 points. CTRL to snap, SHIFT to constrain, ALT to copy")}
+
+ def Activated(self):
+ Modifier.Activated(self,"Move")
+ if self.ui:
+ if not Draft.getSelection():
self.ghost = None
self.linetrack = None
self.constraintrack = None
- if self.ui:
- if not Draft.getSelection():
- self.ui.selectUi()
- msg(translate("draft", "Select an object to trim/extend\n"))
- self.call = self.view.addEventCallback("SoEvent",selectObject)
- else:
- self.proceed()
+ self.ui.selectUi()
+ msg(translate("draft", "Select an object to move\n"))
+ self.call = self.view.addEventCallback("SoEvent",selectObject)
+ else:
+ self.proceed()
- def proceed(self):
- if self.call: self.view.removeEventCallback("SoEvent",self.call)
- self.obj = Draft.getSelection()[0]
- self.ui.radiusUi()
- self.ui.labelRadius.setText("Distance")
- self.ui.radiusValue.setFocus()
- self.ui.radiusValue.selectAll()
- self.linetrack = lineTracker()
- self.constraintrack = lineTracker(dotted=True)
- if not "Shape" in self.obj.PropertiesList: return
- if "Placement" in self.obj.PropertiesList:
- self.placement = self.obj.Placement
- if len(self.obj.Shape.Faces) == 1:
- # simple extrude mode, the object itself is extruded
- self.extrudeMode = True
- self.ghost = [ghostTracker([self.obj])]
- self.normal = self.obj.Shape.Faces[0].normalAt(.5,.5)
- for v in self.obj.Shape.Vertexes:
- self.ghost.append(lineTracker())
- elif len(self.obj.Shape.Faces) > 1:
- # face extrude mode, a new object is created
- ss = FreeCADGui.Selection.getSelectionEx()[0]
- if len(ss.SubObjects) == 1:
- if ss.SubObjects[0].ShapeType == "Face":
- self.obj = self.doc.addObject("Part::Feature","Face")
- self.obj.Shape = ss.SubObjects[0]
- self.extrudeMode = True
- self.ghost = [ghostTracker([self.obj])]
- self.normal = self.obj.Shape.Faces[0].normalAt(.5,.5)
- for v in self.obj.Shape.Vertexes:
- self.ghost.append(lineTracker())
+ def proceed(self):
+ if self.call: self.view.removeEventCallback("SoEvent",self.call)
+ self.sel = Draft.getSelection()
+ self.sel = Draft.getGroupContents(self.sel)
+ self.ui.pointUi()
+ self.ui.modUi()
+ self.ui.xValue.setFocus()
+ self.ui.xValue.selectAll()
+ self.linetrack = lineTracker()
+ self.constraintrack = lineTracker(dotted=True)
+ self.ghost = ghostTracker(self.sel)
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ msg(translate("draft", "Pick start point:\n"))
+ self.ui.cross(True)
+
+ def finish(self,closed=False,cont=False):
+ if self.ui:
+ self.ghost.finalize()
+ self.linetrack.finalize()
+ self.constraintrack.finalize()
+ Modifier.finish(self)
+ if cont and self.ui:
+ if self.ui.continueMode:
+ FreeCADGui.Selection.clearSelection()
+ self.Activated()
+
+ def move(self,delta,copy=False):
+ "moving the real shapes"
+ if copy:
+ self.commit(translate("draft","Copy"),partial(Draft.move,self.sel,delta,copy))
+ else:
+ self.commit(translate("draft","Move"),partial(Draft.move,self.sel,delta,copy))
+ self.doc.recompute()
+
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event": #mouse movement detection
+ point,ctrlPoint = getPoint(self,arg)
+ self.linetrack.p2(point)
+ self.ui.cross(True)
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else: self.constraintrack.off()
+ if (len(self.node) > 0):
+ last = self.node[len(self.node)-1]
+ delta = point.sub(last)
+ self.ghost.trans.translation.setValue([delta.x,delta.y,delta.z])
+ if self.extendedCopy:
+ if not hasMod(arg,MODALT): self.finish()
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ point,ctrlPoint = getPoint(self,arg)
+ if (self.node == []):
+ self.node.append(point)
+ self.ui.isRelative.show()
+ self.linetrack.on()
+ self.ghost.on()
+ self.linetrack.p1(point)
+ msg(translate("draft", "Pick end point:\n"))
+ self.planetrack.set(point)
else:
- # normal wire trimex mode
- self.obj.ViewObject.Visibility = False
- self.extrudeMode = False
- if self.obj.Shape.Wires:
- self.edges = self.obj.Shape.Wires[0].Edges
- self.edges = fcgeo.sortEdges(self.edges)
- else:
- self.edges = self.obj.Shape.Edges
- self.ghost = []
- lc = self.obj.ViewObject.LineColor
- sc = (lc[0],lc[1],lc[2])
- sw = self.obj.ViewObject.LineWidth
- for e in self.edges:
- if isinstance(e.Curve,Part.Line):
- self.ghost.append(lineTracker(scolor=sc,swidth=sw))
- else:
- self.ghost.append(arcTracker(scolor=sc,swidth=sw))
- if not self.ghost: self.finish()
- for g in self.ghost: g.on()
- self.activePoint = 0
- self.nodes = []
- self.shift = False
- self.alt = False
- self.force = None
- self.cv = None
- self.call = self.view.addEventCallback("SoEvent",self.action)
- msg(translate("draft", "Pick distance:\n"))
- self.ui.cross(True)
+ last = self.node[0]
+ if self.ui.isCopy.isChecked() or hasMod(arg,MODALT):
+ self.move(point.sub(last),True)
+ else:
+ self.move(point.sub(last))
+ if hasMod(arg,MODALT):
+ self.extendedCopy = True
+ else:
+ self.finish(cont=True)
+
+ def numericInput(self,numx,numy,numz):
+ "this function gets called by the toolbar when valid x, y, and z have been entered there"
+ point = Vector(numx,numy,numz)
+ if not self.node:
+ self.node.append(point)
+ self.ui.isRelative.show()
+ self.ui.isCopy.show()
+ self.linetrack.p1(point)
+ self.linetrack.on()
+ self.ghost.on()
+ msg(translate("draft", "Pick end point:\n"))
+ else:
+ last = self.node[-1]
+ if self.ui.isCopy.isChecked():
+ self.move(point.sub(last),True)
+ else:
+ self.move(point.sub(last))
+ self.finish()
+
+
+class ApplyStyle(Modifier):
+ "The Draft_ApplyStyle FreeCA command definition"
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Apply',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ApplyStyle", "Apply Current Style"),
+ 'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_ApplyStyle", "Applies current line width and color to selected objects")}
+
+ def IsActive(self):
+ if Draft.getSelection():
+ return True
+ else:
+ return False
+
+ def Activated(self):
+ Modifier.Activated(self)
+ if self.ui:
+ self.sel = Draft.getSelection()
+ if (len(self.sel)>0):
+ for ob in self.sel:
+ if (ob.Type == "App::DocumentObjectGroup"):
+ self.formatGroup(ob)
+ else:
+ self.commit(translate("draft","Change Style"),partial(Draft.formatObject,ob))
+
+ def formatGroup(self,grpob):
+ for ob in grpob.Group:
+ if (ob.Type == "App::DocumentObjectGroup"):
+ self.formatGroup(ob)
+ else:
+ self.commit(translate("draft","Change Style"),partial(Draft.formatObject,ob))
+
+
+class Rotate(Modifier):
+ "The Draft_Rotate FreeCAD command definition"
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Rotate',
+ 'Accel' : "R, O",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Rotate", "Rotate"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Rotate", "Rotates the selected objects. CTRL to snap, SHIFT to constrain, ALT creates a copy")}
+
+ def Activated(self):
+ Modifier.Activated(self,"Rotate")
+ if self.ui:
+ if not Draft.getSelection():
+ self.ghost = None
+ self.linetrack = None
+ self.arctrack = None
+ self.constraintrack = None
+ self.ui.selectUi()
+ msg(translate("draft", "Select an object to rotate\n"))
+ self.call = self.view.addEventCallback("SoEvent",selectObject)
+ else:
+ self.proceed()
+
+ def proceed(self):
+ if self.call: self.view.removeEventCallback("SoEvent",self.call)
+ self.sel = Draft.getSelection()
+ self.sel = Draft.getGroupContents(self.sel)
+ self.step = 0
+ self.center = None
+ self.ui.arcUi()
+ self.ui.isCopy.show()
+ self.ui.setTitle("Rotate")
+ self.linetrack = lineTracker()
+ self.constraintrack = lineTracker(dotted=True)
+ self.arctrack = arcTracker()
+ self.ghost = ghostTracker(self.sel)
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ msg(translate("draft", "Pick rotation center:\n"))
+ self.ui.cross(True)
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"): #mouse movement detection
- self.ui.cross(True)
- self.shift = hasMod(arg,MODCONSTRAIN)
- self.alt = hasMod(arg,MODALT)
- wp = not(self.extrudeMode and self.shift)
- self.point = getPoint(self,arg,workingplane=wp)[0]
- if hasMod(arg,MODSNAP): self.snapped = None
- else: self.snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
- if self.extrudeMode:
- dist = self.extrude(self.shift)
- else:
- dist = self.redraw(self.point,self.snapped,self.shift,self.alt)
- self.constraintrack.p1(self.point)
- self.constraintrack.p2(self.newpoint)
- self.constraintrack.on()
- self.ui.radiusValue.setText("%.2f" % dist)
- self.ui.radiusValue.setFocus()
- self.ui.radiusValue.selectAll()
-
- if (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- cursor = arg["Position"]
- self.shift = hasMod(arg,MODCONSTRAIN)
- self.alt = hasMod(arg,MODALT)
- if hasMod(arg,MODSNAP): self.snapped = None
- else: self.snapped = self.view.getObjectInfo((cursor[0],cursor[1]))
- self.trimObject()
- self.finish()
+ def finish(self,closed=False,cont=False):
+ "finishes the arc"
+ Modifier.finish(self)
+ if self.ui:
+ self.linetrack.finalize()
+ self.constraintrack.finalize()
+ self.arctrack.finalize()
+ self.ghost.finalize()
+ self.doc.recompute()
+ if cont and self.ui:
+ if self.ui.continueMode:
+ FreeCADGui.Selection.clearSelection()
+ self.Activated()
- def extrude(self,shift=False,real=False):
- "redraws the ghost in extrude mode"
- self.newpoint = self.obj.Shape.Faces[0].CenterOfMass
- dvec = self.point.sub(self.newpoint)
- if shift: delta = fcvec.project(dvec,self.normal)
- else: delta = dvec
- if self.force:
- ratio = self.force/delta.Length
- delta.multiply(ratio)
- if real: return delta
- self.ghost[0].trans.translation.setValue([delta.x,delta.y,delta.z])
- for i in range(1,len(self.ghost)):
- base = self.obj.Shape.Vertexes[i-1].Point
- self.ghost[i].p1(base)
- self.ghost[i].p2(base.add(delta))
- return delta.Length
-
- def redraw(self,point,snapped=None,shift=False,alt=False,real=None):
- "redraws the ghost"
- #initializing
- reverse = False
- for g in self.ghost: g.off()
- if real: newedges = []
-
- # finding the active point
- vlist = []
- for e in self.edges: vlist.append(e.Vertexes[0].Point)
- vlist.append(self.edges[-1].Vertexes[-1].Point)
- if shift: npoint = self.activePoint
- else: npoint = fcgeo.findClosest(point,vlist)
- if npoint > len(self.edges)/2: reverse = True
- if alt: reverse = not reverse
- self.activePoint = npoint
-
- # sorting out directions
- if reverse and (npoint > 0): npoint = npoint-1
- if (npoint > len(self.edges)-1):
- edge = self.edges[-1]
- ghost = self.ghost[-1]
- else:
- edge = self.edges[npoint]
- ghost = self.ghost[npoint]
- if reverse:
- v1 = edge.Vertexes[-1].Point
- v2 = edge.Vertexes[0].Point
- else:
- v1 = edge.Vertexes[0].Point
- v2 = edge.Vertexes[-1].Point
-
- # snapping
- if snapped:
- snapped = self.doc.getObject(snapped['Object'])
- pts = []
- for e in snapped.Shape.Edges:
- int = fcgeo.findIntersection(edge,e,True,True)
- if int: pts.extend(int)
- if pts:
- point = pts[fcgeo.findClosest(point,pts)]
+ def rot (self,angle,copy=False):
+ "rotating the real shapes"
+ if copy:
+ self.commit(translate("draft","Copy"),
+ partial(Draft.rotate,self.sel,
+ math.degrees(angle),self.center,plane.axis,copy))
+ else:
+ self.commit(translate("draft","Rotate"),
+ partial(Draft.rotate,self.sel,
+ math.degrees(angle),self.center,plane.axis,copy))
- # modifying active edge
- if isinstance(edge.Curve,Part.Line):
- perp = fcgeo.vec(edge).cross(Vector(0,0,1))
- chord = v1.sub(point)
- proj = fcvec.project(chord,perp)
- self.newpoint = Vector.add(point,proj)
- dist = v1.sub(self.newpoint).Length
- ghost.p1(self.newpoint)
- ghost.p2(v2)
- self.ui.labelRadius.setText("Distance")
- if real:
- if self.force:
- ray = self.newpoint.sub(v1)
- ray = fcvec.scale(ray,self.force/ray.Length)
- self.newpoint = Vector.add(v1,ray)
- newedges.append(Part.Line(self.newpoint,v2).toShape())
- else:
- center = edge.Curve.Center
- rad = edge.Curve.Radius
- ang1 = fcvec.angle(v2.sub(center))
- ang2 = fcvec.angle(point.sub(center))
- self.newpoint=Vector.add(center,fcvec.rotate(Vector(rad,0,0),-ang2))
- self.ui.labelRadius.setText("Angle")
- dist = math.degrees(-ang2)
- # if ang1 > ang2: ang1,ang2 = ang2,ang1
- print "last calculated:",math.degrees(-ang1),math.degrees(-ang2)
- ghost.setEndAngle(-ang2)
- ghost.setStartAngle(-ang1)
- ghost.setCenter(center)
- ghost.setRadius(rad)
- if real:
- if self.force:
- angle = math.radians(self.force)
- newray = fcvec.rotate(Vector(rad,0,0),-angle)
- self.newpoint = Vector.add(center,newray)
- chord = self.newpoint.sub(v2)
- perp = chord.cross(Vector(0,0,1))
- scaledperp = fcvec.scaleTo(perp,rad)
- midpoint = Vector.add(center,scaledperp)
- newedges.append(Part.Arc(self.newpoint,midpoint,v2).toShape())
- ghost.on()
-
- # resetting the visible edges
- if not reverse: list = range(npoint+1,len(self.edges))
- else: list = range(npoint-1,-1,-1)
- for i in list:
- edge = self.edges[i]
- ghost = self.ghost[i]
- if isinstance(edge.Curve,Part.Line):
- ghost.p1(edge.Vertexes[0].Point)
- ghost.p2(edge.Vertexes[-1].Point)
- else:
- ang1 = fcvec.angle(edge.Vertexes[0].Point.sub(center))
- ang2 = fcvec.angle(edge.Vertexes[-1].Point.sub(center))
- #if ang1 > ang2: ang1,ang2 = ang2,ang1
- ghost.setEndAngle(-ang2)
- ghost.setStartAngle(-ang1)
- ghost.setCenter(edge.Curve.Center)
- ghost.setRadius(edge.Curve.Radius)
- if real: newedges.append(edge)
- ghost.on()
-
- # finishing
- if real: return newedges
- else: return dist
-
- def trimObject(self):
- "trims the actual object"
- if self.extrudeMode:
- delta = self.extrude(self.shift,real=True)
- print "delta",delta
- self.doc.openTransaction("Extrude")
- obj = Draft.extrude(self.obj,delta)
- self.doc.commitTransaction()
- self.obj = obj
- else:
- edges = self.redraw(self.point,self.snapped,self.shift,self.alt,real=True)
- newshape = Part.Wire(edges)
- self.doc.openTransaction("Trim/extend")
- if Draft.getType(self.obj) in ["Wire","BSpline"]:
- p = []
- if self.placement: invpl = self.placement.inverse()
- for v in newshape.Vertexes:
- np = v.Point
- if self.placement: np = invpl.multVec(np)
- p.append(np)
- self.obj.Points = p
- elif Draft.getType(self.obj) == "Circle":
- angles = self.ghost[0].getAngles()
- print "original",self.obj.FirstAngle," ",self.obj.LastAngle
- print "new",angles
- if angles[0] > angles[1]: angles = (angles[1],angles[0])
- self.obj.FirstAngle = angles[0]
- self.obj.LastAngle = angles[1]
- else:
- self.obj.Shape = newshape
- self.doc.commitTransaction()
- for g in self.ghost: g.off()
-
- def finish(self,closed=False):
- Modifier.finish(self)
- self.force = None
- if self.ui:
- self.ui.labelRadius.setText("Distance")
- self.linetrack.finalize()
- self.constraintrack.finalize()
- if self.ghost:
- for g in self.ghost:
- g.finalize()
- self.obj.ViewObject.Visibility = True
- Draft.select(self.obj)
-
- def numericRadius(self,dist):
- "this function gets called by the toolbar when valid distance have been entered there"
- self.force = dist
- self.trimObject()
- self.finish()
-
-class Scale(Modifier):
- '''The Draft_Scale FreeCAD command definition.
- This tool scales the selected objects from a base point.'''
-
- def GetResources(self):
- return {'Pixmap' : 'Draft_Scale',
- 'Accel' : "S, C",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Scale", "Scale"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Scale", "Scales the selected objects from a base point. CTRL to snap, SHIFT to constrain, ALT to copy")}
-
- def Activated(self):
- Modifier.Activated(self,"Scale")
- if self.ui:
- if not Draft.getSelection():
- self.ghost = None
- self.linetrack = None
- self.constraintrack = None
- self.ui.selectUi()
- msg(translate("draft", "Select an object to scale\n"))
- self.call = self.view.addEventCallback("SoEvent",selectObject)
- else:
- self.proceed()
-
- def proceed(self):
- if self.call: self.view.removeEventCallback("SoEvent",self.call)
- self.sel = Draft.getSelection()
- self.sel = Draft.getGroupContents(self.sel)
- self.ui.pointUi()
- self.ui.modUi()
- self.ui.xValue.setFocus()
- self.ui.xValue.selectAll()
- self.linetrack = lineTracker()
- self.constraintrack = lineTracker(dotted=True)
- self.ghost = ghostTracker(self.sel)
- self.call = self.view.addEventCallback("SoEvent",self.action)
- msg(translate("draft", "Pick base point:\n"))
- self.ui.cross(True)
-
- def finish(self,closed=False,cont=False):
- Modifier.finish(self)
- if self.ui:
- self.ghost.finalize()
- self.linetrack.finalize()
- self.constraintrack.finalize()
- if cont and self.ui:
- if self.ui.continueMode:
- FreeCADGui.Selection.clearSelection()
- self.Activated()
-
- def scale(self,delta,copy=False):
- "moving the real shapes"
- if copy:
- self.commit(translate("draft","Copy"),partial(Draft.scale,self.sel,delta,self.node[0],copy))
- else:
- self.commit(translate("draft","Scale"),partial(Draft.scale,self.sel,delta,self.node[0],copy))
-
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"): #mouse movement detection
- point,ctrlPoint = getPoint(self,arg,sym=True)
- self.linetrack.p2(point)
- self.ui.cross(True)
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- if (len(self.node) > 0):
- last = self.node[len(self.node)-1]
- delta = point.sub(last)
- self.ghost.trans.scaleFactor.setValue([delta.x,delta.y,delta.z])
- corr = Vector(self.node[0].x,self.node[0].y,self.node[0].z)
- corr.scale(delta.x,delta.y,delta.z)
- corr = fcvec.neg(corr.sub(self.node[0]))
- self.ghost.trans.translation.setValue([corr.x,corr.y,corr.z])
- if self.extendedCopy:
- if not hasMod(arg,MODALT): self.finish()
- if (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- point,ctrlPoint = getPoint(self,arg,sym=True)
- if (self.node == []):
- self.node.append(point)
- self.ui.isRelative.show()
- self.ui.isCopy.show()
- self.linetrack.on()
- self.ghost.on()
- self.linetrack.p1(point)
- msg(translate("draft", "Pick scale factor:\n"))
- else:
- last = self.node[0]
- if self.ui.isCopy.isChecked() or hasMod(arg,MODALT):
- self.scale(point.sub(last),True)
- else:
- self.scale(point.sub(last))
- if hasMod(arg,MODALT):
- self.extendedCopy = True
- else:
- self.finish(cont=True)
-
- def numericInput(self,numx,numy,numz):
- "this function gets called by the toolbar when valid x, y, and z have been entered there"
- point = Vector(numx,numy,numz)
- if not self.node:
- self.node.append(point)
- self.ui.isRelative.show()
- self.ui.isCopy.show()
- self.linetrack.p1(point)
- self.linetrack.on()
- self.ghost.on()
- msg(translate("draft", "Pick scale factor:\n"))
- else:
- last = self.node[-1]
- if self.ui.isCopy.isChecked():
- self.scale(point.sub(last),True)
- else:
- self.scale(point.sub(last))
- self.finish(cont=True)
-
-class ToggleConstructionMode():
- "The Draft_ToggleConstructionMode FreeCAD command definition"
-
- def GetResources(self):
- return {'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleConstructionMode", "Toggle construcion Mode"),
- 'Accel' : "C, M",
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleConstructionMode", "Toggles the Construction Mode for next objects.")}
-
- def Activated(self):
- FreeCADGui.draftToolBar.constrButton.toggle()
-
-class ToggleContinueMode():
- "The Draft_ToggleContinueMode FreeCAD command definition"
-
- def GetResources(self):
- return {'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleContinueMode", "Toggle continue Mode"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleContinueMode", "Toggles the Continue Mode for next commands.")}
-
- def Activated(self):
- FreeCADGui.draftToolBar.continueCmd.toggle()
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event":
+ point,ctrlPoint = getPoint(self,arg)
+ self.ui.cross(True)
+ # this is to make sure radius is what you see on screen
+ if self.center and fcvec.dist(point,self.center):
+ viewdelta = fcvec.project(point.sub(self.center), plane.axis)
+ if not fcvec.isNull(viewdelta):
+ point = point.add(fcvec.neg(viewdelta))
+ if self.extendedCopy:
+ if not hasMod(arg,MODALT):
+ self.step = 3
+ self.finish()
+ if (self.step == 0):
+ pass
+ elif (self.step == 1):
+ currentrad = fcvec.dist(point,self.center)
+ if (currentrad != 0):
+ angle = fcvec.angle(plane.u, point.sub(self.center), plane.axis)
+ else: angle = 0
+ self.linetrack.p2(point)
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else:
+ self.constraintrack.off()
+ self.ui.radiusValue.setText("%.2f" % math.degrees(angle))
+ self.firstangle = angle
+ self.ui.radiusValue.setFocus()
+ self.ui.radiusValue.selectAll()
+ elif (self.step == 2):
+ currentrad = fcvec.dist(point,self.center)
+ if (currentrad != 0):
+ angle = fcvec.angle(plane.u, point.sub(self.center), plane.axis)
+ else: angle = 0
+ if (angle < self.firstangle):
+ sweep = (2*math.pi-self.firstangle)+angle
+ else:
+ sweep = angle - self.firstangle
+ self.arctrack.setApertureAngle(sweep)
+ self.ghost.trans.rotation.setValue(coin.SbVec3f(fcvec.tup(plane.axis)),sweep)
+ self.linetrack.p2(point)
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else:
+ self.constraintrack.off()
+ self.ui.radiusValue.setText("%.2f" % math.degrees(sweep))
+ self.ui.radiusValue.setFocus()
+ self.ui.radiusValue.selectAll()
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ point,ctrlPoint = getPoint(self,arg)
+ if self.center and fcvec.dist(point,self.center):
+ viewdelta = fcvec.project(point.sub(self.center), plane.axis)
+ if not fcvec.isNull(viewdelta): point = point.add(fcvec.neg(viewdelta))
+ if (self.step == 0):
+ self.center = point
+ self.node = [point]
+ self.ui.radiusUi()
+ self.ui.hasFill.hide()
+ self.ui.labelRadius.setText("Base angle")
+ self.linetrack.p1(self.center)
+ self.arctrack.setCenter(self.center)
+ self.ghost.trans.center.setValue(self.center.x,self.center.y,self.center.z)
+ self.linetrack.on()
+ self.step = 1
+ msg(translate("draft", "Pick base angle:\n"))
+ self.planetrack.set(point)
+ elif (self.step == 1):
+ self.ui.labelRadius.setText("Rotation")
+ self.rad = fcvec.dist(point,self.center)
+ self.arctrack.on()
+ self.arctrack.setStartPoint(point)
+ self.ghost.on()
+ self.step = 2
+ msg(translate("draft", "Pick rotation angle:\n"))
+ else:
+ currentrad = fcvec.dist(point,self.center)
+ angle = point.sub(self.center).getAngle(plane.u)
+ if fcvec.project(point.sub(self.center), plane.v).getAngle(plane.v) > 1:
+ angle = -angle
+ if (angle < self.firstangle):
+ sweep = (2*math.pi-self.firstangle)+angle
+ else:
+ sweep = angle - self.firstangle
+ if self.ui.isCopy.isChecked() or hasMod(arg,MODALT):
+ self.rot(sweep,True)
+ else:
+ self.rot(sweep)
+ if hasMod(arg,MODALT):
+ self.extendedCopy = True
+ else:
+ self.finish(cont=True)
+
+ def numericInput(self,numx,numy,numz):
+ "this function gets called by the toolbar when valid x, y, and z have been entered there"
+ self.center = Vector(numx,numy,numz)
+ self.node = [self.center]
+ self.arctrack.setCenter(self.center)
+ self.ghost.trans.center.setValue(self.center.x,self.center.y,self.center.z)
+ self.linetrack.p1(self.center)
+ # self.arctrack.on()
+ self.linetrack.on()
+ self.ui.radiusUi()
+ self.ui.hasFill.hide()
+ self.ui.labelRadius.setText("Base angle")
+ self.step = 1
+ msg(translate("draft", "Pick base angle:\n"))
+
+ def numericRadius(self,rad):
+ "this function gets called by the toolbar when valid radius have been entered there"
+ if (self.step == 1):
+ self.ui.labelRadius.setText("Rotation")
+ self.firstangle = math.radians(rad)
+ self.arctrack.setStartAngle(self.firstangle)
+ self.arctrack.on()
+ self.ghost.on()
+ self.step = 2
+ msg(translate("draft", "Pick rotation angle:\n"))
+ else:
+ self.rot(math.radians(rad),self.ui.isCopy.isChecked())
+ self.finish(cont=True)
+
+
+class Offset(Modifier):
+ "The Draft_Offset FreeCAD command definition"
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Offset',
+ 'Accel' : "O, S",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Offset", "Offset"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Offset", "Offsets the active object. CTRL to snap, SHIFT to constrain, ALT to copy")}
+
+ def Activated(self):
+ self.running = False
+ Modifier.Activated(self,"Offset")
+ if self.ui:
+ if not Draft.getSelection():
+ self.ghost = None
+ self.linetrack = None
+ self.arctrack = None
+ self.constraintrack = None
+ self.ui.selectUi()
+ msg(translate("draft", "Select an object to offset\n"))
+ self.call = self.view.addEventCallback("SoEvent",selectObject)
+ elif len(Draft.getSelection()) > 1:
+ msg(translate("draft", "Offset only works on one object at a time\n"),"warning")
+ else:
+ self.proceed()
+
+ def proceed(self):
+ if self.call: self.view.removeEventCallback("SoEvent",self.call)
+ self.sel = Draft.getSelection()[0]
+ if not self.sel.isDerivedFrom("Part::Feature"):
+ msg(translate("draft", "Cannot offset this object type\n"),"warning")
+ self.finish()
+ else:
+ self.step = 0
+ self.dvec = None
+ self.constrainSeg = None
+ self.ui.offsetUi()
+ self.linetrack = lineTracker()
+ self.constraintrack = lineTracker(dotted=True)
+ self.faces = False
+ self.shape = self.sel.Shape
+ self.mode = None
+ if Draft.getType(self.sel) in ["Circle","Arc"]:
+ self.ghost = arcTracker()
+ self.mode = "Circle"
+ self.center = self.shape.Edges[0].Curve.Center
+ self.ghost.setCenter(self.center)
+ self.ghost.setStartAngle(math.radians(self.sel.FirstAngle))
+ self.ghost.setEndAngle(math.radians(self.sel.LastAngle))
+ else:
+ self.ghost = wireTracker(self.shape)
+ self.mode = "Wire"
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ msg(translate("draft", "Pick distance:\n"))
+ self.ui.cross(True)
+ self.planetrack.set(self.shape.Vertexes[0].Point)
+ self.running = True
+
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event":
+ self.ui.cross(True)
+ point,ctrlPoint = getPoint(self,arg)
+ if hasMod(arg,MODCONSTRAIN) and self.constrainSeg:
+ dist = fcgeo.findPerpendicular(point,self.shape,self.constrainSeg[1])
+ e = self.shape.Edges[self.constrainSeg[1]]
+ self.constraintrack.p1(e.Vertexes[0].Point)
+ self.constraintrack.p2(point.add(dist[0]))
+ self.constraintrack.on()
+ else:
+ dist = fcgeo.findPerpendicular(point,self.shape.Edges)
+ self.constraintrack.off()
+ if dist:
+ self.ghost.on()
+ if self.mode == "Wire":
+ d = fcvec.neg(dist[0])
+ v1 = fcgeo.getTangent(self.shape.Edges[0],point)
+ v2 = fcgeo.getTangent(self.shape.Edges[dist[1]],point)
+ a = -fcvec.angle(v1,v2)
+ self.dvec = fcvec.rotate(d,a,plane.axis)
+ self.ghost.update(fcgeo.offsetWire(self.shape,self.dvec,occ=self.ui.occOffset.isChecked()))
+ elif self.mode == "Circle":
+ self.dvec = point.sub(self.center).Length
+ self.ghost.setRadius(self.dvec)
+ self.constrainSeg = dist
+ self.linetrack.on()
+ self.linetrack.p1(point)
+ self.linetrack.p2(point.add(dist[0]))
+ self.ui.radiusValue.setText("%.2f" % dist[0].Length)
+ else:
+ self.dvec = None
+ self.ghost.off()
+ self.constrainSeg = None
+ self.linetrack.off()
+ self.ui.radiusValue.setText("off")
+ self.ui.radiusValue.setFocus()
+ self.ui.radiusValue.selectAll()
+ if self.extendedCopy:
+ if not hasMod(arg,MODALT): self.finish()
+
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ copymode = False
+ occmode = self.ui.occOffset.isChecked()
+ if hasMod(arg,MODALT) or self.ui.isCopy.isChecked(): copymode = True
+ if self.dvec:
+ self.commit(translate("draft","Offset"),
+ partial(Draft.offset,self.sel,
+ self.dvec,copymode,occ=occmode))
+ if hasMod(arg,MODALT):
+ self.extendedCopy = True
+ else:
+ self.finish()
+
+ def finish(self,closed=False):
+ Modifier.finish(self)
+ if self.ui and self.running:
+ self.linetrack.finalize()
+ self.constraintrack.finalize()
+ self.ghost.finalize()
+
+ def numericRadius(self,rad):
+ '''this function gets called by the toolbar when
+ valid radius have been entered there'''
+ if self.dvec:
+ self.dvec.normalize()
+ self.dvec.multiply(rad)
+ copymode = False
+ occmode = self.ui.occOffset.isChecked()
+ if self.ui.isCopy.isChecked(): copymode = True
+ self.commit(translate("draft","Offset"),
+ partial(Draft.offset,self.sel,
+ self.dvec,copymode,occ=occmode))
+ self.finish()
+
+
+class Upgrade(Modifier):
+ '''The Draft_Upgrade FreeCAD command definition.
+ This class upgrades selected objects in different ways,
+ following this list (in order):
+ - if there are more than one faces, the faces are merged (union)
+ - if there is only one face, nothing is done
+ - if there are closed wires, they are transformed in a face
+ - otherwise join all edges into a wire (closed if applicable)
+ - if nothing of the above is possible, a Compound is created
+ '''
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Upgrade',
+ 'Accel' : "U, P",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Upgrade", "Upgrade"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Upgrade", "Joins the selected objects into one, or converts closed wires to filled faces, or unite faces")}
+
+ def Activated(self):
+ Modifier.Activated(self,"Upgrade")
+ if self.ui:
+ if not Draft.getSelection():
+ self.ui.selectUi()
+ msg(translate("draft", "Select an object to upgrade\n"))
+ self.call = self.view.addEventCallback("SoEvent",selectObject)
+ else:
+ self.proceed()
+
+ def compound(self):
+ # shapeslist = []
+ # for ob in self.sel: shapeslist.append(ob.Shape)
+ # newob = self.doc.addObject("Part::Feature","Compound")
+ # newob.Shape = Part.makeCompound(shapeslist)
+ newob = Draft.makeBlock(self.sel)
+ self.nodelete = True
+ return newob
+
+ def proceed(self):
+ if self.call: self.view.removeEventCallback("SoEvent",self.call)
+ self.sel = Draft.getSelection()
+ newob = None
+ self.nodelete = False
+ edges = []
+ wires = []
+ openwires = []
+ faces = []
+ groups = []
+ curves = []
+ facewires = []
+
+ # determining what we have in our selection
+ for ob in self.sel:
+ if ob.Type == "App::DocumentObjectGroup":
+ groups.append(ob)
+ else:
+ if ob.Shape.ShapeType == 'Edge': openwires.append(ob.Shape)
+ for f in ob.Shape.Faces:
+ faces.append(f)
+ facewires.extend(f.Wires)
+ for w in ob.Shape.Wires:
+ if w.isClosed():
+ wires.append(w)
+ else:
+ openwires.append(w)
+ for e in ob.Shape.Edges:
+ if not isinstance(e.Curve,Part.Line):
+ curves.append(e)
+ lastob = ob
+ # print "objects:",self.sel," edges:",edges," wires:",wires," openwires:",openwires," faces:",faces
+ # print "groups:",groups," curves:",curves," facewires:",facewires
+
+ # applying transformation
+ self.doc.openTransaction("Upgrade")
+
+ if groups:
+ # if we have a group: turn each closed wire inside into a face
+ msg(translate("draft", "Found groups: closing each open object inside\n"))
+ for grp in groups:
+ for ob in grp.Group:
+ if not ob.Shape.Faces:
+ for w in ob.Shape.Wires:
+ newob = Draft.makeWire(w,closed=w.isClosed())
+ self.sel.append(ob)
+ grp.addObject(newob)
+
+ elif faces and (len(wires)+len(openwires)==len(facewires)):
+ # we have only faces here, no lone edges
+
+ if (len(self.sel) == 1) and (len(faces) > 1):
+ # we have a shell: we try to make a solid
+ sol = Part.makeSolid(self.sel[0].Shape)
+ if sol.isClosed():
+ msg(translate("draft", "Found 1 solidificable object: solidifying it\n"))
+ newob = self.doc.addObject("Part::Feature","Solid")
+ newob.Shape = sol
+ Draft.formatObject(newob,lastob)
+
+ elif (len(self.sel) == 2) and (not curves):
+ # we have exactly 2 objects: we fuse them
+ msg(translate("draft", "Found 2 objects: fusing them\n"))
+ newob = Draft.fuse(self.sel[0],self.sel[1])
+ self.nodelete = True
+
+ elif (len(self.sel) > 2) and (len(faces) > 10):
+ # we have many separate faces: we try to make a shell
+ sh = Part.makeShell(faces)
+ newob = self.doc.addObject("Part::Feature","Shell")
+ newob.Shape = sh
+ Draft.formatObject(newob,lastob)
+
+ elif (len(self.sel) > 2) or (len(faces) > 1):
+ # more than 2 objects or faces: we try the draft way: make one face out of them
+ u = faces.pop(0)
+ for f in faces:
+ u = u.fuse(f)
+ if fcgeo.isCoplanar(faces):
+ if self.sel[0].ViewObject.DisplayMode == "Wireframe":
+ f = False
+ else:
+ f = True
+ u = fcgeo.concatenate(u)
+ if not curves:
+ msg(translate("draft", "Found several objects or faces: making a parametric face\n"))
+ newob = Draft.makeWire(u.Wires[0],closed=True,face=f)
+ Draft.formatObject(newob,lastob)
+ else:
+ # if not possible, we do a non-parametric union
+ msg(translate("draft", "Found objects containing curves: fusing them\n"))
+ newob = self.doc.addObject("Part::Feature","Union")
+ newob.Shape = u
+ Draft.formatObject(newob,lastob)
+ else:
+ # if not possible, we do a non-parametric union
+ msg(translate("draft", "Found several objects: fusing them\n"))
+ # if we have a solid, make sure we really return a solid
+ if (len(u.Faces) > 1) and u.isClosed():
+ u = Part.makeSolid(u)
+ newob = self.doc.addObject("Part::Feature","Union")
+ newob.Shape = u
+ Draft.formatObject(newob,lastob)
+ elif len(self.sel) == 1:
+ # only one object: if not parametric, we "draftify" it
+ self.nodelete = True
+ if (not curves) and (Draft.getType(self.sel[0]) == "Part"):
+ msg(translate("draft", "Found 1 non-parametric objects: draftifying it\n"))
+ Draft.draftify(self.sel[0])
+
+ elif wires and (not faces) and (not openwires):
+ # we have only wires, no faces
+
+ if (len(self.sel) == 1) and self.sel[0].isDerivedFrom("Sketcher::SketchObject") and (not curves):
+ # we have a sketch
+ msg(translate("draft", "Found 1 closed sketch object: making a face from it\n"))
+ newob = Draft.makeWire(self.sel[0].Shape,closed=True)
+ newob.Base = self.sel[0]
+ self.sel[0].ViewObject.Visibility = False
+ self.nodelete = True
+
+ else:
+ # only closed wires
+ for w in wires:
+ f = Part.Face(w)
+ faces.append(f)
+ for f in faces:
+ if not curves:
+ newob = Draft.makeWire(f.Wire,closed=True)
+ else:
+ # if there are curved segments, we do a non-parametric face
+ msg(translate("draft", "Found closed wires: making faces\n"))
+ newob = self.doc.addObject("Part::Feature","Face")
+ newob.Shape = f
+ Draft.formatObject(newob,lastob)
+
+ elif (len(openwires) == 1) and (not faces) and (not wires):
+ # special case, we have only one open wire. We close it!"
+ p0 = openwires[0].Vertexes[0].Point
+ p1 = openwires[0].Vertexes[-1].Point
+ edges = openwires[0].Edges
+ edges.append(Part.Line(p1,p0).toShape())
+ w = Part.Wire(fcgeo.sortEdges(edges))
+ msg(translate("draft", "Found 1 open wire: closing it\n"))
+ if not curves:
+ newob = Draft.makeWire(w,closed=True)
+ else:
+ # if not possible, we do a non-parametric union
+ newob = self.doc.addObject("Part::Feature","Wire")
+ newob.Shape = w
+ Draft.formatObject(newob,lastob)
+
+ elif openwires and (not wires) and (not faces):
+ # only open wires and edges: we try to join their edges
+ for ob in self.sel:
+ for e in ob.Shape.Edges:
+ edges.append(e)
+ newob = None
+ nedges = fcgeo.sortEdges(edges[:])
+ # for e in nedges: print "debug: ",e.Curve,e.Vertexes[0].Point,e.Vertexes[-1].Point
+ w = Part.Wire(nedges)
+ if len(w.Edges) == len(edges):
+ msg(translate("draft", "Found several edges: wiring them\n"))
+ if not curves:
+ newob = Draft.makeWire(w)
+ else:
+ newob = self.doc.addObject("Part::Feature","Wire")
+ newob.Shape = w
+ Draft.formatObject(newob,lastob)
+ if not newob:
+ print "no new object found"
+ msg(translate("draft", "Found several non-connected edges: making compound\n"))
+ newob = self.compound()
+ Draft.formatObject(newob,lastob)
+ else:
+ # all other cases
+ msg(translate("draft", "Found several non-treatable objects: making compound\n"))
+ newob = self.compound()
+ Draft.formatObject(newob,lastob)
+
+ if not self.nodelete:
+ # deleting original objects, if needed
+ for ob in self.sel:
+ if not ob.Type == "App::DocumentObjectGroup":
+ self.doc.removeObject(ob.Name)
+
+ self.doc.commitTransaction()
+ if newob: Draft.select(newob)
+ Modifier.finish(self)
+
+
+class Downgrade(Modifier):
+ '''
+ The Draft_Downgrade FreeCAD command definition.
+ This class downgrades selected objects in different ways,
+ following this list (in order):
+ - if there are more than one faces, the subsequent
+ faces are subtracted from the first one
+ - if there is only one face, it gets converted to a wire
+ - otherwise wires are exploded into single edges
+ '''
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Downgrade',
+ 'Accel' : "D, N",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Downgrade", "Downgrade"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Downgrade", "Explodes the selected objects into simpler objects, or subtract faces")}
+
+ def Activated(self):
+ Modifier.Activated(self,"Downgrade")
+ if self.ui:
+ if not Draft.getSelection():
+ self.ui.selectUi()
+ msg(translate("draft", "Select an object to upgrade\n"))
+ self.call = self.view.addEventCallback("SoEvent",selectObject)
+ else:
+ self.proceed()
+
+ def proceed(self):
+ self.sel = Draft.getSelection()
+ edges = []
+ faces = []
+
+ # scanning objects
+ for ob in self.sel:
+ for f in ob.Shape.Faces:
+ faces.append(f)
+ for ob in self.sel:
+ for e in ob.Shape.Edges:
+ edges.append(e)
+ lastob = ob
+
+ # applying transformation
+ self.doc.openTransaction("Downgrade")
+
+ if (len(self.sel) == 1) and (Draft.getType(self.sel[0]) == "Block"):
+ # a block, we explode it
+ pl = self.sel[0].Placement
+ newob = []
+ for ob in self.sel[0].Components:
+ ob.ViewObject.Visibility = True
+ ob.Placement = ob.Placement.multiply(pl)
+ newob.append(ob)
+ self.doc.removeObject(self.sel[0].Name)
+
+ elif (len(self.sel) == 1) and (self.sel[0].isDerivedFrom("Part::Feature")) and ("Base" in self.sel[0].PropertiesList):
+ # special case, we have one parametric object: we "de-parametrize" it
+ msg(translate("draft", "Found 1 parametric object: breaking its dependencies\n"))
+ newob = Draft.shapify(self.sel[0])
+
+ elif len(self.sel) == 2:
+ # we have only 2 objects: cut 2nd from 1st
+ msg(translate("draft", "Found 2 objects: subtracting them\n"))
+ newob = Draft.cut(self.sel[0],self.sel[1])
+
+ elif (len(faces) > 1):
+
+ if len(self.sel) == 1:
+ # one object with several faces: split it
+ for f in faces:
+ msg(translate("draft", "Found several faces: splitting them\n"))
+ newob = self.doc.addObject("Part::Feature","Face")
+ newob.Shape = f
+ Draft.formatObject(newob,self.sel[0])
+ self.doc.removeObject(ob.Name)
+
+ else:
+ # several objects: remove all the faces from the first one
+ msg(translate("draft", "Found several objects: subtracting them from the first one\n"))
+ u = faces.pop(0)
+ for f in faces:
+ u = u.cut(f)
+ newob = self.doc.addObject("Part::Feature","Subtraction")
+ newob.Shape = u
+ for ob in self.sel:
+ Draft.formatObject(newob,ob)
+ self.doc.removeObject(ob.Name)
+
+ elif (len(faces) > 0):
+ # only one face: we extract its wires
+ msg(translate("draft", "Found 1 face: extracting its wires\n"))
+ for w in faces[0].Wires:
+ newob = self.doc.addObject("Part::Feature","Wire")
+ newob.Shape = w
+ Draft.formatObject(newob,lastob)
+ for ob in self.sel:
+ self.doc.removeObject(ob.Name)
+
+ else:
+ # no faces: split wire into single edges
+ msg(translate("draft", "Found only wires: extracting their edges\n"))
+ for ob in self.sel:
+ for e in edges:
+ newob = self.doc.addObject("Part::Feature","Edge")
+ newob.Shape = e
+ Draft.formatObject(newob,ob)
+ self.doc.removeObject(ob.Name)
+ self.doc.commitTransaction()
+ Draft.select(newob)
+ Modifier.finish(self)
+
+
+class Trimex(Modifier):
+ ''' The Draft_Trimex FreeCAD command definition.
+ This tool trims or extends lines, wires and arcs,
+ or extrudes single faces. SHIFT constrains to the last point
+ or extrudes in direction to the face normal.'''
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Trimex',
+ 'Accel' : "T, R",
+ 'MenuText' : QtCore.QT_TRANSLATE_NOOP("Draft_Trimex", "Trimex"),
+ 'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_Trimex", "Trims or extends the selected object, or extrudes single faces. CTRL snaps, SHIFT constrains to current segment or to normal, ALT inverts")}
+
+ def Activated(self):
+ Modifier.Activated(self,"Trimex")
+ self.edges = []
+ self.placement = None
+ self.ghost = None
+ self.linetrack = None
+ self.constraintrack = None
+ if self.ui:
+ if not Draft.getSelection():
+ self.ui.selectUi()
+ msg(translate("draft", "Select an object to trim/extend\n"))
+ self.call = self.view.addEventCallback("SoEvent",selectObject)
+ else:
+ self.proceed()
+
+ def proceed(self):
+ if self.call: self.view.removeEventCallback("SoEvent",self.call)
+ self.obj = Draft.getSelection()[0]
+ self.ui.radiusUi()
+ self.ui.labelRadius.setText("Distance")
+ self.ui.radiusValue.setFocus()
+ self.ui.radiusValue.selectAll()
+ self.linetrack = lineTracker()
+ self.constraintrack = lineTracker(dotted=True)
+ if not "Shape" in self.obj.PropertiesList: return
+ if "Placement" in self.obj.PropertiesList:
+ self.placement = self.obj.Placement
+ if len(self.obj.Shape.Faces) == 1:
+ # simple extrude mode, the object itself is extruded
+ self.extrudeMode = True
+ self.ghost = [ghostTracker([self.obj])]
+ self.normal = self.obj.Shape.Faces[0].normalAt(.5,.5)
+ for v in self.obj.Shape.Vertexes:
+ self.ghost.append(lineTracker())
+ elif len(self.obj.Shape.Faces) > 1:
+ # face extrude mode, a new object is created
+ ss = FreeCADGui.Selection.getSelectionEx()[0]
+ if len(ss.SubObjects) == 1:
+ if ss.SubObjects[0].ShapeType == "Face":
+ self.obj = self.doc.addObject("Part::Feature","Face")
+ self.obj.Shape = ss.SubObjects[0]
+ self.extrudeMode = True
+ self.ghost = [ghostTracker([self.obj])]
+ self.normal = self.obj.Shape.Faces[0].normalAt(.5,.5)
+ for v in self.obj.Shape.Vertexes:
+ self.ghost.append(lineTracker())
+ else:
+ # normal wire trimex mode
+ self.obj.ViewObject.Visibility = False
+ self.extrudeMode = False
+ if self.obj.Shape.Wires:
+ self.edges = self.obj.Shape.Wires[0].Edges
+ self.edges = fcgeo.sortEdges(self.edges)
+ else:
+ self.edges = self.obj.Shape.Edges
+ self.ghost = []
+ lc = self.obj.ViewObject.LineColor
+ sc = (lc[0],lc[1],lc[2])
+ sw = self.obj.ViewObject.LineWidth
+ for e in self.edges:
+ if isinstance(e.Curve,Part.Line):
+ self.ghost.append(lineTracker(scolor=sc,swidth=sw))
+ else:
+ self.ghost.append(arcTracker(scolor=sc,swidth=sw))
+ if not self.ghost: self.finish()
+ for g in self.ghost: g.on()
+ self.activePoint = 0
+ self.nodes = []
+ self.shift = False
+ self.alt = False
+ self.force = None
+ self.cv = None
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ msg(translate("draft", "Pick distance:\n"))
+ self.ui.cross(True)
+
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event": #mouse movement detection
+ self.ui.cross(True)
+ self.shift = hasMod(arg,MODCONSTRAIN)
+ self.alt = hasMod(arg,MODALT)
+ wp = not(self.extrudeMode and self.shift)
+ self.point = getPoint(self,arg,workingplane=wp)[0]
+ if hasMod(arg,MODSNAP): self.snapped = None
+ else: self.snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
+ if self.extrudeMode:
+ dist = self.extrude(self.shift)
+ else:
+ dist = self.redraw(self.point,self.snapped,self.shift,self.alt)
+ self.constraintrack.p1(self.point)
+ self.constraintrack.p2(self.newpoint)
+ self.constraintrack.on()
+ self.ui.radiusValue.setText("%.2f" % dist)
+ self.ui.radiusValue.setFocus()
+ self.ui.radiusValue.selectAll()
+
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ cursor = arg["Position"]
+ self.shift = hasMod(arg,MODCONSTRAIN)
+ self.alt = hasMod(arg,MODALT)
+ if hasMod(arg,MODSNAP): self.snapped = None
+ else: self.snapped = self.view.getObjectInfo((cursor[0],cursor[1]))
+ self.trimObject()
+ self.finish()
+
+ def extrude(self,shift=False,real=False):
+ "redraws the ghost in extrude mode"
+ self.newpoint = self.obj.Shape.Faces[0].CenterOfMass
+ dvec = self.point.sub(self.newpoint)
+ if shift: delta = fcvec.project(dvec,self.normal)
+ else: delta = dvec
+ if self.force:
+ ratio = self.force/delta.Length
+ delta.multiply(ratio)
+ if real: return delta
+ self.ghost[0].trans.translation.setValue([delta.x,delta.y,delta.z])
+ for i in range(1,len(self.ghost)):
+ base = self.obj.Shape.Vertexes[i-1].Point
+ self.ghost[i].p1(base)
+ self.ghost[i].p2(base.add(delta))
+ return delta.Length
+
+ def redraw(self,point,snapped=None,shift=False,alt=False,real=None):
+ "redraws the ghost"
+
+ # initializing
+ reverse = False
+ for g in self.ghost: g.off()
+ if real: newedges = []
+
+ # finding the active point
+ vlist = []
+ for e in self.edges: vlist.append(e.Vertexes[0].Point)
+ vlist.append(self.edges[-1].Vertexes[-1].Point)
+ if shift: npoint = self.activePoint
+ else: npoint = fcgeo.findClosest(point,vlist)
+ if npoint > len(self.edges)/2: reverse = True
+ if alt: reverse = not reverse
+ self.activePoint = npoint
+
+ # sorting out directions
+ if reverse and (npoint > 0): npoint = npoint-1
+ if (npoint > len(self.edges)-1):
+ edge = self.edges[-1]
+ ghost = self.ghost[-1]
+ else:
+ edge = self.edges[npoint]
+ ghost = self.ghost[npoint]
+ if reverse:
+ v1 = edge.Vertexes[-1].Point
+ v2 = edge.Vertexes[0].Point
+ else:
+ v1 = edge.Vertexes[0].Point
+ v2 = edge.Vertexes[-1].Point
+
+ # snapping
+ if snapped:
+ snapped = self.doc.getObject(snapped['Object'])
+ pts = []
+ for e in snapped.Shape.Edges:
+ int = fcgeo.findIntersection(edge,e,True,True)
+ if int: pts.extend(int)
+ if pts:
+ point = pts[fcgeo.findClosest(point,pts)]
+
+ # modifying active edge
+ if isinstance(edge.Curve,Part.Line):
+ perp = fcgeo.vec(edge).cross(Vector(0,0,1))
+ chord = v1.sub(point)
+ proj = fcvec.project(chord,perp)
+ self.newpoint = Vector.add(point,proj)
+ dist = v1.sub(self.newpoint).Length
+ ghost.p1(self.newpoint)
+ ghost.p2(v2)
+ self.ui.labelRadius.setText("Distance")
+ if real:
+ if self.force:
+ ray = self.newpoint.sub(v1)
+ ray = fcvec.scale(ray,self.force/ray.Length)
+ self.newpoint = Vector.add(v1,ray)
+ newedges.append(Part.Line(self.newpoint,v2).toShape())
+ else:
+ center = edge.Curve.Center
+ rad = edge.Curve.Radius
+ ang1 = fcvec.angle(v2.sub(center))
+ ang2 = fcvec.angle(point.sub(center))
+ self.newpoint=Vector.add(center,fcvec.rotate(Vector(rad,0,0),-ang2))
+ self.ui.labelRadius.setText("Angle")
+ dist = math.degrees(-ang2)
+ # if ang1 > ang2: ang1,ang2 = ang2,ang1
+ print "last calculated:",math.degrees(-ang1),math.degrees(-ang2)
+ ghost.setEndAngle(-ang2)
+ ghost.setStartAngle(-ang1)
+ ghost.setCenter(center)
+ ghost.setRadius(rad)
+ if real:
+ if self.force:
+ angle = math.radians(self.force)
+ newray = fcvec.rotate(Vector(rad,0,0),-angle)
+ self.newpoint = Vector.add(center,newray)
+ chord = self.newpoint.sub(v2)
+ perp = chord.cross(Vector(0,0,1))
+ scaledperp = fcvec.scaleTo(perp,rad)
+ midpoint = Vector.add(center,scaledperp)
+ newedges.append(Part.Arc(self.newpoint,midpoint,v2).toShape())
+ ghost.on()
+
+ # resetting the visible edges
+ if not reverse: list = range(npoint+1,len(self.edges))
+ else: list = range(npoint-1,-1,-1)
+ for i in list:
+ edge = self.edges[i]
+ ghost = self.ghost[i]
+ if isinstance(edge.Curve,Part.Line):
+ ghost.p1(edge.Vertexes[0].Point)
+ ghost.p2(edge.Vertexes[-1].Point)
+ else:
+ ang1 = fcvec.angle(edge.Vertexes[0].Point.sub(center))
+ ang2 = fcvec.angle(edge.Vertexes[-1].Point.sub(center))
+ # if ang1 > ang2: ang1,ang2 = ang2,ang1
+ ghost.setEndAngle(-ang2)
+ ghost.setStartAngle(-ang1)
+ ghost.setCenter(edge.Curve.Center)
+ ghost.setRadius(edge.Curve.Radius)
+ if real: newedges.append(edge)
+ ghost.on()
+
+ # finishing
+ if real: return newedges
+ else: return dist
+
+ def trimObject(self):
+ "trims the actual object"
+ if self.extrudeMode:
+ delta = self.extrude(self.shift,real=True)
+ print "delta",delta
+ self.doc.openTransaction("Extrude")
+ obj = Draft.extrude(self.obj,delta)
+ self.doc.commitTransaction()
+ self.obj = obj
+ else:
+ edges = self.redraw(self.point,self.snapped,self.shift,self.alt,real=True)
+ newshape = Part.Wire(edges)
+ self.doc.openTransaction("Trim/extend")
+ if Draft.getType(self.obj) in ["Wire","BSpline"]:
+ p = []
+ if self.placement: invpl = self.placement.inverse()
+ for v in newshape.Vertexes:
+ np = v.Point
+ if self.placement: np = invpl.multVec(np)
+ p.append(np)
+ self.obj.Points = p
+ elif Draft.getType(self.obj) == "Circle":
+ angles = self.ghost[0].getAngles()
+ print "original",self.obj.FirstAngle," ",self.obj.LastAngle
+ print "new",angles
+ if angles[0] > angles[1]: angles = (angles[1],angles[0])
+ self.obj.FirstAngle = angles[0]
+ self.obj.LastAngle = angles[1]
+ else:
+ self.obj.Shape = newshape
+ self.doc.commitTransaction()
+ for g in self.ghost: g.off()
+
+ def finish(self,closed=False):
+ Modifier.finish(self)
+ self.force = None
+ if self.ui:
+ self.ui.labelRadius.setText("Distance")
+ self.linetrack.finalize()
+ self.constraintrack.finalize()
+ if self.ghost:
+ for g in self.ghost:
+ g.finalize()
+ self.obj.ViewObject.Visibility = True
+ Draft.select(self.obj)
+
+ def numericRadius(self,dist):
+ "this function gets called by the toolbar when valid distance have been entered there"
+ self.force = dist
+ self.trimObject()
+ self.finish()
+
+
+class Scale(Modifier):
+ '''The Draft_Scale FreeCAD command definition.
+ This tool scales the selected objects from a base point.'''
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Scale',
+ 'Accel' : "S, C",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Scale", "Scale"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Scale", "Scales the selected objects from a base point. CTRL to snap, SHIFT to constrain, ALT to copy")}
+
+ def Activated(self):
+ Modifier.Activated(self,"Scale")
+ if self.ui:
+ if not Draft.getSelection():
+ self.ghost = None
+ self.linetrack = None
+ self.constraintrack = None
+ self.ui.selectUi()
+ msg(translate("draft", "Select an object to scale\n"))
+ self.call = self.view.addEventCallback("SoEvent",selectObject)
+ else:
+ self.proceed()
+
+ def proceed(self):
+ if self.call: self.view.removeEventCallback("SoEvent",self.call)
+ self.sel = Draft.getSelection()
+ self.sel = Draft.getGroupContents(self.sel)
+ self.ui.pointUi()
+ self.ui.modUi()
+ self.ui.xValue.setFocus()
+ self.ui.xValue.selectAll()
+ self.linetrack = lineTracker()
+ self.constraintrack = lineTracker(dotted=True)
+ self.ghost = ghostTracker(self.sel)
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ msg(translate("draft", "Pick base point:\n"))
+ self.ui.cross(True)
+
+ def finish(self,closed=False,cont=False):
+ Modifier.finish(self)
+ if self.ui:
+ self.ghost.finalize()
+ self.linetrack.finalize()
+ self.constraintrack.finalize()
+ if cont and self.ui:
+ if self.ui.continueMode:
+ FreeCADGui.Selection.clearSelection()
+ self.Activated()
+
+ def scale(self,delta,copy=False):
+ "moving the real shapes"
+ if copy:
+ self.commit(translate("draft","Copy"),
+ partial(Draft.scale,self.sel,delta,self.node[0],copy))
+ else:
+ self.commit(translate("draft","Scale"),
+ partial(Draft.scale,self.sel,delta,self.node[0],copy))
+
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event": #mouse movement detection
+ point,ctrlPoint = getPoint(self,arg,sym=True)
+ self.linetrack.p2(point)
+ self.ui.cross(True)
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else: self.constraintrack.off()
+ if (len(self.node) > 0):
+ last = self.node[len(self.node)-1]
+ delta = point.sub(last)
+ self.ghost.trans.scaleFactor.setValue([delta.x,delta.y,delta.z])
+ corr = Vector(self.node[0].x,self.node[0].y,self.node[0].z)
+ corr.scale(delta.x,delta.y,delta.z)
+ corr = fcvec.neg(corr.sub(self.node[0]))
+ self.ghost.trans.translation.setValue([corr.x,corr.y,corr.z])
+ if self.extendedCopy:
+ if not hasMod(arg,MODALT): self.finish()
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ point,ctrlPoint = getPoint(self,arg,sym=True)
+ if (self.node == []):
+ self.node.append(point)
+ self.ui.isRelative.show()
+ self.ui.isCopy.show()
+ self.linetrack.on()
+ self.ghost.on()
+ self.linetrack.p1(point)
+ msg(translate("draft", "Pick scale factor:\n"))
+ else:
+ last = self.node[0]
+ if self.ui.isCopy.isChecked() or hasMod(arg,MODALT):
+ self.scale(point.sub(last),True)
+ else:
+ self.scale(point.sub(last))
+ if hasMod(arg,MODALT):
+ self.extendedCopy = True
+ else:
+ self.finish(cont=True)
+
+ def numericInput(self,numx,numy,numz):
+ "this function gets called by the toolbar when valid x, y, and z have been entered there"
+ point = Vector(numx,numy,numz)
+ if not self.node:
+ self.node.append(point)
+ self.ui.isRelative.show()
+ self.ui.isCopy.show()
+ self.linetrack.p1(point)
+ self.linetrack.on()
+ self.ghost.on()
+ msg(translate("draft", "Pick scale factor:\n"))
+ else:
+ last = self.node[-1]
+ if self.ui.isCopy.isChecked():
+ self.scale(point.sub(last),True)
+ else:
+ self.scale(point.sub(last))
+ self.finish(cont=True)
+
+
+class ToggleConstructionMode():
+ "The Draft_ToggleConstructionMode FreeCAD command definition"
+
+ def GetResources(self):
+ return {'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleConstructionMode", "Toggle construcion Mode"),
+ 'Accel' : "C, M",
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleConstructionMode", "Toggles the Construction Mode for next objects.")}
+
+ def Activated(self):
+ FreeCADGui.draftToolBar.constrButton.toggle()
+
+
+class ToggleContinueMode():
+ "The Draft_ToggleContinueMode FreeCAD command definition"
+
+ def GetResources(self):
+ return {'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleContinueMode", "Toggle continue Mode"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleContinueMode", "Toggles the Continue Mode for next commands.")}
+
+ def Activated(self):
+ FreeCADGui.draftToolBar.continueCmd.toggle()
+
+
class Drawing(Modifier):
- "The Draft Drawing command definition"
+ "The Draft Drawing command definition"
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Drawing',
+ 'Accel' : "D, D",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Drawing", "Drawing"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Drawing", "Puts the selected objects on a Drawing sheet.")}
- def GetResources(self):
- return {'Pixmap' : 'Draft_Drawing',
- 'Accel' : "D, D",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Drawing", "Drawing"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Drawing", "Puts the selected objects on a Drawing sheet.")}
+ def IsActive(self):
+ if Draft.getSelection():
+ return True
+ else:
+ return False
- def IsActive(self):
- if Draft.getSelection():
- return True
- else:
- return False
+ def Activated(self):
+ Modifier.Activated(self,"Drawing")
+ sel = Draft.getSelection()
+ if not sel:
+ self.page = self.createDefaultPage()
+ else:
+ self.page = None
+ for obj in sel:
+ if obj.isDerivedFrom("Drawing::FeaturePage"):
+ self.page = obj
+ sel.pop(sel.index(obj))
+ if not self.page:
+ for obj in self.doc.Objects:
+ if obj.isDerivedFrom("Drawing::FeaturePage"):
+ self.page = obj
+ if not self.page:
+ self.page = self.createDefaultPage()
+ sel.reverse()
+ for obj in sel:
+ self.insertPattern(obj)
+ if obj.ViewObject.isVisible():
+ name = 'View'+obj.Name
+ oldobj = self.page.getObject(name)
+ if oldobj: self.doc.removeObject(oldobj.Name)
+ Draft.makeDrawingView(obj,self.page)
+ self.doc.recompute()
- def Activated(self):
- Modifier.Activated(self,"Drawing")
- sel = Draft.getSelection()
- if not sel:
- self.page = self.createDefaultPage()
- else:
- self.page = None
- for obj in sel:
- if obj.isDerivedFrom("Drawing::FeaturePage"):
- self.page = obj
- sel.pop(sel.index(obj))
- if not self.page:
- for obj in self.doc.Objects:
- if obj.isDerivedFrom("Drawing::FeaturePage"):
- self.page = obj
- if not self.page:
- self.page = self.createDefaultPage()
- sel.reverse()
- for obj in sel:
- self.insertPattern(obj)
- if obj.ViewObject.isVisible():
- name = 'View'+obj.Name
- oldobj = self.page.getObject(name)
- if oldobj: self.doc.removeObject(oldobj.Name)
- Draft.makeDrawingView(obj,self.page)
- self.doc.recompute()
+ def insertPattern(self,obj):
+ "inserts a pattern object on the page"
+ if 'FillStyle' in obj.ViewObject.PropertiesList:
+ if obj.ViewObject.FillStyle != 'shape color':
+ hatch = obj.ViewObject.FillStyle
+ vobj = self.page.getObject('Pattern'+hatch)
+ if not vobj:
+ if hatch in FreeCAD.svgpatterns:
+ view = self.doc.addObject('Drawing::FeatureView','Pattern'+hatch)
+ svg = FreeCAD.svgpatterns[hatch]
+ view.ViewResult = svg
+ view.X = 0
+ view.Y = 0
+ view.Scale = 1
+ self.page.addObject(view)
- def insertPattern(self,obj):
- if 'FillStyle' in obj.ViewObject.PropertiesList:
- if obj.ViewObject.FillStyle != 'shape color':
- hatch = obj.ViewObject.FillStyle
- vobj = self.page.getObject('Pattern'+hatch)
- if not vobj:
- if hatch in FreeCAD.svgpatterns:
- view = self.doc.addObject('Drawing::FeatureView','Pattern'+hatch)
- svg = FreeCAD.svgpatterns[hatch]
- view.ViewResult = svg
- view.X = 0
- view.Y = 0
- view.Scale = 1
- self.page.addObject(view)
+ def createDefaultPage(self):
+ "created a default page"
+ template = Draft.getParam("template")
+ if not template:
+ template = FreeCAD.getResourceDir()+'Mod/Drawing/Templates/A3_Landscape.svg'
+ page = self.doc.addObject('Drawing::FeaturePage','Page')
+ page.ViewObject.HintOffsetX = 200
+ page.ViewObject.HintOffsetY = 100
+ page.ViewObject.HintScale = 20
+ page.Template = template
+ self.doc.recompute()
+ return page
- def createDefaultPage(self):
- template = Draft.getParam("template")
- if not template:
- template = FreeCAD.getResourceDir()+'Mod/Drawing/Templates/A3_Landscape.svg'
- page = self.doc.addObject('Drawing::FeaturePage','Page')
- page.ViewObject.HintOffsetX = 200
- page.ViewObject.HintOffsetY = 100
- page.ViewObject.HintScale = 20
- page.Template = template
- self.doc.recompute()
- return page
-
+
class ToggleDisplayMode():
- "The ToggleDisplayMode FreeCAD command definition"
+ "The ToggleDisplayMode FreeCAD command definition"
- def GetResources(self):
- return {'Pixmap' : 'Draft_SwitchMode',
- 'Accel' : "Shift+Space",
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleDisplayMode", "Toggle display mode"),
- 'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_ToggleDisplayMode", "Swaps display mode of selected objects between wireframe and flatlines")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_SwitchMode',
+ 'Accel' : "Shift+Space",
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_ToggleDisplayMode", "Toggle display mode"),
+ 'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_ToggleDisplayMode", "Swaps display mode of selected objects between wireframe and flatlines")}
- def IsActive(self):
- if Draft.getSelection():
- return True
- else:
- return False
+ def IsActive(self):
+ if Draft.getSelection():
+ return True
+ else:
+ return False
- def Activated(self):
- for obj in Draft.getSelection():
- if obj.ViewObject.DisplayMode == "Flat Lines":
- if "Wireframe" in obj.ViewObject.listDisplayModes():
- obj.ViewObject.DisplayMode = "Wireframe"
- elif obj.ViewObject.DisplayMode == "Wireframe":
- if "Flat Lines" in obj.ViewObject.listDisplayModes():
- obj.ViewObject.DisplayMode = "Flat Lines"
+ def Activated(self):
+ for obj in Draft.getSelection():
+ if obj.ViewObject.DisplayMode == "Flat Lines":
+ if "Wireframe" in obj.ViewObject.listDisplayModes():
+ obj.ViewObject.DisplayMode = "Wireframe"
+ elif obj.ViewObject.DisplayMode == "Wireframe":
+ if "Flat Lines" in obj.ViewObject.listDisplayModes():
+ obj.ViewObject.DisplayMode = "Flat Lines"
class Edit(Modifier):
- "The Draft_Edit FreeCAD command definition"
+ "The Draft_Edit FreeCAD command definition"
- def __init__(self):
- self.running = False
+ def __init__(self):
+ self.running = False
- def GetResources(self):
- return {'Pixmap' : 'Draft_Edit',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Edit", "Edit"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Edit", "Edits the active object")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_Edit',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Edit", "Edit"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Edit", "Edits the active object")}
- def IsActive(self):
- if Draft.getSelection():
- self.selection = Draft.getSelection()
- if "Proxy" in self.selection[0].PropertiesList:
- if hasattr(self.selection[0].Proxy,"Type"):
- return True
- return False
+ def IsActive(self):
+ if Draft.getSelection():
+ self.selection = Draft.getSelection()
+ if "Proxy" in self.selection[0].PropertiesList:
+ if hasattr(self.selection[0].Proxy,"Type"):
+ return True
+ return False
- def Activated(self):
- if self.running:
+ def Activated(self):
+ if self.running:
+ self.finish()
+ else:
+ Modifier.Activated(self,"Edit")
+ self.ui.editUi()
+ if self.doc:
+ self.obj = Draft.getSelection()
+ if self.obj:
+ self.obj = self.obj[0]
+ # store selectable state of the object
+ self.selectstate = self.obj.ViewObject.Selectable
+ self.obj.ViewObject.Selectable = False
+ if not Draft.getType(self.obj) in ["Wire","BSpline"]:
+ self.ui.addButton.setEnabled(False)
+ self.ui.delButton.setEnabled(False)
+ else:
+ self.ui.addButton.setEnabled(True)
+ self.ui.delButton.setEnabled(True)
+ # self.ui.addButton.setChecked(False)
+ # self.ui.delButton.setChecked(False)
+ self.editing = None
+ self.editpoints = []
+ self.pl = None
+ if "Placement" in self.obj.PropertiesList:
+ self.pl = self.obj.Placement
+ self.invpl = self.pl.inverse()
+ if Draft.getType(self.obj) in ["Wire","BSpline"]:
+ for p in self.obj.Points:
+ if self.pl: p = self.pl.multVec(p)
+ self.editpoints.append(p)
+ elif Draft.getType(self.obj) == "Circle":
+ self.editpoints.append(self.obj.Placement.Base)
+ if self.obj.FirstAngle == self.obj.LastAngle:
+ self.editpoints.append(self.obj.Shape.Vertexes[0].Point)
+ elif Draft.getType(self.obj) == "Rectangle":
+ self.editpoints.append(self.obj.Placement.Base)
+ self.editpoints.append(self.obj.Shape.Vertexes[2].Point)
+ v = self.obj.Shape.Vertexes
+ self.bx = v[1].Point.sub(v[0].Point)
+ if self.obj.Length < 0: self.bx = fcvec.neg(self.bx)
+ self.by = v[2].Point.sub(v[1].Point)
+ if self.obj.Height < 0: self.by = fcvec.neg(self.by)
+ elif Draft.getType(self.obj) == "Polygon":
+ self.editpoints.append(self.obj.Placement.Base)
+ self.editpoints.append(self.obj.Shape.Vertexes[0].Point)
+ elif Draft.getType(self.obj) == "Dimension":
+ p = self.obj.ViewObject.Proxy.textpos.translation.getValue()
+ self.editpoints.append(self.obj.Start)
+ self.editpoints.append(self.obj.End)
+ self.editpoints.append(self.obj.Dimline)
+ self.editpoints.append(Vector(p[0],p[1],p[2]))
+ self.trackers = []
+ self.constraintrack = None
+ if self.editpoints:
+ for ep in range(len(self.editpoints)):
+ self.trackers.append(editTracker(self.editpoints[ep],self.obj.Name,
+ ep,self.obj.ViewObject.LineColor))
+ self.constraintrack = lineTracker(dotted=True)
+ self.call = self.view.addEventCallback("SoEvent",self.action)
+ self.running = True
+ plane.save()
+ if "Shape" in self.obj.PropertiesList:
+ plane.alignToFace(self.obj.Shape)
+ self.planetrack.set(self.editpoints[0])
+ else:
+ msg(translate("draft", "This object type is not editable\n"),'warning')
self.finish()
else:
- Modifier.Activated(self,"Edit")
- self.ui.editUi()
- if self.doc:
- self.obj = Draft.getSelection()
- if self.obj:
- self.obj = self.obj[0]
- # store selectable state of the object
- self.selectstate = self.obj.ViewObject.Selectable
- self.obj.ViewObject.Selectable = False
- if not Draft.getType(self.obj) in ["Wire","BSpline"]:
- self.ui.addButton.setEnabled(False)
- self.ui.delButton.setEnabled(False)
- else:
- self.ui.addButton.setEnabled(True)
- self.ui.delButton.setEnabled(True)
- #self.ui.addButton.setChecked(False)
- #self.ui.delButton.setChecked(False)
- self.editing = None
- self.editpoints = []
- self.pl = None
- if "Placement" in self.obj.PropertiesList:
- self.pl = self.obj.Placement
- self.invpl = self.pl.inverse()
- if Draft.getType(self.obj) in ["Wire","BSpline"]:
- for p in self.obj.Points:
- if self.pl: p = self.pl.multVec(p)
- self.editpoints.append(p)
- elif Draft.getType(self.obj) == "Circle":
- self.editpoints.append(self.obj.Placement.Base)
- if self.obj.FirstAngle == self.obj.LastAngle:
- self.editpoints.append(self.obj.Shape.Vertexes[0].Point)
- elif Draft.getType(self.obj) == "Rectangle":
- self.editpoints.append(self.obj.Placement.Base)
- self.editpoints.append(self.obj.Shape.Vertexes[2].Point)
- v = self.obj.Shape.Vertexes
- self.bx = v[1].Point.sub(v[0].Point)
- if self.obj.Length < 0: self.bx = fcvec.neg(self.bx)
- self.by = v[2].Point.sub(v[1].Point)
- if self.obj.Height < 0: self.by = fcvec.neg(self.by)
- elif Draft.getType(self.obj) == "Polygon":
- self.editpoints.append(self.obj.Placement.Base)
- self.editpoints.append(self.obj.Shape.Vertexes[0].Point)
- elif Draft.getType(self.obj) == "Dimension":
- p = self.obj.ViewObject.Proxy.textpos.translation.getValue()
- self.editpoints.append(self.obj.Start)
- self.editpoints.append(self.obj.End)
- self.editpoints.append(self.obj.Dimline)
- self.editpoints.append(Vector(p[0],p[1],p[2]))
- self.trackers = []
- self.constraintrack = None
- if self.editpoints:
- for ep in range(len(self.editpoints)):
- self.trackers.append(editTracker(self.editpoints[ep],self.obj.Name,
- ep,self.obj.ViewObject.LineColor))
- self.constraintrack = lineTracker(dotted=True)
- self.call = self.view.addEventCallback("SoEvent",self.action)
- self.running = True
- plane.save()
- if "Shape" in self.obj.PropertiesList:
- plane.alignToFace(self.obj.Shape)
- self.planetrack.set(self.editpoints[0])
- else:
- msg(translate("draft", "This object type is not editable\n"),'warning')
- self.finish()
- else:
- self.finish()
+ self.finish()
- def finish(self,closed=False):
- "terminates the operation"
- if closed:
- if "Closed" in self.obj.PropertiesList:
- if not self.obj.Closed:
- self.obj.Closed = True
- if self.ui:
- if self.trackers:
- for t in self.trackers:
- t.finalize()
- if self.constraintrack:
- self.constraintrack.finalize()
- self.obj.ViewObject.Selectable = self.selectstate
- Modifier.finish(self)
- plane.restore()
- self.running = False
+ def finish(self,closed=False):
+ "terminates the operation"
+ if closed:
+ if "Closed" in self.obj.PropertiesList:
+ if not self.obj.Closed:
+ self.obj.Closed = True
+ if self.ui:
+ if self.trackers:
+ for t in self.trackers:
+ t.finalize()
+ if self.constraintrack:
+ self.constraintrack.finalize()
+ self.obj.ViewObject.Selectable = self.selectstate
+ Modifier.finish(self)
+ plane.restore()
+ self.running = False
- def action(self,arg):
- "scene event handler"
- if arg["Type"] == "SoKeyboardEvent" and arg["Key"] == "ESCAPE":
- self.finish()
- if (arg["Type"] == "SoLocation2Event"): #mouse movement detection
- if self.editing != None:
+ def action(self,arg):
+ "scene event handler"
+ if arg["Type"] == "SoKeyboardEvent":
+ if arg["Key"] == "ESCAPE":
+ self.finish()
+ elif arg["Type"] == "SoLocation2Event": #mouse movement detection
+ if self.editing != None:
+ point,ctrlPoint = getPoint(self,arg)
+ # Draw constraint tracker line.
+ if hasMod(arg,MODCONSTRAIN):
+ self.constraintrack.p1(point)
+ self.constraintrack.p2(ctrlPoint)
+ self.constraintrack.on()
+ else:
+ self.constraintrack.off()
+ self.trackers[self.editing].set(point)
+ self.update(self.trackers[self.editing].get())
+ elif arg["Type"] == "SoMouseButtonEvent":
+ if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
+ if self.editing == None:
+ snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
+ if snapped:
+ if snapped['Object'] == self.obj.Name:
+ if self.ui.addButton.isChecked():
point,ctrlPoint = getPoint(self,arg)
- # Draw constraint tracker line.
- if hasMod(arg,MODCONSTRAIN):
- self.constraintrack.p1(point)
- self.constraintrack.p2(ctrlPoint)
- self.constraintrack.on()
- else: self.constraintrack.off()
- self.trackers[self.editing].set(point)
- self.update(self.trackers[self.editing].get())
- elif (arg["Type"] == "SoMouseButtonEvent"):
- if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
- if self.editing == None:
- snapped = self.view.getObjectInfo((arg["Position"][0],arg["Position"][1]))
- if snapped:
- if snapped['Object'] == self.obj.Name:
- if self.ui.addButton.isChecked():
- point,ctrlPoint = getPoint(self,arg)
- self.pos = arg["Position"]
- self.addPoint(point)
- elif self.ui.delButton.isChecked():
- if 'EditNode' in snapped['Component']:
- self.delPoint(int(snapped['Component'][8:]))
- elif 'EditNode' in snapped['Component']:
- self.ui.pointUi()
- self.ui.isRelative.show()
- self.editing = int(snapped['Component'][8:])
- self.trackers[self.editing].off()
- self.obj.ViewObject.Selectable = False
- if "Points" in self.obj.PropertiesList:
- self.node.append(self.obj.Points[self.editing])
- else:
- self.trackers[self.editing].on()
- self.obj.ViewObject.Selectable = True
- self.numericInput(self.trackers[self.editing].get())
+ self.pos = arg["Position"]
+ self.addPoint(point)
+ elif self.ui.delButton.isChecked():
+ if 'EditNode' in snapped['Component']:
+ self.delPoint(int(snapped['Component'][8:]))
+ elif 'EditNode' in snapped['Component']:
+ self.ui.pointUi()
+ self.ui.isRelative.show()
+ self.editing = int(snapped['Component'][8:])
+ self.trackers[self.editing].off()
+ self.obj.ViewObject.Selectable = False
+ if "Points" in self.obj.PropertiesList:
+ self.node.append(self.obj.Points[self.editing])
+ else:
+ print "finishing edit"
+ self.trackers[self.editing].on()
+ self.obj.ViewObject.Selectable = True
+ self.numericInput(self.trackers[self.editing].get())
- def update(self,v):
- if Draft.getType(self.obj) in ["Wire","BSpline"]:
- pts = self.obj.Points
- editPnt = self.invpl.multVec(v)
- # DNC: allows to close the curve by placing ends close to each other
- tol = 0.001
- if ( ( self.editing == 0 ) and ( (editPnt - pts[-1]).Length < tol) ) or ( self.editing == len(pts) - 1 ) and ( (editPnt - pts[0]).Length < tol):
- self.obj.Closed = True
- # DNC: fix error message if edited point coinsides with one of the existing points
- if ( editPnt in pts ) == False:
- pts[self.editing] = editPnt
- self.obj.Points = pts
- self.trackers[self.editing].set(v)
- elif Draft.getType(self.obj) == "Circle":
- delta = v.sub(self.obj.Placement.Base)
- if self.editing == 0:
- p = self.obj.Placement
- p.move(delta)
- self.obj.Placement = p
- self.trackers[0].set(self.obj.Placement.Base)
- elif self.editing == 1:
- self.obj.Radius = delta.Length
- self.trackers[1].set(self.obj.Shape.Vertexes[0].Point)
- elif Draft.getType(self.obj) == "Rectangle":
- delta = v.sub(self.obj.Placement.Base)
- if self.editing == 0:
- p = self.obj.Placement
- p.move(delta)
- self.obj.Placement = p
- elif self.editing == 1:
- diag = v.sub(self.obj.Placement.Base)
- nx = fcvec.project(diag,self.bx)
- ny = fcvec.project(diag,self.by)
- ax = nx.Length
- ay = ny.Length
- if ax and ay:
- if abs(nx.getAngle(self.bx)) > 0.1:
- ax = -ax
- if abs(ny.getAngle(self.by)) > 0.1:
- ay = -ay
- self.obj.Length = ax
- self.obj.Height = ay
- self.trackers[0].set(self.obj.Placement.Base)
- self.trackers[1].set(self.obj.Shape.Vertexes[2].Point)
- elif Draft.getType(self.obj) == "Polygon":
- delta = v.sub(self.obj.Placement.Base)
- if self.editing == 0:
- p = self.obj.Placement
- p.move(delta)
- self.obj.Placement = p
- self.trackers[0].set(self.obj.Placement.Base)
- elif self.editing == 1:
- if self.obj.DrawMode == 'inscribed':
- self.obj.Radius = delta.Length
- else:
- halfangle = ((math.pi*2)/self.obj.FacesNumber)/2
- rad = math.cos(halfangle)*delta.Length
- self.obj.Radius = rad
- self.trackers[1].set(self.obj.Shape.Vertexes[0].Point)
- elif Draft.getType(self.obj) == "Dimension":
- if self.editing == 0:
- self.obj.Start = v
- elif self.editing == 1:
- self.obj.End = v
- elif self.editing == 2:
- self.obj.Dimline = v
- elif self.editing == 3:
- self.obj.ViewObject.TextPosition = v
-
+ def update(self,v):
+ if Draft.getType(self.obj) in ["Wire","BSpline"]:
+ pts = self.obj.Points
+ editPnt = self.invpl.multVec(v)
+ # DNC: allows to close the curve by placing ends close to each other
+ tol = 0.001
+ if ( ( self.editing == 0 ) and ( (editPnt - pts[-1]).Length < tol) ) or ( self.editing == len(pts) - 1 ) and ( (editPnt - pts[0]).Length < tol):
+ self.obj.Closed = True
+ # DNC: fix error message if edited point coinsides with one of the existing points
+ if ( editPnt in pts ) == False:
+ pts[self.editing] = editPnt
+ self.obj.Points = pts
+ self.trackers[self.editing].set(v)
+ elif Draft.getType(self.obj) == "Circle":
+ delta = v.sub(self.obj.Placement.Base)
+ if self.editing == 0:
+ p = self.obj.Placement
+ p.move(delta)
+ self.obj.Placement = p
+ self.trackers[0].set(self.obj.Placement.Base)
+ elif self.editing == 1:
+ self.obj.Radius = delta.Length
+ self.trackers[1].set(self.obj.Shape.Vertexes[0].Point)
+ elif Draft.getType(self.obj) == "Rectangle":
+ delta = v.sub(self.obj.Placement.Base)
+ if self.editing == 0:
+ p = self.obj.Placement
+ p.move(delta)
+ self.obj.Placement = p
+ elif self.editing == 1:
+ diag = v.sub(self.obj.Placement.Base)
+ nx = fcvec.project(diag,self.bx)
+ ny = fcvec.project(diag,self.by)
+ ax = nx.Length
+ ay = ny.Length
+ if ax and ay:
+ if abs(nx.getAngle(self.bx)) > 0.1:
+ ax = -ax
+ if abs(ny.getAngle(self.by)) > 0.1:
+ ay = -ay
+ self.obj.Length = ax
+ self.obj.Height = ay
+ self.trackers[0].set(self.obj.Placement.Base)
+ self.trackers[1].set(self.obj.Shape.Vertexes[2].Point)
+ elif Draft.getType(self.obj) == "Polygon":
+ delta = v.sub(self.obj.Placement.Base)
+ if self.editing == 0:
+ p = self.obj.Placement
+ p.move(delta)
+ self.obj.Placement = p
+ self.trackers[0].set(self.obj.Placement.Base)
+ elif self.editing == 1:
+ if self.obj.DrawMode == 'inscribed':
+ self.obj.Radius = delta.Length
+ else:
+ halfangle = ((math.pi*2)/self.obj.FacesNumber)/2
+ rad = math.cos(halfangle)*delta.Length
+ self.obj.Radius = rad
+ self.trackers[1].set(self.obj.Shape.Vertexes[0].Point)
+ elif Draft.getType(self.obj) == "Dimension":
+ if self.editing == 0:
+ self.obj.Start = v
+ elif self.editing == 1:
+ self.obj.End = v
+ elif self.editing == 2:
+ self.obj.Dimline = v
+ elif self.editing == 3:
+ self.obj.ViewObject.TextPosition = v
- def numericInput(self,v,numy=None,numz=None):
- '''this function gets called by the toolbar
- when valid x, y, and z have been entered there'''
- if (numy != None):
- v = Vector(v,numy,numz)
- self.doc.openTransaction("Edit "+self.obj.Name)
- self.update(v)
- self.doc.commitTransaction()
- self.editing = None
- self.ui.editUi()
- self.node = []
+ def numericInput(self,v,numy=None,numz=None):
+ '''this function gets called by the toolbar
+ when valid x, y, and z have been entered there'''
+ if (numy != None):
+ v = Vector(v,numy,numz)
+ self.doc.openTransaction("Edit "+self.obj.Name)
+ self.update(v)
+ self.doc.commitTransaction()
+ self.editing = None
+ self.ui.editUi()
+ self.node = []
- def addPoint(self,point):
- if not (Draft.getType(self.obj) in ["Wire","BSpline"]): return
- pts = self.obj.Points
- if ( Draft.getType(self.obj) == "Wire" ):
- if (self.obj.Closed == True):
- # DNC: work around.... seems there is a
- # bug in approximate method for closed wires...
- edges = self.obj.Shape.Wires[0].Edges
- e1 = edges[-1] # last edge
- v1 = e1.Vertexes[0].Point
- v2 = e1.Vertexes[1].Point
- v2.multiply(0.9999)
- edges[-1] = Part.makeLine(v1,v2)
- edges.reverse()
- wire = Part.Wire(edges)
- curve = wire.approximate(0.0001,0.0001,100,25)
- else:
- # DNC: this version is much more reliable near sharp edges!
- curve = self.obj.Shape.Wires[0].approximate(0.0001,0.0001,100,25)
- elif ( Draft.getType(self.obj) == "BSpline" ):
- if (self.obj.Closed == True):
- curve = self.obj.Shape.Edges[0].Curve
- else:
- curve = self.obj.Shape.Curve
- uNewPoint = curve.parameter(point)
- uPoints = []
- for p in self.obj.Points:
- uPoints.append(curve.parameter(p))
- for i in range(len(uPoints)-1):
- if ( uNewPoint > uPoints[i] ) and ( uNewPoint < uPoints[i+1] ):
- pts.insert(i+1, self.invpl.multVec(point))
- break
- # DNC: fix: add points to last segment if curve is closed
- if ( self.obj.Closed ) and ( uNewPoint > uPoints[-1] ) :
- pts.append(self.invpl.multVec(point))
- self.doc.openTransaction("Edit "+self.obj.Name)
- self.obj.Points = pts
- self.doc.commitTransaction()
- self.resetTrackers()
-
+ def addPoint(self,point):
+ if not (Draft.getType(self.obj) in ["Wire","BSpline"]): return
+ pts = self.obj.Points
+ if ( Draft.getType(self.obj) == "Wire" ):
+ if (self.obj.Closed == True):
+ # DNC: work around.... seems there is a
+ # bug in approximate method for closed wires...
+ edges = self.obj.Shape.Wires[0].Edges
+ e1 = edges[-1] # last edge
+ v1 = e1.Vertexes[0].Point
+ v2 = e1.Vertexes[1].Point
+ v2.multiply(0.9999)
+ edges[-1] = Part.makeLine(v1,v2)
+ edges.reverse()
+ wire = Part.Wire(edges)
+ curve = wire.approximate(0.0001,0.0001,100,25)
+ else:
+ # DNC: this version is much more reliable near sharp edges!
+ curve = self.obj.Shape.Wires[0].approximate(0.0001,0.0001,100,25)
+ elif ( Draft.getType(self.obj) == "BSpline" ):
+ if (self.obj.Closed == True):
+ curve = self.obj.Shape.Edges[0].Curve
+ else:
+ curve = self.obj.Shape.Curve
+ uNewPoint = curve.parameter(point)
+ uPoints = []
+ for p in self.obj.Points:
+ uPoints.append(curve.parameter(p))
+ for i in range(len(uPoints)-1):
+ if ( uNewPoint > uPoints[i] ) and ( uNewPoint < uPoints[i+1] ):
+ pts.insert(i+1, self.invpl.multVec(point))
+ break
+ # DNC: fix: add points to last segment if curve is closed
+ if ( self.obj.Closed ) and ( uNewPoint > uPoints[-1] ) :
+ pts.append(self.invpl.multVec(point))
+ self.doc.openTransaction("Edit "+self.obj.Name)
+ self.obj.Points = pts
+ self.doc.commitTransaction()
+ self.resetTrackers()
- def delPoint(self,point):
- if not (Draft.getType(self.obj) in ["Wire","BSpline"]): return
- if len(self.obj.Points) <= 2:
- msg(translate("draft", "Active object must have more than two points/nodes\n"),'warning')
- else:
- pts = self.obj.Points
- pts.pop(point)
- self.doc.openTransaction("Edit "+self.obj.Name)
- self.obj.Points = pts
- self.doc.commitTransaction()
- self.resetTrackers()
+ def delPoint(self,point):
+ if not (Draft.getType(self.obj) in ["Wire","BSpline"]): return
+ if len(self.obj.Points) <= 2:
+ msg(translate("draft", "Active object must have more than two points/nodes\n"),'warning')
+ else:
+ pts = self.obj.Points
+ pts.pop(point)
+ self.doc.openTransaction("Edit "+self.obj.Name)
+ self.obj.Points = pts
+ self.doc.commitTransaction()
+ self.resetTrackers()
- def resetTrackers(self):
- for t in self.trackers:
- t.finalize()
- self.trackers = []
- for ep in range(len(self.obj.Points)):
- objPoints = self.obj.Points[ep]
- if self.pl: objPoints = self.pl.multVec(objPoints)
- self.trackers.append(editTracker(objPoints,self.obj.Name,ep,self.obj.ViewObject.LineColor))
+ def resetTrackers(self):
+ for t in self.trackers:
+ t.finalize()
+ self.trackers = []
+ for ep in range(len(self.obj.Points)):
+ objPoints = self.obj.Points[ep]
+ if self.pl: objPoints = self.pl.multVec(objPoints)
+ self.trackers.append(editTracker(objPoints,self.obj.Name,ep,self.obj.ViewObject.LineColor))
+
class AddToGroup():
- "The AddToGroup FreeCAD command definition"
+ "The AddToGroup FreeCAD command definition"
- def GetResources(self):
- return {'Pixmap' : 'Draft_AddToGroup',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_AddToGroup", "Add to group..."),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_AddToGroup", "Adds the selected object(s) to an existing group")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_AddToGroup',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_AddToGroup", "Add to group..."),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_AddToGroup", "Adds the selected object(s) to an existing group")}
- def IsActive(self):
- if Draft.getSelection():
- return True
- else:
- return False
+ def IsActive(self):
+ if Draft.getSelection():
+ return True
+ else:
+ return False
- def Activated(self):
- self.groups = ["Ungroup"]
- self.groups.extend(Draft.getGroupNames())
- self.labels = ["Ungroup"]
- for g in self.groups:
- o = FreeCAD.ActiveDocument.getObject(g)
- if o: self.labels.append(o.Label)
- self.ui = FreeCADGui.draftToolBar
- self.ui.sourceCmd = self
- self.ui.popupMenu(self.labels)
+ def Activated(self):
+ self.groups = ["Ungroup"]
+ self.groups.extend(Draft.getGroupNames())
+ self.labels = ["Ungroup"]
+ for g in self.groups:
+ o = FreeCAD.ActiveDocument.getObject(g)
+ if o: self.labels.append(o.Label)
+ self.ui = FreeCADGui.draftToolBar
+ self.ui.sourceCmd = self
+ self.ui.popupMenu(self.labels)
- def proceed(self,labelname):
- self.ui.sourceCmd = None
- if labelname == "Ungroup":
- for obj in Draft.getSelection():
- try:
- Draft.ungroup(obj)
- except:
- pass
- else:
- if labelname in self.labels:
- i = self.labels.index(labelname)
- g = FreeCAD.ActiveDocument.getObject(self.groups[i])
- for obj in Draft.getSelection():
- try:
- g.addObject(obj)
- except:
- pass
+ def proceed(self,labelname):
+ self.ui.sourceCmd = None
+ if labelname == "Ungroup":
+ for obj in Draft.getSelection():
+ try:
+ Draft.ungroup(obj)
+ except:
+ pass
+ else:
+ if labelname in self.labels:
+ i = self.labels.index(labelname)
+ g = FreeCAD.ActiveDocument.getObject(self.groups[i])
+ for obj in Draft.getSelection():
+ try:
+ g.addObject(obj)
+ except:
+ pass
+
class AddPoint(Modifier):
- "The Draft_AddPoint FreeCAD command definition"
+ "The Draft_AddPoint FreeCAD command definition"
- def __init__(self):
- self.running = False
+ def __init__(self):
+ self.running = False
- def GetResources(self):
- return {'Pixmap' : 'Draft_AddPoint',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_AddPoint", "Add Point"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_AddPoint", "Adds a point to an existing wire/bspline")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_AddPoint',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_AddPoint", "Add Point"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_AddPoint", "Adds a point to an existing wire/bspline")}
- def IsActive(self):
- self.selection = Draft.getSelection()
- if (Draft.getType(self.selection[0]) in ['Wire','BSpline']):
- return True
- else:
- return False
+ def IsActive(self):
+ self.selection = Draft.getSelection()
+ if (Draft.getType(self.selection[0]) in ['Wire','BSpline']):
+ return True
+ else:
+ return False
- def Activated(self):
- FreeCADGui.draftToolBar.addButton.setChecked(True)
- FreeCADGui.draftToolBar.delButton.setChecked(False)
- FreeCADGui.runCommand("Draft_Edit")
-
+ def Activated(self):
+ FreeCADGui.draftToolBar.addButton.setChecked(True)
+ FreeCADGui.draftToolBar.delButton.setChecked(False)
+ FreeCADGui.runCommand("Draft_Edit")
+
+
class DelPoint(Modifier):
- "The Draft_DelPoint FreeCAD command definition"
+ "The Draft_DelPoint FreeCAD command definition"
- def __init__(self):
- self.running = False
+ def __init__(self):
+ self.running = False
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_DelPoint',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_DelPoint", "Remove Point"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_DelPoint", "Removes a point from an existing wire or bspline")}
- def GetResources(self):
- return {'Pixmap' : 'Draft_DelPoint',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_DelPoint", "Remove Point"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_DelPoint", "Removes a point from an existing wire or bspline")}
+ def IsActive(self):
+ self.selection = Draft.getSelection()
+ if (Draft.getType(self.selection[0]) in ['Wire','BSpline']):
+ return True
+ else:
+ return False
- def IsActive(self):
- self.selection = Draft.getSelection()
- if (Draft.getType(self.selection[0]) in ['Wire','BSpline']):
- return True
- else:
- return False
-
- def Activated(self):
- FreeCADGui.draftToolBar.addButton.setChecked(False)
- FreeCADGui.draftToolBar.delButton.setChecked(True)
- FreeCADGui.runCommand("Draft_Edit")
+ def Activated(self):
+ FreeCADGui.draftToolBar.addButton.setChecked(False)
+ FreeCADGui.draftToolBar.delButton.setChecked(True)
+ FreeCADGui.runCommand("Draft_Edit")
+
class WireToBSpline(Modifier):
- "The Draft_Wire2BSpline FreeCAD command definition"
+ "The Draft_Wire2BSpline FreeCAD command definition"
- def __init__(self):
- self.running = False
+ def __init__(self):
+ self.running = False
+
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_WireToBSpline',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_WireToBSpline", "Wire to BSpline"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_WireToBSpline", "Converts between Wire and BSpline")}
- def GetResources(self):
- return {'Pixmap' : 'Draft_WireToBSpline',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_WireToBSpline", "Wire to BSpline"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_WireToBSpline", "Converts between Wire and BSpline")}
+ def IsActive(self):
+ self.selection = Draft.getSelection()
+ if (Draft.getType(self.selection[0]) in ['Wire','BSpline']):
+ return True
+ else:
+ return False
- def IsActive(self):
- self.selection = Draft.getSelection()
- if (Draft.getType(self.selection[0]) in ['Wire','BSpline']):
- return True
- else:
- return False
-
- def Activated(self):
- if self.running:
- self.finish()
+ def Activated(self):
+ if self.running:
+ self.finish()
+ else:
+ Modifier.Activated(self,"Convert Curve Type")
+ if self.doc:
+ self.obj = Draft.getSelection()
+ if self.obj:
+ self.obj = self.obj[0]
+ self.pl = None
+ if "Placement" in self.obj.PropertiesList:
+ self.pl = self.obj.Placement
+ self.Points = self.obj.Points
+ self.closed = self.obj.Closed
+ n = None
+ if (Draft.getType(self.selection[0]) == 'Wire'):
+ n = Draft.makeBSpline(self.Points, self.closed, self.pl)
+ elif (Draft.getType(self.selection[0]) == 'BSpline'):
+ n = Draft.makeWire(self.Points, self.closed, self.pl)
+ if n:
+ Draft.formatObject(n,self.selection[0])
else:
- Modifier.Activated(self,"Convert Curve Type")
- if self.doc:
- self.obj = Draft.getSelection()
- if self.obj:
- self.obj = self.obj[0]
- self.pl = None
- if "Placement" in self.obj.PropertiesList:
- self.pl = self.obj.Placement
- self.Points = self.obj.Points
- self.closed = self.obj.Closed
- n = None
- if (Draft.getType(self.selection[0]) == 'Wire'):
- n = Draft.makeBSpline(self.Points, self.closed, self.pl)
- elif (Draft.getType(self.selection[0]) == 'BSpline'):
- n = Draft.makeWire(self.Points, self.closed, self.pl)
- if n:
- Draft.formatObject(n,self.selection[0])
- else:
- self.finish()
+ self.finish()
def finish(self):
Modifier.finish(self)
+
class SelectGroup():
- "The SelectGroup FreeCAD command definition"
+ "The SelectGroup FreeCAD command definition"
- def GetResources(self):
- return {'Pixmap' : 'Draft_SelectGroup',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_SelectGroup", "Select group"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_SelectGroup", "Selects all objects with the same parents as this group")}
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_SelectGroup',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_SelectGroup", "Select group"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_SelectGroup", "Selects all objects with the same parents as this group")}
- def IsActive(self):
- if Draft.getSelection():
- return True
- else:
- return False
+ def IsActive(self):
+ if Draft.getSelection():
+ return True
+ else:
+ return False
- def Activated(self):
- sellist = []
- for ob in Draft.getSelection():
- for child in ob.OutList:
- FreeCADGui.Selection.addSelection(child)
- for parent in ob.InList:
- FreeCADGui.Selection.addSelection(parent)
- for child in parent.OutList:
- FreeCADGui.Selection.addSelection(child)
+ def Activated(self):
+ sellist = []
+ for ob in Draft.getSelection():
+ for child in ob.OutList:
+ FreeCADGui.Selection.addSelection(child)
+ for parent in ob.InList:
+ FreeCADGui.Selection.addSelection(parent)
+ for child in parent.OutList:
+ FreeCADGui.Selection.addSelection(child)
+
class Shape2DView():
- "The Shape2DView FreeCAD command definition"
- def GetResources(self):
- return {'Pixmap' : 'Draft_2DShapeView',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Shape2DView", "Shape 2D view"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Shape2DView", "Creates Shape 2D views of selected objects")}
+ "The Shape2DView FreeCAD command definition"
+ def GetResources(self):
+ return {'Pixmap' : 'Draft_2DShapeView',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Shape2DView", "Shape 2D view"),
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Shape2DView", "Creates Shape 2D views of selected objects")}
- def IsActive(self):
- if Draft.getSelection():
- return True
- else:
- return False
+ def IsActive(self):
+ if Draft.getSelection():
+ return True
+ else:
+ return False
- def Activated(self):
- sellist = []
- for ob in Draft.getSelection():
- Draft.makeShape2DView(ob)
+ def Activated(self):
+ sellist = []
+ for ob in Draft.getSelection():
+ Draft.makeShape2DView(ob)
#---------------------------------------------------------------------------
# Adds the icons & commands to the FreeCAD command manager, and sets defaults