diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py index f6bc68143..68e3eb110 100644 --- a/src/Mod/Arch/ArchComponent.py +++ b/src/Mod/Arch/ArchComponent.py @@ -462,7 +462,13 @@ class ViewProviderComponent: def claimChildren(self): if hasattr(self,"Object"): - c = [self.Object.Base]+self.Object.Additions+self.Object.Subtractions + if Draft.getType(self.Object) != "Wall": + c = [self.Object.Base] + elif Draft.getType(self.Object.Base) == "Space": + c = [] + else: + c = [self.Object.Base] + c = c + self.Object.Additions + self.Object.Subtractions if hasattr(self.Object,"Fixtures"): c.extend(self.Object.Fixtures) if hasattr(self.Object,"Tool"): diff --git a/src/Mod/Arch/ArchWall.py b/src/Mod/Arch/ArchWall.py index 8de79cc5c..ac625c589 100644 --- a/src/Mod/Arch/ArchWall.py +++ b/src/Mod/Arch/ArchWall.py @@ -21,7 +21,7 @@ #* * #*************************************************************************** -import FreeCAD,FreeCADGui,Draft,ArchComponent,DraftVecUtils,ArchCommands +import FreeCAD,FreeCADGui,Draft,ArchComponent,DraftVecUtils,ArchCommands,math from FreeCAD import Vector from PyQt4 import QtCore from DraftTools import translate @@ -30,16 +30,18 @@ __title__="FreeCAD Wall" __author__ = "Yorik van Havre" __url__ = "http://free-cad.sourceforge.net" -def makeWall(baseobj=None,length=None,width=None,height=None,align="Center",name=str(translate("Arch","Wall"))): - '''makeWall([obj],[length],[width],[height],[align],[name]): creates a wall based on the +def makeWall(baseobj=None,length=None,width=None,height=None,align="Center",face=None,name=str(translate("Arch","Wall"))): + '''makeWall([obj],[length],[width],[height],[align],[face],[name]): creates a wall based on the given object, which can be a sketch, a draft object, a face or a solid, or no object at - all, then you must provide length, width and height. Align - can be "Center","Left" or "Right"''' + all, then you must provide length, width and height. Align can be "Center","Left" or "Right", + face can be an index number of a face in the base object to base the wall on.''' obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name) _Wall(obj) _ViewProviderWall(obj.ViewObject) if baseobj: obj.Base = baseobj + if face: + obj.Face = face if length: obj.Length = length if width: @@ -48,7 +50,8 @@ def makeWall(baseobj=None,length=None,width=None,height=None,align="Center",name obj.Height = height obj.Align = align if obj.Base: - obj.Base.ViewObject.hide() + if Draft.getType(obj.Base) != "Space": + obj.Base.ViewObject.hide() obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Wall") return obj @@ -143,20 +146,34 @@ class _CommandWall: self.Width = p.GetFloat("WallWidth",200) self.Height = p.GetFloat("WallHeight",3000) self.JOIN_WALLS = p.GetBool("joinWallSketches") - sel = FreeCADGui.Selection.getSelection() + sel = FreeCADGui.Selection.getSelectionEx() done = False self.existing = [] + if sel: + # automatic mode import Draft - if Draft.getType(sel[0]) != "Wall": + if Draft.getType(sel[0].Object) != "Wall": FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Wall"))) FreeCADGui.doCommand('import Arch') - for obj in sel: - FreeCADGui.doCommand('Arch.makeWall(FreeCAD.ActiveDocument.'+obj.Name+')') + for selobj in sel: + if Draft.getType(selobj.Object) == "Space": + spacedone = False + if selobj.HasSubObjects: + if "Face" in selobj.SubElementNames[0]: + idx = int(selobj.SubElementNames[0][4:]) + FreeCADGui.doCommand("Arch.makeWall(FreeCAD.ActiveDocument."+selobj.Object.Name+",face="+str(idx)+")") + spacedone = True + if not spacedone: + FreeCADGui.doCommand('Arch.makeWall(FreeCAD.ActiveDocument.'+selobj.Object.Name+')') + else: + FreeCADGui.doCommand('Arch.makeWall(FreeCAD.ActiveDocument.'+selobj.Object.Name+')') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() done = True + if not done: + # interactive mode import DraftTrackers self.points = [] self.tracker = DraftTrackers.boxTracker() @@ -345,6 +362,8 @@ class _Wall(ArchComponent.Component): str(translate("Arch","The normal extrusion direction of this object (keep (0,0,0) for automatic normal)"))) obj.addProperty("App::PropertyBool","ForceWire","Base", str(translate("Arch","If True, if this wall is based on a face, it will use its border wire as trace, and disconsider the face."))) + obj.addProperty("App::PropertyInteger","Face","Base", + str(translate("Arch","The face number of the base object used to build this wall"))) obj.Align = ['Left','Right','Center'] obj.ForceWire = False self.Type = "Wall" @@ -357,7 +376,7 @@ class _Wall(ArchComponent.Component): def onChanged(self,obj,prop): self.hideSubobjects(obj,prop) - if prop in ["Base","Height","Width","Align","Additions","Subtractions"]: + if prop in ["Base","Height","Width","Align","Additions","Subtractions","Face"]: self.createGeometry(obj) # propagate movements to children windows if prop == "Placement": @@ -455,7 +474,25 @@ class _Wall(ArchComponent.Component): if not obj.Base.Shape.isNull(): if obj.Base.Shape.isValid(): base = obj.Base.Shape.copy() - if base.Solids: + face = None + if hasattr(obj,"Face"): + if obj.Face: + if len(base.Faces) >= obj.Face: + face = base.Faces[obj.Face-1] + if face: + # wall is based on a face + normal = face.normalAt(0,0) + if normal.getAngle(Vector(0,0,1)) > math.pi/4: + normal.multiply(width) + base = face.extrude(normal) + if obj.Align == "Center": + base.translate(normal.negative().multiply(0.5)) + elif obj.Align == "Right": + base.translate(normal.negative()) + else: + normal.multiply(height) + base = face.extrude(normal) + elif base.Solids: pass elif (len(base.Faces) == 1) and (not obj.ForceWire): if height: