Arch: Applied fix to cyclic dependency problem to windows

This commit is contained in:
Yorik van Havre
2017-09-02 17:24:34 -03:00
parent 7af5b78bfd
commit 4cde30c181
4 changed files with 34 additions and 139 deletions

View File

@@ -154,7 +154,6 @@ def removeComponents(objectsList,host=None):
for o in objectsList:
if not o in s:
s.append(o)
fixDAG(o)
if FreeCAD.GuiUp:
if not Draft.getType(o) in ["Window","Roof"]:
setAsSubcomponent(o)
@@ -244,23 +243,6 @@ def setAsSubcomponent(obj):
obj.ViewObject.Transparency = int(color[3]*100)
obj.ViewObject.hide()
def fixDAG(obj,force=False):
'''fixDAG(object): Fixes non-DAG problems in windows and rebars
by removing supports and external geometry from underlying sketches'''
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
if p.GetBool("archRemoveExternal",False) or force:
if Draft.getType(obj) in ["Window","Rebar"]:
if obj.Base:
if hasattr(obj.Base,"Support"):
if obj.Base.Support:
FreeCAD.Console.PrintMessage(translate("Arch","removing sketch support to avoid cross-referencing"))
obj.Base.Support = None
if hasattr(obj.Base,"ExternalGeometry"):
if obj.Base.ExternalGeometry:
for g in obj.Base.ExternalGeometry:
obj.Base.delExternal(0)
FreeCAD.Console.PrintMessage(translate("Arch","removing sketch external reference to avoid cross-referencing"))
def copyProperties(obj1,obj2):
'''copyProperties(obj1,obj2): Copies properties values from obj1 to obj2,
when that property exists in both objects'''

View File

@@ -63,7 +63,7 @@ def addToComponent(compobject,addobject,mod=None):
if compobject == addobject: return
# first check zis already there
found = False
attribs = ["Additions","Objects","Components","Subtractions","Base","Group"]
attribs = ["Additions","Objects","Components","Subtractions","Base","Group","Hosts"]
for a in attribs:
if hasattr(compobject,a):
if a == "Base":
@@ -108,7 +108,7 @@ def removeFromComponent(compobject,subobject):
it is added as a subtraction.'''
if compobject == subobject: return
found = False
attribs = ["Additions","Subtractions","Objects","Components","Base","Axes","Fixtures","Group"]
attribs = ["Additions","Subtractions","Objects","Components","Base","Axes","Fixtures","Group","Hosts"]
for a in attribs:
if hasattr(compobject,a):
if a == "Base":
@@ -158,7 +158,7 @@ class ComponentTaskPanel:
# the categories are shown only if they are not empty.
self.obj = None
self.attribs = ["Base","Additions","Subtractions","Objects","Components","Axes","Fixtures","Group"]
self.attribs = ["Base","Additions","Subtractions","Objects","Components","Axes","Fixtures","Group","Hosts"]
self.baseform = QtGui.QWidget()
self.baseform.setObjectName("TaskPanel")
self.grid = QtGui.QGridLayout(self.baseform)
@@ -304,6 +304,7 @@ class ComponentTaskPanel:
self.treeComponents.setText(0,QtGui.QApplication.translate("Arch", "Components", None))
self.treeFixtures.setText(0,QtGui.QApplication.translate("Arch", "Fixtures", None))
self.treeGroup.setText(0,QtGui.QApplication.translate("Arch", "Group", None))
self.treeHosts.setText(0,QtGui.QApplication.translate("Arch", "Hosts", None))
class Component:
"The default Arch Component object"
@@ -516,18 +517,6 @@ class Component:
add.Placement = add.Placement.multiply(placement)
base = base.fuse(add)
elif (Draft.getType(o) == "Window") or (Draft.isClone(o,"Window",True)):
if hasattr(o.Proxy,"getSubVolume"):
f = o.Proxy.getSubVolume(o)
if f:
if base.Solids and f.Solids:
if placement:
f.Placement = f.Placement.multiply(placement)
if len(base.Solids) > 1:
base = Part.makeCompound([sol.cut(f) for sol in base.Solids])
else:
base = base.cut(f)
elif o.isDerivedFrom("Part::Feature"):
if o.Shape:
if not o.Shape.isNull():
@@ -545,7 +534,13 @@ class Component:
base = s
# treat subtractions
for o in obj.Subtractions:
subs = obj.Subtractions
for link in obj.InList:
if hasattr(link,"Hosts"):
for host in link.Hosts:
if host == obj:
subs.append(link)
for o in subs:
if base:
if base.isNull():
@@ -841,10 +836,6 @@ class ViewProviderComponent:
def claimChildren(self):
if hasattr(self,"Object"):
prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
swalA = prefs.GetBool("swallowAdditions",True)
swalS = prefs.GetBool("swallowSubtractions",True)
swalW = prefs.GetBool("swallowWindows",True)
c = []
if hasattr(self.Object,"Base"):
if Draft.getType(self.Object) != "Wall":
@@ -853,16 +844,13 @@ class ViewProviderComponent:
c = []
else:
c = [self.Object.Base]
if hasattr(self.Object,"Additions") and swalA:
if hasattr(self.Object,"Additions"):
c.extend(self.Object.Additions)
if hasattr(self.Object,"Subtractions") and swalS:
if hasattr(self.Object,"Subtractions"):
for s in self.Object.Subtractions:
if Draft.getType(self.Object) == "Wall":
if Draft.getType(s) == "Roof":
continue
if (Draft.getType(s) == "Window") or Draft.isClone(s,"Window"):
if not swalW:
continue
c.append(s)
for link in ["Armatures","Group"]:
if hasattr(self.Object,link):
@@ -878,6 +866,10 @@ class ViewProviderComponent:
if link.Host:
if link.Host == self.Object:
c.append(link)
elif hasattr(link,"Hosts"):
for host in link.Hosts:
if host == self.Object:
c.append(link)
return c
return []

View File

@@ -440,19 +440,11 @@ class _CommandWindow:
FreeCADGui.addModule("Arch")
FreeCADGui.doCommand("win = Arch.makeWindow(FreeCAD.ActiveDocument."+obj.Name+")")
if host and self.Include:
if self.RemoveExternal:
FreeCADGui.doCommand("Arch.removeComponents(win,host=FreeCAD.ActiveDocument."+host.Name+")")
else:
# make a new object to avoid circular references
FreeCADGui.doCommand("host=Arch.make"+Draft.getType(host)+"(FreeCAD.ActiveDocument."+host.Name+")")
FreeCADGui.doCommand("Arch.removeComponents(win,host)")
FreeCADGui.doCommand("win.Hosts = [FreeCAD.ActiveDocument."+host.Name+"]")
siblings = host.Proxy.getSiblings(host)
for sibling in siblings:
if self.RemoveExternal:
FreeCADGui.doCommand("Arch.removeComponents(win,host=FreeCAD.ActiveDocument."+sibling.Name+")")
else:
FreeCADGui.doCommand("host=Arch.make"+Draft.getType(sibling)+"(FreeCAD.ActiveDocument."+sibling.Name+")")
FreeCADGui.doCommand("Arch.removeComponents(win,host)")
if not sibling in win.Hosts:
FreeCADGui.doCommand("win.Hosts = win.Hosts+[FreeCAD.ActiveDocument."+sibling.Name+"]")
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
return
@@ -495,18 +487,10 @@ class _CommandWindow:
FreeCADGui.doCommand("win = Arch.makeWindowPreset(\"" + WindowPresets[self.Preset] + "\"," + wp + "placement=pl)")
if obj and self.Include:
if Draft.getType(obj) in AllowedHosts:
if self.RemoveExternal:
FreeCADGui.doCommand("Arch.removeComponents(win,host=FreeCAD.ActiveDocument."+obj.Name+")")
else:
FreeCADGui.doCommand("host=Arch.make"+Draft.getType(obj)+"(FreeCAD.ActiveDocument."+obj.Name+")")
FreeCADGui.doCommand("Arch.removeComponents(win,host)")
FreeCADGui.doCommand("win.Hosts = [FreeCAD.ActiveDocument."+obj.Name+"]")
siblings = obj.Proxy.getSiblings(obj)
for sibling in siblings:
if self.RemoveExternal:
FreeCADGui.doCommand("Arch.removeComponents(win,host=FreeCAD.ActiveDocument."+sibling.Name+")")
else:
FreeCADGui.doCommand("host=Arch.make"+Draft.getType(sibling)+"(FreeCAD.ActiveDocument."+sibling.Name+")")
FreeCADGui.doCommand("Arch.removeComponents(win,host)")
FreeCADGui.doCommand("win.Hosts = win.Hosts+[FreeCAD.ActiveDocument."+sibling.Name+"]")
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
return
@@ -637,6 +621,7 @@ class _Window(ArchComponent.Component):
"The Window object"
def __init__(self,obj):
ArchComponent.Component.__init__(self,obj)
obj.addProperty("App::PropertyLinkList","Hosts","Arch",QT_TRANSLATE_NOOP("App::Property","The objects that host this window"))
obj.addProperty("App::PropertyStringList","WindowParts","Arch",QT_TRANSLATE_NOOP("App::Property","the components of this window"))
obj.addProperty("App::PropertyLength","WindowParts","Arch",QT_TRANSLATE_NOOP("App::Property","the components of this window"))
obj.addProperty("App::PropertyLength","HoleDepth","Arch",QT_TRANSLATE_NOOP("App::Property","The depth of the hole that this window makes in its host object. Keep 0 for automatic."))
@@ -665,6 +650,11 @@ class _Window(ArchComponent.Component):
def onChanged(self,obj,prop):
self.hideSubobjects(obj,prop)
if prop == "Hosts":
if hasattr(obj,"Hosts"):
for host in obj.Hosts:
# mark host to recompute so it can detect this object
host.touch()
if not "Restore" in obj.State:
if prop in ["Base","WindowParts"]:
self.execute(obj)
@@ -1109,8 +1099,8 @@ class _ArchWindowTaskPanel:
self.grid.setObjectName("grid")
self.title = QtGui.QLabel(self.baseform)
self.grid.addWidget(self.title, 0, 0, 1, 7)
basepanel = ArchComponent.ComponentTaskPanel()
self.form = [self.baseform,basepanel.baseform]
self.basepanel = ArchComponent.ComponentTaskPanel()
self.form = [self.baseform,self.basepanel.baseform]
# base object
self.tree = QtGui.QTreeWidget(self.baseform)
@@ -1320,7 +1310,9 @@ class _ArchWindowTaskPanel:
else:
self.holeNumber.setText("0")
self.retranslateUi(self.baseform)
self.retranslateUi(self.baseform)
self.basepanel.obj = self.obj
self.basepanel.update()
def addElement(self):
'opens the component creation dialog'

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>396</width>
<height>694</height>
<height>689</height>
</rect>
</property>
<property name="windowTitle">
@@ -109,77 +109,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>Tree behaviour</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<item>
<widget class="QLabel" name="label_4">
<property name="toolTip">
<string>If these options are checked, the respective components will appear under their host object in the tree view. Otherwise, next to them.</string>
</property>
<property name="text">
<string>Swallow </string>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_5">
<property name="text">
<string>Additions</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>swallowAdditions</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_6">
<property name="text">
<string>Subtractions</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>swallowSubtractions</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_4">
<property name="text">
<string>Windows</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>swallowWindows</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">