Misc improvements to the Arch module

+ Added Draft box tracker
+ Fixed bug in Arch cell
+ Fixed bugs in Draft Snap
+ Better Arch Wall tool
This commit is contained in:
Yorik van Havre 2012-01-24 08:41:13 -02:00
parent 76927b7ad7
commit 9f9dd45d4d
5 changed files with 163 additions and 43 deletions

View File

@ -89,30 +89,28 @@ class _Cell(ArchComponent.Component):
import Part
pl = obj.Placement
if obj.Components:
shapes = []
if obj.JoinMode:
walls = []
structs = []
compshapes = []
for comp in obj.Components:
if Draft.getType(comp) == "Wall":
walls.append(comp.Shape)
elif Draft.getType(comp) == "Structure":
structs.append(comp.Shape)
for c in obj.Components:
if Draft.getType(c) == "Wall":
walls.append(c.Shape)
elif Draft.getType(c) == "Structure":
structs.append(c.Shape)
else:
compshapes.append(comp.Shape)
for gr in [walls,structs]:
if gr:
sh = gr.pop(0)
for csh in gr:
sh = sh.oldFuse(csh)
compshapes.append(sh)
baseShape = Part.makeCompound(compshapes)
shapes.append(c.Shape)
for group in [walls,structs]:
if group:
sh = group.pop(0).copy()
for subsh in group:
sh = sh.oldFuse(subsh)
shapes.append(sh)
else:
compshapes = []
for o in obj.Components:
compshapes.append(o.Shape)
baseShape = Part.makeCompound(compshapes)
obj.Shape = baseShape
for c in obj.Components:
shapes.append(c.Shape)
if shapes:
obj.Shape = Part.makeCompound(shapes)
obj.Placement = pl
class _ViewProviderCell(ArchComponent.ViewProviderComponent):

View File

@ -59,13 +59,42 @@ class _CommandWall:
def Activated(self):
sel = FreeCADGui.Selection.getSelection()
done = False
if sel:
FreeCAD.ActiveDocument.openTransaction("Wall")
for obj in sel:
makeWall(obj)
FreeCAD.ActiveDocument.commitTransaction()
else:
wall = makeWall()
import Draft
if Draft.getType(sel[0]) != "Wall":
FreeCAD.ActiveDocument.openTransaction("Wall")
for obj in sel:
makeWall(obj)
FreeCAD.ActiveDocument.commitTransaction()
done = True
if not done:
import DraftTrackers
self.points = []
self.tracker = DraftTrackers.boxTracker()
FreeCADGui.Snapper.getPoint(callback=self.getPoint)
def getPoint(self,point):
"this function is called by the snapper when it has a 3D point"
if point == None:
self.tracker.finalize()
return
self.points.append(point)
if len(self.points) == 1:
self.tracker.on()
FreeCADGui.Snapper.getPoint(last=self.points[0],callback=self.getPoint,movecallback=self.update)
elif len(self.points) == 2:
import Draft
l = Draft.makeWire(self.points)
makeWall(l)
self.tracker.finalize()
def update(self,point):
"this function is called by the Snapper when the mouse is moved"
self.tracker.update([self.points[0],point])
class _Wall(ArchComponent.Component):
"The Wall object"

View File

@ -154,6 +154,7 @@ class DraftToolBar:
def __init__(self):
self.tray = None
self.sourceCmd = None
self.cancel = None
self.taskmode = Draft.getParam("UiMode")
self.paramcolor = Draft.getParam("color")>>8
self.color = QtGui.QColor(self.paramcolor)
@ -465,14 +466,14 @@ class DraftToolBar:
def taskUi(self,title):
if self.taskmode:
self.isTaskOn = True
FreeCADGui.Control.closeDialog()
todo.delay(FreeCADGui.Control.closeDialog,None)
self.baseWidget = QtGui.QWidget()
self.setTitle(title)
self.layout = QtGui.QVBoxLayout(self.baseWidget)
self.setupToolBar(task=True)
self.retranslateUi(self.baseWidget)
self.panel = DraftTaskPanel(self.baseWidget)
FreeCADGui.Control.showDialog(self.panel)
todo.delay(FreeCADGui.Control.showDialog,self.panel)
else:
self.setTitle(title)
@ -509,7 +510,8 @@ class DraftToolBar:
self.labelx.setText(translate("draft", "Center X"))
self.continueCmd.show()
def pointUi(self,title=translate("draft","Point")):
def pointUi(self,title=translate("draft","Point"),cancel=None):
if cancel: self.cancel = cancel
self.taskUi(title)
self.xValue.setEnabled(True)
self.yValue.setEnabled(True)
@ -832,7 +834,11 @@ class DraftToolBar:
def finish(self):
"finish button action"
self.sourceCmd.finish(False)
if self.sourceCmd:
self.sourceCmd.finish(False)
if self.cancel:
self.cancel()
self.cancel = None
def closeLine(self):
"close button action"

View File

@ -430,13 +430,16 @@ class Snapper:
# get the intersection points
pt = fcgeo.findIntersection(tmpEdge1,tmpEdge2,True,True)
if pt:
return [pt[0],'ortho',pt[0]]
return [pt[0],'ortho',pt[0]]
if eline:
tmpEdge2 = Part.Line(self.extLine.p1(),self.extLine.p2()).toShape()
# get the intersection points
pt = fcgeo.findIntersection(eline,tmpEdge2,True,True)
if pt:
try:
tmpEdge2 = Part.Line(self.extLine.p1(),self.extLine.p2()).toShape()
# get the intersection points
pt = fcgeo.findIntersection(eline,tmpEdge2,True,True)
if pt:
return [pt[0],'ortho',pt[0]]
except:
return None
return None
def snapToElines(self,e1,e2):
@ -613,15 +616,23 @@ class Snapper:
if self.constrainLine:
self.constrainLine.off()
def getPoint(self,last=None,callback=None):
"""getPoint([last],[callback]) : 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 passa function as
callback, which will get called with the resulting point as argument, when a point is clicked:
def getPoint(self,last=None,callback=None,movecallback=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
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):
print "got a 3D point: ",point
FreeCADGui.Snapper.getPoint(callback=cb)
"""
if point:
print "got a 3D point: ",point
FreeCADGui.Snapper.getPoint(callback=cb)"""
self.pt = None
self.ui = FreeCADGui.draftToolBar
self.view = FreeCADGui.ActiveDocument.ActiveView
@ -642,6 +653,8 @@ class Snapper:
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 click(event_cb):
event = event_cb.getEvent()
@ -656,10 +669,21 @@ class Snapper:
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 2 callback functions
self.ui.pointUi()
self.ui.pointUi(cancel=cancel)
self.callbackClick = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(),click)
self.callbackMove = self.view.addEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(),move)
if not hasattr(FreeCADGui,"Snapper"):
FreeCADGui.Snapper = Snapper()

View File

@ -623,3 +623,66 @@ class gridTracker(Tracker):
rot = FreeCAD.Rotation()
rot.Q = self.trans.rotation.getValue().getValue()
return rot.multVec(Vector(pu,pv,0))
class boxTracker(Tracker):
"A box tracker, can be based on a line object"
def __init__(self,line=None,width=0.1,height=1):
self.trans = coin.SoTransform()
m = coin.SoMaterial()
m.transparency.setValue(0.8)
m.diffuseColor.setValue([0.4,0.4,0.6])
self.cube = coin.SoCube()
self.cube.height.setValue(width)
self.cube.depth.setValue(height)
self.baseline = None
if line:
self.baseline = line
self.update()
Tracker.__init__(self,children=[self.trans,m,self.cube])
def update(self,line=None,normal=None):
import WorkingPlane
from draftlibs import fcgeo
if not normal:
normal = FreeCAD.DraftWorkingPlane.axis
if line:
if isinstance(line,list):
bp = line[0]
lvec = line[1].sub(line[0])
else:
lvec = fcgeo.vec(line.Shape.Edges[0])
bp = line.Shape.Edges[0].Vertexes[0].Point
elif self.baseline:
lvec = fcgeo.vec(self.baseline.Shape.Edges[0])
bp = self.baseline.Shape.Edges[0].Vertexes[0].Point
else:
return
right = lvec.cross(normal)
self.cube.width.setValue(lvec.Length)
p = WorkingPlane.getPlacementFromPoints([bp,bp.add(lvec),bp.add(right)])
self.trans.rotation.setValue(p.Rotation.Q)
bp = bp.add(fcvec.scale(lvec,0.5))
bp = bp.add(fcvec.scaleTo(normal,self.cube.depth.getValue()/2))
self.pos(bp)
def pos(self,p):
self.trans.translation.setValue(fcvec.tup(p))
def width(self,w=None):
if w:
self.cube.height.setValue(w)
else:
return self.cube.height.getValue()
def length(self,l=None):
if l:
self.cube.width.setValue(l)
else:
return self.cube.width.getValue()
def heigth(self,h=None):
if h:
self.cube.depth.setValue(h)
self.update()
else:
return self.cube.depth.getValue()