From d652d84c19def86b1ce674ea75da8c0a41000b76 Mon Sep 17 00:00:00 2001 From: WandererFan Date: Wed, 27 Nov 2013 18:41:35 -0500 Subject: [PATCH] Add Draft makePathArray and _PathArray Add Draft PathArray GUI tool --- src/Mod/Draft/Draft.py | 197 +++- src/Mod/Draft/DraftTools.py | 35 + src/Mod/Draft/Draft_rc.py | 289 +++++- src/Mod/Draft/InitGui.py | 2 +- src/Mod/Draft/Resources/Draft.qrc | 1 + .../Draft/Resources/icons/Draft_PathArray.svg | 904 ++++++++++++++++++ src/Mod/Test/testPathArray.py | 34 + src/Mod/Test/testPathArraySel.py | 40 + 8 files changed, 1470 insertions(+), 32 deletions(-) create mode 100644 src/Mod/Draft/Resources/icons/Draft_PathArray.svg create mode 100644 src/Mod/Test/testPathArray.py create mode 100644 src/Mod/Test/testPathArraySel.py diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 959061fafe..4ad4b40de8 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -430,6 +430,12 @@ def getSelection(): return FreeCADGui.Selection.getSelection() return None +def getSelectionEx(): + "getSelectionEx(): returns the current FreeCAD selection (with subobjects)" + if gui: + return FreeCADGui.Selection.getSelectionEx() + return None + def select(objs=None): "select(object): deselects everything and selects only the passed object or list" if gui: @@ -953,7 +959,33 @@ def makeArray(baseobject,arg1,arg2,arg3,arg4=None,name="Array"): baseobject.ViewObject.hide() select(obj) return obj - + +def makePathArray(baseobject,pathobject,count,xlate=None,align=False,pathobjsubs=[]): + '''makePathArray(docobj,path,count,xlate,align,pathobjsubs): distribute + count copies of a document baseobject along a pathobject or subobjects of a + pathobject. Optionally translates each copy by FreeCAD.Vector xlate direction + and distance to adjust for difference in shape centre vs shape reference point. + Optionally aligns baseobject to tangent/normal/binormal of path.''' + obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","PathArray") + _PathArray(obj) + obj.Base = baseobject + obj.PathObj = pathobject + if pathobjsubs: + sl = [] + for sub in pathobjsubs: + sl.append((obj.PathObj,sub)) + obj.PathSubs = list(sl) + if count > 1: + obj.Count = count + if xlate: + obj.Xlate = xlate + obj.Align = align + if gui: + _ViewProviderDraftPart(obj.ViewObject) + baseobject.ViewObject.hide() + select(obj) + return obj + def makeEllipse(majradius,minradius,placement=None,face=True,support=None): '''makeEllipse(majradius,minradius,[placement],[face],[support]): makes an ellipse with the given major and minor radius, and optionally @@ -4127,6 +4159,169 @@ class _Array(_DraftObject): base.append(nshape) return Part.makeCompound(base) +class _PathArray(_DraftObject): + "The Draft Path Array object" + + def __init__(self,obj): + _DraftObject.__init__(self,obj,"PathArray") + obj.addProperty("App::PropertyLink","Base","Draft", + "The base object that must be duplicated") + obj.addProperty("App::PropertyLink","PathObj","Draft", + "The path object along which to distribute objects") + obj.addProperty("App::PropertyLinkSubList","PathSubs","Draft", + "Selected subobjects (edges) of PathObj") + obj.addProperty("App::PropertyInteger","Count","Draft", + "Number of copies") + obj.addProperty("App::PropertyVector","Xlate","Draft", + "Optional translation vector") + obj.addProperty("App::PropertyBool","Align","Draft","Orientation of Base along path") + obj.Count = 2 + obj.PathSubs = [] + obj.Xlate = FreeCAD.Vector(0,0,0) + obj.Align = False + + def execute(self,obj): + self.createGeometry(obj) + + def onChanged(self,obj,prop): + if prop in ["Count","Xlate","Align"]: + self.createGeometry(obj) + + def createGeometry(self,obj): + import FreeCAD + import Part + import DraftGeomUtils + if obj.Base and obj.PathObj: + pl = obj.Placement + if obj.PathSubs: + w = self.getWireFromSubs(obj) + elif (hasattr(obj.PathObj.Shape,'Wires') and obj.PathObj.Shape.Wires): + w = obj.PathObj.Shape.Wires[0] + elif obj.PathObj.Shape.Edges: + w = Part.Wire(obj.PathObj.Shape.Edges) + else: + FreeCAD.Console.PrintLog ("_PathArray.createGeometry: path " + obj.PathObj.Name + " has no edges\n") + return + obj.Shape = self.pathArray(obj.Base.Shape,w,obj.Count,obj.Xlate,obj.Align) + if not DraftGeomUtils.isNull(pl): + obj.Placement = pl + + def getWireFromSubs(self,obj): + '''Make a wire from PathObj subelements''' + import Part + sl = [] + for sub in obj.PathSubs: + e = sub[0].Shape.getElement(sub[1]) + sl.append(e) + return Part.Wire(sl) + + def getParameterFromV0(self, edge, offset): + '''return parameter at distance offset from edge.Vertexes[0]''' + '''sb method in Part.TopoShapeEdge???''' + lpt = edge.valueAt(edge.getParameterByLength(0)) + vpt = edge.Vertexes[0].Point + if not DraftVecUtils.equals(vpt,lpt): + # this edge is flipped + length = edge.Length - offset + else: + # this edge is right way around + length = offset + return(edge.getParameterByLength(length)) + + def orientShape(self,shape,edge,offset,RefPt,xlate,align): + '''Orient shape to edge tangent at offset.''' + import Part + import DraftGeomUtils + import math + z = FreeCAD.Vector(0,0,1) # unit +Z Probably defined elsewhere? + y = FreeCAD.Vector(0,1,0) # unit +Y + x = FreeCAD.Vector(1,0,0) # unit +X + nullv = FreeCAD.Vector(0,0,0) + ns = shape.copy() + ns.translate(RefPt+xlate) + if not align: + return ns + + # get local coord system - tangent, normal, binormal, if possible + t = edge.tangentAt(self.getParameterFromV0(edge,offset)) + t.normalize() + try: + n = edge.normalAt(self.getParameterFromV0(edge,offset)) + n.normalize() + b = (t.cross(n)) + b.normalize() + except: # no normal defined here + n = nullv + b = nullv + FreeCAD.Console.PrintLog ("Draft PathArray.orientShape - Shape not oriented (no normal).\n") + lnodes = z.cross(b) + if lnodes != nullv: + lnodes.normalize() # Can't normalize null vector. + # pathological cases: + if n == nullv: # 1) edge has inf. normals (ie line segment) + psi = math.degrees(DraftVecUtils.angle(x,t,z)) # align shape to tangent + theta = 0.0 + phi = 0.0 + elif b == z: # 2) binormal is same as z + psi = math.degrees(DraftVecUtils.angle(x,t,z)) # align shape to tangent + theta = 0.0 + phi = 0.0 + FreeCAD.Console.PrintLog ("Draft PathArray.orientShape - Aligned to tangent only (no line of nodes).\n") + else: # regular case + psi = math.degrees(DraftVecUtils.angle(lnodes,t,z)) + theta = abs(math.degrees(DraftVecUtils.angle(z,b,x))) # 0<=theta<=pi + phi = math.degrees(DraftVecUtils.angle(x,lnodes,z)) + ns.rotate(RefPt,z,psi) + ns.rotate(RefPt,x,theta) + ns.rotate(RefPt,z,phi) + return ns + + def pathArray(self,shape,pathwire,count,xlate,align): + '''Distribute shapes along a path.''' + import Part + import DraftGeomUtils + closedpath = DraftGeomUtils.isReallyClosed(pathwire) + path = DraftGeomUtils.sortEdges(pathwire.Edges) + ends = [] + cdist = 0 + for e in path: # find cumulative edge end distance + cdist += e.Length + ends.append(cdist) + base = [] + pt = path[0].Vertexes[0].Point # place the start shape + ns = self.orientShape(shape,path[0],0,pt,xlate,align) + base.append(ns) + if not(closedpath): # closed path doesn't need shape on last vertex + pt = path[-1].Vertexes[-1].Point # place the end shape + ns = self.orientShape(shape,path[-1],path[-1].Length,pt,xlate,align) + base.append(ns) + if count < 3: + return(Part.makeCompound(base)) + + # place the middle shapes + if closedpath: + stop = count + else: + stop = count - 1 + step = cdist/stop + remain = 0 + travel = step + for i in range(1,stop): + # which edge in path should contain this shape? + iend = len(ends) - 1 # avoids problems with float math travel > ends[-1] + for j in range(0,len(ends)): + if travel <= ends[j]: + iend = j + break + # place shape at proper spot on proper edge + remains = ends[iend] - travel + offset = path[iend].Length - remains + pt = path[iend].valueAt(self.getParameterFromV0(path[iend],offset)) + ns = self.orientShape(shape,path[iend],offset,pt,xlate,align) + base.append(ns) + travel += step + return(Part.makeCompound(base)) + class _Point(_DraftObject): "The Draft Point object" def __init__(self, obj,x,y,z): diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index f420c28026..881f1c432a 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -3631,6 +3631,40 @@ class Array(Modifier): FreeCAD.ActiveDocument.commitTransaction() self.finish() +class PathArray(Modifier): + "The PathArray FreeCAD command definition" + + def GetResources(self): + return {'Pixmap' : 'Draft_PathArray', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_PathArray", "PathArray"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_PathArray", "Creates copies of a selected object along a selected path.")} + + def Activated(self): + Modifier.Activated(self) + if not Draft.getSelectionEx(): + if self.ui: + self.ui.selectUi() + msg(translate("draft", "Please select base and path objects\n")) +# print "Please select base and path objects" + self.call = self.view.addEventCallback("SoEvent",selectObject) + else: + self.proceed() + + def proceed(self): + if self.call: + self.view.removeEventCallback("SoEvent",self.call) + sel = Draft.getSelectionEx() + if sel: + base = sel[0].Object + path = sel[1].Object + pathsubs = list(sel[1].SubElementNames) + defXlate = FreeCAD.Vector(0,0,0) + defCount = 4 + defAlign = False + FreeCAD.ActiveDocument.openTransaction("PathArray") + Draft.makePathArray(base,path,defCount,defXlate,defAlign,pathsubs) + FreeCAD.ActiveDocument.commitTransaction() + self.finish() class Point: "this class will create a vertex after the user clicks a point on the screen" @@ -4007,6 +4041,7 @@ FreeCADGui.addCommand('Draft_WireToBSpline',WireToBSpline()) FreeCADGui.addCommand('Draft_Draft2Sketch',Draft2Sketch()) FreeCADGui.addCommand('Draft_Array',Array()) FreeCADGui.addCommand('Draft_Clone',Draft_Clone()) +FreeCADGui.addCommand('Draft_PathArray',PathArray()) FreeCADGui.addCommand('Draft_Heal',Heal()) # context commands diff --git a/src/Mod/Draft/Draft_rc.py b/src/Mod/Draft/Draft_rc.py index 3558b8e597..bc1a0e9933 100644 --- a/src/Mod/Draft/Draft_rc.py +++ b/src/Mod/Draft/Draft_rc.py @@ -2,8 +2,8 @@ # Resource object code # -# Created: Mon Nov 11 13:33:06 2013 -# by: The Resource Compiler for PyQt (Qt v4.8.6) +# Created: Wed Nov 27 18:33:26 2013 +# by: The Resource Compiler for PyQt (Qt v4.8.1) # # WARNING! All changes made in this file will be lost! @@ -48384,6 +48384,229 @@ qt_resource_data = "\ \x4b\x1e\x8f\xd8\x68\x55\x45\xac\x6f\x07\xcf\x23\x0b\x77\x08\x41\ \x2b\x25\x81\x15\x65\xa4\x15\xe6\xcb\xe5\xdb\xc5\x74\x15\xef\xe2\ \xf1\x75\x41\xbf\x1d\xbc\x7e\xf1\x1f\x62\x9b\x4c\x39\ +\x00\x00\x0d\xc1\ +\x00\ +\x00\x74\xa0\x78\x9c\xed\x5d\xeb\x6f\xe3\xb8\x11\xff\xbe\x7f\x85\ +\xea\xfd\x72\x8b\x5a\x34\xdf\x0f\x6f\xb2\x87\xa2\x8b\x2b\x0e\xb8\ +\xa2\x45\xef\x0e\xfd\x78\x90\x25\xd9\x51\x63\x5b\x86\xa4\xbc\xf6\ +\xaf\xef\x50\x7e\x49\x36\x6d\x4b\x89\xed\xec\x25\xb6\xb1\x9b\x88\ +\x1c\xbe\x86\x33\xbf\x99\x21\x29\xe6\xea\xc7\xc7\xc9\xd8\xbb\x8f\ +\xb3\x3c\x49\xa7\xd7\x1d\x82\x70\xc7\x8b\xa7\x61\x1a\x25\xd3\xd1\ +\x75\xe7\xf7\xdf\x7e\xf2\x75\xc7\xcb\x8b\x60\x1a\x05\xe3\x74\x1a\ +\x5f\x77\xa6\x69\xe7\xc7\x2f\x1f\xae\xfe\xe2\xfb\xde\xdf\xb3\x38\ +\x28\xe2\xc8\x7b\x48\x8a\x1b\xef\xe7\xe9\x6d\x1e\x06\xb3\xd8\xfb\ +\xe1\xa6\x28\x66\xfd\x5e\xef\xe1\xe1\x01\x25\x8b\x44\x94\x66\xa3\ +\xde\x27\xcf\xf7\xbf\x7c\xf8\x70\x95\xdf\x8f\x3e\x78\x9e\x07\xed\ +\x4e\xf3\x7e\x9a\x0f\xae\x3b\x95\x12\xe9\x2c\x9e\xe6\x0f\x41\x11\ +\xde\x0c\xd2\xf4\xb6\x2c\x77\x97\x25\x3d\x8a\xb1\xe9\x01\x6d\x67\ +\x5d\x32\x0a\x57\x05\x67\x77\xd9\xb8\x24\x8d\xc2\x5e\x3c\x8e\x27\ +\xf1\xb4\xc8\x7b\x04\x91\x5e\x85\x3c\x5c\x93\x87\xb6\xdf\xc9\x7d\ +\x1c\xa6\x93\x49\x3a\xcd\xcb\x92\xd3\xfc\x63\x85\x38\x8b\x86\xb5\ +\x5e\x3d\xb0\x92\x88\x18\x63\x7a\x98\xf6\x28\xf5\x81\xc2\xcf\x9f\ +\xa6\x45\xf0\xe8\xd7\x8b\xc2\xe8\x5c\x45\x61\x00\xb8\x07\x79\x6b\ +\xca\x66\x54\xfd\xc7\x31\x30\x71\x67\x67\xca\xdc\x6a\xeb\x30\x71\ +\x33\xf8\xb7\x2a\xb0\x4c\x40\x79\x7a\x97\x85\xf1\x10\x4a\xc6\x68\ +\x1a\x17\xbd\xaf\xbf\x7d\x5d\x65\xfa\x18\x45\x45\x54\xa9\x66\x39\ +\x6f\xb5\x76\x6b\x93\x39\x0d\x26\x71\x3e\x0b\xc2\x38\xef\x2d\xd3\ +\xcb\xf2\x0f\x49\x54\xdc\x5c\x77\x24\x9f\x3d\x96\xcf\x37\x71\x32\ +\xba\x29\x2a\x09\x49\x74\xdd\x81\x11\x32\x49\x68\xf9\x5c\x11\x3d\ +\x32\x27\x58\x54\xd7\x5f\xe5\x60\xc4\x35\x62\x88\x78\x99\xd1\x5a\ +\x96\x44\xcb\x9e\xf7\xa3\x34\xb4\x5d\xb9\xee\x7c\xcd\x82\x61\xf1\ +\xc7\xbf\x83\xe2\xe6\x6f\x59\x16\x3c\x21\xcb\xc5\x2f\x40\x7a\x15\ +\xc5\xc3\xdc\x16\x99\x37\x6d\x9f\xa0\x6d\x5e\xe6\x41\x2e\xf0\x2f\ +\x0e\xb2\x7f\x64\x41\x94\x80\xd4\xcc\xe9\xe6\x94\xf5\x1c\xc1\x89\ +\xe9\x2c\xb3\x41\x10\xfb\xb3\x20\x99\xc2\xb8\xf2\x74\x9c\x44\x8b\ +\xca\xa0\xba\xbc\x48\x67\x4b\x2a\xe8\x65\xf1\x34\x86\xae\xd9\x44\ +\x3f\x4c\xc7\x69\xd6\xff\x88\xcb\xcf\xe7\x32\x29\x05\xfe\x25\xc5\ +\x53\x9f\x7c\xee\xac\xcb\xa4\xc3\x61\x1e\x43\xc5\xb8\x92\x56\xf2\ +\x0c\x4a\x08\x4e\x49\xc7\xeb\x2d\xba\xde\xab\xf7\x70\x91\xba\x62\ +\xdf\x0c\xd8\x37\x8b\x43\x2b\xe8\xcb\x9a\x56\x5c\x2b\x9e\xec\xdc\ +\xd6\x49\x59\xb4\x6a\x71\x3d\x05\xb3\x3f\x1e\xa1\x2b\x5e\xdf\x63\ +\x14\xfe\x23\x4e\x8a\xa7\x39\x05\x81\x71\xc1\x0f\xec\xa4\xf9\x66\ +\x25\x60\x4f\x35\x8b\x1e\xf8\x69\x96\x8c\x12\x98\xf2\x92\x8e\x12\ +\xc4\xca\x4f\xbd\x0c\x30\xa3\x32\x36\x26\x29\x5e\xf3\x64\xdf\xe8\ +\x37\x0b\x0a\xad\x0f\x77\x04\x23\x61\x07\xb5\xe8\xc8\x66\x57\xea\ +\x23\x24\x25\xa5\x78\x11\xa3\x16\xec\xde\xac\xe6\xd0\xcc\x3d\x8b\ +\x01\xd2\xd0\xb7\xc7\x80\xa6\x0a\xcd\x08\xe7\xbe\xdc\xa5\xb9\x4b\ +\x8d\x03\x2a\xe9\x9b\xce\x5e\x95\x1e\x96\x9f\x0d\x95\x76\x6a\xf4\ +\xb2\x93\xfb\x9a\xd3\x3e\x6d\xdf\x1c\x76\x34\x77\x10\x29\x1a\x73\ +\x4a\x61\x72\x90\x4f\x0a\xb3\xf3\x71\x49\x61\x71\x26\x1e\xd9\xa7\ +\x60\xbc\xc5\xa3\xa5\xf4\x41\x73\x63\x50\xa6\xeb\x4e\x30\x7e\x08\ +\x9e\xf2\x55\x0b\xa5\x59\xee\xdf\x64\x31\xb8\x11\x1f\x9d\x72\x57\ +\x65\x77\xbd\x11\x26\x2b\xb8\x34\x5a\x24\xfe\x3e\x4d\x0a\xf0\x18\ +\xee\xf2\x38\xfb\xd5\x5a\xdd\x7f\x4d\x7f\xcf\xe3\x2d\xaa\xdf\xb2\ +\x60\x9a\x83\x89\x9f\x5c\x77\x26\x41\x91\x25\x8f\x3f\x90\x2e\xb6\ +\x5f\x24\x8d\x16\xd4\x70\xf8\x9d\x62\x8a\x34\xd5\x92\x7d\x5a\x15\ +\x0f\x41\xe7\x28\x15\x88\x4a\x8e\xd7\xc2\x17\x82\xb6\x4a\x45\x91\ +\x32\x8a\xad\xfb\x3b\x74\xd2\x0e\x9d\xb4\x19\xe0\x38\x47\x8c\x0b\ +\x02\x23\x6a\xaf\xa0\x0a\xeb\xc3\x62\x47\xf0\x19\xc5\x8e\x9c\x4b\ +\x35\xdb\xa0\xb8\xae\x28\xc3\xfb\x43\x71\x2d\xb9\x8f\x7d\x7c\x50\ +\x50\xb4\x94\xbe\xf0\xd5\x01\x47\xcb\xe5\xb0\x49\x62\xc2\x6d\x87\ +\xed\xb0\xb4\x68\xa9\x7d\x55\xd1\xf4\xea\xf4\xef\x6d\x91\x29\x13\ +\x0e\x07\x3b\x5b\x7c\x29\x9a\x33\xa5\x0e\x72\x0b\xba\xd0\x9e\x53\ +\xc3\x61\x10\x38\x5c\xdb\xc3\x9c\x62\xda\xa5\x91\x07\xb8\x34\x0c\ +\x86\x43\x7a\x3a\x2e\x95\x72\xd5\x4c\xaa\xce\x2d\x53\xe7\x92\xa8\ +\x36\x20\x64\xf0\x3b\x76\x25\x05\xe6\x3b\x2d\xd5\xf6\x6c\x0c\xc6\ +\x41\x78\xbb\x61\x23\x1a\x07\x80\x58\x34\x30\x54\x40\xe5\x82\x1d\ +\xe0\xc3\x5e\x31\x71\x74\x6c\x9f\x50\x3e\x7f\x64\xc4\x3d\x32\x7a\ +\x3c\xe5\xe5\x04\x8c\x02\x3b\xac\xbe\x9c\xf9\xc4\x67\xe7\x54\x60\ +\x2e\xa0\x67\xfa\x5c\x2a\xec\x76\x5f\x9b\x39\x95\xd6\xa7\x23\x84\ +\x23\x21\x35\xaf\xbb\x7f\x18\x69\x43\xb1\x59\x9b\x08\x70\xf4\xc0\ +\x23\xac\x08\x5d\xe8\x2a\x1b\x3a\xcb\x5a\xd6\x04\xc9\x28\x8b\xe8\ +\xa1\xe9\x22\x42\x48\xb9\x9f\x4b\x3f\x61\xfb\x7d\x9e\x7b\x67\xab\ +\xd7\xfb\xab\x37\x81\xfd\x6e\x4c\x02\xc2\x8b\x35\x1d\xd7\xa4\x2e\ +\x33\x2b\x13\x55\x9f\x93\x23\x4d\x94\xb4\xbc\x56\x55\x14\xde\x3b\ +\x53\xaa\x36\x53\xdb\x85\x0f\x4c\xd5\x41\xcd\x02\x5e\xaa\x03\xf1\ +\xe0\x0b\xa7\x4a\x1d\x88\x00\x4f\x37\x55\x4d\x51\x88\x80\xb4\xee\ +\x94\xe9\xa6\x91\xca\xbe\x1e\xe3\x55\x8f\x5d\x1c\x92\x92\xb7\xc1\ +\xee\x8f\x43\x6d\xbf\xcf\x62\x98\xbb\x79\xf9\x3c\x70\x02\x09\xd5\ +\x12\x41\xec\xc7\x45\x4d\xc2\x99\x40\x10\x5b\x1a\x52\x0f\x45\x19\ +\x43\x06\x9a\xaa\xb8\xab\xa1\x93\x36\x74\xd2\xee\x8e\x9b\x31\x90\ +\x62\x6e\xa8\x51\x65\x00\x0d\x63\xe5\x84\x30\xda\xf5\x05\x45\x10\ +\xc0\x53\x6e\xba\xbe\x82\x48\x9a\x31\x22\xf4\xa7\xad\x0a\xf7\x2b\ +\xec\x76\xcc\xcf\xb9\x58\x2b\xdf\x9e\xc5\x03\x2a\x2a\xda\xb8\x6b\ +\x11\xa2\xb5\xff\x62\x6b\x6d\x21\x28\x81\xfd\x1e\x49\x4e\xa9\xdc\ +\xa3\xee\x8e\xc6\x07\xe5\xe7\x48\x52\x4a\xe5\x33\xd7\x7f\xec\xc2\ +\x86\x42\x4a\x10\x45\x58\x5d\x48\x21\x51\x12\xaa\x45\x4d\x48\x35\ +\xd2\x94\x57\xf7\x0f\x42\x27\x69\xe8\x22\xdd\x2f\xa2\x9a\xaa\x8a\ +\x88\x32\xaa\xa4\xea\xfa\x5c\x23\x00\x73\x69\x4a\x11\x25\x48\x6a\ +\x41\xd8\x51\x44\x94\x37\x12\x51\x79\x12\x11\x95\x6d\x44\x34\x60\ +\xf6\x7b\x2c\x11\x55\xed\x44\x94\x87\xf6\x7b\x2c\x11\x55\xc7\x5c\ +\x2b\xe2\x86\xab\xed\xc9\x79\x2f\x61\x1a\xc7\x46\xb4\xda\xa9\x13\ +\x83\x2d\x7b\xdc\x34\x50\x83\xb6\x54\x2b\xa9\x09\x49\xcc\x86\xaa\ +\x41\x6b\xae\xe0\x89\x5b\x2f\xed\x78\x62\x22\x30\x7d\x83\x62\xd2\ +\x8a\x01\x4a\xbe\x3d\x06\xec\xd0\x93\x17\xec\x65\x80\x1f\xa4\x3a\ +\x7b\x14\x8e\x8a\xb5\x79\x7c\x24\x60\xf3\x0c\x47\x44\xa8\x4a\x4c\ +\xf8\x04\xa9\x44\x0b\x44\x18\xae\x58\x17\x7a\xdd\xe1\x8c\x83\x0f\ +\x57\xc5\xab\x27\x48\x25\x1c\x23\x4a\x15\x5b\x8f\xfe\xa5\x1b\x24\ +\x60\x45\x39\x65\x44\x53\xb9\xd8\x29\x59\x3d\x52\xb0\xd0\x54\x09\ +\xf0\xf4\xac\x51\x96\x30\x16\xf9\xe9\x19\xa0\x63\x59\xd4\x1c\x06\ +\x68\xac\x29\x6e\x02\x03\x4e\xd0\x01\xb7\xb4\x15\xe8\x08\x3a\x1c\ +\x36\x3a\x8c\xe0\x04\x1d\x2a\x8e\x69\x9b\x04\xe1\x0d\xce\x05\xfc\ +\xd9\x74\xae\x0d\x03\x28\x7d\xcf\x1b\x39\x76\x5b\xf4\xf0\x7e\x5f\ +\xb9\x1d\x7f\x60\x11\xe8\xd8\xfb\xf1\xbc\x7d\x73\xa7\xde\xf4\x13\ +\x0c\xbf\x41\x65\x39\xd1\x66\x7b\x75\x06\x1d\x71\x0d\x63\xdb\xd1\ +\xd6\x7b\xdc\x6e\x5f\xb2\xaa\x99\x0a\xfa\x07\x96\x4a\x8f\xae\x84\ +\xfe\x33\x36\xfa\x4f\xaf\x86\xea\x0d\x3a\xca\xc7\xf7\x13\xcb\x0d\ +\x19\xd6\xd9\x2d\x7c\x5c\xc8\x35\x23\x4b\x4f\x91\x72\xc4\x39\xa9\ +\x6c\x29\x58\x4f\xd1\x6a\x02\x67\xb4\xb2\x82\x67\x5d\x45\x26\x04\ +\x32\x76\xf5\xbe\xe6\x2a\x6e\xd3\xee\x57\xee\x67\x1c\x3d\x28\x07\ +\xd5\x68\x8f\xe9\xac\x7b\xc4\x5c\x9c\x6f\x83\xe9\x15\x64\x45\x88\ +\xca\x31\x9c\xb9\xac\x30\xa4\x19\x11\xbc\x91\xac\x48\x24\xa8\x10\ +\xea\x38\xb2\x72\x02\x8b\x55\x0e\x7f\xef\x01\x31\x01\x91\x88\x5f\ +\x5f\xda\xf6\x19\x12\x5c\x12\xe0\x44\x7d\x8d\x91\x21\x43\x19\xe7\ +\x95\x45\x4a\x37\xf1\xd0\x49\x9c\xd9\xd8\x0c\x61\x8d\x55\x25\x8e\ +\x3b\x6c\xfc\x8c\x02\xd9\x85\x09\x99\x3f\x18\x30\x54\x1a\x93\xa6\ +\x0b\x90\xcf\x54\xc3\x06\x27\x39\xe7\x8a\xe8\xbb\xb7\x9c\x4e\xa8\ +\x8a\xe7\x3b\xb0\xb1\x73\xb1\x7a\x7b\x16\xdd\x13\xbe\x43\x3a\xdc\ +\xa2\xb4\x43\xee\x4e\x2c\x1f\xfb\xd4\x42\x91\xe7\x69\xd8\xc1\x55\ +\xea\x93\xa9\x39\x39\xa8\xe6\xe2\xa2\xe7\x1b\x1c\x6b\xa8\xe7\x67\ +\x3d\xea\x57\xea\xb9\xeb\x1c\xc9\x45\xcf\x4f\xa2\xe7\x15\x14\x6f\ +\xa0\xe9\xbe\xc3\x97\x7e\xf1\x8e\x54\xa5\xf2\xa6\x96\xe7\xec\x27\ +\x8d\xec\x01\x54\x77\x0c\x74\x91\xca\x63\x4b\xa5\xe4\x8d\xb6\x47\ +\x9f\x25\x93\xef\x9c\xb5\xa5\xc2\x8b\x56\xdc\x75\x9c\x46\x3d\x9e\ +\xc6\x1f\x3c\xa9\xb6\xd6\x78\x57\x20\x76\x6a\x8d\xbf\xd8\xa1\xf3\ +\x89\xa5\x6a\x25\x95\xa7\x38\x19\x51\xa9\xbc\xb1\x54\xf2\x57\x90\ +\x4a\x57\x9b\x17\xa9\x3c\x89\x1d\x6a\xe9\x1d\xb5\x91\xca\x57\x59\ +\xf0\x90\xb8\x72\xda\xf3\x58\x4b\xf4\x07\xf8\x7f\xa6\x68\xeb\x0c\ +\x8c\xdd\x1b\x64\x02\x6b\xd5\x85\xb5\xcf\x66\xad\xd9\xcf\xda\xe3\ +\x6f\x2c\x7d\x67\xac\x75\x1b\x29\xf7\x92\xea\x8e\xa5\x7a\xf7\x52\ +\xad\x73\x0b\xa0\x39\x26\x6e\xac\x18\x33\xd3\x06\x11\x1d\xb7\x02\ +\x1c\xcb\x4a\x1f\xde\xe0\x5e\xd8\xe8\xea\x8b\xa6\xe7\xb1\xd0\xae\ +\x17\xfe\xce\xb8\x65\xf0\xbd\xc9\x8c\x24\xb8\x8d\x6f\xd7\x46\x66\ +\x5e\x09\x8f\x98\x3d\xc8\xfa\xc6\xf1\xe8\x94\xac\xdd\x7b\x8a\xc0\ +\x32\xd7\x7f\xf3\x4e\x4a\xfb\x98\xa4\xc1\x79\x82\x75\x54\xf2\x2a\ +\xd1\x32\x77\x62\xed\x25\x32\x39\x7a\x64\xc2\xa8\x6e\x19\x2d\x57\ +\x35\xee\x55\x51\xd5\xaf\xbc\x8b\xb4\x43\xf7\xdb\x5a\x9c\x77\xa1\ +\xfb\x3b\x8f\xdb\xbb\x94\xff\xec\x67\x24\x4a\xe5\x7f\xe5\x57\x71\ +\xdf\x93\xf2\x57\x16\x26\xdb\x6b\xdd\xf7\xeb\x55\x55\x2e\xd1\x7a\ +\xa3\xaa\xff\x8a\x5e\x95\xe1\x17\xe6\x9e\xce\x6e\x99\x37\x6f\xb5\ +\x5e\x0b\x15\xaa\xe7\xb3\x2f\xac\x6d\x2f\xb8\xfa\x00\x73\xfd\x77\ +\xba\xb4\xb6\xd7\xdf\x6a\xbc\xba\x54\xc6\x5a\xee\xd3\xd8\xa7\xf6\ +\xb7\x2e\x9b\x93\xe7\xf1\xb7\x18\xd1\xcf\x57\xb9\xd7\x0d\xb6\xd4\ +\x21\xdd\xbf\xac\xb3\xb8\x98\xd6\x42\xf7\xcf\xbf\xba\x5c\xaa\xfe\ +\x65\xa1\xe5\x6c\xba\xef\xb7\xd5\x7e\xc7\x7b\x2c\x6e\xed\xbf\xea\ +\xd9\x2b\xb4\xcb\xdf\x56\x6f\x94\xd8\x1b\xb8\xa3\xfb\x24\x7e\xf8\ +\xb0\xea\xd2\x20\x58\xf5\x71\x16\x8c\xe2\x72\x3a\xa1\xfd\xf9\x5b\ +\x3a\x8b\x8c\x41\x9a\x45\x71\xb6\xcc\x92\xe5\xa7\x96\xb5\x98\xf1\ +\xf9\xb5\xf4\x1f\xea\xbd\xb3\xb5\xae\xf2\xb1\x3b\x3f\xbf\x09\xa2\ +\xf4\xe1\xba\x43\x37\x33\xbf\xa5\x29\x4c\x87\x44\x00\x27\x42\x1b\ +\xb5\x99\x5d\xce\x28\x41\x4a\x70\xc1\x56\x77\x71\xac\x73\xa1\x41\ +\xaa\x90\x5a\x5d\x2f\xb3\xce\xb9\xcb\x32\x60\xab\x3f\x0e\x9e\x62\ +\x18\x52\xf9\x63\x29\xe0\xf9\x4d\xfa\x30\xca\x2c\x6b\x8a\xec\x2e\ +\xde\x2c\x19\xa5\xe1\x9d\xbd\xb6\xde\xbf\x9b\x4f\xf6\xe2\xb2\xf4\ +\x0a\x85\x2d\xeb\x0f\x06\xe9\xa3\xbb\x82\x87\x64\x0a\x43\xf5\x17\ +\xd7\xaf\x13\x26\xb7\x3a\xb7\xa0\x58\x5d\xc8\xbe\x0a\xad\x36\x29\ +\x1e\xd7\x60\xb0\x99\x65\x47\x2e\x76\xe4\x4d\x82\xc7\x64\x92\x7c\ +\x8b\xa3\xf5\x3b\x56\x57\x93\xb8\x08\xa2\xa0\x08\xd6\x72\xb1\x4c\ +\x61\x92\x2c\x21\xeb\x2a\x8b\x86\xfd\xff\x7c\xfd\x69\x85\x24\x61\ +\xd8\xff\x6f\x9a\xdd\xae\x81\xc1\x12\x04\x83\xf4\x0e\xba\xbd\x82\ +\x39\xa0\x8b\xc2\xbe\xd5\xab\xa0\xf8\x92\x4c\x60\xb6\xed\xc5\xf9\ +\x7f\x7d\x9c\x8c\x41\x42\x57\x19\x35\x62\xfb\xe2\xd3\xba\xd2\x79\ +\xb5\x59\x3c\xbf\x18\xdf\xf9\xb7\x04\xa2\x70\x92\xd8\x42\xbd\x5f\ +\x8b\x64\x3c\xfe\xd9\x36\x52\x41\xbc\x45\xa5\x49\x31\x8e\x2b\x30\ +\xd8\x5b\xf4\x7e\x75\x87\xd4\x7a\x70\x57\xbd\xe5\xe8\xcb\xa7\xd1\ +\x9a\x2b\x35\x49\x59\x31\x76\x1c\x0c\xe2\xf1\x75\xe7\x17\x9b\xe9\ +\x6d\xe5\x8e\xb2\xf4\x6e\x36\x49\xa3\x78\x51\x7c\xc9\xcd\x51\x15\ +\x19\x46\x8c\x55\x2f\xf7\x19\xad\x87\xbf\xc8\xa5\xba\xca\xd1\x59\ +\x50\xdc\x54\x39\x54\xc1\x82\xe9\x14\xb0\x20\xcd\x7c\x90\xf1\xfb\ +\xa0\xb8\xcb\xe2\xba\xc9\xa8\xbc\x5f\x36\x85\x3e\x59\xae\x81\x18\ +\x87\x61\x9e\x97\xff\x6a\x94\xe5\x5b\x74\xd0\x92\xbd\x47\xa9\xb6\ +\xec\xe7\x79\x56\x42\x3c\x22\x40\xf5\x40\xf7\x68\x97\x6b\x24\xb0\ +\x31\x54\x78\x3e\x46\x94\x33\x22\x45\x17\x32\x35\xd1\x84\x7b\xa1\ +\x07\xb8\xe9\x11\x86\xa8\x16\x8a\x99\x2e\x45\x84\x58\x48\xf5\x00\ +\xe5\x89\xc1\x9c\xf3\xae\x0f\x2a\x6e\x5f\xe1\x67\x9e\x40\x80\xcd\ +\x4a\x76\x7d\x83\x28\x25\x98\x52\xcf\xa7\x88\x69\x69\x28\xa4\x11\ +\x8e\x20\x89\x48\xee\x51\x68\x0f\xda\xd1\x5d\x9f\x52\x84\x8d\xc4\ +\xc2\x96\xc4\x04\x12\x34\x92\x12\x1a\x56\x1e\x81\x4a\xb5\x11\x5a\ +\xda\x34\x80\x6c\x41\xa4\x33\x6d\xec\x01\x86\x18\x6e\xa4\xd6\xb6\ +\x23\x44\x61\xe8\xf8\xa2\xd7\xb6\x49\x0c\xb5\x41\x01\x7b\xe5\x80\ +\xd6\x1a\x3a\x44\x0c\x32\x04\x2b\x42\xba\xc4\xbe\x42\xca\xc1\x36\ +\x78\xbe\x40\x42\x51\x2e\x48\xd7\x20\x18\xbe\xe4\xda\x23\x88\x09\ +\x89\x99\xea\x42\xa3\x4a\x50\xcc\x84\x6d\x48\x0a\x43\xb8\xee\x52\ +\x68\x52\x71\xae\x8d\x07\x26\xc9\xde\xf5\xaa\xf9\x9c\x63\xc4\x10\ +\x20\x63\x08\xea\x50\x5a\x75\x39\x30\x86\x1b\xdb\x00\xa4\x01\xc8\ +\x29\x21\x21\x8d\x2b\xca\x04\xf7\xbe\xd5\x27\x76\x6e\x96\x57\x2f\ +\x55\x22\xf9\x79\x08\xea\xb0\xfa\x5b\x06\xf6\xa1\x62\x9c\xf3\x22\ +\x4b\x6f\x63\x90\x82\xe9\x86\xb2\x9c\x5f\xb8\x1c\xa2\x05\x93\x6e\ +\x60\xb8\xac\xcb\xed\xae\xb2\x02\x96\xfd\x19\x45\xeb\x17\x8f\x2b\ +\xf8\x1d\x9e\x74\x57\x23\xa5\x24\x81\x96\xdb\x89\x16\x35\xdf\x91\ +\x6c\xcd\xe5\x69\xf1\x0a\xaf\x5b\x9e\xd6\x7f\x39\xc3\x3e\xce\x0d\ +\x5d\x1f\x3a\x04\x4d\x11\xc2\x96\x64\xbe\x75\x70\x40\xa8\xfa\x83\ +\xbb\xa2\xa8\xa6\xfd\x2f\x4d\xa6\x7d\x40\xf3\x38\x5b\xa6\x96\x0f\ +\x63\x30\x59\x45\x9f\x2f\xd3\x36\x5b\xf5\xa3\x00\x7c\x08\xfb\xf7\ +\x44\x36\xe5\xf9\xaa\x37\xda\x83\xaa\x82\xef\x43\xd5\x8d\x37\x71\ +\xf3\x22\xc8\x5c\x4c\xa9\xff\xc5\x90\x92\x45\x60\x9b\x7e\xf8\xb8\ +\x1d\x11\x7d\xda\xe4\x59\xf9\x98\xdd\x8d\x4b\x35\xfc\x06\x8e\xd4\ +\x01\x2e\x82\x1c\xdb\x8f\x78\x01\x6f\x3e\x4f\x82\xec\x36\xce\xe6\ +\xbf\xdf\x27\x79\x32\x48\xc6\x96\xbc\xfc\x75\x1c\x7f\x8e\x92\x7c\ +\x06\x76\xaa\x9f\x4c\xed\x74\x7c\x4e\xef\xe3\x6c\x38\x4e\x1f\x56\ +\xf9\xf1\x34\x80\x1f\xfe\x20\x08\x6f\xad\x65\x9b\x46\xfd\x20\x04\ +\x9f\xe8\x6e\x1c\x14\xb1\x53\xc1\x05\xf8\xe0\x7e\xfd\x3d\xf4\x0a\ +\x6b\xf3\x24\xb2\x18\x21\xdc\xb9\x0b\x97\x9d\x12\x4e\x28\xd9\x51\ +\x43\xe9\xec\x5b\xa5\x25\x12\x4b\x37\x49\x46\xae\x3b\x06\xa0\x81\ +\x63\x62\xf8\x0e\x12\x5a\x46\x1d\x14\x54\x95\x19\x37\x49\x90\x8d\ +\xa0\x1e\x8b\x42\x42\x10\x7b\xfd\xdb\x4e\x32\x6a\x3d\x5d\xa6\x18\ +\xb8\x77\xb8\x5e\xd9\x0a\x4b\x87\xc0\x2f\x3b\x76\x60\xd2\x30\x18\ +\xe7\xb1\x9b\xaa\x64\xb0\xa5\xc1\x3b\xf2\x03\x70\xe9\x16\xce\x1c\ +\xde\x44\xd1\x7f\x02\x6e\x49\xcc\x95\xc4\xaa\xcb\xa0\xd7\x18\x00\ +\x4e\x59\xb0\x54\xc2\x48\x4a\xbb\x0c\x58\xc2\x25\x27\x00\x26\xd2\ +\x00\x58\x52\xd3\xe5\x18\xcc\x9f\x32\x9c\x7b\x3e\x07\xdc\xd2\x82\ +\x61\xd9\x15\x16\x89\x94\x11\x80\x13\xda\x86\x3f\xc0\x69\x61\x0b\ +\x43\x20\xc5\x4b\x10\xc5\x48\xdb\xbb\x0c\xa0\x15\x65\x41\x54\x49\ +\x8b\x28\xe0\x96\x63\x70\x09\x78\x97\x42\x33\xca\x50\xcc\x4b\x98\ +\xc1\x1c\x5b\x20\x23\x40\x09\x00\xc5\x2c\x04\x4b\x25\x01\xe1\xb9\ +\xbd\xc8\x87\x63\xc6\x19\xf5\x34\xa0\x1b\x96\x00\xdb\x5d\x98\x12\ +\x6e\x21\x7d\x13\x8f\x56\x1c\x28\x96\x51\x9b\x1f\x82\x92\xc5\x59\ +\xe9\x15\x43\x3d\x8a\xdb\xcb\x9e\x9b\x15\x29\x03\x13\xb0\x1f\x58\ +\x8b\xfa\x9c\x16\x8e\x6b\x88\x24\x58\x1a\x25\x15\x5f\xde\x20\xb1\ +\x7c\x84\x11\x41\x0d\x8a\xb0\x2e\x05\x67\xc8\xf2\xfd\xd3\x7e\xb3\ +\x7a\x64\x74\x21\xfa\x5d\xa3\x8b\xbf\x43\x1b\x2f\xf8\x72\xc1\x97\ +\x37\x81\x2f\xc0\x25\xaa\x94\x12\xe0\x86\x5a\xd7\x50\x81\x87\x4a\ +\xcf\x8d\x30\xfe\x7b\xc7\x98\x0b\xc8\xd4\x24\xfd\x02\x32\x6f\x0c\ +\x64\x40\x04\x39\x85\x71\x76\x25\x30\x06\xe6\x9d\x91\x4f\xae\x58\ +\x6a\xf1\x4b\xf9\xe3\xca\x2e\xe7\x7d\xf9\xf0\x7f\xf3\x2c\xbf\x8c\ +\ \x00\x00\x07\x50\ \x00\ \x00\x36\x1d\x78\x9c\xed\x5a\x5b\x6f\xe3\x36\x16\x7e\xcf\xaf\xd0\ @@ -54351,6 +54574,11 @@ qt_resource_name = "\ \x00\x44\ \x00\x72\x00\x61\x00\x66\x00\x74\x00\x5f\x00\x42\x00\x53\x00\x70\x00\x6c\x00\x69\x00\x6e\x00\x65\x00\x2e\x00\x73\x00\x76\x00\x67\ \ +\x00\x13\ +\x0b\x82\xa0\xa7\ +\x00\x44\ +\x00\x72\x00\x61\x00\x66\x00\x74\x00\x5f\x00\x50\x00\x61\x00\x74\x00\x68\x00\x41\x00\x72\x00\x72\x00\x61\x00\x79\x00\x2e\x00\x73\ +\x00\x76\x00\x67\ \x00\x0e\ \x07\x2c\x24\xc7\ \x00\x53\ @@ -54472,8 +54700,8 @@ qt_resource_name = "\ qt_resource_struct = "\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x01\ -\x00\x00\x00\x10\x00\x02\x00\x00\x00\x03\x00\x00\x00\x5c\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x3b\x00\x00\x00\x21\ +\x00\x00\x00\x10\x00\x02\x00\x00\x00\x03\x00\x00\x00\x5d\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x3c\x00\x00\x00\x21\ \x00\x00\x00\x38\x00\x02\x00\x00\x00\x05\x00\x00\x00\x1c\ \x00\x00\x00\x1a\x00\x02\x00\x00\x00\x17\x00\x00\x00\x05\ \x00\x00\x01\xb4\x00\x01\x00\x00\x00\x01\x00\x04\x13\x04\ @@ -54506,63 +54734,64 @@ qt_resource_struct = "\ \x00\x00\x00\x7c\x00\x01\x00\x00\x00\x01\x00\x00\x0f\x23\ \x00\x00\x06\xfa\x00\x01\x00\x00\x00\x01\x00\x0b\x0c\xf5\ \x00\x00\x04\xa8\x00\x00\x00\x00\x00\x01\x00\x0a\x69\xde\ -\x00\x00\x09\x8e\x00\x01\x00\x00\x00\x01\x00\x0b\xf0\x5d\ -\x00\x00\x0c\x7e\x00\x01\x00\x00\x00\x01\x00\x0c\xed\x27\ +\x00\x00\x09\xba\x00\x01\x00\x00\x00\x01\x00\x0b\xfe\x22\ +\x00\x00\x0c\xaa\x00\x01\x00\x00\x00\x01\x00\x0c\xfa\xec\ \x00\x00\x05\xb2\x00\x01\x00\x00\x00\x01\x00\x0a\xa9\x89\ \x00\x00\x07\x70\x00\x00\x00\x00\x00\x01\x00\x0b\x36\xb1\ \x00\x00\x08\x84\x00\x01\x00\x00\x00\x01\x00\x0b\x9f\x5f\ -\x00\x00\x0b\x80\x00\x01\x00\x00\x00\x01\x00\x0c\xa3\x25\ +\x00\x00\x0b\xac\x00\x01\x00\x00\x00\x01\x00\x0c\xb0\xea\ \x00\x00\x07\xe4\x00\x00\x00\x00\x00\x01\x00\x0b\x60\x80\ -\x00\x00\x0a\x28\x00\x01\x00\x00\x00\x01\x00\x0c\x30\xfe\ -\x00\x00\x0c\xce\x00\x01\x00\x00\x00\x01\x00\x0d\x09\x4b\ +\x00\x00\x0a\x54\x00\x01\x00\x00\x00\x01\x00\x0c\x3e\xc3\ +\x00\x00\x0c\xfa\x00\x01\x00\x00\x00\x01\x00\x0d\x17\x10\ \x00\x00\x04\xee\x00\x01\x00\x00\x00\x01\x00\x0a\x83\x00\ -\x00\x00\x09\x36\x00\x00\x00\x00\x00\x01\x00\x0b\xce\x03\ +\x00\x00\x09\x62\x00\x00\x00\x00\x00\x01\x00\x0b\xdb\xc8\ \x00\x00\x08\xaa\x00\x01\x00\x00\x00\x01\x00\x0b\xa5\x23\ \x00\x00\x07\x4a\x00\x00\x00\x00\x00\x01\x00\x0b\x24\x1b\ \x00\x00\x07\x1c\x00\x01\x00\x00\x00\x01\x00\x0b\x17\xa9\ -\x00\x00\x0c\x20\x00\x00\x00\x00\x00\x01\x00\x0c\xd1\x89\ +\x00\x00\x0c\x4c\x00\x00\x00\x00\x00\x01\x00\x0c\xdf\x4e\ \x00\x00\x05\x12\x00\x01\x00\x00\x00\x01\x00\x0a\x88\x7f\ \x00\x00\x07\xb8\x00\x01\x00\x00\x00\x01\x00\x0b\x4f\x76\ \x00\x00\x04\xca\x00\x01\x00\x00\x00\x01\x00\x0a\x78\x94\ -\x00\x00\x0b\xa8\x00\x00\x00\x00\x00\x01\x00\x0c\xae\x94\ +\x00\x00\x0b\xd4\x00\x00\x00\x00\x00\x01\x00\x0c\xbc\x59\ \x00\x00\x04\x28\x00\x01\x00\x00\x00\x01\x00\x0a\x44\x4c\ \x00\x00\x06\x02\x00\x01\x00\x00\x00\x01\x00\x0a\xc4\xa8\ -\x00\x00\x0b\x38\x00\x01\x00\x00\x00\x01\x00\x0c\x8b\xf6\ -\x00\x00\x0b\x5a\x00\x01\x00\x00\x00\x01\x00\x0c\x99\x91\ +\x00\x00\x0b\x64\x00\x01\x00\x00\x00\x01\x00\x0c\x99\xbb\ +\x00\x00\x0b\x86\x00\x01\x00\x00\x00\x01\x00\x0c\xa7\x56\ \x00\x00\x05\xe0\x00\x00\x00\x00\x00\x01\x00\x0a\xb2\x8f\ \x00\x00\x03\xf6\x00\x01\x00\x00\x00\x01\x00\x0a\x3c\x93\ -\x00\x00\x09\x14\x00\x01\x00\x00\x00\x01\x00\x0b\xc6\xaf\ -\x00\x00\x0a\x82\x00\x00\x00\x00\x00\x01\x00\x0c\x41\x46\ +\x00\x00\x09\x40\x00\x01\x00\x00\x00\x01\x00\x0b\xd4\x74\ +\x00\x00\x0a\xae\x00\x00\x00\x00\x00\x01\x00\x0c\x4f\x0b\ \x00\x00\x06\x56\x00\x01\x00\x00\x00\x01\x00\x0a\xd6\x18\ -\x00\x00\x0a\xa6\x00\x00\x00\x00\x00\x01\x00\x0c\x57\xf9\ +\x00\x00\x0a\xd2\x00\x00\x00\x00\x00\x01\x00\x0c\x65\xbe\ \x00\x00\x08\x3e\x00\x00\x00\x00\x00\x01\x00\x0b\x78\x33\ \x00\x00\x05\x64\x00\x01\x00\x00\x00\x01\x00\x0a\x98\x7f\ -\x00\x00\x0c\x9e\x00\x00\x00\x00\x00\x01\x00\x0c\xf7\xd5\ +\x00\x00\x0c\xca\x00\x00\x00\x00\x00\x01\x00\x0d\x05\x9a\ \x00\x00\x06\xb0\x00\x00\x00\x00\x00\x01\x00\x0a\xed\x57\ \x00\x00\x04\x54\x00\x00\x00\x00\x00\x01\x00\x0a\x4c\x53\ -\x00\x00\x0c\xfe\x00\x00\x00\x00\x00\x01\x00\x0d\x15\x24\ -\x00\x00\x0a\xee\x00\x00\x00\x00\x00\x01\x00\x0c\x75\x80\ +\x00\x00\x0d\x2a\x00\x00\x00\x00\x00\x01\x00\x0d\x22\xe9\ +\x00\x00\x0b\x1a\x00\x00\x00\x00\x00\x01\x00\x0c\x83\x45\ \x00\x00\x04\x78\x00\x01\x00\x00\x00\x01\x00\x0a\x61\x73\ -\x00\x00\x0b\x16\x00\x01\x00\x00\x00\x01\x00\x0c\x84\xa7\ -\x00\x00\x09\xb0\x00\x01\x00\x00\x00\x01\x00\x0b\xf9\x06\ -\x00\x00\x0b\xce\x00\x01\x00\x00\x00\x01\x00\x0c\xb7\x21\ +\x00\x00\x09\x14\x00\x01\x00\x00\x00\x01\x00\x0b\xc6\xaf\ +\x00\x00\x0b\x42\x00\x01\x00\x00\x00\x01\x00\x0c\x92\x6c\ +\x00\x00\x09\xdc\x00\x01\x00\x00\x00\x01\x00\x0c\x06\xcb\ +\x00\x00\x0b\xfa\x00\x01\x00\x00\x00\x01\x00\x0c\xc4\xe6\ \x00\x00\x06\xd8\x00\x01\x00\x00\x00\x01\x00\x0a\xff\x96\ \x00\x00\x08\x16\x00\x01\x00\x00\x00\x01\x00\x0b\x6e\x82\ -\x00\x00\x0a\x06\x00\x00\x00\x00\x00\x01\x00\x0c\x1c\x6d\ +\x00\x00\x0a\x32\x00\x00\x00\x00\x00\x01\x00\x0c\x2a\x32\ \x00\x00\x05\x88\x00\x01\x00\x00\x00\x01\x00\x0a\x9f\x48\ \x00\x00\x08\x64\x00\x00\x00\x00\x00\x01\x00\x0b\x89\xeb\ \x00\x00\x06\x36\x00\x01\x00\x00\x00\x01\x00\x0a\xd0\x99\ -\x00\x00\x0a\x52\x00\x01\x00\x00\x00\x01\x00\x0c\x37\x73\ +\x00\x00\x0a\x7e\x00\x01\x00\x00\x00\x01\x00\x0c\x45\x38\ \x00\x00\x08\xec\x00\x01\x00\x00\x00\x01\x00\x0b\xbb\x3d\ -\x00\x00\x09\x66\x00\x01\x00\x00\x00\x01\x00\x0b\xe0\x87\ -\x00\x00\x0c\x54\x00\x01\x00\x00\x00\x01\x00\x0c\xe2\xa5\ -\x00\x00\x0a\xca\x00\x01\x00\x00\x00\x01\x00\x0c\x6a\xd0\ +\x00\x00\x09\x92\x00\x01\x00\x00\x00\x01\x00\x0b\xee\x4c\ +\x00\x00\x0c\x80\x00\x01\x00\x00\x00\x01\x00\x0c\xf0\x6a\ +\x00\x00\x0a\xf6\x00\x01\x00\x00\x00\x01\x00\x0c\x78\x95\ \x00\x00\x05\x34\x00\x01\x00\x00\x00\x01\x00\x0a\x90\x5d\ -\x00\x00\x0b\xf4\x00\x01\x00\x00\x00\x01\x00\x0c\xc1\xe6\ +\x00\x00\x0c\x20\x00\x01\x00\x00\x00\x01\x00\x0c\xcf\xab\ \x00\x00\x08\xcc\x00\x00\x00\x00\x00\x01\x00\x0b\xab\x6b\ \x00\x00\x06\x84\x00\x00\x00\x00\x00\x01\x00\x0a\xdd\xfd\ \x00\x00\x07\x98\x00\x01\x00\x00\x00\x01\x00\x0b\x46\x02\ -\x00\x00\x09\xd4\x00\x00\x00\x00\x00\x01\x00\x0c\x00\x57\ +\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x01\x00\x0c\x0e\x1c\ \x00\x00\x03\xa2\x00\x01\x00\x00\x00\x01\x00\x0a\x27\xd8\ \x00\x00\x03\xce\x00\x01\x00\x00\x00\x01\x00\x0a\x32\x53\ \x00\x00\x03\x76\x00\x01\x00\x00\x00\x01\x00\x0a\x1c\x55\ diff --git a/src/Mod/Draft/InitGui.py b/src/Mod/Draft/InitGui.py index 8dfabdf95b..b8dc22e75c 100644 --- a/src/Mod/Draft/InitGui.py +++ b/src/Mod/Draft/InitGui.py @@ -112,7 +112,7 @@ class DraftWorkbench (Workbench): "Draft_Trimex", "Draft_Upgrade", "Draft_Downgrade", "Draft_Scale", "Draft_Drawing","Draft_Edit","Draft_WireToBSpline","Draft_AddPoint", "Draft_DelPoint","Draft_Shape2DView","Draft_Draft2Sketch","Draft_Array", - "Draft_Clone"] + "Draft_Clone","Draft_PathArray"] self.treecmdList = ["Draft_ApplyStyle","Draft_ToggleDisplayMode","Draft_AddToGroup", "Draft_SelectGroup","Draft_SelectPlane", "Draft_ShowSnapBar","Draft_ToggleGrid"] diff --git a/src/Mod/Draft/Resources/Draft.qrc b/src/Mod/Draft/Resources/Draft.qrc index 802231c419..88425dd9c4 100644 --- a/src/Mod/Draft/Resources/Draft.qrc +++ b/src/Mod/Draft/Resources/Draft.qrc @@ -40,6 +40,7 @@ icons/Draft_Dot.svg icons/Draft_Point.svg icons/Draft_Snap.svg + icons/Draft_PathArray.svg icons/Snap_Lock.svg icons/Snap_Endpoint.svg icons/Snap_Midpoint.svg diff --git a/src/Mod/Draft/Resources/icons/Draft_PathArray.svg b/src/Mod/Draft/Resources/icons/Draft_PathArray.svg new file mode 100644 index 0000000000..8646c78672 --- /dev/null +++ b/src/Mod/Draft/Resources/icons/Draft_PathArray.svg @@ -0,0 +1,904 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/Test/testPathArray.py b/src/Mod/Test/testPathArray.py new file mode 100644 index 0000000000..3c9a6f934a --- /dev/null +++ b/src/Mod/Test/testPathArray.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# tester for Draft makePathArray - shapes on a path - without subelements (see testPathArraySel.py) +# Usage: in FC gui, select a "shape" document object (sphere, box, etc) (!!select in +# tree, not document view!!), then a "wire" document object (Wire, Circle, Rectangle, +# DWire, etc) then run this macro. + +import FreeCAD +import Part +import Draft + +print "testPathArray started" +items = 4 # count +centretrans = FreeCAD.Vector(0,0,0) # no translation +#centretrans = FreeCAD.Vector(-5,-5,0) # translation +orient = True # align to curve +#orient = False # don't align to curve + +s = FreeCADGui.Selection.getSelection() +print "testPathArray: Objects in selection: ", len(s) +print "First object in selection is a: ", s[0].Shape.ShapeType +print "Second object in selection is a: ", s[1].Shape.ShapeType +base = s[0] +path = s[1] +pathsubs = [] + +#o = Draft.makePathArray(base,path,items) # test with defaults +o = Draft.makePathArray(base,path,items,centretrans,orient,pathsubs) # test with non-defaults + +print "testPathArray ended" + + + diff --git a/src/Mod/Test/testPathArraySel.py b/src/Mod/Test/testPathArraySel.py new file mode 100644 index 0000000000..e337dc1f3e --- /dev/null +++ b/src/Mod/Test/testPathArraySel.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# tester for Draft makePathArray - shapes on a path - with selected subobjects +# Usage: in FC gui, select a "shape" document object (sphere, box, etc) (!select in +# tree, not document view!!), then select edges from the "wire" object. + +import FreeCAD +import Part +import Draft + +print "testPathArray started" +items = 4 # count +centretrans = FreeCAD.Vector(0,0,0) # translation +#centretrans = FreeCAD.Vector(10,10,10) # translation +orient = True # align to curve +#orient = False # don't align to curve + +# use this to test w/ path subelements +s = FreeCADGui.Selection.getSelectionEx() +for o in s: + print "Selection: ", o.ObjectName + for name in o.SubElementNames: + print " name: ", name + for obj in o.SubObjects: + print " object: ",obj + +print "testPathArray: Objects in selection: ", len(s) +base = s[0].Object +path = s[1].Object +pathsubs = list(s[1].SubElementNames) +print "testPathArray: pathsubs: ", pathsubs + +#o = Draft.makePathArray(base,path,items) # test with defaults +o = Draft.makePathArray(base,path,items,centretrans,orient,pathsubs) # test w/o orienting shapes + +print "testPathArray ended" + + +