Skip to content

Commit

Permalink
Arch: Better support for App::Parts in Arch Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
yorikvanhavre committed Jun 12, 2020
1 parent fbf0b23 commit be0c8ea
Show file tree
Hide file tree
Showing 5 changed files with 647 additions and 575 deletions.
1 change: 1 addition & 0 deletions src/Mod/Arch/Arch.py
Expand Up @@ -49,6 +49,7 @@
from ArchCommands import *
from ArchSectionPlane import *
from ArchWindow import *
from ArchWindowPresets import *
from ArchAxis import *
from ArchRoof import *
from ArchSpace import *
Expand Down
134 changes: 67 additions & 67 deletions src/Mod/Arch/ArchComponent.py
Expand Up @@ -172,7 +172,7 @@ class Component(ArchIFC.IfcProduct):
----------
obj: <App::FeaturePython>
The object to turn into an Arch Component
"""
"""

def __init__(self, obj):
obj.Proxy = self
Expand Down Expand Up @@ -275,7 +275,7 @@ def __setstate__(self,state):
return None

def onBeforeChange(self,obj,prop):
"""Method called before the object has a property changed.
"""Method called before the object has a property changed.
Specifically, this method is called before the value changes.
Expand Down Expand Up @@ -392,7 +392,7 @@ def getParentHeight(self,obj):
<App::PropertyLength>
The Height value of the found Floor or BuildingPart.
"""

for parent in obj.InList:
if Draft.getType(parent) in ["Floor","BuildingPart"]:
if obj in parent.Group:
Expand Down Expand Up @@ -476,7 +476,7 @@ def getExtrusionData(self,obj):
Recursively scrape the Bases of the object, until a Base that is
derived from a <Part::Extrusion> is found. From there, copy the
extrusion to the (0,0,0) origin.
extrusion to the (0,0,0) origin.
With this copy, get the <Part.Face> the shape was originally
extruded from, the <Base.Vector> of the extrusion, and the
Expand Down Expand Up @@ -645,7 +645,7 @@ def hideSubobjects(self,obj,prop):
"""Hides Additions and Subtractions of this Component when that list changes.
Intended to be used in conjunction with the .onChanged() method, to
access the property that has changed.
access the property that has changed.
When an object loses or gains an Addition, this method hides all
Additions. When it gains or loses a Subtraction, this method hides all
Expand Down Expand Up @@ -697,7 +697,7 @@ def processSubShapes(self,obj,base,placement=None):
The base shape to add Additions and Subtractions to.
placement: <Base.Placement>, optional
Prior to adding or subtracting subshapes, the <Base.Placement> of
the subshapes are multiplied by the inverse of this parameter.
the subshapes are multiplied by the inverse of this parameter.
Returns
-------
Expand Down Expand Up @@ -753,41 +753,44 @@ def processSubShapes(self,obj,base,placement=None):

# treat subtractions
subs = obj.Subtractions
for link in obj.InList:
for link in obj.InListRecursive:
if hasattr(link,"Hosts"):
for host in link.Hosts:
if host == obj:
subs.append(link)
elif hasattr(link,"Host"):
if link.Host == obj:
subs.append(link)
for o in subs:

if base:
if base.isNull():
base = None

if base:
subvolume = None
if (Draft.getType(o) == "Window") or (Draft.isClone(o,"Window",True)):
# windows can be additions or subtractions, treated the same way
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)

subvolume = o.Proxy.getSubVolume(o)
elif (Draft.getType(o) == "Roof") or (Draft.isClone(o,"Roof")):
# roofs define their own special subtraction volume
f = o.Proxy.getSubVolume(o)
if f:
if base.Solids and f.Solids:
if len(base.Solids) > 1:
base = Part.makeCompound([sol.cut(f) for sol in base.Solids])
else:
base = base.cut(f)
subvolume = o.Proxy.getSubVolume(o)
elif hasattr(o,"Subvolume") and hasattr(o.Subvolume,"Shape"):
# Any other object with a Subvolume property
subvolume = o.Subvolume.Shape.copy()
if hasattr(o,"Placement"):
subvolume.Placement = subvolume.Placement.multiply(o.Placement)

if subvolume:
if base.Solids and subvolume.Solids:
if placement:
subvolume.Placement = subvolume.Placement.multiply(placement)
if len(base.Solids) > 1:
base = Part.makeCompound([sol.cut(subvolume) for sol in base.Solids])
else:
base = base.cut(subvolume)

elif hasattr(o,'Shape'):
# no subvolume, we subtract the whole shape
if o.Shape:
if not o.Shape.isNull():
if o.Shape.Solids and base.Solids:
Expand Down Expand Up @@ -941,7 +944,7 @@ def computeAreas(self,obj):
"""Compute the area properties of the object's shape.
Compute the vertical area, horizontal area, and perimeter length of
the object's shape.
the object's shape.
The vertical area is the surface area of the faces perpendicular to the
ground.
Expand Down Expand Up @@ -1101,6 +1104,30 @@ def isStandardCase(self,obj):
# - must have an IfcWindowType and IfcRelFillsElement (to be implemented in IFC exporter)
return False

def getHosts(self,obj):
"""Return the objects that have this one as host,
that is, objects with a "Host" property pointing
at this object, or a "Hosts" property containing
this one.
Returns
-------
list of <Arch._Structure>
The Arch Structures hosting this component.
"""

hosts = []
for link in obj.InListRecursive:
if hasattr(link,"Host"):
if link.Host:
if link.Host == obj:
hosts.append(link)
elif hasattr(link,"Hosts"):
for host in link.Hosts:
if host == obj:
hosts.append(link)
return hosts


class ViewProviderComponent:
"""A default View Provider for Component objects.
Expand All @@ -1112,13 +1139,13 @@ class ViewProviderComponent:
----------
vobj: <Gui.ViewProviderDocumentObject>
The view provider to turn into a component view provider.
"""
"""

def __init__(self,vobj):
vobj.Proxy = self
self.Object = vobj.Object
self.setProperties(vobj)

def setProperties(self,vobj):
"""Give the component view provider its component view provider specific properties.
Expand Down Expand Up @@ -1242,7 +1269,7 @@ def onChanged(self,vobj,prop):
d = vobj.DiffuseColor
vobj.DiffuseColor = d
elif prop == "Visibility":
for host in self.getHosts():
for host in vobj.Object.Proxy.getHosts(vobj.Object):
if hasattr(host, 'ViewObject'):
host.ViewObject.Visibility = vobj.Visibility

Expand All @@ -1252,7 +1279,7 @@ def attach(self,vobj):
"""Add display modes' data to the coin scenegraph.
Add each display mode as a coin node, whose parent is this view
provider.
provider.
Each display mode's node includes the data needed to display the object
in that mode. This might include colors of faces, or the draw style of
Expand Down Expand Up @@ -1304,7 +1331,7 @@ def setDisplayMode(self,mode):
When HiRes is set as display mode, display the component as a copy of
the mesh associated as the HiRes property of the host object. See
ArchComponent.Component's properties.
ArchComponent.Component's properties.
If no shape is set in the HiRes property, just display the object as
the Flat Lines display mode.
Expand Down Expand Up @@ -1414,8 +1441,9 @@ def claimChildren(self):
objlink = getattr(self.Object,link)
if objlink:
c.append(objlink)
for link in self.getHosts():
c.append(link)
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetBool("ClaimHosted",True):
for link in self.Object.Proxy.getHosts(self.Object):
c.append(link)

return c
return []
Expand Down Expand Up @@ -1527,39 +1555,11 @@ def colorize(self,obj,force=False):
"""

if obj.CloneOf:
if (self.areDifferentColors(obj.ViewObject.DiffuseColor,
obj.CloneOf.ViewObject.DiffuseColor)
if (self.areDifferentColors(obj.ViewObject.DiffuseColor,
obj.CloneOf.ViewObject.DiffuseColor)
or force):

obj.ViewObject.DiffuseColor = obj.CloneOf.ViewObject.DiffuseColor

def getHosts(self):
"""Return the hosts of the view provider's host object.
Note that in this case, the hosts are the objects referenced by Arch
Rebar's "Host" and/or "Hosts" properties specifically. Only Arch Rebar
has these properties.
Returns
-------
list of <Arch._Structure>
The Arch Structures hosting this component.
"""

hosts = []

if hasattr(self,"Object"):
for link in self.Object.InList:
if hasattr(link,"Host"):
if link.Host:
if link.Host == self.Object:
hosts.append(link)
elif hasattr(link,"Hosts"):
for host in link.Hosts:
if host == self.Object:
hosts.append(link)

return hosts


class ArchSelectionObserver:
Expand Down Expand Up @@ -1660,7 +1660,7 @@ def getStandardButtons(self):

def reject(self):
"""The method run when the user selects the cancel button."""

if hasattr(FreeCAD,"ArchObserver"):
FreeCADGui.Selection.removeObserver(FreeCAD.ArchObserver)
del FreeCAD.ArchObserver
Expand Down Expand Up @@ -2062,7 +2062,7 @@ def editIfcProperties(self):

def acceptIfcProperties(self):
"""This method runs as a callback when the user selects the ok button in the IFC editor.
Scrape through the rows of the IFC editor's items, and compare them to
the object being edited's .IfcData. If the two are different, change
the object's .IfcData to match the editor's items.
Expand Down Expand Up @@ -2159,7 +2159,7 @@ def addIfcProperty(self,idx=0,pset=None,prop=None,ptype=None):

def addIfcPset(self,idx=0):
"""Add an IFC property set to the object, within the IFC editor.
This method runs as a callback when the user selects a property set
within the Add property set dropdown.
Expand Down Expand Up @@ -2265,7 +2265,7 @@ def createEditor(self,parent,option,index):
----------
parent: <pyside2.qtwidgets.qwidget>
The table cell that is being edited.
option:
option:
Unused?
index: <PySide2.QtCore.QModelIndex>
The index object of the table of the IFC editor.
Expand Down

0 comments on commit be0c8ea

Please sign in to comment.