Site: fix computeAreas return prematuro, excepts genéricos a ImportError/Exception

This commit is contained in:
2026-05-02 23:16:27 +02:00
parent 9d65323052
commit e129aba2fe
+31 -37
View File
@@ -182,16 +182,14 @@ def makeSolarDiagram(longitude, latitude, scale=1, complete=False, tz=None):
import ladybug import ladybug
from ladybug import location from ladybug import location
from ladybug import sunpath from ladybug import sunpath
except: except ImportError:
# TODO - remove pysolar dependency
# FreeCAD.Console.PrintWarning("Ladybug module not found, using pysolar instead. Warning, this will be deprecated in the future\n")
ladybug = False ladybug = False
try: try:
import pysolar import pysolar
except: except ImportError:
try: try:
import Pysolar as pysolar import Pysolar as pysolar
except: except ImportError:
FreeCAD.Console.PrintError("The pysolar module was not found. Unable to generate solar diagrams\n") FreeCAD.Console.PrintError("The pysolar module was not found. Unable to generate solar diagrams\n")
return None return None
else: else:
@@ -361,7 +359,7 @@ def makeWindRose(epwfile, scale=1, sectors=24):
try: try:
import ladybug import ladybug
from ladybug import epw from ladybug import epw
except: except ImportError:
FreeCAD.Console.PrintError("The ladybug module was not found. Unable to generate solar diagrams\n") FreeCAD.Console.PrintError("The ladybug module was not found. Unable to generate solar diagrams\n")
return None return None
if not epwfile: if not epwfile:
@@ -667,23 +665,22 @@ class _PVPlantSite(ArchSite._Site):
self.computeAreas(obj) self.computeAreas(obj)
def computeAreas(self, obj): def computeAreas(self, obj):
"""
Compute areas, perimeter and volumes.
Override to add custom logic after parent computation.
"""
ArchSite._Site.computeAreas(self, obj) ArchSite._Site.computeAreas(self, obj)
return
if not obj.Shape: if not obj.Shape:
return return
if obj.Shape.isNull() or not obj.Shape.isValid() or not obj.Shape.Faces:
if obj.Shape.isNull():
return return
if not obj.Shape.isValid(): if not hasattr(obj, "Perimeter"):
return
if not obj.Shape.Faces:
return
if not hasattr(obj, "Perimeter"): # check we have a latest version site
return return
if not obj.Terrain: if not obj.Terrain:
return return
# compute area
# Compute projected area (horizontal projection of all near-horizontal faces)
fset = [] fset = []
for f in obj.Shape.Faces: for f in obj.Shape.Faces:
if f.normalAt(0, 0).getAngle(FreeCAD.Vector(0, 0, 1)) < 1.5707: if f.normalAt(0, 0).getAngle(FreeCAD.Vector(0, 0, 1)) < 1.5707:
@@ -694,13 +691,11 @@ class _PVPlantSite(ArchSite._Site):
for f in fset: for f in fset:
try: try:
pf = Part.Face(Part.Wire(Drawing.project(f, FreeCAD.Vector(0, 0, 1))[0].Edges)) pf = Part.Face(Part.Wire(Drawing.project(f, FreeCAD.Vector(0, 0, 1))[0].Edges))
except Part.OCCError:
# error in computing the area. Better set it to zero than show a wrong value
if obj.ProjectedArea.Value != 0:
print("Error computing areas for ", obj.Label)
obj.ProjectedArea = 0
else:
pset.append(pf) pset.append(pf)
except Part.OCCError:
if getattr(obj, 'ProjectedArea', None) and obj.ProjectedArea.Value != 0:
FreeCAD.Console.PrintWarning(f"Error computing projected area for {obj.Label}\n")
obj.ProjectedArea = 0
if pset: if pset:
self.flatarea = pset.pop() self.flatarea = pset.pop()
for f in pset: for f in pset:
@@ -708,28 +703,27 @@ class _PVPlantSite(ArchSite._Site):
self.flatarea = self.flatarea.removeSplitter() self.flatarea = self.flatarea.removeSplitter()
if obj.ProjectedArea.Value != self.flatarea.Area: if obj.ProjectedArea.Value != self.flatarea.Area:
obj.ProjectedArea = self.flatarea.Area obj.ProjectedArea = self.flatarea.Area
# compute perimeter
# Compute perimeter (border edges only)
lut = {} lut = {}
for e in obj.Shape.Edges: for e in obj.Shape.Edges:
lut.setdefault(e.hashCode(), []).append(e) lut.setdefault(e.hashCode(), []).append(e)
l = 0 perimeter = sum(e[0].Length for e in lut.values() if len(e) == 1)
for e in lut.values(): if perimeter and obj.Perimeter.Value != perimeter:
if len(e) == 1: # keep only border edges obj.Perimeter = perimeter
l += e[0].Length
if l: # Compute cut/fill volumes relative to terrain
if obj.Perimeter.Value != l: try:
obj.Perimeter = l
# compute volumes
if obj.Terrain.Shape.Solids: if obj.Terrain.Shape.Solids:
shapesolid = obj.Terrain.Shape.copy() shapesolid = obj.Terrain.Shape.copy()
else: else:
shapesolid = obj.Terrain.Shape.extrude(obj.ExtrusionVector) shapesolid = obj.Terrain.Shape.extrude(obj.ExtrusionVector)
addvol = 0 except Exception:
subvol = 0 return
for sub in obj.Subtractions:
subvol += sub.Shape.common(shapesolid).Volume subvol = sum(sub.Shape.common(shapesolid).Volume for sub in obj.Subtractions)
for sub in obj.Additions: addvol = sum(sub.Shape.cut(shapesolid).Volume for sub in obj.Additions)
addvol += sub.Shape.cut(shapesolid).Volume
if obj.SubtractionVolume.Value != subvol: if obj.SubtractionVolume.Value != subvol:
obj.SubtractionVolume = subvol obj.SubtractionVolume = subvol
if obj.AdditionVolume.Value != addvol: if obj.AdditionVolume.Value != addvol:
@@ -1056,7 +1050,7 @@ class _ViewProviderSite:
if hasattr(vobj.Object,"EPWFile") and vobj.Object.EPWFile: if hasattr(vobj.Object,"EPWFile") and vobj.Object.EPWFile:
try: try:
import ladybug import ladybug
except: except ImportError:
pass pass
else: else:
self.windrosenode = makeWindRose(vobj.Object.EPWFile,vobj.SolarDiagramScale) self.windrosenode = makeWindRose(vobj.Object.EPWFile,vobj.SolarDiagramScale)