# -*- coding: utf-8 -*- #*************************************************************************** #* * #* Copyright (c) 2016 Juan Vanyo Cerda <juavacer@inf.upv.es> * #* * #* This program is free software; you can redistribute it and/or modify * #* it under the terms of the GNU Lesser General Public License (LGPL) * #* as published by the Free Software Foundation; either version 2 of * #* the License, or (at your option) any later version. * #* for detail see the LICENCE text file. * #* * #* This program is distributed in the hope that it will be useful, * #* but WITHOUT ANY WARRANTY; without even the implied warranty of * #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * #* GNU Library General Public License for more details. * #* * #* You should have received a copy of the GNU Library General Public * #* License along with this program; if not, write to the Free Software * #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * #* USA * #* * #*************************************************************************** __title__="FreeCAD GDT Workbench" __author__ = "Juan Vanyo Cerda <juavacer@inf.upv.es>" __url__ = "http://www.freecadweb.org" # Description of tool import numpy import FreeCAD as App import FreeCAD, math, sys, os, DraftVecUtils, Draft_rc from math import pi from FreeCAD import Vector import traceback import Draft import Part from pivy import coin import FreeCADGui, WorkingPlane if FreeCAD.GuiUp: gui = True else: FreeCAD.Console.PrintMessage("FreeCAD Gui not present. GDT module will have some features disabled.") gui = True try: from PySide import QtCore,QtGui,QtSvg except ImportError: FreeCAD.Console.PrintMessage("Error: Python-pyside package must be installed on your system to use the Geometric Dimensioning & Tolerancing module.") __dir__ = os.path.dirname(__file__) iconPath = os.path.join( __dir__, 'Gui','Resources', 'icons' ) path_dd_resources = os.path.join( os.path.dirname(__file__), 'Gui', 'Resources', 'dd_resources.rcc') resourcesLoaded = QtCore.QResource.registerResource(path_dd_resources) assert resourcesLoaded checkBoxState = True auxDictionaryDS=[] for i in range(1,100): auxDictionaryDS.append('DS'+str(i)) dictionaryAnnotation=[] for i in range(1,100): dictionaryAnnotation.append('Annotation'+str(i)) #--------------------------------------------------------------------------- # Param functions #--------------------------------------------------------------------------- def getParamType(param): if param in ["lineWidth"]: return "int" elif param in ["textFamily"]: return "string" elif param in ["textSize","lineScale"]: return "float" elif param in ["alwaysShowGrid","showUnit"]: return "bool" elif param in ["textColor","lineColor"]: return "unsigned" else: return None def getParam(param,default=None): "getParam(parameterName): returns a GDT parameter value from the current config" p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/GDT") t = getParamType(param) if t == "int": if default == None: default = 0 return p.GetInt(param,default) elif t == "string": if default == None: default = "" return p.GetString(param,default) elif t == "float": if default == None: default = 1 return p.GetFloat(param,default) elif t == "bool": if default == None: default = False return p.GetBool(param,default) elif t == "unsigned": if default == None: default = 0 return p.GetUnsigned(param,default) else: return None def setParam(param,value): "setParam(parameterName,value): sets a GDT parameter with the given value" p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/GDT") 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) #--------------------------------------------------------------------------- # General functions #--------------------------------------------------------------------------- def stringencodecoin(ustr): """stringencodecoin(str): Encodes a unicode object to be used as a string in coin""" try: from pivy import coin coin4 = coin.COIN_MAJOR_VERSION >= 4 except (ImportError, AttributeError): coin4 = False if coin4: return ustr.encode('utf-8') else: return ustr.encode('latin1') def stringplusminus(): return ' ± ' if coin.COIN_MAJOR_VERSION >= 4 else ' +- ' def getType(obj): "getType(object): returns the GDT type of the given object" if not obj: return None if "Proxy" in obj.PropertiesList: if hasattr(obj.Proxy,"Type"): return obj.Proxy.Type return "Unknown" def getObjectsOfType(typeList): "getObjectsOfType(string): returns a list of objects of the given type" listObjectsOfType = [] objs = FreeCAD.ActiveDocument.Objects if not isinstance(typeList,list): typeList = [typeList] for obj in objs: for typ in typeList: if typ == getType(obj): listObjectsOfType.append(obj) return listObjectsOfType def getAllAnnotationPlaneObjects(): "getAllAnnotationPlaneObjects(): returns a list of annotation plane objects" return getObjectsOfType("AnnotationPlane") def getAllDatumFeatureObjects(): "getAllDatumFeatureObjects(): returns a list of datum feature objects" return getObjectsOfType("DatumFeature") def getAllDatumSystemObjects(): "getAllDatumSystemObjects(): returns a list of datum system objects" return getObjectsOfType("DatumSystem") def getAllGeometricToleranceObjects(): "getAllGeometricToleranceObjects(): returns a list of geometric tolerance objects" return getObjectsOfType("GeometricTolerance") def getAllGDTObjects(): "getAllGDTObjects(): returns a list of GDT objects" return getObjectsOfType(["AnnotationPlane","DatumFeature","DatumSystem","GeometricTolerance"]) def getAllAnnotationObjects(): "getAllAnnotationObjects(): returns a list of annotation objects" return getObjectsOfType("Annotation") def getRGB(param): color = QtGui.QColor(getParam(param,16753920)>>8) r = float(color.red()/255.0) g = float(color.green()/255.0) b = float(color.blue()/255.0) col = (r,g,b,0.0) return col def getRGBText(): return getRGB("textColor") def getTextFamily(): return getParam("textFamily","") def getTextSize(): return getParam("textSize",2.2) def getLineWidth(): return getParam("lineWidth",2) def getRGBLine(): return getRGB("lineColor") def hideGrid(): if hasattr(FreeCADGui,"Snapper") and getParam("alwaysShowGrid") == False: if FreeCADGui.Snapper.grid: if FreeCADGui.Snapper.grid.Visible: FreeCADGui.Snapper.grid.off() FreeCADGui.Snapper.forceGridOff=True def showGrid(): if hasattr(FreeCADGui,"Snapper"): if FreeCADGui.Snapper.grid: if FreeCADGui.Snapper.grid.Visible == False: FreeCADGui.Snapper.grid.reset() FreeCADGui.Snapper.grid.on() FreeCADGui.Snapper.forceGridOff=False else: FreeCADGui.Snapper.show() def getSelection(): "getSelection(): returns the current FreeCAD selection" if gui: 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(obj): "select(object): deselects everything and selects only the working faces of the passed object" if gui: FreeCADGui.Selection.clearSelection() for i in range(len(obj.faces)): FreeCADGui.Selection.addSelection(obj.faces[i][0],obj.faces[i][1]) def makeContainerOfData(): "" faces = [] for i in range(len(getSelectionEx())): for j in range(len(getSelectionEx()[i].SubElementNames)): faces.append((getSelectionEx()[i].Object, getSelectionEx()[i].SubElementNames[j])) faces.sort() container = ContainerOfData(faces) return container def getAnnotationObj(obj): List = getAllAnnotationObjects() for l in List: if l.faces == obj.faces: return l return None def getAnnotationWithDF(obj): List = getAllAnnotationObjects() for l in List: if l.DF == obj: return l return None def getAnnotationWithGT(obj): List = getAllAnnotationObjects() for l in List: for gt in l.GT: if gt == obj: return l return None def getPointsToPlot(obj): points = [] segments = [] if obj.GT <> [] or obj.DF <> None: X = FreeCAD.Vector(1.0,0.0,0.0) Y = FreeCAD.Vector(0.0,1.0,0.0) Direction = X if abs(X.dot(obj.AP.Direction)) < 0.8 else Y Vertical = obj.AP.Direction.cross(Direction).normalize() Horizontal = Vertical.cross(obj.AP.Direction).normalize() point = obj.selectedPoint d = point.distanceToPlane(obj.p1, obj.Direction) if obj.circumferenceBool: P3 = point + obj.Direction * (-d) d2 = (P3 - obj.p1) * Vertical P2 = obj.p1 + Vertical * (d2*3/4) else: P2 = obj.p1 + obj.Direction * (d*3/4) P3 = point points = [obj.p1, P2, P3] segments = [0,1,2] existGT = True if obj.GT <> []: points, segments = getPointsToPlotGT(obj, points, segments, Vertical, Horizontal) else: existGT = False if obj.DF <> None: points, segments = getPointsToPlotDF(obj, existGT, points, segments, Vertical, Horizontal) segments = segments + [] return points, segments def getPointsToPlotGT(obj, points, segments, Vertical, Horizontal): newPoints = points newSegments = segments if obj.ViewObject.LineScale > 0: sizeOfLine = obj.ViewObject.LineScale else: sizeOfLine = 1.0 for i in range(len(obj.GT)): d = len(newPoints) if points[2].x < points[0].x: P0 = newPoints[-1] + Vertical * (sizeOfLine) if i == 0 else FreeCAD.Vector(newPoints[-2]) else: P0 = newPoints[-1] + Vertical * (sizeOfLine) if i == 0 else FreeCAD.Vector(newPoints[-1]) P1 = P0 + Vertical * (-sizeOfLine*2) P2 = P0 + Horizontal * (sizeOfLine*2) P3 = P1 + Horizontal * (sizeOfLine*2) lengthToleranceValue = len(stringencodecoin(displayExternal(obj.GT[i].ToleranceValue, obj.ViewObject.Decimals, 'Length', obj.ViewObject.ShowUnit))) if obj.GT[i].FeatureControlFrameIcon <> '': lengthToleranceValue += 2 if obj.GT[i].Circumference: lengthToleranceValue += 2 P4 = P2 + Horizontal * (sizeOfLine*lengthToleranceValue) P5 = P3 + Horizontal * (sizeOfLine*lengthToleranceValue) if obj.GT[i].DS == None or obj.GT[i].DS.Primary == None: newPoints = newPoints + [P0, P2, P3, P4, P5, P1] newSegments = newSegments + [-1, 0+d, 3+d, 4+d, 5+d, 0+d, -1, 1+d, 2+d] if points[2].x < points[0].x: displacement = newPoints[-3].x - newPoints[-6].x for i in range(len(newPoints)-6, len(newPoints)): newPoints[i].x-=displacement else: P6 = P4 + Horizontal * (sizeOfLine*2) P7 = P5 + Horizontal * (sizeOfLine*2) if obj.GT[i].DS.Secondary <> None: P8 = P6 + Horizontal * (sizeOfLine*2) P9 = P7 + Horizontal * (sizeOfLine*2) if obj.GT[i].DS.Tertiary <> None: P10 = P8 + Horizontal * (sizeOfLine*2) P11 = P9 + Horizontal * (sizeOfLine*2) newPoints = newPoints + [P0, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P1] newSegments = newSegments + [-1, 0+d, 9+d, 10+d, 11+d, 0+d, -1, 1+d, 2+d, -1, 3+d, 4+d, -1, 5+d, 6+d, -1, 7+d, 8+d] if points[2].x < points[0].x: displacement = newPoints[-3].x - newPoints[-12].x for i in range(len(newPoints)-12, len(newPoints)): newPoints[i].x-=displacement else: newPoints = newPoints + [P0, P2, P3, P4, P5, P6, P7, P8, P9, P1] newSegments = newSegments + [-1, 0+d, 7+d, 8+d, 9+d, 0+d, -1, 1+d, 2+d, -1, 3+d, 4+d, -1, 5+d, 6+d] if points[2].x < points[0].x: displacement = newPoints[-3].x - newPoints[-10].x for i in range(len(newPoints)-10, len(newPoints)): newPoints[i].x-=displacement else: newPoints = newPoints + [P0, P2, P3, P4, P5, P6, P7, P1] newSegments = newSegments + [-1, 0+d, 5+d, 6+d, 7+d, 0+d, -1, 1+d, 2+d, -1, 3+d, 4+d] if points[2].x < points[0].x: displacement = newPoints[-3].x - newPoints[-8].x for i in range(len(newPoints)-8, len(newPoints)): newPoints[i].x-=displacement return newPoints, newSegments def getPointsToPlotDF(obj, existGT, points, segments, Vertical, Horizontal): d = len(points) newPoints = points newSegments = segments if obj.ViewObject.LineScale > 0: sizeOfLine = obj.ViewObject.LineScale else: sizeOfLine = 1.0 if not existGT: P0 = points[-1] + Vertical * (sizeOfLine) P1 = P0 + Horizontal * (sizeOfLine*2) P2 = P1 + Vertical * (-sizeOfLine*2) P3 = P2 + Horizontal * (-sizeOfLine*2) newPoints = newPoints + [P0, P1, P2, P3] newSegments = newSegments + [-1, 0+d, 1+d, 2+d, 3+d, 0+d] if points[2].x < points[0].x: displacement = newPoints[-2].x - newPoints[-1].x for i in range(len(newPoints)-4, len(newPoints)): newPoints[i].x-=displacement d=len(newPoints) P0 = newPoints[-1] + Horizontal * (sizeOfLine/2) P1 = P0 + Horizontal * (sizeOfLine) h = math.sqrt(sizeOfLine*sizeOfLine+(sizeOfLine/2)*(sizeOfLine/2)) PAux = newPoints[-1] + Horizontal * (sizeOfLine) P2 = PAux + Vertical * (-h) P3 = PAux + Vertical * (-sizeOfLine*3) P4 = P3 + Horizontal * (sizeOfLine) P5 = P4 + Vertical * (-sizeOfLine*2) P6 = P5 + Horizontal * (-sizeOfLine*2) P7 = P6 + Vertical * (sizeOfLine*2) newPoints = newPoints + [P0, P1, P2, P3, P4, P5, P6, P7] newSegments = newSegments + [-1, 0+d, 2+d, -1, 1+d, 2+d, 3+d, 4+d, 5+d, 6+d, 7+d, 3+d] return newPoints, newSegments def plotStrings(self, fp, points): import DraftGeomUtils if fp.ViewObject.LineScale > 0: sizeOfLine = fp.ViewObject.LineScale else: sizeOfLine = 1.0 X = FreeCAD.Vector(1.0,0.0,0.0) Y = FreeCAD.Vector(0.0,1.0,0.0) Direction = X if abs(X.dot(fp.AP.Direction)) < 0.8 else Y Vertical = fp.AP.Direction.cross(Direction).normalize() Horizontal = Vertical.cross(fp.AP.Direction).normalize() index = 0 indexIcon = 0 displacement = 0 if fp.GT <> []: for i in range(len(fp.GT)): distance = 0 # posToleranceValue v = (points[7+displacement] - points[5+displacement]) if v.x <> 0: distance = (v.x)/2 elif v.y <> 0: distance = (v.y)/2 else: distance = (v.z)/2 if fp.GT[i].FeatureControlFrameIcon <> '': distance -= sizeOfLine if fp.GT[i].Circumference: distance += sizeOfLine centerPoint = points[5+displacement] + Horizontal * (distance) posToleranceValue = centerPoint + Vertical * (sizeOfLine/2) # posCharacteristic auxPoint = points[3+displacement] + Vertical * (-sizeOfLine*2) self.points[indexIcon].point.setValues([[auxPoint.x,auxPoint.y,auxPoint.z],[points[5+displacement].x,points[5+displacement].y,points[5+displacement].z],[points[4+displacement].x,points[4+displacement].y,points[4+displacement].z],[points[3+displacement].x,points[3+displacement].y,points[3+displacement].z]]) self.face[indexIcon].numVertices = 4 s = 1/(sizeOfLine*2) dS = FreeCAD.Vector(Horizontal) * s dT = FreeCAD.Vector(Vertical) * s self.svgPos[indexIcon].directionS.setValue(dS.x, dS.y, dS.z) self.svgPos[indexIcon].directionT.setValue(dT.x, dT.y, dT.z) displacementH = ((Horizontal*auxPoint)%(sizeOfLine*2))/(sizeOfLine*2) displacementV = ((Vertical*auxPoint)%(sizeOfLine*2))/(sizeOfLine*2) self.textureTransform[indexIcon].translation.setValue(-displacementH,-displacementV) filename = fp.GT[i].CharacteristicIcon filename = filename.replace(':/dd/icons', iconPath) self.svg[indexIcon].filename = str(filename) indexIcon+=1 # posFeactureControlFrame if fp.GT[i].FeatureControlFrameIcon <> '': auxPoint1 = points[7+displacement] + Horizontal * (-sizeOfLine*2) auxPoint2 = auxPoint1 + Vertical * (sizeOfLine*2) self.points[indexIcon].point.setValues([[auxPoint1.x,auxPoint1.y,auxPoint1.z],[points[7+displacement].x,points[7+displacement].y,points[7+displacement].z],[points[6+displacement].x,points[6+displacement].y,points[6+displacement].z],[auxPoint2.x,auxPoint2.y,auxPoint2.z]]) self.face[indexIcon].numVertices = 4 self.svgPos[indexIcon].directionS.setValue(dS.x, dS.y, dS.z) self.svgPos[indexIcon].directionT.setValue(dT.x, dT.y, dT.z) displacementH = ((Horizontal*auxPoint1)%(sizeOfLine*2))/(sizeOfLine*2) displacementV = ((Vertical*auxPoint1)%(sizeOfLine*2))/(sizeOfLine*2) self.textureTransform[indexIcon].translation.setValue(-displacementH,-displacementV) filename = fp.GT[i].FeatureControlFrameIcon filename = filename.replace(':/dd/icons', iconPath) self.svg[indexIcon].filename = str(filename) indexIcon+=1 # posDiameter if fp.GT[i].Circumference: auxPoint1 = points[5+displacement] + Horizontal * (sizeOfLine*2) auxPoint2 = auxPoint1 + Vertical * (sizeOfLine*2) self.points[indexIcon].point.setValues([[points[5+displacement].x,points[5+displacement].y,points[5+displacement].z],[auxPoint1.x,auxPoint1.y,auxPoint1.z],[auxPoint2.x,auxPoint2.y,auxPoint2.z],[points[4+displacement].x,points[4+displacement].y,points[4+displacement].z]]) self.face[indexIcon].numVertices = 4 self.svgPos[indexIcon].directionS.setValue(dS.x, dS.y, dS.z) self.svgPos[indexIcon].directionT.setValue(dT.x, dT.y, dT.z) displacementH = ((Horizontal*points[5+displacement])%(sizeOfLine*2))/(sizeOfLine*2) displacementV = ((Vertical*points[5+displacement])%(sizeOfLine*2))/(sizeOfLine*2) self.textureTransform[indexIcon].translation.setValue(-displacementH,-displacementV) filename = iconPath + '/diameter.svg' self.svg[indexIcon].filename = str(filename) indexIcon+=1 self.textGT[index].string = self.textGT3d[index].string = stringencodecoin(displayExternal(fp.GT[i].ToleranceValue, fp.ViewObject.Decimals, 'Length', fp.ViewObject.ShowUnit)) self.textGTpos[index].translation.setValue([posToleranceValue.x, posToleranceValue.y, posToleranceValue.z]) self.textGT[index].justification = coin.SoAsciiText.CENTER index+=1 displacement+=6 if fp.GT[i].DS <> None and fp.GT[i].DS.Primary <> None: if fp.GT[i].FeatureControlFrameIcon <> '': distance += (sizeOfLine*2) if fp.GT[i].Circumference: distance -= (sizeOfLine*2) posPrimary = posToleranceValue + Horizontal * (distance+sizeOfLine) self.textGT[index].string = self.textGT3d[index].string = str(fp.GT[i].DS.Primary.Label) self.textGTpos[index].translation.setValue([posPrimary.x, posPrimary.y, posPrimary.z]) self.textGT[index].justification = coin.SoAsciiText.CENTER index+=1 displacement+=2 if fp.GT[i].DS.Secondary <> None: posSecondary = posPrimary + Horizontal * (sizeOfLine*2) self.textGT[index].string = self.textGT3d[index].string = str(fp.GT[i].DS.Secondary.Label) self.textGTpos[index].translation.setValue([posSecondary.x, posSecondary.y, posSecondary.z]) self.textGT[index].justification = coin.SoAsciiText.CENTER index+=1 displacement+=2 if fp.GT[i].DS.Tertiary <> None: posTertiary = posSecondary + Horizontal * (sizeOfLine*2) self.textGT[index].string = self.textGT3d[index].string = str(fp.GT[i].DS.Tertiary.Label) self.textGTpos[index].translation.setValue([posTertiary.x, posTertiary.y, posTertiary.z]) self.textGT[index].justification = coin.SoAsciiText.CENTER index+=1 displacement+=2 if fp.circumferenceBool and True in [l.Circumference for l in fp.GT]: # posDiameterTolerance auxPoint1 = FreeCAD.Vector(points[4]) auxPoint2 = auxPoint1 + Horizontal * (sizeOfLine*2) auxPoint3 = auxPoint2 + Vertical * (sizeOfLine*2) auxPoint4 = auxPoint1 + Vertical * (sizeOfLine*2) self.points[indexIcon].point.setValues([[auxPoint1.x,auxPoint1.y,auxPoint1.z],[auxPoint2.x,auxPoint2.y,auxPoint2.z],[auxPoint3.x,auxPoint3.y,auxPoint3.z],[auxPoint4.x,auxPoint4.y,auxPoint4.z]]) self.face[indexIcon].numVertices = 4 self.svgPos[indexIcon].directionS.setValue(dS.x, dS.y, dS.z) self.svgPos[indexIcon].directionT.setValue(dT.x, dT.y, dT.z) displacementH = ((Horizontal*auxPoint1)%(sizeOfLine*2))/(sizeOfLine*2) displacementV = ((Vertical*auxPoint1)%(sizeOfLine*2))/(sizeOfLine*2) self.textureTransform[indexIcon].translation.setValue(-displacementH,-displacementV) filename = iconPath + '/diameter.svg' self.svg[indexIcon].filename = str(filename) indexIcon+=1 posDiameterTolerance = auxPoint2 + Vertical * (sizeOfLine/2) self.textGT[index].justification = coin.SoAsciiText.LEFT self.textGTpos[index].translation.setValue([posDiameterTolerance.x, posDiameterTolerance.y, posDiameterTolerance.z]) if fp.toleranceSelectBool: text = stringencodecoin(displayExternal(fp.diameter, fp.ViewObject.Decimals, 'Length', fp.ViewObject.ShowUnit) + stringplusminus() + displayExternal(fp.toleranceDiameter, fp.ViewObject.Decimals, 'Length', fp.ViewObject.ShowUnit)) else: text = stringencodecoin(displayExternal(fp.lowLimit, fp.ViewObject.Decimals, 'Length', fp.ViewObject.ShowUnit) + ' - ' + displayExternal(fp.highLimit, fp.ViewObject.Decimals, 'Length', fp.ViewObject.ShowUnit)) self.textGT[index].string = self.textGT3d[index].string = text index+=1 for i in range(index): try: DirectionAux = FreeCAD.Vector(fp.AP.Direction) DirectionAux.x = abs(DirectionAux.x) DirectionAux.y = abs(DirectionAux.y) DirectionAux.z = abs(DirectionAux.z) rotation=(DraftGeomUtils.getRotation(DirectionAux)).Q self.textGTpos[i].rotation.setValue(rotation) except: pass for i in range(index,len(self.textGT)): if str(self.textGT[i].string) <> "": self.textGT[i].string = self.textGT3d[i].string = "" else: break for i in range(indexIcon,len(self.svg)): if str(self.face[i].numVertices) <> 0: self.face[i].numVertices = 0 self.svg[i].filename = "" else: for i in range(len(self.textGT)): if str(self.textGT[i].string) <> "" or str(self.svg[i].filename) <> "": self.textGT[i].string = self.textGT3d[i].string = "" self.face[i].numVertices = 0 self.svg[i].filename = "" else: break if fp.DF <> None: self.textDF.string = self.textDF3d.string = str(fp.DF.Label) distance = 0 v = (points[-3] - points[-2]) if v.x <> 0: distance = (v.x)/2 elif v.y <> 0: distance = (v.y)/2 else: distance = (v.z)/2 centerPoint = points[-2] + Horizontal * (distance) centerPoint = centerPoint + Vertical * (sizeOfLine/2) self.textDFpos.translation.setValue([centerPoint.x, centerPoint.y, centerPoint.z]) try: DirectionAux = FreeCAD.Vector(fp.AP.Direction) DirectionAux.x = abs(DirectionAux.x) DirectionAux.y = abs(DirectionAux.y) DirectionAux.z = abs(DirectionAux.z) rotation=(DraftGeomUtils.getRotation(DirectionAux)).Q self.textDFpos.rotation.setValue(rotation) except: pass else: self.textDF.string = self.textDF3d.string = "" if fp.GT <> [] or fp.DF <> None: if len(fp.faces) > 1: # posNumFaces centerPoint = points[3] + Horizontal * (sizeOfLine) posNumFaces = centerPoint + Vertical * (sizeOfLine/2) self.textGT[index].string = self.textGT3d[index].string = (str(len(fp.faces))+'x') self.textGTpos[index].translation.setValue([posNumFaces.x, posNumFaces.y, posNumFaces.z]) self.textGT[index].justification = coin.SoAsciiText.CENTER try: DirectionAux = FreeCAD.Vector(fp.AP.Direction) DirectionAux.x = abs(DirectionAux.x) DirectionAux.y = abs(DirectionAux.y) DirectionAux.z = abs(DirectionAux.z) rotation=(DraftGeomUtils.getRotation(DirectionAux)).Q self.textGTpos[index].rotation.setValue(rotation) except: pass index+=1 #--------------------------------------------------------------------------- # UNITS handling #--------------------------------------------------------------------------- def getDefaultUnit(dim): '''return default Unit of Measure for a Dimension based on user preference Units Schema''' # only Length and Angle so far from FreeCAD import Units if dim == 'Length': qty = FreeCAD.Units.Quantity(1.0,FreeCAD.Units.Length) UOM = qty.getUserPreferred()[2] elif dim == 'Angle': qty = FreeCAD.Units.Quantity(1.0,FreeCAD.Units.Angle) UOM = qty.getUserPreferred()[2] else: UOM = "xx" return UOM def makeFormatSpec(decimals=4,dim='Length'): ''' return a % format spec with specified decimals for a specified dimension based on on user preference Units Schema''' if dim == 'Length': fmtSpec = "%." + str(decimals) + "f "+ getDefaultUnit('Length') elif dim == 'Angle': fmtSpec = "%." + str(decimals) + "f "+ getDefaultUnit('Angle') else: fmtSpec = "%." + str(decimals) + "f " + "??" return fmtSpec def displayExternal(internValue,decimals=4,dim='Length',showUnit=True): '''return an internal value (ie mm) Length or Angle converted for display according to Units Schema in use.''' from FreeCAD import Units if dim == 'Length': qty = FreeCAD.Units.Quantity(internValue,FreeCAD.Units.Length) pref = qty.getUserPreferred() conversion = pref[1] uom = pref[2] elif dim == 'Angle': qty = FreeCAD.Units.Quantity(internValue,FreeCAD.Units.Angle) pref=qty.getUserPreferred() conversion = pref[1] uom = pref[2] else: conversion = 1.0 uom = "??" if not showUnit: uom = "" fmt = "{0:."+ str(decimals) + "f} "+ uom displayExt = fmt.format(float(internValue) / float(conversion)) displayExt = displayExt.replace(".",QtCore.QLocale().decimalPoint()) return displayExt #--------------------------------------------------------------------------- # Python Features definitions #--------------------------------------------------------------------------- #----------------------------------------------------------------------- # Base class for GDT objects #----------------------------------------------------------------------- class _GDTObject: "The base class for GDT objects" def __init__(self,obj,tp="Unknown"): '''Add some custom properties to our GDT feature''' obj.Proxy = self self.Type = tp def __getstate__(self): return self.Type def __setstate__(self,state): if state: self.Type = state def execute(self,obj): '''Do something when doing a recomputation, this method is mandatory''' pass def onChanged(self, vobj, prop): '''Do something when a property has changed''' pass class _ViewProviderGDT: "The base class for GDT Viewproviders" def __init__(self, vobj): '''Set this object to the proxy object of the actual view provider''' vobj.Proxy = self self.Object = vobj.Object def __getstate__(self): return None def __setstate__(self, state): return None def attach(self,vobj): '''Setup the scene sub-graph of the view provider, this method is mandatory''' self.Object = vobj.Object return def updateData(self, obj, prop): '''If a property of the handled feature has changed we have the chance to handle this here''' # fp is the handled feature, prop is the name of the property that has changed return def getDisplayModes(self, vobj): '''Return a list of display modes.''' modes=[] return modes def setDisplayMode(self, mode): '''Map the display mode defined in attach with those defined in getDisplayModes.\ Since they have the same names nothing needs to be done. This method is optional''' return mode def onChanged(self, vobj, prop): '''Here we can do something when a single property got changed''' return def execute(self,vobj): return def getIcon(self): '''Return the icon in XPM format which will appear in the tree view. This method is\ optional and if not defined a default icon is shown.''' return(":/dd/icons/GDT.svg") #----------------------------------------------------------------------- # Annotation Plane #----------------------------------------------------------------------- class _AnnotationPlane(_GDTObject): "The GDT AnnotationPlane object" def __init__(self, obj): _GDTObject.__init__(self,obj,"AnnotationPlane") obj.addProperty("App::PropertyFloat","Offset","GDT","The offset value to aply in this annotation plane") obj.addProperty("App::PropertyLinkSub","faces","GDT","Linked face of the object").faces = (getSelectionEx()[0].Object, getSelectionEx()[0].SubElementNames[0]) obj.addProperty("App::PropertyVectorDistance","p1","GDT","Center point of Grid").p1 = obj.faces[0].Shape.getElement(obj.faces[1][0]).CenterOfMass obj.addProperty("App::PropertyVector","Direction","GDT","The normal direction of this annotation plane").Direction = obj.faces[0].Shape.getElement(obj.faces[1][0]).normalAt(0,0) obj.addProperty("App::PropertyVectorDistance","PointWithOffset","GDT","Center point of Grid with offset applied") def onChanged(self,vobj,prop): if hasattr(vobj,"PointWithOffset"): vobj.setEditorMode('PointWithOffset',1) def execute(self, fp): '''"Print a short message when doing a recomputation, this method is mandatory" ''' fp.p1 = fp.faces[0].Shape.getElement(fp.faces[1][0]).CenterOfMass fp.Direction = fp.faces[0].Shape.getElement(fp.faces[1][0]).normalAt(0,0) class _ViewProviderAnnotationPlane(_ViewProviderGDT): "A View Provider for the GDT AnnotationPlane object" def __init__(self, obj): _ViewProviderGDT.__init__(self,obj) def updateData(self, obj, prop): "called when the base object is changed" if prop in ["Point","Direction","Offset"]: obj.PointWithOffset = obj.p1 + obj.Direction * obj.Offset def doubleClicked(self,obj): showGrid() if hasattr(FreeCADGui,"Snapper"): if FreeCADGui.Snapper.grid: FreeCAD.DraftWorkingPlane.alignToPointAndAxis(self.Object.PointWithOffset, self.Object.Direction, 0) FreeCADGui.Snapper.grid.set() FreeCAD.ActiveDocument.recompute() def getIcon(self): return(":/dd/icons/annotationPlane.svg") def makeAnnotationPlane(Name, Offset): ''' Explanation ''' if len(getAllAnnotationPlaneObjects()) == 0: group = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroupPython", "GDT") _GDTObject(group) _ViewProviderGDT(group.ViewObject) else: group = FreeCAD.ActiveDocument.getObject("GDT") obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython","AnnotationPlane") _AnnotationPlane(obj) if gui: _ViewProviderAnnotationPlane(obj.ViewObject) obj.Label = Name obj.Offset = Offset group.addObject(obj) hideGrid() for l in getAllAnnotationObjects(): l.touch() FreeCAD.ActiveDocument.recompute() return obj #----------------------------------------------------------------------- # Datum Feature #----------------------------------------------------------------------- class _DatumFeature(_GDTObject): "The GDT DatumFeature object" def __init__(self, obj): _GDTObject.__init__(self,obj,"DatumFeature") def execute(self,obj): '''Do something when doing a recomputation, this method is mandatory''' pass class _ViewProviderDatumFeature(_ViewProviderGDT): "A View Provider for the GDT DatumFeature object" def __init__(self, obj): _ViewProviderGDT.__init__(self,obj) def getIcon(self): return(":/dd/icons/datumFeature.svg") def makeDatumFeature(Name, ContainerOfData): ''' Explanation ''' obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython","DatumFeature") _DatumFeature(obj) if gui: _ViewProviderDatumFeature(obj.ViewObject) obj.Label = Name group = FreeCAD.ActiveDocument.getObject("GDT") group.addObject(obj) AnnotationObj = getAnnotationObj(ContainerOfData) if AnnotationObj == None: makeAnnotation(ContainerOfData.faces, ContainerOfData.annotationPlane, DF=obj, GT=[]) else: faces = AnnotationObj.faces AP = AnnotationObj.AP GT = AnnotationObj.GT diameter = AnnotationObj.diameter toleranceSelect = AnnotationObj.toleranceSelectBool toleranceDiameter = AnnotationObj.toleranceDiameter lowLimit = AnnotationObj.lowLimit highLimit = AnnotationObj.highLimit group = makeAnnotation(faces, AP, DF=obj, GT=GT, modify = True, Object = AnnotationObj, diameter=diameter, toleranceSelect=toleranceSelect, toleranceDiameter=toleranceDiameter, lowLimit=lowLimit, highLimit=highLimit) group.addObject(obj) for l in getAllAnnotationObjects(): l.touch() FreeCAD.ActiveDocument.recompute() return obj #----------------------------------------------------------------------- # Datum System #----------------------------------------------------------------------- class _DatumSystem(_GDTObject): "The GDT DatumSystem object" def __init__(self, obj): _GDTObject.__init__(self,obj,"DatumSystem") obj.addProperty("App::PropertyLink","Primary","GDT","Primary datum feature used") obj.addProperty("App::PropertyLink","Secondary","GDT","Secondary datum feature used") obj.addProperty("App::PropertyLink","Tertiary","GDT","Tertiary datum feature used") class _ViewProviderDatumSystem(_ViewProviderGDT): "A View Provider for the GDT DatumSystem object" def __init__(self, obj): _ViewProviderGDT.__init__(self,obj) def updateData(self, obj, prop): "called when the base object is changed" if prop in ["Primary","Secondary","Tertiary"]: textName = obj.Label.split(":")[0] if obj.Primary <> None: textName+=': '+obj.Primary.Label if obj.Secondary <> None: textName+=' | '+obj.Secondary.Label if obj.Tertiary <> None: textName+=' | '+obj.Tertiary.Label obj.Label = textName def getIcon(self): return(":/dd/icons/datumSystem.svg") def makeDatumSystem(Name, Primary, Secondary=None, Tertiary=None): ''' Explanation ''' obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython","DatumSystem") _DatumSystem(obj) if gui: _ViewProviderDatumSystem(obj.ViewObject) obj.Label = Name obj.Primary = Primary obj.Secondary = Secondary obj.Tertiary = Tertiary group = FreeCAD.ActiveDocument.getObject("GDT") group.addObject(obj) for l in getAllAnnotationObjects(): l.touch() FreeCAD.ActiveDocument.recompute() return obj #----------------------------------------------------------------------- # Geometric Tolerance #----------------------------------------------------------------------- class _GeometricTolerance(_GDTObject): "The GDT GeometricTolerance object" def __init__(self, obj): _GDTObject.__init__(self,obj,"GeometricTolerance") obj.addProperty("App::PropertyString","Characteristic","GDT","Characteristic of the geometric tolerance") obj.addProperty("App::PropertyString","CharacteristicIcon","GDT","Characteristic icon path of the geometric tolerance") obj.addProperty("App::PropertyBool","Circumference","GDT","Indicates whether the tolerance applies to a given diameter") obj.addProperty("App::PropertyFloat","ToleranceValue","GDT","Tolerance value of the geometric tolerance") obj.addProperty("App::PropertyString","FeatureControlFrame","GDT","Feature control frame of the geometric tolerance") obj.addProperty("App::PropertyString","FeatureControlFrameIcon","GDT","Feature control frame icon path of the geometric tolerance") obj.addProperty("App::PropertyLink","DS","GDT","Datum system used") def onChanged(self,vobj,prop): "Do something when a property has changed" if hasattr(vobj,"CharacteristicIcon"): vobj.setEditorMode('CharacteristicIcon',2) if hasattr(vobj,"FeatureControlFrameIcon"): vobj.setEditorMode('FeatureControlFrameIcon',2) class _ViewProviderGeometricTolerance(_ViewProviderGDT): "A View Provider for the GDT GeometricTolerance object" def __init__(self, obj): _ViewProviderGDT.__init__(self,obj) def getIcon(self): icon = self.Object.CharacteristicIcon return icon def makeGeometricTolerance(Name, ContainerOfData): ''' Explanation ''' obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython","GeometricTolerance") _GeometricTolerance(obj) if gui: _ViewProviderGeometricTolerance(obj.ViewObject) obj.Label = Name obj.Characteristic = ContainerOfData.characteristic.Label obj.CharacteristicIcon = ContainerOfData.characteristic.Icon obj.Circumference = ContainerOfData.circumference obj.ToleranceValue = ContainerOfData.toleranceValue obj.FeatureControlFrame = ContainerOfData.featureControlFrame.toolTip obj.FeatureControlFrameIcon = ContainerOfData.featureControlFrame.Icon obj.DS = ContainerOfData.datumSystem group = FreeCAD.ActiveDocument.getObject("GDT") group.addObject(obj) AnnotationObj = getAnnotationObj(ContainerOfData) if AnnotationObj == None: makeAnnotation(ContainerOfData.faces, ContainerOfData.annotationPlane, DF=None, GT=obj, diameter=ContainerOfData.diameter, toleranceSelect=ContainerOfData.toleranceSelect, toleranceDiameter=ContainerOfData.toleranceDiameter, lowLimit=ContainerOfData.lowLimit, highLimit=ContainerOfData.highLimit) else: gt=AnnotationObj.GT gt.append(obj) faces = AnnotationObj.faces AP = AnnotationObj.AP DF = AnnotationObj.DF if ContainerOfData.circumference: diameter = ContainerOfData.diameter toleranceSelect = ContainerOfData.toleranceSelect toleranceDiameter = ContainerOfData.toleranceDiameter lowLimit = ContainerOfData.lowLimit highLimit = ContainerOfData.highLimit else: diameter = AnnotationObj.diameter toleranceSelect = AnnotationObj.toleranceSelectBool toleranceDiameter = AnnotationObj.toleranceDiameter lowLimit = AnnotationObj.lowLimit highLimit = AnnotationObj.highLimit group = makeAnnotation(faces, AP, DF=DF, GT=gt, modify = True, Object = AnnotationObj, diameter=diameter, toleranceSelect=toleranceSelect, toleranceDiameter=toleranceDiameter, lowLimit=lowLimit, highLimit=highLimit) group.addObject(obj) for l in getAllAnnotationObjects(): l.touch() FreeCAD.ActiveDocument.recompute() return obj #----------------------------------------------------------------------- # Annotation #----------------------------------------------------------------------- class _Annotation(_GDTObject): "The GDT Annotation object" def __init__(self, obj): _GDTObject.__init__(self,obj,"Annotation") obj.addProperty("App::PropertyLinkSubList","faces","GDT","Linked faces of the object") obj.addProperty("App::PropertyLink","AP","GDT","Annotation plane used") obj.addProperty("App::PropertyLink","DF","GDT","Text").DF=None obj.addProperty("App::PropertyLinkList","GT","GDT","Text").GT=[] obj.addProperty("App::PropertyVectorDistance","p1","GDT","Start point") obj.addProperty("App::PropertyVector","Direction","GDT","The normal direction of your annotation plane") obj.addProperty("App::PropertyVector","selectedPoint","GDT","Selected point to where plot the annotation") obj.addProperty("App::PropertyBool","spBool","GDT","Boolean to confirm that a selected point exists").spBool = False obj.addProperty("App::PropertyBool","circumferenceBool","GDT","Boolean to determine if this annotation is over a circumference").circumferenceBool = False obj.addProperty("App::PropertyFloat","diameter","GDT","Diameter") obj.addProperty("App::PropertyBool","toleranceSelectBool","GDT","Determinates if use plus-minus or low and high limits").toleranceSelectBool = True obj.addProperty("App::PropertyFloat","toleranceDiameter","GDT","Diameter tolerance (Plus-minus)") obj.addProperty("App::PropertyFloat","lowLimit","GDT","Low limit diameter tolerance") obj.addProperty("App::PropertyFloat","highLimit","GDT","High limit diameter tolerance") def onChanged(self,obj,prop): if hasattr(obj,"spBool"): obj.setEditorMode('spBool',2) if hasattr(obj,"diameter"): if obj.circumferenceBool: obj.setEditorMode('diameter',0) else: obj.setEditorMode('diameter',2) if hasattr(obj,"toleranceDiameter") and hasattr(obj,"toleranceSelectBool"): if obj.circumferenceBool and obj.toleranceSelectBool: obj.setEditorMode('toleranceDiameter',0) else: obj.setEditorMode('toleranceDiameter',2) if hasattr(obj,"lowLimit") and hasattr(obj,"toleranceSelectBool"): if obj.circumferenceBool and not obj.toleranceSelectBool: obj.setEditorMode('lowLimit',0) else: obj.setEditorMode('lowLimit',2) if hasattr(obj,"highLimit") and hasattr(obj,"toleranceSelectBool"): if obj.circumferenceBool and not obj.toleranceSelectBool: obj.setEditorMode('highLimit',0) else: obj.setEditorMode('highLimit',2) def execute(self, fp): '''"Print a short message when doing a recomputation, this method is mandatory" ''' # FreeCAD.Console.PrintMessage('Executed\n') auxP1 = fp.p1 if fp.circumferenceBool: vertexex = fp.faces[0][0].Shape.getElement(fp.faces[0][1]).Vertexes fp.p1 = vertexex[0].Point if vertexex[0].Point.z > vertexex[1].Point.z else vertexex[1].Point fp.Direction = fp.AP.Direction else: fp.p1 = (fp.faces[0][0].Shape.getElement(fp.faces[0][1]).CenterOfMass).projectToPlane(fp.AP.PointWithOffset, fp.AP.Direction) fp.Direction = fp.faces[0][0].Shape.getElement(fp.faces[0][1]).normalAt(0,0) diff = fp.p1-auxP1 if fp.spBool: fp.selectedPoint = fp.selectedPoint + diff class _ViewProviderAnnotation(_ViewProviderGDT): "A View Provider for the GDT Annotation object" def __init__(self, obj): obj.addProperty("App::PropertyFloat","LineWidth","GDT","Line width").LineWidth = getLineWidth() obj.addProperty("App::PropertyColor","LineColor","GDT","Line color").LineColor = getRGBLine() obj.addProperty("App::PropertyFloat","LineScale","GDT","Line scale").LineScale = getParam("lineScale",1.0) obj.addProperty("App::PropertyLength","FontSize","GDT","Font size").FontSize = getTextSize() obj.addProperty("App::PropertyString","FontName","GDT","Font name").FontName = getTextFamily() obj.addProperty("App::PropertyColor","FontColor","GDT","Font color").FontColor = getRGBText() obj.addProperty("App::PropertyInteger","Decimals","GDT","The number of decimals to show").Decimals = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt("Decimals",2) obj.addProperty("App::PropertyBool","ShowUnit","GDT","Show the unit suffix").ShowUnit = getParam("showUnit",True) _ViewProviderGDT.__init__(self,obj) def attach(self, obj): "called on object creation" from pivy import coin self.node = coin.SoGroup() self.node3d = coin.SoGroup() self.lineColor = coin.SoBaseColor() self.textColor = coin.SoBaseColor() self.data = coin.SoCoordinate3() self.data.point.isDeleteValuesEnabled() self.lines = coin.SoIndexedLineSet() selectionNode = coin.SoType.fromName("SoFCSelection").createInstance() selectionNode.documentName.setValue(FreeCAD.ActiveDocument.Name) selectionNode.objectName.setValue(obj.Object.Name) # here obj is the ViewObject, we need its associated App Object selectionNode.subElementName.setValue("Lines") selectionNode.addChild(self.lines) self.font = coin.SoFont() self.font3d = coin.SoFont() self.textDF = coin.SoAsciiText() self.textDF3d = coin.SoText2() self.textDF.string = "" # some versions of coin crash if string is not set self.textDF3d.string = "" self.textDFpos = coin.SoTransform() self.textDF.justification = self.textDF3d.justification = coin.SoAsciiText.CENTER labelDF = coin.SoSeparator() labelDF.addChild(self.textDFpos) labelDF.addChild(self.textColor) labelDF.addChild(self.font) labelDF.addChild(self.textDF) labelDF3d = coin.SoSeparator() labelDF3d.addChild(self.textDFpos) labelDF3d.addChild(self.textColor) labelDF3d.addChild(self.font3d) labelDF3d.addChild(self.textDF3d) self.textGT = [] self.textGT3d = [] self.textGTpos = [] self.svg = [] self.svgPos = [] self.points = [] self.face = [] self.textureTransform = [] for i in range(20): self.textGT.append(coin.SoAsciiText()) self.textGT3d.append(coin.SoText2()) self.textGT[i].string = "" self.textGT3d[i].string = "" self.textGTpos.append(coin.SoTransform()) self.textGT[i].justification = self.textGT3d[i].justification = coin.SoAsciiText.CENTER labelGT = coin.SoSeparator() labelGT.addChild(self.textGTpos[i]) labelGT.addChild(self.textColor) labelGT.addChild(self.font) labelGT.addChild(self.textGT[i]) labelGT3d = coin.SoSeparator() labelGT3d.addChild(self.textGTpos[i]) labelGT3d.addChild(self.textColor) labelGT3d.addChild(self.font3d) labelGT3d.addChild(self.textGT3d[i]) self.svg.append(coin.SoTexture2()) self.face.append(coin.SoFaceSet()) self.textureTransform.append(coin.SoTexture2Transform()) self.svgPos.append(coin.SoTextureCoordinatePlane()) self.face[i].numVertices = 0 self.points.append(coin.SoVRMLCoordinate()) image = coin.SoSeparator() image.addChild(self.svg[i]) image.addChild(self.textureTransform[i]) image.addChild(self.svgPos[i]) image.addChild(self.points[i]) image.addChild(self.face[i]) self.node.addChild(labelGT) self.node3d.addChild(labelGT3d) self.node.addChild(image) self.node3d.addChild(image) self.drawstyle = coin.SoDrawStyle() self.drawstyle.style = coin.SoDrawStyle.LINES self.node.addChild(labelDF) self.node.addChild(self.drawstyle) self.node.addChild(self.lineColor) self.node.addChild(self.data) self.node.addChild(self.lines) self.node.addChild(selectionNode) obj.addDisplayMode(self.node,"2D") self.node3d.addChild(labelDF3d) self.node3d.addChild(self.lineColor) self.node3d.addChild(self.data) self.node3d.addChild(self.lines) self.node3d.addChild(selectionNode) obj.addDisplayMode(self.node3d,"3D") self.onChanged(obj,"LineColor") self.onChanged(obj,"LineWidth") self.onChanged(obj,"FontSize") self.onChanged(obj,"FontName") self.onChanged(obj,"FontColor") def updateData(self, fp, prop): "If a property of the handled feature has changed we have the chance to handle this here" # fp is the handled feature, prop is the name of the property that has changed if prop in "selectedPoint" and hasattr(fp.ViewObject,"Decimals") and hasattr(fp.ViewObject,"ShowUnit") and fp.spBool: points, segments = getPointsToPlot(fp) # print str(points) # print str(segments) self.data.point.setNum(len(points)) cnt=0 for p in points: self.data.point.set1Value(cnt,p.x,p.y,p.z) cnt=cnt+1 self.lines.coordIndex.setNum(len(segments)) self.lines.coordIndex.setValues(0,len(segments),segments) plotStrings(self, fp, points) if prop in "faces" and fp.faces <> []: fp.circumferenceBool = True if (True in [l.Closed for l in fp.faces[0][0].Shape.getElement(fp.faces[0][1]).Edges] and len(fp.faces[0][0].Shape.getElement(fp.faces[0][1]).Vertexes) == 2) else False def doubleClicked(self,obj): try: select(self.Object) except: select(obj.Object) def getDisplayModes(self,obj): "Return a list of display modes." modes=[] modes.append("2D") modes.append("3D") return modes def getDefaultDisplayMode(self): "Return the name of the default display mode. It must be defined in getDisplayModes." return "2D" def setDisplayMode(self,mode): return mode def onChanged(self, vobj, prop): "Here we can do something when a single property got changed" if (prop == "LineColor") and hasattr(vobj,"LineColor"): if hasattr(self,"lineColor"): c = vobj.getPropertyByName("LineColor") self.lineColor.rgb.setValue(c[0],c[1],c[2]) elif (prop == "LineWidth") and hasattr(vobj,"LineWidth"): if hasattr(self,"drawstyle"): w = vobj.getPropertyByName("LineWidth") self.drawstyle.lineWidth = w elif (prop == "FontColor") and hasattr(vobj,"FontColor"): if hasattr(self,"textColor"): c = vobj.getPropertyByName("FontColor") self.textColor.rgb.setValue(c[0],c[1],c[2]) elif (prop == "FontSize") and hasattr(vobj,"FontSize"): if hasattr(self,"font"): if vobj.FontSize.Value > 0: self.font.size = vobj.FontSize.Value if hasattr(self,"font3d"): if vobj.FontSize.Value > 0: self.font3d.size = vobj.FontSize.Value*100 vobj.Object.touch() elif (prop == "FontName") and hasattr(vobj,"FontName"): if hasattr(self,"font") and hasattr(self,"font3d"): self.font.name = self.font3d.name = str(vobj.FontName) vobj.Object.touch() else: self.updateData(vobj.Object, "selectedPoint") def getIcon(self): return(":/dd/icons/annotation.svg") def makeAnnotation(faces, AP, DF=None, GT=[], modify=False, Object=None, diameter = 0.0, toleranceSelect = True, toleranceDiameter = 0.0, lowLimit = 0.0, highLimit = 0.0): ''' Explanation ''' if not modify: obj = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroupPython",dictionaryAnnotation[len(getAllAnnotationObjects())]) _Annotation(obj) if gui: _ViewProviderAnnotation(obj.ViewObject) group = FreeCAD.ActiveDocument.getObject("GDT") group.addObject(obj) obj.faces = faces obj.AP = AP if obj.circumferenceBool: vertexex = obj.faces[0][0].Shape.getElement(obj.faces[0][1]).Vertexes index = [l.Point.z for l in vertexex].index(max([l.Point.z for l in vertexex])) obj.p1 = vertexex[index].Point obj.Direction = obj.AP.Direction else: obj.p1 = (obj.faces[0][0].Shape.getElement(obj.faces[0][1]).CenterOfMass).projectToPlane(obj.AP.PointWithOffset, obj.AP.Direction) obj.Direction = obj.faces[0][0].Shape.getElement(obj.faces[0][1]).normalAt(0,0) else: obj = Object obj.DF = DF obj.GT = GT obj.diameter = diameter obj.toleranceSelectBool = toleranceSelect if toleranceSelect: obj.toleranceDiameter = toleranceDiameter obj.lowLimit = 0.0 obj.highLimit = 0.0 else: obj.toleranceDiameter = 0.0 obj.lowLimit = lowLimit obj.highLimit = highLimit def getPoint(point): if point: obj.spBool = True obj.selectedPoint = point hideGrid() obj.addObject(obj.DF) if obj.DF <> None else obj.addObject(obj.GT[0]) select(obj) for l in getAllAnnotationObjects(): l.touch() FreeCAD.ActiveDocument.recompute() return obj else: if DF: FreeCAD.ActiveDocument.removeObject(obj.DF.Name) if checkBoxState: FreeCAD.ActiveDocument.removeObject(getAllDatumSystemObjects()[-1].Name) else: FreeCAD.ActiveDocument.removeObject(obj.GT[-1].Name) FreeCAD.ActiveDocument.removeObject(obj.Name) hideGrid() for l in getAllAnnotationObjects(): l.touch() FreeCAD.ActiveDocument.recompute() return None if not obj.spBool: return FreeCADGui.Snapper.getPoint(callback=getPoint) else: hideGrid() select(obj) for l in getAllAnnotationObjects(): l.touch() FreeCAD.ActiveDocument.recompute() return obj #----------------------------------------------------------------------- # Other classes #----------------------------------------------------------------------- class Characteristics(object): def __init__(self, Label, Icon): self.Label = Label self.Icon = Icon self.Proxy = self def makeCharacteristics(label=None): Label = ['Straightness', 'Flatness', 'Circularity', 'Cylindricity', 'Profile of a line', 'Profile of a surface', 'Perpendicularity', 'Angularity', 'Parallelism', 'Symmetry', 'Position', 'Concentricity','Circular run-out', 'Total run-out'] Icon = [':/dd/icons/Characteristic/straightness.svg', ':/dd/icons/Characteristic/flatness.svg', ':/dd/icons/Characteristic/circularity.svg', ':/dd/icons/Characteristic/cylindricity.svg', ':/dd/icons/Characteristic/profileOfALine.svg', ':/dd/icons/Characteristic/profileOfASurface.svg', ':/dd/icons/Characteristic/perpendicularity.svg', ':/dd/icons/Characteristic/angularity.svg', ':/dd/icons/Characteristic/parallelism.svg', ':/dd/icons/Characteristic/symmetry.svg', ':/dd/icons/Characteristic/position.svg', ':/dd/icons/Characteristic/concentricity.svg',':/dd/icons/Characteristic/circularRunOut.svg', ':/dd/icons/Characteristic/totalRunOut.svg'] if label == None: characteristics = Characteristics(Label, Icon) return characteristics else: index = Label.index(label) icon = Icon[index] characteristics = Characteristics(label, icon) return characteristics class FeatureControlFrame(object): def __init__(self, Label, Icon, toolTip): self.Label = Label self.Icon = Icon self.toolTip = toolTip self.Proxy = self def makeFeatureControlFrame(toolTip=None): Label = ['','','','','','','',''] Icon = ['', ':/dd/icons/FeatureControlFrame/freeState.svg', ':/dd/icons/FeatureControlFrame/leastMaterialCondition.svg', ':/dd/icons/FeatureControlFrame/maximumMaterialCondition.svg', ':/dd/icons/FeatureControlFrame/projectedToleranceZone.svg', ':/dd/icons/FeatureControlFrame/regardlessOfFeatureSize.svg', ':/dd/icons/FeatureControlFrame/tangentPlane.svg', ':/dd/icons/FeatureControlFrame/unequalBilateral.svg'] ToolTip = ['Feature control frame', 'Free state', 'Least material condition', 'Maximum material condition', 'Projected tolerance zone', 'Regardless of feature size', 'Tangent plane', 'Unequal Bilateral'] if toolTip == None: featureControlFrame = FeatureControlFrame(Label, Icon, ToolTip) return featureControlFrame elif toolTip == '': featureControlFrame = FeatureControlFrame(Label[0], Icon[0], '') return featureControlFrame else: index = ToolTip.index(toolTip) icon = Icon[index] label = Label[index] featureControlFrame = FeatureControlFrame(label, icon, toolTip) return featureControlFrame class ContainerOfData(object): def __init__(self, faces = []): self.faces = faces self.diameter = 0.0 if self.faces <> []: self.Direction = self.faces[0][0].Shape.getElement(self.faces[0][1]).normalAt(0,0) self.DirectionAxis = self.faces[0][0].Shape.getElement(self.faces[0][1]).Surface.Axis self.p1 = self.faces[0][0].Shape.getElement(self.faces[0][1]).CenterOfMass try: edge = [l.Closed for l in self.faces[0][0].Shape.getElement(self.faces[0][1]).Edges].index(True) self.diameter = self.faces[0][0].Shape.getElement(self.faces[0][1]).Edges[edge].Length/pi except: pass self.circumference = False self.toleranceSelect = True self.toleranceDiameter = 0.0 self.lowLimit = 0.0 self.highLimit = 0.0 self.OffsetValue = 0 self.textName = '' self.textDS = ['','',''] self.primary = None self.secondary = None self.tertiary = None self.characteristic = None self.toleranceValue = 0.0 self.featureControlFrame = '' self.datumSystem = 0 self.annotationPlane = 0 self.annotation = None self.combo = ['','','','','',''] self.Proxy = self #--------------------------------------------------------------------------- # Customized widgets #--------------------------------------------------------------------------- class GDTWidget: def __init__(self): self.dialogWidgets = [] self.ContainerOfData = None def activate( self, idGDT=0, dialogTitle='GD&T Widget', dialogIconPath=':/dd/icons/GDT.svg', endFunction=None, dictionary=None): self.dialogTitle=dialogTitle self.dialogIconPath = dialogIconPath self.endFunction = endFunction self.dictionary = dictionary self.idGDT=idGDT self.ContainerOfData = makeContainerOfData() extraWidgets = [] if dictionary <> None: extraWidgets.append(textLabelWidget(Text='Name:',Mask='NNNn', Dictionary=self.dictionary)) #http://doc.qt.io/qt-5/qlineedit.html#inputMask-prop else: extraWidgets.append(textLabelWidget(Text='Name:',Mask='NNNn')) self.taskDialog = GDTDialog( self.dialogTitle, self.dialogIconPath, self.idGDT, extraWidgets + self.dialogWidgets, self.ContainerOfData) FreeCADGui.Control.showDialog( self.taskDialog ) class GDTDialog: def __init__(self, title, iconPath, idGDT, dialogWidgets, ContainerOfData): self.initArgs = title, iconPath, idGDT, dialogWidgets, ContainerOfData self.createForm() def createForm(self): title, iconPath, idGDT, dialogWidgets, ContainerOfData = self.initArgs self.form = GDTGuiClass( title, idGDT, dialogWidgets, ContainerOfData) self.form.setWindowTitle( title ) self.form.setWindowIcon( QtGui.QIcon( iconPath ) ) def reject(self): #close button hideGrid() FreeCAD.ActiveDocument.recompute() FreeCADGui.Control.closeDialog() def getStandardButtons(self): #http://forum.freecadweb.org/viewtopic.php?f=10&t=11801 return 0x00200000 #close button class GDTGuiClass(QtGui.QWidget): def __init__(self, title, idGDT, dialogWidgets, ContainerOfData): super(GDTGuiClass, self).__init__() self.dd_dialogWidgets = dialogWidgets self.title = title self.idGDT = idGDT self.ContainerOfData = ContainerOfData self.initUI( self.title , self.idGDT, self.ContainerOfData) def initUI(self, title, idGDT, ContainerOfData): self.idGDT = idGDT self.ContainerOfData = ContainerOfData vbox = QtGui.QVBoxLayout() for widg in self.dd_dialogWidgets: if widg <> None: w = widg.generateWidget(self.idGDT,self.ContainerOfData) if isinstance(w, QtGui.QLayout): vbox.addLayout( w ) else: vbox.addWidget( w ) hbox = QtGui.QHBoxLayout() buttonCreate = QtGui.QPushButton(title) buttonCreate.setDefault(True) buttonCreate.clicked.connect(self.createObject) hbox.addStretch(1) hbox.addWidget( buttonCreate ) hbox.addStretch(1) vbox.addLayout( hbox ) self.setLayout(vbox) def createObject(self): global auxDictionaryDS self.textName = self.ContainerOfData.textName.encode('utf-8') if self.idGDT == 1: obj = makeDatumFeature(self.textName, self.ContainerOfData) if checkBoxState: makeDatumSystem(auxDictionaryDS[len(getAllDatumSystemObjects())] + ': ' + self.textName, obj, None, None) elif self.idGDT == 2: separator = ' | ' if self.ContainerOfData.textDS[0] <> '': if self.ContainerOfData.textDS[1] <> '': if self.ContainerOfData.textDS[2] <> '': self.textName = self.textName + ': ' + separator.join(self.ContainerOfData.textDS) else: self.textName = self.textName + ': ' + separator.join([self.ContainerOfData.textDS[0], self.ContainerOfData.textDS[1]]) else: self.textName = self.textName + ': ' + self.ContainerOfData.textDS[0] else: self.textName = self.textName makeDatumSystem(self.textName, self.ContainerOfData.primary, self.ContainerOfData.secondary, self.ContainerOfData.tertiary) elif self.idGDT == 3: makeGeometricTolerance(self.textName, self.ContainerOfData) elif self.idGDT == 4: makeAnnotationPlane(self.textName, self.ContainerOfData.OffsetValue) else: pass if self.idGDT != 1 and self.idGDT != 3: hideGrid() FreeCADGui.Control.closeDialog() def GDTDialog_hbox( label, inputWidget): hbox = QtGui.QHBoxLayout() hbox.addWidget( QtGui.QLabel(label) ) if inputWidget <> None: hbox.addStretch(1) hbox.addWidget(inputWidget) return hbox class textLabelWidget: def __init__(self, Text='Label', Mask=None, Dictionary=None): self.Text = Text self.Mask = Mask self.Dictionary = Dictionary def generateWidget( self, idGDT, ContainerOfData ): self.idGDT = idGDT self.ContainerOfData = ContainerOfData self.lineEdit = QtGui.QLineEdit() if self.Mask <> None: self.lineEdit.setInputMask(self.Mask) if self.Dictionary == None: self.lineEdit.setText('text') self.text = 'text' else: NumberOfObjects = self.getNumberOfObjects() if NumberOfObjects > len(self.Dictionary)-1: NumberOfObjects = len(self.Dictionary)-1 self.lineEdit.setText(self.Dictionary[NumberOfObjects]) self.text = self.Dictionary[NumberOfObjects] self.lineEdit.textChanged.connect(self.valueChanged) self.ContainerOfData.textName = self.text.strip() return GDTDialog_hbox(self.Text,self.lineEdit) def valueChanged(self, argGDT): self.text = argGDT.strip() self.ContainerOfData.textName = self.text def getNumberOfObjects(self): "getNumberOfObjects(): returns the number of objects of the same type as the active widget" if self.idGDT == 1: NumberOfObjects = len(getAllDatumFeatureObjects()) elif self.idGDT == 2: NumberOfObjects = len(getAllDatumSystemObjects()) elif self.idGDT == 3: NumberOfObjects = len(getAllGeometricToleranceObjects()) elif self.idGDT == 4: NumberOfObjects = len(getAllAnnotationPlaneObjects()) else: NumberOfObjects = 0 return NumberOfObjects class fieldLabelWidget: def __init__(self, Text='Label'): self.Text = Text def generateWidget( self, idGDT, ContainerOfData ): self.idGDT = idGDT self.ContainerOfData = ContainerOfData if hasattr(FreeCADGui,"Snapper"): if FreeCADGui.Snapper.grid: FreeCAD.DraftWorkingPlane.alignToPointAndAxis(self.ContainerOfData.p1, self.ContainerOfData.Direction, 0.0) FreeCADGui.Snapper.grid.set() self.FORMAT = makeFormatSpec(0,'Length') self.uiloader = FreeCADGui.UiLoader() self.inputfield = self.uiloader.createWidget("Gui::InputField") self.inputfield.setText(self.FORMAT % 0) self.ContainerOfData.OffsetValue = 0 QtCore.QObject.connect(self.inputfield,QtCore.SIGNAL("valueChanged(double)"),self.valueChanged) return GDTDialog_hbox(self.Text,self.inputfield) def valueChanged(self, d): self.ContainerOfData.OffsetValue = d if hasattr(FreeCADGui,"Snapper"): if FreeCADGui.Snapper.grid: FreeCAD.DraftWorkingPlane.alignToPointAndAxis(self.ContainerOfData.p1, self.ContainerOfData.Direction, self.ContainerOfData.OffsetValue) FreeCADGui.Snapper.grid.set() class comboLabelWidget: def __init__(self, Text='Label', List=None, Icons=None, ToolTip = None): self.Text = Text self.List = List self.Icons = Icons self.ToolTip = ToolTip def generateWidget( self, idGDT, ContainerOfData ): self.idGDT = idGDT self.ContainerOfData = ContainerOfData if self.Text == 'Primary:': self.k=0 elif self.Text == 'Secondary:': self.k=1 elif self.Text == 'Tertiary:': self.k=2 elif self.Text == 'Characteristic:': self.k=3 elif self.Text == 'Datum system:': self.k=4 elif self.Text == 'Active annotation plane:': self.k=5 else: self.k=6 self.ContainerOfData.combo[self.k] = QtGui.QComboBox() for i in range(len(self.List)): if self.Icons <> None: self.ContainerOfData.combo[self.k].addItem( QtGui.QIcon(self.Icons[i]), self.List[i] ) else: if self.List[i] == None: self.ContainerOfData.combo[self.k].addItem( '' ) else: self.ContainerOfData.combo[self.k].addItem( self.List[i].Label ) if self.Text == 'Secondary:' or self.Text == 'Tertiary:': self.ContainerOfData.combo[self.k].setEnabled(False) if self.ToolTip <> None: self.ContainerOfData.combo[self.k].setToolTip( self.ToolTip[0] ) self.comboIndex = self.ContainerOfData.combo[self.k].currentIndex() if self.k <> 0 and self.k <> 1: self.updateDate(self.comboIndex) self.ContainerOfData.combo[self.k].activated.connect(lambda comboIndex = self.comboIndex: self.updateDate(comboIndex)) return GDTDialog_hbox(self.Text,self.ContainerOfData.combo[self.k]) def updateDate(self, comboIndex): if self.ToolTip <> None: self.ContainerOfData.combo[self.k].setToolTip( self.ToolTip[comboIndex] ) if self.Text == 'Primary:': self.ContainerOfData.textDS[0] = self.ContainerOfData.combo[self.k].currentText() self.ContainerOfData.primary = self.List[comboIndex] if comboIndex <> 0: self.ContainerOfData.combo[1].setEnabled(True) else: self.ContainerOfData.combo[1].setEnabled(False) self.ContainerOfData.combo[2].setEnabled(False) self.ContainerOfData.combo[1].setCurrentIndex(0) self.ContainerOfData.combo[2].setCurrentIndex(0) self.ContainerOfData.textDS[1] = '' self.ContainerOfData.textDS[2] = '' self.ContainerOfData.secondary = None self.ContainerOfData.tertiary = None self.updateItemsEnabled(self.k) elif self.Text == 'Secondary:': self.ContainerOfData.textDS[1] = self.ContainerOfData.combo[self.k].currentText() self.ContainerOfData.secondary = self.List[comboIndex] if comboIndex <> 0: self.ContainerOfData.combo[2].setEnabled(True) else: self.ContainerOfData.combo[2].setEnabled(False) self.ContainerOfData.combo[2].setCurrentIndex(0) self.ContainerOfData.textDS[2] = '' self.ContainerOfData.tertiary = None self.updateItemsEnabled(self.k) elif self.Text == 'Tertiary:': self.ContainerOfData.textDS[2] = self.ContainerOfData.combo[self.k].currentText() self.ContainerOfData.tertiary = self.List[comboIndex] self.updateItemsEnabled(self.k) elif self.Text == 'Characteristic:': self.ContainerOfData.characteristic = makeCharacteristics(self.List[comboIndex]) elif self.Text == 'Datum system:': self.ContainerOfData.datumSystem = self.List[comboIndex] elif self.Text == 'Active annotation plane:': self.ContainerOfData.annotationPlane = self.List[comboIndex] self.ContainerOfData.Direction = self.List[comboIndex].Direction self.ContainerOfData.PointWithOffset = self.List[comboIndex].PointWithOffset if hasattr(FreeCADGui,"Snapper"): if FreeCADGui.Snapper.grid: FreeCAD.DraftWorkingPlane.alignToPointAndAxis(self.ContainerOfData.PointWithOffset, self.ContainerOfData.Direction, 0.0) FreeCADGui.Snapper.grid.set() def updateItemsEnabled(self, comboIndex): comboIndex0 = comboIndex comboIndex1 = (comboIndex+1) % 3 comboIndex2 = (comboIndex+2) % 3 for i in range(self.ContainerOfData.combo[comboIndex0].count()): self.ContainerOfData.combo[comboIndex0].model().item(i).setEnabled(True) if self.ContainerOfData.combo[comboIndex1].currentIndex() <> 0: self.ContainerOfData.combo[comboIndex0].model().item(self.ContainerOfData.combo[comboIndex1].currentIndex()).setEnabled(False) if self.ContainerOfData.combo[comboIndex2].currentIndex() <> 0: self.ContainerOfData.combo[comboIndex0].model().item(self.ContainerOfData.combo[comboIndex2].currentIndex()).setEnabled(False) for i in range(self.ContainerOfData.combo[comboIndex1].count()): self.ContainerOfData.combo[comboIndex1].model().item(i).setEnabled(True) if self.ContainerOfData.combo[comboIndex0].currentIndex() <> 0: self.ContainerOfData.combo[comboIndex1].model().item(self.ContainerOfData.combo[comboIndex0].currentIndex()).setEnabled(False) if self.ContainerOfData.combo[comboIndex2].currentIndex() <> 0: self.ContainerOfData.combo[comboIndex1].model().item(self.ContainerOfData.combo[comboIndex2].currentIndex()).setEnabled(False) for i in range(self.ContainerOfData.combo[comboIndex2].count()): self.ContainerOfData.combo[comboIndex2].model().item(i).setEnabled(True) if self.ContainerOfData.combo[comboIndex0].currentIndex() <> 0: self.ContainerOfData.combo[comboIndex2].model().item(self.ContainerOfData.combo[comboIndex0].currentIndex()).setEnabled(False) if self.ContainerOfData.combo[comboIndex1].currentIndex() <> 0: self.ContainerOfData.combo[comboIndex2].model().item(self.ContainerOfData.combo[comboIndex1].currentIndex()).setEnabled(False) class groupBoxWidget: def __init__(self, Text='Label', List=[]): self.Text = Text self.List = List def generateWidget( self, idGDT, ContainerOfData ): self.idGDT = idGDT self.ContainerOfData = ContainerOfData self.group = QtGui.QGroupBox(self.Text) vbox = QtGui.QVBoxLayout() for l in self.List: vbox.addLayout(l.generateWidget(self.idGDT, self.ContainerOfData)) self.group.setLayout(vbox) return self.group class fieldLabeCombolWidget: def __init__(self, Text='Label', Circumference = [''], Diameter = 0.0, toleranceSelect = True, tolerance = 0.0, lowLimit = 0.0, highLimit = 0.0, List=[''], Icons=None, ToolTip = None): self.Text = Text self.Circumference = Circumference self.Diameter = Diameter self.toleranceSelect = toleranceSelect self.tolerance = tolerance self.lowLimit = lowLimit self.highLimit = highLimit self.List = List self.Icons = Icons self.ToolTip = ToolTip def generateWidget( self, idGDT, ContainerOfData ): self.idGDT = idGDT self.ContainerOfData = ContainerOfData self.DECIMALS = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt("Decimals",2) self.FORMAT = makeFormatSpec(self.DECIMALS,'Length') self.AFORMAT = makeFormatSpec(self.DECIMALS,'Angle') self.uiloader = FreeCADGui.UiLoader() self.comboCircumference = QtGui.QComboBox() self.combo = QtGui.QComboBox() for i in range(len(self.Circumference)): self.comboCircumference.addItem(QtGui.QIcon(self.Circumference[i]), '' ) self.comboCircumference.setSizeAdjustPolicy(QtGui.QComboBox.SizeAdjustPolicy(2)) self.comboCircumference.setToolTip("Indicates whether the tolerance applies to a given diameter") self.combo.setSizeAdjustPolicy(QtGui.QComboBox.SizeAdjustPolicy(2)) for i in range(len(self.List)): if self.Icons <> None: self.combo.addItem( QtGui.QIcon(self.Icons[i]), self.List[i] ) else: self.combo.addItem( self.List[i] ) if self.ToolTip <> None: self.updateDate() self.combo.activated.connect(self.updateDate) self.comboCircumference.activated.connect(self.updateDateCircumference) vbox = QtGui.QVBoxLayout() hbox1 = QtGui.QHBoxLayout() self.inputfield = self.uiloader.createWidget("Gui::InputField") self.inputfield.setText(self.FORMAT % 0) QtCore.QObject.connect(self.inputfield,QtCore.SIGNAL("valueChanged(double)"),self.valueChanged) hbox1.addWidget( QtGui.QLabel(self.Text) ) hbox1.addWidget(self.comboCircumference) hbox1.addStretch(1) hbox1.addWidget(self.inputfield) hbox1.addStretch(1) hbox1.addWidget(self.combo) vbox.addLayout(hbox1) hbox2 = QtGui.QHBoxLayout() self.label = QtGui.QLabel('Diameter:') self.inputfield2 = self.uiloader.createWidget("Gui::InputField") auxText = displayExternal(self.Diameter,self.DECIMALS,'Length',True) self.inputfield2.setText(auxText) QtCore.QObject.connect(self.inputfield2,QtCore.SIGNAL("valueChanged(double)"),self.valueChangedDiameter) self.comboTolerance = QtGui.QComboBox() simbol = '±' self.comboTolerance.addItem( simbol[-1] ) self.comboTolerance.addItem( 'Limit' ) if self.toleranceSelect: self.comboTolerance.setCurrentIndex(0) else: self.comboTolerance.setCurrentIndex(1) self.updateDateTolerance self.comboTolerance.activated.connect(self.updateDateTolerance) self.labelTolerance = QtGui.QLabel(simbol[-1]) self.labelLow = QtGui.QLabel('Low') self.labelHigh = QtGui.QLabel('High') self.inputfieldTolerance = self.uiloader.createWidget("Gui::InputField") auxText = displayExternal(self.tolerance,self.DECIMALS,'Length',True) self.inputfieldTolerance.setText(auxText) QtCore.QObject.connect(self.inputfieldTolerance,QtCore.SIGNAL("valueChanged(double)"),self.valueChangedTolerance) self.inputfieldLow = self.uiloader.createWidget("Gui::InputField") auxText = displayExternal(self.lowLimit,self.DECIMALS,'Length',True) self.inputfieldLow.setText(auxText) QtCore.QObject.connect(self.inputfieldLow,QtCore.SIGNAL("valueChanged(double)"),self.valueChangedLow) self.inputfieldHigh = self.uiloader.createWidget("Gui::InputField") auxText = displayExternal(self.highLimit,self.DECIMALS,'Length',True) self.inputfieldHigh.setText(auxText) QtCore.QObject.connect(self.inputfieldHigh,QtCore.SIGNAL("valueChanged(double)"),self.valueChangedHigh) hbox2.addWidget(self.label) hbox2.addStretch(1) hbox2.addWidget(self.inputfield2) vbox.addLayout(hbox2) hbox3 = QtGui.QHBoxLayout() hbox3.addWidget(self.comboTolerance) hbox3.addStretch(1) hbox3.addWidget(self.labelTolerance) hbox3.addWidget(self.inputfieldTolerance) hbox3.addWidget(self.labelLow) hbox3.addWidget(self.inputfieldLow) hbox3.addWidget(self.labelHigh) hbox3.addWidget(self.inputfieldHigh) vbox.addLayout(hbox3) self.label.hide() self.inputfield2.hide() self.label.hide() self.inputfield2.hide() self.comboTolerance.hide() self.labelTolerance.hide() self.inputfieldTolerance.hide() self.labelLow.hide() self.labelHigh.hide() self.inputfieldLow.hide() self.inputfieldHigh.hide() return vbox def updateDate(self): if self.ToolTip <> None: self.combo.setToolTip( self.ToolTip[self.combo.currentIndex()] ) if self.Text == 'Tolerance value:': if self.combo.currentIndex() <> 0: self.ContainerOfData.featureControlFrame = makeFeatureControlFrame(self.ToolTip[self.combo.currentIndex()]) else: self.ContainerOfData.featureControlFrame = makeFeatureControlFrame('') def updateDateCircumference(self): if self.comboCircumference.currentIndex() <> 0: self.ContainerOfData.circumference = True self.label.show() self.inputfield2.show() self.label.show() self.inputfield2.show() self.comboTolerance.show() if self.comboTolerance.currentIndex() == 0: self.labelTolerance.show() self.inputfieldTolerance.show() else: self.labelLow.show() self.labelHigh.show() self.inputfieldLow.show() self.inputfieldHigh.show() else: self.ContainerOfData.circumference = False self.label.hide() self.inputfield2.hide() self.label.hide() self.inputfield2.hide() self.comboTolerance.hide() if self.comboTolerance.currentIndex() == 0: self.labelTolerance.hide() self.inputfieldTolerance.hide() else: self.labelLow.hide() self.labelHigh.hide() self.inputfieldLow.hide() self.inputfieldHigh.hide() def updateDateTolerance(self): if self.comboTolerance.currentIndex() <> 0: self.ContainerOfData.toleranceSelect = False self.labelTolerance.hide() self.inputfieldTolerance.hide() self.labelLow.show() self.labelHigh.show() self.inputfieldLow.show() self.inputfieldHigh.show() else: self.ContainerOfData.toleranceSelect = True self.labelTolerance.show() self.inputfieldTolerance.show() self.labelLow.hide() self.labelHigh.hide() self.inputfieldLow.hide() self.inputfieldHigh.hide() def valueChanged(self,d): self.ContainerOfData.toleranceValue = d def valueChangedDiameter(self,d): self.ContainerOfData.diameter = d def valueChangedTolerance(self,d): self.ContainerOfData.toleranceDiameter = d def valueChangedLow(self,d): self.ContainerOfData.lowLimit = d def valueChangedHigh(self,d): self.ContainerOfData.highLimit = d class CheckBoxWidget: def __init__(self, Text='Label'): self.Text = Text def generateWidget( self, idGDT, ContainerOfData ): self.idGDT = idGDT self.ContainerOfData = ContainerOfData self.checkBox = QtGui.QCheckBox(self.Text) self.checkBox.setChecked(True) global checkBoxState checkBoxState = True hbox = QtGui.QHBoxLayout() hbox.addWidget(self.checkBox) hbox.addStretch(1) self.checkBox.stateChanged.connect(self.updateState) return hbox def updateState(self): global checkBoxState if self.checkBox.isChecked(): checkBoxState = True else: checkBoxState = False