From 796d51ac38bae03583bb430b174a28102d44e282 Mon Sep 17 00:00:00 2001 From: Roy-043 Date: Fri, 6 Sep 2024 10:33:01 +0200 Subject: [PATCH] BIM: Fix window transparency V1.0 fix for the transparency of glass panels in windows and doors. --- src/Mod/BIM/ArchWindow.py | 115 +++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 44 deletions(-) diff --git a/src/Mod/BIM/ArchWindow.py b/src/Mod/BIM/ArchWindow.py index 753d8a661e..75d1cc83ea 100644 --- a/src/Mod/BIM/ArchWindow.py +++ b/src/Mod/BIM/ArchWindow.py @@ -81,11 +81,11 @@ def recolorize(attr): # names is [docname,objname] if obj: if obj.ViewObject: if obj.ViewObject.Proxy: - obj.ViewObject.Proxy.colorize(obj,force=True) + obj.ViewObject.Proxy.colorize(obj) elif hasattr(attr,"ViewObject") and attr.ViewObject: obj = attr if hasattr(obj.ViewObject,"Proxy") and hasattr(obj.ViewObject.Proxy,"colorize"): - obj.ViewObject.Proxy.colorize(obj,force=True) + obj.ViewObject.Proxy.colorize(obj) @@ -665,34 +665,57 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent): def onChanged(self,vobj,prop): - if (prop in ["DiffuseColor","Transparency"]) and vobj.Object: + if prop == "ShapeAppearance": self.colorize(vobj.Object) - elif prop == "ShapeColor": - self.colorize(vobj.Object,force=True) ArchComponent.ViewProviderComponent.onChanged(self,vobj,prop) - def colorize(self,obj,force=False): + def colorize(self,obj): + + def _shapeAppearanceMaterialIsSame(sapp_mat1, sapp_mat2): + for prop in ( + "AmbientColor", + "DiffuseColor", + "EmissiveColor", + "Shininess", + "SpecularColor", + "Transparency", + ): + if getattr(sapp_mat1, prop) != getattr(sapp_mat2, prop): + return False + return True + + def _shapeAppearanceIsSame(sapp1, sapp2): + if len(sapp1) != len(sapp2): + return False + for sapp_mat1, sapp_mat2 in zip(sapp1, sapp2): + if not _shapeAppearanceMaterialIsSame(sapp_mat1, sapp_mat2): + return False + return True - "setting different part colors" - if hasattr(obj,"CloneOf") and obj.CloneOf: - if self.areDifferentColors(obj.ViewObject.DiffuseColor,obj.CloneOf.ViewObject.DiffuseColor) or force: - obj.ViewObject.DiffuseColor = obj.CloneOf.ViewObject.DiffuseColor - return if not obj.Shape: return if not obj.Shape.Solids: return + + # setting different part colors + if hasattr(obj, "CloneOf") and obj.CloneOf: + obj, clone = obj.CloneOf, obj + base_sapp_mat = clone.ViewObject.ShapeAppearance[0] + arch_mat = getattr(clone, "Material", None) + else: + clone = None + base_sapp_mat = obj.ViewObject.ShapeAppearance[0] + arch_mat = getattr(obj, "Material", None) + solids = obj.Shape.copy().Solids - #print("Colorizing ", solids) - colors = [] - base = obj.ViewObject.ShapeColor + sapp = [] for i in range(len(solids)): - ccol = None + color = None if obj.WindowParts and len(obj.WindowParts) > i*5: # WindowParts-based window name = obj.WindowParts[(i*5)] mtype = obj.WindowParts[(i*5)+1] - ccol = self.getSolidMaterial(obj,name,mtype) + color = self.getSolidMaterial(obj,arch_mat,name,mtype) elif obj.Base and hasattr(obj.Base,"Shape"): # Type-based window: obj.Base furnishes the window solids sol1 = self.getSolidSignature(solids[i]) @@ -703,20 +726,27 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent): if hasattr(child,"Shape") and child.Shape and child.Shape.Solids: sol2 = self.getSolidSignature(child.Shape) if sol1 == sol2: - ccol = self.getSolidMaterial(obj,child.Label) + color = self.getSolidMaterial(obj,arch_mat,child.Label) break - if not ccol: + if color is None: typeidx = (i*5)+1 if typeidx < len(obj.WindowParts): typ = obj.WindowParts[typeidx] if typ == WindowPartTypes[2]: # "Glass panel" - ccol = ArchCommands.getDefaultColor("WindowGlass") - if not ccol: - ccol = base - colors.extend([ccol for f in solids[i].Faces]) - #print("colors: ",colors) - if self.areDifferentColors(colors,obj.ViewObject.DiffuseColor) or force: - obj.ViewObject.DiffuseColor = colors + color = ArchCommands.getDefaultColor("WindowGlass") + + if color is None: + sapp_mat = base_sapp_mat + else: + sapp_mat = FreeCAD.Material() # ShapeAppearance material with default v0.21 properties. + sapp_mat.DiffuseColor = color[:3] + (0.0, ) + sapp_mat.Transparency = color[3] + sapp.extend((sapp_mat, ) * len(solids[i].Faces)) + + if clone is not None: + obj = clone + if not _shapeAppearanceIsSame(obj.ViewObject.ShapeAppearance, sapp): + obj.ViewObject.ShapeAppearance = sapp def getSolidSignature(self,solid): @@ -724,26 +754,23 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent): return (solid.ShapeType,round(solid.Volume,3),round(solid.Area,3),round(solid.Length,3)) - def getSolidMaterial(self,obj,name,mtype=None): + def getSolidMaterial(self,obj,arch_mat,name,mtype=None): - ccol = None - if hasattr(obj,"Material"): - if obj.Material: - if hasattr(obj.Material,"Materials"): - if obj.Material.Names: - mat = None - if name in obj.Material.Names: - mat = obj.Material.Materials[obj.Material.Names.index(name)] - elif mtype and (mtype in obj.Material.Names): - mat = obj.Material.Materials[obj.Material.Names.index(mtype)] - if mat: - if 'DiffuseColor' in mat.Material: - if "(" in mat.Material['DiffuseColor']: - ccol = tuple([float(f) for f in mat.Material['DiffuseColor'].strip("()").split(",")]) - if ccol and ('Transparency' in mat.Material): - t = float(mat.Material['Transparency'])/100.0 - ccol = (ccol[0],ccol[1],ccol[2],t) - return ccol + color = None + if arch_mat is not None and hasattr(arch_mat,"Materials") and arch_mat.Names: + mat = None + if name in arch_mat.Names: + mat = arch_mat.Materials[arch_mat.Names.index(name)] + elif mtype is not None and (mtype in arch_mat.Names): + mat = arch_mat.Materials[arch_mat.Names.index(mtype)] + if mat: + if 'DiffuseColor' in mat.Material: + if "(" in mat.Material['DiffuseColor']: + color = tuple([float(f) for f in mat.Material['DiffuseColor'].strip("()").split(",")]) + if color and ('Transparency' in mat.Material): + t = float(mat.Material['Transparency'])/100.0 + color = color[:3] + (t, ) + return color def getHingeEdgeIndices(self):