import FreeCAD, traceback from PySide import QtGui, QtCore, QtSvg #code duplicated from dimensioning .py def DimensioningTaskDialog_generate_row_hbox( label, inputWidget ): hbox = QtGui.QHBoxLayout() hbox.addWidget( QtGui.QLabel(label) ) hbox.addStretch(1) if inputWidget != None: hbox.addWidget(inputWidget) return hbox class ClickRect(QtGui.QGraphicsRectItem): def mousePressEvent( self, event ): if event.button() == QtCore.Qt.MouseButton.LeftButton: self.clickFun() def RGBtoUnsigned( r,g,b ): return (r << 24) + (g << 16) + (b << 8) def unsignedToRGB( v ): r = v >> 24 g = (v >> 16) - (v >> 24 << 8 ) b = (v >> 8) - (v >> 16 << 8 ) return r, g, b def unsignedToRGBText(v): return 'rgb(%i,%i,%i)' % unsignedToRGB(v) #/end of duplicated code default_grid_clr = RGBtoUnsigned(170,170,255) default_grid_spacing = 1 default_grid_display_period = 20 default_grid_line_width = 0.15 def unsignedToRGBText(v): return 'rgb(%i,%i,%i)' % unsignedToRGB(v) class GridOptionsGroupBox: def __init__(self): self.dd_parms = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Drawing_Dimensioning") def groupBoxToggled( self, checked): self.dd_parms.SetBool("show_grid_options", checked) self.groupbox.setMaximumHeight(1000 if checked else 18) def gridOn_checkbox_stateChanged( self, arg1=None): self.dd_parms.SetBool( 'grid_on', self.gridOn_checkbox.isChecked()) dimensioningGrid.update() def spacingSpinbox_valueChanged( self, newValue ): self.dd_parms.SetFloat( 'grid_spacing', newValue ) dimensioningGrid.update() def displayPeriodSpinbox_valueChanged(self, newValue ): self.dd_parms.SetInt( 'grid_display_period', newValue ) dimensioningGrid.update() def lineWidthSpinbox_valueChanged(self, newValue ): self.dd_parms.SetFloat( 'grid_line_width', newValue ) dimensioningGrid.update() def specifyNewGridColor(self): color = QtGui.QColorDialog.getColor( self.colorRect.brush().color() ) if color.isValid(): self.colorRect.setBrush( QtGui.QBrush(color) ) self.dd_parms.SetUnsigned( 'grid_color', RGBtoUnsigned(color.red(), color.green(), color.blue()) ) dimensioningGrid.update() def generateWidget(self, dimensioningProcess): self.dimensioningProcess = dimensioningProcess groupbox = QtGui.QGroupBox("Grid Options") groupbox.setCheckable( True ) groupbox.toggled.connect( self.groupBoxToggled ) self.groupbox = groupbox checked = self.dd_parms.GetBool("show_grid_options",True) groupbox.setChecked(checked) vbox = QtGui.QVBoxLayout() gridOn_checkbox = QtGui.QCheckBox('grid on') gridOn_checkbox.setChecked( self.dd_parms.GetBool( 'grid_on', False )) gridOn_checkbox.stateChanged.connect( self.gridOn_checkbox_stateChanged ) vbox.addWidget( gridOn_checkbox ) self.gridOn_checkbox = gridOn_checkbox spacingSpinbox = QtGui.QDoubleSpinBox() spacingSpinbox.setValue( self.dd_parms.GetFloat( 'grid_spacing', default_grid_spacing ) ) spacingSpinbox.setMinimum( 0.01 ) spacingSpinbox.setDecimals( 2 ) spacingSpinbox.setSingleStep( 0.5 ) spacingSpinbox.setSuffix('mm') spacingSpinbox.valueChanged.connect( self.spacingSpinbox_valueChanged ) vbox.addLayout( DimensioningTaskDialog_generate_row_hbox('spacing', spacingSpinbox) ) self.spacingSpinbox = spacingSpinbox displayPeriodSpinbox = QtGui.QSpinBox() displayPeriodSpinbox.setValue( min( self.dd_parms.GetInt( 'grid_display_period', default_grid_display_period ), 200) ) displayPeriodSpinbox.setMinimum( 0 ) displayPeriodSpinbox.valueChanged.connect( self.displayPeriodSpinbox_valueChanged ) vbox.addLayout( DimensioningTaskDialog_generate_row_hbox('display period', displayPeriodSpinbox) ) self.displayPeriodSpinbox = displayPeriodSpinbox clr = QtGui.QColor(*unsignedToRGB(self.dd_parms.GetUnsigned( 'grid_color', default_grid_clr )) ) graphicsScene = QtGui.QGraphicsScene(0,0,30,30) pen = QtGui.QPen( QtGui.QColor(0,0,0,0) ) pen.setWidth(0.0) rect = ClickRect(-100, -100, 200, 200) rect.setPen(pen) rect.clickFun = self.specifyNewGridColor graphicsScene.addItem(rect) self.graphicsScene = graphicsScene #protect from garbage collector self.colorRect = rect self.colorRect.setBrush( QtGui.QBrush( clr ) ) colorBox = QtGui.QGraphicsView( self.graphicsScene ) colorBox.setMaximumWidth( 60 ) colorBox.setMaximumHeight( 30 ) colorBox.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff ) colorBox.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff ) vbox.addLayout( DimensioningTaskDialog_generate_row_hbox( 'color', colorBox ) ) lineWidthSpinbox = QtGui.QDoubleSpinBox() lineWidthSpinbox.setValue( self.dd_parms.GetFloat( 'grid_line_width', default_grid_line_width ) ) lineWidthSpinbox.setMinimum( 0. ) lineWidthSpinbox.setDecimals( 2 ) lineWidthSpinbox.setSingleStep( 0.05 ) lineWidthSpinbox.valueChanged.connect( self.lineWidthSpinbox_valueChanged ) vbox.addLayout( DimensioningTaskDialog_generate_row_hbox('lineWidth', lineWidthSpinbox) ) self.lineWidthSpinbox = lineWidthSpinbox groupbox.setLayout(vbox) return groupbox gridOptionsGroupBox = GridOptionsGroupBox() class GridManager: gridWidget = None def initialize(self, drawingVars): self.drawingVars = drawingVars self.update() def update(self): try: if hasattr( self, 'SVG'): self.remove() drawingVars = self.drawingVars parms = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Drawing_Dimensioning") div_period = parms.GetInt( 'grid_display_period',default_grid_display_period ) lineWidth = parms.GetFloat( 'grid_line_width', default_grid_line_width ) if parms.GetBool('grid_on', False) and div_period > 0 and lineWidth > 0: self.SVG = QtSvg.QGraphicsSvgItem() self.SVGRenderer = QtSvg.QSvgRenderer() dArg ='' div = parms.GetFloat( 'grid_spacing', default_grid_spacing ) clr = unsignedToRGBText(parms.GetUnsigned( 'grid_color', default_grid_clr )) W = drawingVars.width / drawingVars.VRT_scale H = drawingVars.height / drawingVars.VRT_scale for i in range(1, int(W / (div*div_period) )+1): dArg = dArg + ' M %f 0 L %f %f' % (i*div*div_period, i*div*div_period, H) for i in range(1, int(H / (div*div_period) )+1): dArg = dArg + ' M 0 %f L %f %f' % (i*div*div_period, W, i*div*div_period) self.SVGRenderer.load( QtCore.QByteArray( '''<svg width="%i" height="%i"> <path stroke="%srgb(0, 255, 0)" stroke-width="%f" d="%s"/> </svg>''' % (drawingVars.width, drawingVars.height, clr, lineWidth, dArg) ) ) self.SVG.setSharedRenderer( self.SVGRenderer ) self.SVG.setTransform( drawingVars.transform ) self.SVG.setZValue( 0.08 ) #ensure behind dimension preview SVG ... drawingVars.graphicsScene.addItem( self.SVG ) #FreeCAD.Console.PrintMessage('Grid Svg Added to Scene\n') except: FreeCAD.Console.PrintError(traceback.format_exc()) def remove(self): if hasattr( self, 'SVG'): try: self.drawingVars.graphicsScene.removeItem( self.SVG ) except RuntimeError: pass #Internal C++ object (PySide.QtSvg.QGraphicsSvgItem) already deleted. del self.SVG, self.SVGRenderer dimensioningGrid = GridManager() def applyGridRounding( x, y): parms = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Drawing_Dimensioning") if parms.GetBool('grid_on', False): #then alter x and y div = parms.GetFloat( 'grid_spacing', 5 ) new_x = x - x%div new_y = y - y%div return new_x, new_y else: return x, y