def setupUi(self, Dialog): self.view = FreeCADGui.ActiveDocument.ActiveView self.stack = [] self.callback = self.view.addEventCallbackPivy(pvy.SoMouseButtonEvent.getClassTypeId(),self.getpoint) self.callmouse=self.view.addEventCallbackPivy(pvy.SoLocation2Event.getClassTypeId(),self.getmousepoint) self.distance=0 self.dialog=Dialog Dialog.setObjectName(_fromUtf8("Dialog")) Dialog.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) Dialog.resize(sizeX, sizeY) self.buttonBox = QtGui.QDialogButtonBox(Dialog) self.buttonBox.setGeometry(QtCore.QRect(50, 70, 191, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False) self.label = QtGui.QLabel(Dialog) self.label.setGeometry(QtCore.QRect(30, 10, 66, 17)) self.label.setObjectName(_fromUtf8("label")) self.lineEdit = QtGui.QLineEdit(Dialog) self.lineEdit.setGeometry(QtCore.QRect(100, 10, 113, 29)) self.lineEdit.setObjectName(_fromUtf8("lineEdit")) self.label1 = QtGui.QLabel(Dialog) self.label1.setGeometry(QtCore.QRect(20, 45, 260, 17)) self.label1.setObjectName(_fromUtf8("label1")) self.retranslateUi(Dialog) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), self.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), self.reject) QtCore.QMetaObject.connectSlotsByName(Dialog) self.tracker = DraftTrackers.lineTracker(scolor=(1,0,0)) self.tracker.raiseTracker() self.tracker.on() self.dialog.show()
def setTrackers(self): v = Draft.get3DView() if v in self.trackers[0]: i = self.trackers[0].index(v) self.grid = self.trackers[1][i] self.tracker = self.trackers[2][i] self.extLine = self.trackers[3][i] self.radiusTracker = self.trackers[4][i] self.dim1 = self.trackers[5][i] self.dim2 = self.trackers[6][i] else: if Draft.getParam("grid"): self.grid = DraftTrackers.gridTracker() else: self.grid = None self.tracker = DraftTrackers.snapTracker() self.extLine = DraftTrackers.lineTracker(dotted=True) self.radiusTracker = DraftTrackers.radiusTracker() self.dim1 = DraftTrackers.archDimTracker(mode=2) self.dim2 = DraftTrackers.archDimTracker(mode=3) self.trackers[0].append(v) self.trackers[1].append(self.grid) self.trackers[2].append(self.tracker) self.trackers[3].append(self.extLine) self.trackers[4].append(self.radiusTracker) self.trackers[5].append(self.dim1) self.trackers[6].append(self.dim2) if self.grid and (not self.forceGridOff): self.grid.set()
def getPoint(self,last=None,callback=None,movecallback=None,extradlg=None): """ getPoint([last],[callback],[movecallback],[extradlg]) : gets a 3D point from the screen. You can provide an existing point, in that case additional snap options and a tracker are available. You can also pass a function as callback, which will get called with the resulting point as argument, when a point is clicked, and optionally another callback which gets called when the mouse is moved. If the operation gets cancelled (the user pressed Escape), no point is returned. Example: def cb(point): if point: print "got a 3D point: ",point FreeCADGui.Snapper.getPoint(callback=cb) If the callback function accepts more than one argument, it will also receive the last snapped object. Finally, a pyqt dialog can be passed as extra taskbox. """ import inspect self.pt = None self.lastSnappedObject = None self.ui = FreeCADGui.draftToolBar self.view = Draft.get3DView() # setting a track line if we got an existing point if last: if not self.trackLine: self.trackLine = DraftTrackers.lineTracker() self.trackLine.p1(last) self.trackLine.on() def move(event_cb): event = event_cb.getEvent() mousepos = event.getPosition() ctrl = event.wasCtrlDown() shift = event.wasShiftDown() self.pt = FreeCADGui.Snapper.snap(mousepos,lastpoint=last,active=ctrl,constrain=shift) if hasattr(FreeCAD,"DraftWorkingPlane"): self.ui.displayPoint(self.pt,last,plane=FreeCAD.DraftWorkingPlane,mask=FreeCADGui.Snapper.affinity) if self.trackLine: self.trackLine.p2(self.pt) if movecallback: movecallback(self.pt) def getcoords(point,relative=False): self.pt = point if relative and last and hasattr(FreeCAD,"DraftWorkingPlane"): v = FreeCAD.DraftWorkingPlane.getGlobalCoords(point) self.pt = last.add(v) accept() def click(event_cb): event = event_cb.getEvent() if event.getButton() == 1: if event.getState() == coin.SoMouseButtonEvent.DOWN: accept() def accept(): self.view.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),self.callbackClick) self.view.removeEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),self.callbackMove) obj = FreeCADGui.Snapper.lastSnappedObject FreeCADGui.Snapper.off() self.ui.offUi() if self.trackLine: self.trackLine.off() if callback: if len(inspect.getargspec(callback).args) > 2: callback(self.pt,obj) else: callback(self.pt) self.pt = None def cancel(): self.view.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),self.callbackClick) self.view.removeEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),self.callbackMove) FreeCADGui.Snapper.off() self.ui.offUi() if self.trackLine: self.trackLine.off() if callback: callback(None) # adding callback functions self.ui.pointUi(cancel=cancel,getcoords=getcoords,extra=extradlg,rel=bool(last)) self.callbackClick = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),click) self.callbackMove = self.view.addEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),move)
def setupUi(self, Dialog): self.view = FreeCADGui.ActiveDocument.ActiveView self.stack = [] self.callback = self.view.addEventCallbackPivy(pvy.SoMouseButtonEvent.getClassTypeId(),self.getpoint) self.callmouse=self.view.addEventCallbackPivy(pvy.SoLocation2Event.getClassTypeId(),self.getmousepoint) self.distance=0 self.dialog=Dialog Dialog.setObjectName(_fromUtf8("Dialog")) Dialog.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) Dialog.resize(sizeX, sizeY) self.buttonBox = QtGui.QDialogButtonBox(Dialog) self.buttonBox.setGeometry(QtCore.QRect(50, 70, 191, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False) self.label = QtGui.QLabel(Dialog) self.label.setGeometry(QtCore.QRect(30, 10, 86, 17)) self.label.setObjectName(_fromUtf8("label")) self.lineEdit = QtGui.QLineEdit(Dialog) self.lineEdit.setGeometry(QtCore.QRect(140, 10, 153, 29)) self.lineEdit.setObjectName(_fromUtf8("lineEdit")) self.label1 = QtGui.QLabel(Dialog) self.label1.setGeometry(QtCore.QRect(20, 45, 260, 17)) self.label1.setObjectName(_fromUtf8("label1")) self.retranslateUi(Dialog) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), self.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), self.reject) QtCore.QMetaObject.connectSlotsByName(Dialog) self.tracker = DraftTrackers.lineTracker(scolor=(1,0,0)) self.tracker.raiseTracker() self.tracker.on() self.dialog.show()
def constrain(self,point,basepoint=None,axis=None): '''constrain(point,basepoint=None,axis=None: Returns a constrained point. Axis can be "x","y" or "z" or a custom vector. If None, the closest working plane axis will be picked. Basepoint is the base point used to figure out from where the point must be constrained. If no basepoint is given, the current point is used as basepoint.''' # without the Draft module fully loaded, no axes system!" if not hasattr(FreeCAD,"DraftWorkingPlane"): return point point = Vector(point) # setup trackers if needed if not self.constrainLine: self.constrainLine = DraftTrackers.lineTracker(dotted=True) # setting basepoint if not basepoint: if not self.basepoint: self.basepoint = point else: self.basepoint = basepoint delta = point.sub(self.basepoint) # setting constraint axis if not self.affinity: self.affinity = FreeCAD.DraftWorkingPlane.getClosestAxis(delta) if isinstance(axis,FreeCAD.Vector): self.constraintAxis = axis elif axis == "x": self.constraintAxis = FreeCAD.DraftWorkingPlane.u elif axis == "y": self.constraintAxis = FreeCAD.DraftWorkingPlane.v elif axis == "z": self.constraintAxis = FreeCAD.DraftWorkingPlane.axis else: if self.affinity == "x": self.constraintAxis = FreeCAD.DraftWorkingPlane.u elif self.affinity == "y": self.constraintAxis = FreeCAD.DraftWorkingPlane.v else: self.constraintAxis = FreeCAD.DraftWorkingPlane.axis # calculating constrained point cdelta = fcvec.project(delta,self.constraintAxis) npoint = self.basepoint.add(cdelta) # setting constrain line if self.constrainLine: if point != npoint: self.constrainLine.p1(point) self.constrainLine.p2(npoint) self.constrainLine.on() else: self.constrainLine.off() return npoint
def __init__(self,beam): self.beam=beam self.doc=FreeCAD.ActiveDocument if self.doc == None: FreeCAD.newDocument("Sans_Nom") self.view = FreeCADGui.ActiveDocument.ActiveView self.units=FreeCAD.Units.Quantity(1.0,FreeCAD.Units.Length) self.points = [] #snapper starting self.tracker = DraftTrackers.lineTracker() self.tracker.on() FreeCADGui.Snapper.getPoint(callback=self.getPoint1)
def __init__(self,beam,originPoint,structure=None): self.beam=beam self.originPoint=originPoint self.structure=structure self.doc=FreeCAD.ActiveDocument if self.doc == None: FreeCAD.newDocument("Sans_Nom") self.view = FreeCADGui.ActiveDocument.ActiveView self.units=FreeCAD.Units.Quantity(1.0,FreeCAD.Units.Length) self.points = [] #snapper starting self.tracker = DraftTrackers.lineTracker() self.tracker.on() #ask for a point FreeCADGui.Snapper.getPoint(last=self.originPoint,callback=self.getPoint,movecallback=self.update,title="Chagne the insertion Point")
def Activated(self, name=translate("draft", "Fillet")): DraftTools.Creator.Activated(self, name) if not self.doc: FCC.PrintWarning(translate("draft", "No active document") + "\n") return if self.ui: self.rad = 100 self.chamfer = False self.delete = False label = translate("draft", "Fillet radius") tooltip = translate("draft", "Radius of fillet") # Call the Task panel for a radius # The graphical widgets are defined in DraftGui self.ui.taskUi(title=name, icon="Draft_Fillet") self.ui.radiusUi() self.ui.sourceCmd = self self.ui.labelRadius.setText(label) self.ui.radiusValue.setToolTip(tooltip) self.ui.setRadiusValue(self.rad, "Length") self.ui.check_delete = self.ui._checkbox("isdelete", self.ui.layout, checked=self.delete) self.ui.check_delete.setText( translate("draft", "Delete original objects")) self.ui.check_delete.show() self.ui.check_chamfer = self.ui._checkbox("ischamfer", self.ui.layout, checked=self.chamfer) self.ui.check_chamfer.setText(translate("draft", "Create chamfer")) self.ui.check_chamfer.show() QtCore.QObject.connect(self.ui.check_delete, QtCore.SIGNAL("stateChanged(int)"), self.set_delete) QtCore.QObject.connect(self.ui.check_chamfer, QtCore.SIGNAL("stateChanged(int)"), self.set_chamfer) self.linetrack = DraftTrackers.lineTracker(dotted=True) self.arctrack = DraftTrackers.arcTracker() # self.call = self.view.addEventCallback("SoEvent", self.action) FCC.PrintMessage(translate("draft", "Enter radius") + "\n")
def __init__(self, view): self.view = view self.stack = [] self.impl=None self.callback = self.view.addEventCallbackPivy(pvy.SoMouseButtonEvent.getClassTypeId(),self.getpoint) self.callmouse=self.view.addEventCallbackPivy(pvy.SoLocation2Event.getClassTypeId(),self.getmousepoint) self.distance=0 self.form=QtGui.QWidget() self.label = QtGui.QLabel(self.form) self.label.setGeometry(QtCore.QRect(30, 10, 66, 17)) self.lineEdit = QtGui.QLineEdit(self.form) self.lineEdit.setGeometry(QtCore.QRect(100, 10, 113, 29)) self.label1 = QtGui.QLabel(self.form) self.label1.setGeometry(QtCore.QRect(20, 45, 260, 17)) self.label.setText("Distance") self.label1.setText("Select first point") self.tracker = DraftTrackers.lineTracker(scolor=(1,0,0)) self.tracker.raiseTracker() self.tracker.on() FreeCADGui.Control.showDialog(self)
def constrain(self, point, basepoint=None, axis=None): '''constrain(point,basepoint=None,axis=None: Returns a constrained point. Axis can be "x","y" or "z" or a custom vector. If None, the closest working plane axis will be picked. Basepoint is the base point used to figure out from where the point must be constrained. If no basepoint is given, the current point is used as basepoint.''' # without the Draft module fully loaded, no axes system!" if not hasattr(FreeCAD, "DraftWorkingPlane"): return point point = Vector(point) # setup trackers if needed if not self.constrainLine: self.constrainLine = DraftTrackers.lineTracker(dotted=True) # setting basepoint if not basepoint: if not self.basepoint: self.basepoint = point else: self.basepoint = basepoint delta = point.sub(self.basepoint) # setting constraint axis if self.mask: self.affinity = self.mask if not self.affinity: self.affinity = FreeCAD.DraftWorkingPlane.getClosestAxis(delta) if isinstance(axis, FreeCAD.Vector): self.constraintAxis = axis elif axis == "x": self.constraintAxis = FreeCAD.DraftWorkingPlane.u elif axis == "y": self.constraintAxis = FreeCAD.DraftWorkingPlane.v elif axis == "z": self.constraintAxis = FreeCAD.DraftWorkingPlane.axis else: if self.affinity == "x": self.constraintAxis = FreeCAD.DraftWorkingPlane.u elif self.affinity == "y": self.constraintAxis = FreeCAD.DraftWorkingPlane.v else: self.constraintAxis = FreeCAD.DraftWorkingPlane.axis # calculating constrained point cdelta = DraftVecUtils.project(delta, self.constraintAxis) npoint = self.basepoint.add(cdelta) # setting constrain line if self.constrainLine: if point != npoint: self.constrainLine.p1(point) self.constrainLine.p2(npoint) self.constrainLine.on() else: self.constrainLine.off() return npoint
def getPoint(self, last=None, callback=None, movecallback=None, extradlg=None): """ getPoint([last],[callback],[movecallback],[extradlg]) : gets a 3D point from the screen. You can provide an existing point, in that case additional snap options and a tracker are available. You can also pass a function as callback, which will get called with the resulting point as argument, when a point is clicked, and optionally another callback which gets called when the mouse is moved. If the operation gets cancelled (the user pressed Escape), no point is returned. Example: def cb(point): if point: print "got a 3D point: ",point FreeCADGui.Snapper.getPoint(callback=cb) If the callback function accepts more than one argument, it will also receive the last snapped object. Finally, a pyqt dialog can be passed as extra taskbox. """ import inspect self.pt = None self.lastSnappedObject = None self.ui = FreeCADGui.draftToolBar self.view = Draft.get3DView() # setting a track line if we got an existing point if last: if not self.trackLine: self.trackLine = DraftTrackers.lineTracker() self.trackLine.p1(last) self.trackLine.on() def move(event_cb): event = event_cb.getEvent() mousepos = event.getPosition() ctrl = event.wasCtrlDown() shift = event.wasShiftDown() self.pt = FreeCADGui.Snapper.snap(mousepos, lastpoint=last, active=ctrl, constrain=shift) if hasattr(FreeCAD, "DraftWorkingPlane"): self.ui.displayPoint(self.pt, last, plane=FreeCAD.DraftWorkingPlane, mask=FreeCADGui.Snapper.affinity) if self.trackLine: self.trackLine.p2(self.pt) if movecallback: movecallback(self.pt) def getcoords(point, relative=False): self.pt = point if relative and last and hasattr(FreeCAD, "DraftWorkingPlane"): v = FreeCAD.DraftWorkingPlane.getGlobalCoords(point) self.pt = last.add(v) accept() def click(event_cb): event = event_cb.getEvent() if event.getButton() == 1: if event.getState() == coin.SoMouseButtonEvent.DOWN: accept() def accept(): self.view.removeEventCallbackPivy( coin.SoMouseButtonEvent.getClassTypeId(), self.callbackClick) self.view.removeEventCallbackPivy( coin.SoLocation2Event.getClassTypeId(), self.callbackMove) obj = FreeCADGui.Snapper.lastSnappedObject FreeCADGui.Snapper.off() self.ui.offUi() if self.trackLine: self.trackLine.off() if callback: if len(inspect.getargspec(callback).args) > 2: callback(self.pt, obj) else: callback(self.pt) self.pt = None def cancel(): self.view.removeEventCallbackPivy( coin.SoMouseButtonEvent.getClassTypeId(), self.callbackClick) self.view.removeEventCallbackPivy( coin.SoLocation2Event.getClassTypeId(), self.callbackMove) FreeCADGui.Snapper.off() self.ui.offUi() if self.trackLine: self.trackLine.off() if callback: callback(None) # adding callback functions self.ui.pointUi(cancel=cancel, getcoords=getcoords, extra=extradlg, rel=bool(last)) self.callbackClick = self.view.addEventCallbackPivy( coin.SoMouseButtonEvent.getClassTypeId(), click) self.callbackMove = self.view.addEventCallbackPivy( coin.SoLocation2Event.getClassTypeId(), move)
def askInsPoint(self): Console.PrintMessage("##BeamTracker## Ask ins point\r\n") self.tracker=DraftTrackers.lineTracker() FreeCADGui.Snapper.getPoint(callback=self.getSartPoint)
def snap(self,screenpos,lastpoint=None,active=True,constrain=False): """snap(screenpos,lastpoint=None,active=True,constrain=False): returns a snapped point from the given (x,y) screenpos (the position of the mouse cursor), active is to activate active point snapping or not (passive), lastpoint is an optional other point used to draw an imaginary segment and get additional snap locations. Constrain can be True to constrain the point against the closest working plane axis. Screenpos can be a list, a tuple or a coin.SbVec2s object.""" global Part,fcgeo import Part from draftlibs import fcgeo if not hasattr(self,"toolbar"): self.makeSnapToolBar() mw = getMainWindow() bt = mw.findChild(QtGui.QToolBar,"Draft Snap") if not bt: mw.addToolBar(self.toolbar) else: if Draft.getParam("showSnapBar"): bt.show() def cstr(point): "constrains if needed" if constrain: return self.constrain(point,lastpoint) else: self.unconstrain() return point snaps = [] self.snapInfo = None # type conversion if needed if isinstance(screenpos,list): screenpos = tuple(screenpos) elif isinstance(screenpos,coin.SbVec2s): screenpos = tuple(screenpos.getValue()) elif not isinstance(screenpos,tuple): print "snap needs valid screen position (list, tuple or sbvec2s)" return None # setup trackers if needed v = Draft.get3DView() if v in self.trackers[0]: i = self.trackers[0].index(v) self.grid = self.trackers[1][i] self.tracker = self.trackers[2][i] self.extLine = self.trackers[3][i] else: if Draft.getParam("grid"): self.grid = DraftTrackers.gridTracker() else: self.grid = None self.tracker = DraftTrackers.snapTracker() self.extLine = DraftTrackers.lineTracker(dotted=True) self.trackers[0].append(v) self.trackers[1].append(self.grid) self.trackers[2].append(self.tracker) self.trackers[3].append(self.extLine) # getting current snap Radius if not self.radius: self.radius = self.getScreenDist(Draft.getParam("snapRange"),screenpos) # set the grid if self.grid and Draft.getParam("grid"): self.grid.set() # activate snap oldActive = False if Draft.getParam("alwaysSnap"): oldActive = active active = True if not self.active: active = False self.setCursor('passive') if self.tracker: self.tracker.off() if self.extLine: self.extLine.off() point = self.getApparentPoint(screenpos[0],screenpos[1]) # check if we snapped to something self.snapInfo = Draft.get3DView().getObjectInfo((screenpos[0],screenpos[1])) # checking if parallel to one of the edges of the last objects or to a polar direction if active: eline = None point,eline = self.snapToPolar(point,lastpoint) point,eline = self.snapToExtensions(point,lastpoint,constrain,eline) if not self.snapInfo: # nothing has been snapped, check fro grid snap if active: point = self.snapToGrid(point) return cstr(point) else: # we have an object to snap to obj = FreeCAD.ActiveDocument.getObject(self.snapInfo['Object']) if not obj: return cstr(point) self.lastSnappedObject = obj if hasattr(obj.ViewObject,"Selectable"): if not obj.ViewObject.Selectable: return cstr(point) if not active: # passive snapping snaps = [self.snapToVertex(self.snapInfo)] else: # active snapping comp = self.snapInfo['Component'] if (Draft.getType(obj) == "Wall") and not oldActive: edges = [] for o in [obj]+obj.Additions: if Draft.getType(o) == "Wall": if o.Base: edges.extend(o.Base.Shape.Edges) for edge in edges: snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend(self.snapToPerpendicular(edge,lastpoint)) snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge,eline)) elif obj.isDerivedFrom("Part::Feature"): if (not self.maxEdges) or (len(obj.Edges) <= self.maxEdges): if "Edge" in comp: # we are snapping to an edge edge = obj.Shape.Edges[int(comp[4:])-1] snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend(self.snapToPerpendicular(edge,lastpoint)) #snaps.extend(self.snapToOrtho(edge,lastpoint,constrain)) # now part of snapToPolar snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge,eline)) if isinstance (edge.Curve,Part.Circle): # the edge is an arc, we have extra options snaps.extend(self.snapToAngles(edge)) snaps.extend(self.snapToCenter(edge)) elif "Vertex" in comp: # directly snapped to a vertex snaps.append(self.snapToVertex(self.snapInfo,active=True)) elif comp == '': # workaround for the new view provider snaps.append(self.snapToVertex(self.snapInfo,active=True)) else: # all other cases (face, etc...) default to passive snap snapArray = [self.snapToVertex(self.snapInfo)] elif Draft.getType(obj) == "Dimension": # for dimensions we snap to their 3 points for pt in [obj.Start,obj.End,obj.Dimline]: snaps.append([pt,'endpoint',pt]) elif Draft.getType(obj) == "Mesh": # for meshes we only snap to vertices snaps.extend(self.snapToEndpoints(obj.Mesh)) elif Draft.getType(obj) == "Points": # for points we only snap to points snaps.extend(self.snapToEndpoints(obj.Points)) # updating last objects list if not self.lastObj[1]: self.lastObj[1] = obj.Name elif self.lastObj[1] != obj.Name: self.lastObj[0] = self.lastObj[1] self.lastObj[1] = obj.Name if not snaps: return point # calculating the nearest snap point shortest = 1000000000000000000 origin = Vector(self.snapInfo['x'],self.snapInfo['y'],self.snapInfo['z']) winner = [Vector(0,0,0),None,Vector(0,0,0)] for snap in snaps: # if snap[0] == None: print "debug: Snapper: 'i[0]' is 'None'" delta = snap[0].sub(origin) if delta.Length < shortest: shortest = delta.Length winner = snap # see if we are out of the max radius, if any if self.radius: dv = point.sub(winner[2]) if (dv.Length > self.radius): if (not oldActive) and self.isEnabled("passive"): winner = self.snapToVertex(self.snapInfo) # setting the cursors if self.tracker: self.tracker.setCoords(winner[2]) self.tracker.setMarker(self.mk[winner[1]]) self.tracker.on() self.setCursor(winner[1]) # return the final point return cstr(winner[2])
def snap(self, screenpos, lastpoint=None, active=True, constrain=False, noTracker=False): """snap(screenpos,lastpoint=None,active=True,constrain=False,noTracker=False): returns a snapped point from the given (x,y) screenpos (the position of the mouse cursor), active is to activate active point snapping or not (passive), lastpoint is an optional other point used to draw an imaginary segment and get additional snap locations. Constrain can be True to constrain the point against the closest working plane axis. Screenpos can be a list, a tuple or a coin.SbVec2s object. If noTracker is True, the tracking line is not displayed.""" global Part, DraftGeomUtils import Part, DraftGeomUtils if not hasattr(self, "toolbar"): self.makeSnapToolBar() mw = DraftGui.getMainWindow() bt = mw.findChild(QtGui.QToolBar, "Draft Snap") if not bt: mw.addToolBar(self.toolbar) else: if Draft.getParam("showSnapBar"): bt.show() def cstr(point): "constrains if needed" if constrain or self.mask: fpt = self.constrain(point, lastpoint) else: self.unconstrain() fpt = point if self.radiusTracker: self.radiusTracker.update(fpt) return fpt snaps = [] self.snapInfo = None # type conversion if needed if isinstance(screenpos, list): screenpos = tuple(screenpos) elif isinstance(screenpos, coin.SbVec2s): screenpos = tuple(screenpos.getValue()) elif not isinstance(screenpos, tuple): print "snap needs valid screen position (list, tuple or sbvec2s)" return None # setup trackers if needed self.setTrackers() # getting current snap Radius self.radius = self.getScreenDist(Draft.getParam("snapRange"), screenpos) if self.radiusTracker: self.radiusTracker.update(self.radius) self.radiusTracker.off() # activate snap oldActive = False if Draft.getParam("alwaysSnap"): oldActive = active active = True if not self.active: active = False self.setCursor('passive') if self.tracker: self.tracker.off() if self.extLine: self.extLine.off() if self.trackLine: self.trackLine.off() if self.dim1: self.dim1.off() if self.dim2: self.dim2.off() point = self.getApparentPoint(screenpos[0], screenpos[1]) # setup a track line if we got a last point if lastpoint: if not self.trackLine: self.trackLine = DraftTrackers.lineTracker() self.trackLine.p1(lastpoint) # check if we snapped to something self.snapInfo = Draft.get3DView().getObjectInfo( (screenpos[0], screenpos[1])) # checking if parallel to one of the edges of the last objects or to a polar direction if active: eline = None point, eline = self.snapToPolar(point, lastpoint) point, eline = self.snapToExtensions(point, lastpoint, constrain, eline) if not self.snapInfo: # nothing has been snapped, check fro grid snap if active: point = self.snapToGrid(point) fp = cstr(point) if self.trackLine and lastpoint and (not noTracker): self.trackLine.p2(fp) self.trackLine.on() # set the arch point tracking if self.lastArchPoint: self.setArchDims(self.lastArchPoint, fp) return fp else: # we have an object to snap to obj = FreeCAD.ActiveDocument.getObject(self.snapInfo['Object']) if not obj: return cstr(point) self.lastSnappedObject = obj if hasattr(obj.ViewObject, "Selectable"): if not obj.ViewObject.Selectable: return cstr(point) if not active: # passive snapping snaps = [self.snapToVertex(self.snapInfo)] else: # first stick to the snapped object s = self.snapToVertex(self.snapInfo) if s: point = s[0] # active snapping comp = self.snapInfo['Component'] if (Draft.getType(obj) == "Wall") and not oldActive: # special snapping for wall: only to its base shape (except when CTRL is pressed) edges = [] for o in [obj] + obj.Additions: if Draft.getType(o) == "Wall": if o.Base: edges.extend(o.Base.Shape.Edges) for edge in edges: snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend(self.snapToPerpendicular(edge, lastpoint)) snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge, eline)) elif (Draft.getType(obj) == "Structure") and not oldActive: # special snapping for struct: only to its base point (except when CTRL is pressed) if obj.Base: for edge in o.Base.Shape.Edges: snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend( self.snapToPerpendicular(edge, lastpoint)) snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge, eline)) else: b = obj.Placement.Base snaps.append([b, 'endpoint', b]) elif obj.isDerivedFrom("Part::Feature"): if Draft.getType(obj) == "Polygon": snaps.extend(self.snapToPolygon(obj)) if (not self.maxEdges) or (len(obj.Edges) <= self.maxEdges): if "Edge" in comp: # we are snapping to an edge en = int(comp[4:]) - 1 if len(obj.Shape.Edges) > en: edge = obj.Shape.Edges[en] snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend( self.snapToPerpendicular(edge, lastpoint)) #snaps.extend(self.snapToOrtho(edge,lastpoint,constrain)) # now part of snapToPolar snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge, eline)) if DraftGeomUtils.geomType(edge) == "Circle": # the edge is an arc, we have extra options snaps.extend(self.snapToAngles(edge)) snaps.extend(self.snapToCenter(edge)) elif "Vertex" in comp: # directly snapped to a vertex snaps.append( self.snapToVertex(self.snapInfo, active=True)) elif comp == '': # workaround for the new view provider snaps.append( self.snapToVertex(self.snapInfo, active=True)) else: # all other cases (face, etc...) default to passive snap snapArray = [self.snapToVertex(self.snapInfo)] elif Draft.getType(obj) == "Dimension": # for dimensions we snap to their 3 points for pt in [obj.Start, obj.End, obj.Dimline]: snaps.append([pt, 'endpoint', pt]) elif Draft.getType(obj) == "Mesh": # for meshes we only snap to vertices snaps.extend(self.snapToEndpoints(obj.Mesh)) elif Draft.getType(obj) == "Points": # for points we only snap to points snaps.extend(self.snapToEndpoints(obj.Points)) # updating last objects list if not self.lastObj[1]: self.lastObj[1] = obj.Name elif self.lastObj[1] != obj.Name: self.lastObj[0] = self.lastObj[1] self.lastObj[1] = obj.Name if not snaps: return cstr(point) # calculating the nearest snap point shortest = 1000000000000000000 origin = Vector(self.snapInfo['x'], self.snapInfo['y'], self.snapInfo['z']) winner = [Vector(0, 0, 0), None, Vector(0, 0, 0)] for snap in snaps: if (not snap) or (snap[0] == None): print "debug: Snapper: invalid snap point: ", snaps else: delta = snap[0].sub(origin) if delta.Length < shortest: shortest = delta.Length winner = snap # see if we are out of the max radius, if any if self.radius: dv = point.sub(winner[2]) if (dv.Length > self.radius): if (not oldActive) and self.isEnabled("passive"): winner = self.snapToVertex(self.snapInfo) # setting the cursors if self.tracker: self.tracker.setCoords(winner[2]) self.tracker.setMarker(self.mk[winner[1]]) self.tracker.on() # setting the trackline fp = cstr(winner[2]) if self.trackLine and lastpoint: self.trackLine.p2(fp) self.trackLine.on() # set the cursor self.setCursor(winner[1]) # set the arch point tracking if self.lastArchPoint: self.setArchDims(self.lastArchPoint, fp) if Draft.getType(obj) in ["Wall", "Structure"]: self.lastArchPoint = winner[2] else: self.lastArchPoint = None # return the final point return fp
def Activated(self): self.tracker = DraftTrackers.lineTracker() self.tracker.on() self.objList = FreeCADGui.Selection.getSelection() FreeCADGui.Snapper.getPoint(callback=self.getBasePoint, title="Base Point")
def snap(self,screenpos,lastpoint=None,active=True,constrain=False,noTracker=False): """snap(screenpos,lastpoint=None,active=True,constrain=False,noTracker=False): returns a snapped point from the given (x,y) screenpos (the position of the mouse cursor), active is to activate active point snapping or not (passive), lastpoint is an optional other point used to draw an imaginary segment and get additional snap locations. Constrain can be True to constrain the point against the closest working plane axis. Screenpos can be a list, a tuple or a coin.SbVec2s object. If noTracker is True, the tracking line is not displayed.""" global Part, DraftGeomUtils import Part, DraftGeomUtils if not hasattr(self,"toolbar"): self.makeSnapToolBar() mw = DraftGui.getMainWindow() bt = mw.findChild(QtGui.QToolBar,"Draft Snap") if not bt: mw.addToolBar(self.toolbar) else: if Draft.getParam("showSnapBar"): bt.show() def cstr(point): "constrains if needed" if constrain or self.mask: fpt = self.constrain(point,lastpoint) else: self.unconstrain() fpt = point if self.radiusTracker: self.radiusTracker.update(fpt) return fpt snaps = [] self.snapInfo = None # type conversion if needed if isinstance(screenpos,list): screenpos = tuple(screenpos) elif isinstance(screenpos,coin.SbVec2s): screenpos = tuple(screenpos.getValue()) elif not isinstance(screenpos,tuple): print "snap needs valid screen position (list, tuple or sbvec2s)" return None # setup trackers if needed self.setTrackers() # getting current snap Radius self.radius = self.getScreenDist(Draft.getParam("snapRange"),screenpos) if self.radiusTracker: self.radiusTracker.update(self.radius) self.radiusTracker.off() # activate snap oldActive = False if Draft.getParam("alwaysSnap"): oldActive = active active = True if not self.active: active = False self.setCursor('passive') if self.tracker: self.tracker.off() if self.extLine: self.extLine.off() if self.trackLine: self.trackLine.off() if self.dim1: self.dim1.off() if self.dim2: self.dim2.off() point = self.getApparentPoint(screenpos[0],screenpos[1]) # setup a track line if we got a last point if lastpoint: if not self.trackLine: self.trackLine = DraftTrackers.lineTracker() self.trackLine.p1(lastpoint) # check if we snapped to something self.snapInfo = Draft.get3DView().getObjectInfo((screenpos[0],screenpos[1])) # checking if parallel to one of the edges of the last objects or to a polar direction if active: eline = None point,eline = self.snapToPolar(point,lastpoint) point,eline = self.snapToExtensions(point,lastpoint,constrain,eline) if not self.snapInfo: # nothing has been snapped, check fro grid snap if active: point = self.snapToGrid(point) fp = cstr(point) if self.trackLine and lastpoint and (not noTracker): self.trackLine.p2(fp) self.trackLine.on() # set the arch point tracking if self.lastArchPoint: self.setArchDims(self.lastArchPoint,fp) return fp else: # we have an object to snap to obj = FreeCAD.ActiveDocument.getObject(self.snapInfo['Object']) if not obj: return cstr(point) self.lastSnappedObject = obj if hasattr(obj.ViewObject,"Selectable"): if not obj.ViewObject.Selectable: return cstr(point) if not active: # passive snapping snaps = [self.snapToVertex(self.snapInfo)] else: # first stick to the snapped object s = self.snapToVertex(self.snapInfo) if s: point = s[0] # active snapping comp = self.snapInfo['Component'] if (Draft.getType(obj) == "Wall") and not oldActive: # special snapping for wall: only to its base shape (except when CTRL is pressed) edges = [] for o in [obj]+obj.Additions: if Draft.getType(o) == "Wall": if o.Base: edges.extend(o.Base.Shape.Edges) for edge in edges: snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend(self.snapToPerpendicular(edge,lastpoint)) snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge,eline)) elif (Draft.getType(obj) == "Structure") and not oldActive: # special snapping for struct: only to its base point (except when CTRL is pressed) if obj.Base: for edge in obj.Base.Shape.Edges: snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend(self.snapToPerpendicular(edge,lastpoint)) snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge,eline)) else: b = obj.Placement.Base snaps.append([b,'endpoint',b]) elif obj.isDerivedFrom("Part::Feature"): if Draft.getType(obj) == "Polygon": snaps.extend(self.snapToPolygon(obj)) if (not self.maxEdges) or (len(obj.Edges) <= self.maxEdges): if "Edge" in comp: # we are snapping to an edge en = int(comp[4:])-1 if len(obj.Shape.Edges) > en: edge = obj.Shape.Edges[en] snaps.extend(self.snapToEndpoints(edge)) snaps.extend(self.snapToMidpoint(edge)) snaps.extend(self.snapToPerpendicular(edge,lastpoint)) #snaps.extend(self.snapToOrtho(edge,lastpoint,constrain)) # now part of snapToPolar snaps.extend(self.snapToIntersection(edge)) snaps.extend(self.snapToElines(edge,eline)) if DraftGeomUtils.geomType(edge) == "Circle": # the edge is an arc, we have extra options snaps.extend(self.snapToAngles(edge)) snaps.extend(self.snapToCenter(edge)) elif "Vertex" in comp: # directly snapped to a vertex snaps.append(self.snapToVertex(self.snapInfo,active=True)) elif comp == '': # workaround for the new view provider snaps.append(self.snapToVertex(self.snapInfo,active=True)) else: # all other cases (face, etc...) default to passive snap snapArray = [self.snapToVertex(self.snapInfo)] elif Draft.getType(obj) == "Dimension": # for dimensions we snap to their 3 points for pt in [obj.Start,obj.End,obj.Dimline]: snaps.append([pt,'endpoint',pt]) elif Draft.getType(obj) == "Mesh": # for meshes we only snap to vertices snaps.extend(self.snapToEndpoints(obj.Mesh)) elif Draft.getType(obj) == "Points": # for points we only snap to points snaps.extend(self.snapToEndpoints(obj.Points)) # updating last objects list if not self.lastObj[1]: self.lastObj[1] = obj.Name elif self.lastObj[1] != obj.Name: self.lastObj[0] = self.lastObj[1] self.lastObj[1] = obj.Name if not snaps: return cstr(point) # calculating the nearest snap point shortest = 1000000000000000000 origin = Vector(self.snapInfo['x'],self.snapInfo['y'],self.snapInfo['z']) winner = [Vector(0,0,0),None,Vector(0,0,0)] for snap in snaps: if (not snap) or (snap[0] == None): print "debug: Snapper: invalid snap point: ",snaps else: delta = snap[0].sub(origin) if delta.Length < shortest: shortest = delta.Length winner = snap # see if we are out of the max radius, if any if self.radius: dv = point.sub(winner[2]) if (dv.Length > self.radius): if (not oldActive) and self.isEnabled("passive"): winner = self.snapToVertex(self.snapInfo) # setting the cursors if self.tracker: self.tracker.setCoords(winner[2]) self.tracker.setMarker(self.mk[winner[1]]) self.tracker.on() # setting the trackline fp = cstr(winner[2]) if self.trackLine and lastpoint: self.trackLine.p2(fp) self.trackLine.on() # set the cursor self.setCursor(winner[1]) # set the arch point tracking if self.lastArchPoint: self.setArchDims(self.lastArchPoint,fp) if Draft.getType(obj) in ["Wall","Structure"]: self.lastArchPoint = winner[2] else: self.lastArchPoint = None # return the final point return fp