More improvements to the Arch module
+ Draft snap can now pass the object being snapped to + Handle when wall is based on a closed wire + Handle when wall is based on a self-intersecting wire
This commit is contained in:
parent
28a989463d
commit
8d01d70038
|
@ -98,17 +98,14 @@ class _CommandWall:
|
|||
import DraftTrackers
|
||||
self.points = []
|
||||
self.tracker = DraftTrackers.boxTracker()
|
||||
FreeCADGui.Snapper.getPoint(callback=self.getPoint)
|
||||
FreeCADGui.Snapper.getPoint(callback=self.getPoint,extradlg=TaskArchWall())
|
||||
|
||||
def getPoint(self,point):
|
||||
def getPoint(self,point,obj):
|
||||
"this function is called by the snapper when it has a 3D point"
|
||||
pos = FreeCADGui.ActiveDocument.ActiveView.getCursorPos()
|
||||
exi = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo(pos)
|
||||
if exi:
|
||||
exi = FreeCAD.ActiveDocument.getObject(exi['Object'])
|
||||
if Draft.getType(exi) == "Wall":
|
||||
if not exi in self.existing:
|
||||
self.existing.append(exi)
|
||||
if obj:
|
||||
if Draft.getType(obj) == "Wall":
|
||||
if not obj in self.existing:
|
||||
self.existing.append(obj)
|
||||
if point == None:
|
||||
self.tracker.finalize()
|
||||
return
|
||||
|
@ -119,6 +116,8 @@ class _CommandWall:
|
|||
elif len(self.points) == 2:
|
||||
import Part
|
||||
l = Part.Line(self.points[0],self.points[1])
|
||||
self.tracker.finalize()
|
||||
FreeCAD.ActiveDocument.openTransaction("Wall")
|
||||
if not self.existing:
|
||||
s = FreeCAD.ActiveDocument.addObject("Sketcher::SketchObject","WallTrace")
|
||||
s.addGeometry(l)
|
||||
|
@ -126,7 +125,7 @@ class _CommandWall:
|
|||
else:
|
||||
w = joinWalls(self.existing)
|
||||
w.Base.addGeometry(l)
|
||||
self.tracker.finalize()
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def update(self,point):
|
||||
|
@ -182,6 +181,8 @@ class _Wall(ArchComponent.Component):
|
|||
dvec = fcvec.neg(dvec)
|
||||
w2 = fcgeo.offsetWire(wire,dvec)
|
||||
sh = fcgeo.bind(w1,w2)
|
||||
# fixing self-intersections
|
||||
sh.fix(0.1,0,1)
|
||||
if height:
|
||||
norm = Vector(normal).multiply(height)
|
||||
sh = sh.extrude(norm)
|
||||
|
@ -258,4 +259,9 @@ class _ViewProviderWall(ArchComponent.ViewProviderComponent):
|
|||
def getIcon(self):
|
||||
return ":/icons/Arch_Wall_Tree.svg"
|
||||
|
||||
class TaskArchWall:
|
||||
def __init__(self):
|
||||
from PyQt4 import QtGui
|
||||
self.form = QtGui.QWidget()
|
||||
|
||||
FreeCADGui.addCommand('Arch_Wall',_CommandWall())
|
||||
|
|
|
@ -136,7 +136,7 @@ class DraftLineEdit(QtGui.QLineEdit):
|
|||
QtGui.QLineEdit.keyPressEvent(self, event)
|
||||
|
||||
class DraftTaskPanel:
|
||||
def __init__(self,widget):
|
||||
def __init__(self,widget,extradlg=None):
|
||||
self.form = widget
|
||||
def getStandardButtons(self):
|
||||
return int(QtGui.QDialogButtonBox.Cancel)
|
||||
|
@ -463,7 +463,7 @@ class DraftToolBar:
|
|||
# Interface modes
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def taskUi(self,title):
|
||||
def taskUi(self,title,extradlg=None):
|
||||
if self.taskmode:
|
||||
self.isTaskOn = True
|
||||
todo.delay(FreeCADGui.Control.closeDialog,None)
|
||||
|
@ -472,7 +472,7 @@ class DraftToolBar:
|
|||
self.layout = QtGui.QVBoxLayout(self.baseWidget)
|
||||
self.setupToolBar(task=True)
|
||||
self.retranslateUi(self.baseWidget)
|
||||
self.panel = DraftTaskPanel(self.baseWidget)
|
||||
self.panel = DraftTaskPanel(self.baseWidget,extradlg)
|
||||
todo.delay(FreeCADGui.Control.showDialog,self.panel)
|
||||
else:
|
||||
self.setTitle(title)
|
||||
|
@ -510,9 +510,9 @@ class DraftToolBar:
|
|||
self.labelx.setText(translate("draft", "Center X"))
|
||||
self.continueCmd.show()
|
||||
|
||||
def pointUi(self,title=translate("draft","Point"),cancel=None):
|
||||
def pointUi(self,title=translate("draft","Point"),cancel=None,extradlg=None):
|
||||
if cancel: self.cancel = cancel
|
||||
self.taskUi(title)
|
||||
self.taskUi(title,extradlg)
|
||||
self.xValue.setEnabled(True)
|
||||
self.yValue.setEnabled(True)
|
||||
self.labelx.setText(translate("draft", "X"))
|
||||
|
@ -536,6 +536,7 @@ class DraftToolBar:
|
|||
|
||||
def offUi(self):
|
||||
todo.delay(FreeCADGui.Control.closeDialog,None)
|
||||
self.cancel = None
|
||||
if self.taskmode:
|
||||
self.isTaskOn = False
|
||||
self.baseWidget = QtGui.QWidget()
|
||||
|
|
|
@ -68,6 +68,7 @@ class Snapper:
|
|||
self.grid = None
|
||||
self.constrainLine = None
|
||||
self.trackLine = None
|
||||
self.lastSnappedObject = None
|
||||
|
||||
# the snapmarker has "dot","circle" and "square" available styles
|
||||
self.mk = {'passive':'circle',
|
||||
|
@ -175,6 +176,8 @@ class Snapper:
|
|||
obj = FreeCAD.ActiveDocument.getObject(info['Object'])
|
||||
if not obj:
|
||||
return cstr(point)
|
||||
|
||||
self.lastSnappedObject = obj
|
||||
|
||||
if hasattr(obj.ViewObject,"Selectable"):
|
||||
if not obj.ViewObject.Selectable:
|
||||
|
@ -531,6 +534,7 @@ class Snapper:
|
|||
for v in self.views:
|
||||
v.unsetCursor()
|
||||
self.views = []
|
||||
self.cursorMode = None
|
||||
else:
|
||||
if mode != self.cursorMode:
|
||||
if not self.views:
|
||||
|
@ -559,11 +563,9 @@ class Snapper:
|
|||
self.extLine.off()
|
||||
if self.grid:
|
||||
self.grid.off()
|
||||
if self.constrainLine:
|
||||
self.constrainLine.off()
|
||||
self.unconstrain()
|
||||
self.radius = 0
|
||||
self.setCursor()
|
||||
self.cursorMode = None
|
||||
|
||||
def constrain(self,point,basepoint=None,axis=None):
|
||||
'''constrain(point,basepoint=None,axis=None: Returns a
|
||||
|
@ -627,11 +629,12 @@ class Snapper:
|
|||
if self.constrainLine:
|
||||
self.constrainLine.off()
|
||||
|
||||
def getPoint(self,last=None,callback=None,movecallback=None):
|
||||
def getPoint(self,last=None,callback=None,movecallback=None,extradlg=None):
|
||||
|
||||
"""getPoint([last],[callback],[movecallback]) : 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
|
||||
"""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.
|
||||
|
||||
|
@ -642,7 +645,12 @@ class Snapper:
|
|||
def cb(point):
|
||||
if point:
|
||||
print "got a 3D point: ",point
|
||||
FreeCADGui.Snapper.getPoint(callback=cb)"""
|
||||
FreeCADGui.Snapper.getPoint(callback=cb)
|
||||
|
||||
If the callback function accepts more than one argument, it will also receive
|
||||
the last snapped object.Finally, a task dialog can be passed as extradlg."""
|
||||
|
||||
import inspect
|
||||
|
||||
self.pt = None
|
||||
self.ui = FreeCADGui.draftToolBar
|
||||
|
@ -673,12 +681,16 @@ class Snapper:
|
|||
if event.getState() == coin.SoMouseButtonEvent.DOWN:
|
||||
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:
|
||||
callback(self.pt)
|
||||
if len(inspect.getargspec(callback).args) > 2:
|
||||
callback(self.pt,obj)
|
||||
else:
|
||||
callback(self.pt)
|
||||
self.pt = None
|
||||
|
||||
def cancel():
|
||||
|
@ -692,7 +704,7 @@ class Snapper:
|
|||
callback(None)
|
||||
|
||||
# adding 2 callback functions
|
||||
self.ui.pointUi(cancel=cancel)
|
||||
self.ui.pointUi(cancel=cancel,extradlg=extradlg)
|
||||
self.callbackClick = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),click)
|
||||
self.callbackMove = self.view.addEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),move)
|
||||
|
||||
|
|
|
@ -476,7 +476,7 @@ class Line(Creator):
|
|||
if self.isWire:
|
||||
msg(translate("draft", "Pick next point, or (F)inish or (C)lose:\n"))
|
||||
else:
|
||||
currentshape = self.obj.Shape
|
||||
currentshape = self.obj.Shape.copy()
|
||||
last = self.node[len(self.node)-2]
|
||||
newseg = Part.Line(last,point).toShape()
|
||||
newshape=currentshape.fuse(newseg)
|
||||
|
|
|
@ -959,9 +959,19 @@ def getTangent(edge,frompoint=None):
|
|||
def bind(w1,w2):
|
||||
'''bind(wire1,wire2): binds 2 wires by their endpoints and
|
||||
returns a face'''
|
||||
w3 = Part.Line(w1.Vertexes[0].Point,w2.Vertexes[0].Point).toShape()
|
||||
w4 = Part.Line(w1.Vertexes[-1].Point,w2.Vertexes[-1].Point).toShape()
|
||||
return Part.Face(Part.Wire(w1.Edges+[w3]+w2.Edges+[w4]))
|
||||
if w1.isClosed() and w2.isClosed():
|
||||
d1 = w1.BoundBox.DiagonalLength
|
||||
d2 = w2.BoundBox.DiagonalLength
|
||||
if d1 > d2:
|
||||
#w2.reverse()
|
||||
return Part.Face([w1,w2])
|
||||
else:
|
||||
#w1.reverse()
|
||||
return Part.Face([w2,w1])
|
||||
else:
|
||||
w3 = Part.Line(w1.Vertexes[0].Point,w2.Vertexes[0].Point).toShape()
|
||||
w4 = Part.Line(w1.Vertexes[-1].Point,w2.Vertexes[-1].Point).toShape()
|
||||
return Part.Face(Part.Wire(w1.Edges+[w3]+w2.Edges+[w4]))
|
||||
|
||||
def cleanFaces(shape):
|
||||
"removes inner edges from coplanar faces"
|
||||
|
|
Loading…
Reference in New Issue
Block a user