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:
parent
76927b7ad7
commit
9f9dd45d4d
|
@ -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):
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue
Block a user