Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fc4142cfec | |||
| a515f31726 | |||
| e0a0dc2f0d | |||
| 02d6c4f412 | |||
| e129aba2fe | |||
| 9d65323052 | |||
| 0b13a8c5f1 |
@@ -760,7 +760,7 @@ class EarthWorksTaskPanel:
|
|||||||
if len(section) > 0:
|
if len(section) > 0:
|
||||||
try:
|
try:
|
||||||
boundary.add(Part.makePolygon(section))
|
boundary.add(Part.makePolygon(section))
|
||||||
except:
|
except Part.OCCError:
|
||||||
pass
|
pass
|
||||||
Part.show(boundary)'''
|
Part.show(boundary)'''
|
||||||
#mesh.smooth("Laplace", 3)
|
#mesh.smooth("Laplace", 3)
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ def get_elevation_from_oe(coordinates): # v1 deepseek
|
|||||||
response.raise_for_status() # Lanza excepción para códigos 4xx/5xx
|
response.raise_for_status() # Lanza excepción para códigos 4xx/5xx
|
||||||
|
|
||||||
except RequestException as e:
|
except RequestException as e:
|
||||||
print(f"Error en la solicitud: {str(e)}")
|
print(f"Error en la solicitud: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -95,7 +95,7 @@ def get_elevation_from_oe(coordinates): # v1 deepseek
|
|||||||
round(result["elevation"])) * 1000)
|
round(result["elevation"])) * 1000)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error procesando coordenadas: {str(e)}")
|
print(f"Error procesando coordenadas: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return points
|
return points
|
||||||
@@ -392,7 +392,7 @@ def getElevation1(polygon,resolution=10):
|
|||||||
|
|
||||||
s = json.loads(ans)
|
s = json.loads(ans)
|
||||||
res = s['results']
|
res = s['results']
|
||||||
except:
|
except (json.JSONDecodeError, KeyError):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
#points = []
|
#points = []
|
||||||
@@ -526,7 +526,7 @@ class _ImportPointsTaskPanel:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
PointGroups = FreeCAD.ActiveDocument.Point_Groups
|
PointGroups = FreeCAD.ActiveDocument.Point_Groups
|
||||||
except:
|
except AttributeError:
|
||||||
PointGroups = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", 'Point_Groups')
|
PointGroups = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", 'Point_Groups')
|
||||||
PointGroups.Label = "Point Groups"
|
PointGroups.Label = "Point Groups"
|
||||||
|
|
||||||
|
|||||||
+35
-41
@@ -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
|
if obj.Terrain.Shape.Solids:
|
||||||
# compute volumes
|
shapesolid = obj.Terrain.Shape.copy()
|
||||||
if obj.Terrain.Shape.Solids:
|
else:
|
||||||
shapesolid = obj.Terrain.Shape.copy()
|
shapesolid = obj.Terrain.Shape.extrude(obj.ExtrusionVector)
|
||||||
else:
|
except Exception:
|
||||||
shapesolid = obj.Terrain.Shape.extrude(obj.ExtrusionVector)
|
return
|
||||||
addvol = 0
|
|
||||||
subvol = 0
|
subvol = sum(sub.Shape.common(shapesolid).Volume for sub in obj.Subtractions)
|
||||||
for sub in obj.Subtractions:
|
addvol = sum(sub.Shape.cut(shapesolid).Volume for sub in obj.Additions)
|
||||||
subvol += sub.Shape.common(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)
|
||||||
|
|||||||
+147
-71
@@ -129,8 +129,14 @@ class Terrain(ArchComponent.Component):
|
|||||||
# obj.IfcType = "Fence"
|
# obj.IfcType = "Fence"
|
||||||
# obj.MoveWithHost = False
|
# obj.MoveWithHost = False
|
||||||
|
|
||||||
self.site = PVPlantSite.get()
|
try:
|
||||||
self.site.Terrain = obj
|
self.site = PVPlantSite.get()
|
||||||
|
except Exception:
|
||||||
|
self.site = None
|
||||||
|
if self.site:
|
||||||
|
self.site.Terrain = obj
|
||||||
|
else:
|
||||||
|
FreeCAD.Console.PrintWarning('Terrain: No se encontró Site, algunas funciones DEM requerirán Site.\n')
|
||||||
obj.ViewObject.ShapeColor = (0.0000, 0.6667, 0.4980)
|
obj.ViewObject.ShapeColor = (0.0000, 0.6667, 0.4980)
|
||||||
obj.ViewObject.LineColor = (0.0000, 0.6000, 0.4392)
|
obj.ViewObject.LineColor = (0.0000, 0.6000, 0.4392)
|
||||||
|
|
||||||
@@ -192,6 +198,12 @@ class Terrain(ArchComponent.Component):
|
|||||||
|
|
||||||
if prop == "InitialMesh":
|
if prop == "InitialMesh":
|
||||||
obj.mesh = obj.InitialMesh.copy()
|
obj.mesh = obj.InitialMesh.copy()
|
||||||
|
# Forzar actualización visual
|
||||||
|
obj.publishProperty("Mesh")
|
||||||
|
|
||||||
|
if prop == "mesh":
|
||||||
|
# La propiedad mesh cambió → forzar recompute para que updateData se dispare
|
||||||
|
pass
|
||||||
|
|
||||||
if prop == "DEM" or prop == "CuttingBoundary":
|
if prop == "DEM" or prop == "CuttingBoundary":
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@@ -237,7 +249,7 @@ class Terrain(ArchComponent.Component):
|
|||||||
del templist
|
del templist
|
||||||
|
|
||||||
# create xy coordinates
|
# create xy coordinates
|
||||||
offset = self.site.Origin
|
offset = self.site.Origin if self.site else FreeCAD.Vector(0, 0, 0)
|
||||||
x = (cellsize * np.arange(nx)[0::coarse_factor] + xllvalue) * 1000 - offset.x
|
x = (cellsize * np.arange(nx)[0::coarse_factor] + xllvalue) * 1000 - offset.x
|
||||||
y = (cellsize * np.arange(ny)[-1::-1][0::coarse_factor] + yllvalue) * 1000 - offset.y
|
y = (cellsize * np.arange(ny)[-1::-1][0::coarse_factor] + yllvalue) * 1000 - offset.y
|
||||||
datavals = datavals * 1000 # Ajuste de altura
|
datavals = datavals * 1000 # Ajuste de altura
|
||||||
@@ -269,35 +281,95 @@ class Terrain(ArchComponent.Component):
|
|||||||
stepx = math.ceil(nx / stepsize)
|
stepx = math.ceil(nx / stepsize)
|
||||||
stepy = math.ceil(ny / stepsize)
|
stepy = math.ceil(ny / stepsize)
|
||||||
|
|
||||||
|
# Malla completa primero como numpy y filtramos todo de una
|
||||||
|
from datetime import datetime
|
||||||
|
t_start = datetime.now()
|
||||||
|
|
||||||
|
# Crear grid completo de coordenadas
|
||||||
|
XX, YY = np.meshgrid(x, y)
|
||||||
|
ZZ = datavals.copy()
|
||||||
|
|
||||||
|
# Enmascarar nodata
|
||||||
|
mask_valida = ZZ != nodata_value
|
||||||
|
|
||||||
|
# Enmascarar cutting boundary si existe
|
||||||
|
if obj.CuttingBoundary:
|
||||||
|
from FreeCAD import Base
|
||||||
|
shape = obj.CuttingBoundary.Shape
|
||||||
|
mask_boundary = np.zeros_like(ZZ, dtype=bool)
|
||||||
|
# Sampling: revisar solo puntos estratégicos para boundary grande
|
||||||
|
stride = max(1, min(nx, ny) // 200)
|
||||||
|
for i in range(0, ny, stride):
|
||||||
|
for j in range(0, nx, stride):
|
||||||
|
if mask_valida[i, j]:
|
||||||
|
if shape.isInside(FreeCAD.Vector(x[j], y[i], 0), 0, True):
|
||||||
|
mask_boundary[i, j] = True
|
||||||
|
mask_valida = mask_valida & mask_boundary
|
||||||
|
|
||||||
|
# Extraer puntos válidos como lista plana
|
||||||
|
pts_validos = np.column_stack([
|
||||||
|
XX[mask_valida].ravel(),
|
||||||
|
YY[mask_valida].ravel(),
|
||||||
|
ZZ[mask_valida].ravel()
|
||||||
|
])
|
||||||
|
|
||||||
|
del XX, YY, ZZ, mask_valida
|
||||||
|
|
||||||
|
# Triangulación completa de una vez (no por parches)
|
||||||
mesh = Mesh.Mesh()
|
mesh = Mesh.Mesh()
|
||||||
for indx in range(stepx):
|
if len(pts_validos) > 3:
|
||||||
inix = indx * stepsize - 1
|
# Si hay muchos puntos, triangulamos por parches para evitar OOM
|
||||||
finx = min([stepsize * (indx + 1), len(x)-1])
|
patch_size = 50000
|
||||||
for indy in range(stepy):
|
n_patches = max(1, math.ceil(len(pts_validos) / patch_size))
|
||||||
iniy = indy * stepsize - 1
|
for p in range(n_patches):
|
||||||
finy = min([stepsize * (indy + 1), len(y) - 1])
|
patch = pts_validos[p * patch_size:(p + 1) * patch_size].tolist()
|
||||||
pts = []
|
if len(patch) > 3:
|
||||||
for i in range(inix, finx):
|
|
||||||
for j in range(iniy, finy):
|
|
||||||
if datavals[j][i] != nodata_value:
|
|
||||||
if obj.CuttingBoundary:
|
|
||||||
if obj.CuttingBoundary.Shape.isInside(FreeCAD.Vector(x[i], y[j], 0), 0, True):
|
|
||||||
pts.append([x[i], y[j], datavals[j][i]])
|
|
||||||
else:
|
|
||||||
pts.append([x[i], y[j], datavals[j][i]])
|
|
||||||
if len(pts) > 3:
|
|
||||||
try:
|
try:
|
||||||
triangulated = Triangulation.Triangulate(pts)
|
triangulated = Triangulation.Triangulate(patch)
|
||||||
mesh.addMesh(triangulated)
|
mesh.addMesh(triangulated)
|
||||||
except TypeError:
|
except TypeError as e:
|
||||||
print(f"Error al procesar {len(pts)} puntos: {str(e)}")
|
print(f"Patch {p}: error al procesar {len(patch)} puntos: {str(e)}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Patch {p}: error inesperado: {str(e)}")
|
||||||
|
|
||||||
|
print(f'Terraín DEM: {len(pts_validos)} pts válidos, {n_patches} parches, {datetime.now()-t_start}')
|
||||||
|
del pts_validos
|
||||||
|
|
||||||
mesh.removeDuplicatedPoints()
|
mesh.removeDuplicatedPoints()
|
||||||
mesh.removeFoldsOnSurface()
|
mesh.removeFoldsOnSurface()
|
||||||
obj.InitialMesh = mesh.copy()
|
obj.InitialMesh = mesh.copy()
|
||||||
Mesh.show(mesh)
|
# Limpiar objetos mesh huérfanos previos si existen
|
||||||
|
for o in FreeCAD.ActiveDocument.Objects:
|
||||||
|
if o.TypeId == 'Mesh::Feature' and o.Label.startswith('Terrain_mesh_'):
|
||||||
|
FreeCAD.ActiveDocument.removeObject(o.Name)
|
||||||
|
mesh_obj = Mesh.show(mesh)
|
||||||
|
mesh_obj.Label = 'Terrain_mesh_' + obj.Label
|
||||||
elif suffix in ['.xyz']:
|
elif suffix in ['.xyz']:
|
||||||
data = open_xyz_mmap(obj.DEM)
|
pts_array = open_xyz_mmap(obj.DEM)
|
||||||
|
if pts_array is not None and len(pts_array) > 3:
|
||||||
|
import MeshTools.Triangulation as Triangulation
|
||||||
|
import Mesh
|
||||||
|
if obj.CuttingBoundary:
|
||||||
|
mask = []
|
||||||
|
for pt in pts_array:
|
||||||
|
mask.append(obj.CuttingBoundary.Shape.isInside(
|
||||||
|
FreeCAD.Vector(pt[0], pt[1], 0), 0, True))
|
||||||
|
pts_array = pts_array[mask]
|
||||||
|
if len(pts_array) > 3:
|
||||||
|
from datetime import datetime
|
||||||
|
t0 = datetime.now()
|
||||||
|
pts_list = pts_array.tolist()
|
||||||
|
mesh = Triangulation.Triangulate(pts_list)
|
||||||
|
mesh.removeDuplicatedPoints()
|
||||||
|
mesh.removeFoldsOnSurface()
|
||||||
|
obj.InitialMesh = mesh.copy()
|
||||||
|
# Limpiar objetos mesh huérfanos previos
|
||||||
|
for o in FreeCAD.ActiveDocument.Objects:
|
||||||
|
if o.TypeId == 'Mesh::Feature' and o.Label.startswith('Terrain_mesh_'):
|
||||||
|
FreeCAD.ActiveDocument.removeObject(o.Name)
|
||||||
|
mesh_obj = Mesh.show(mesh)
|
||||||
|
mesh_obj.Label = 'Terrain_mesh_' + obj.Label
|
||||||
|
print(f'XYZ import: {len(pts_array)} puntos en {datetime.now()-t0}')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -329,6 +401,11 @@ class Terrain(ArchComponent.Component):
|
|||||||
if obj.DEM:
|
if obj.DEM:
|
||||||
obj.DEM = None
|
obj.DEM = None
|
||||||
obj.mesh = mesh
|
obj.mesh = mesh
|
||||||
|
# Forzar actualización visual llamando a publishProperty
|
||||||
|
try:
|
||||||
|
obj.publishProperty("Mesh")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def execute(self, obj):
|
def execute(self, obj):
|
||||||
''''''
|
''''''
|
||||||
@@ -547,47 +624,47 @@ class ViewProviderTerrain:
|
|||||||
offset.factor = -2.0
|
offset.factor = -2.0
|
||||||
|
|
||||||
# Boundary features.
|
# Boundary features.
|
||||||
'''self.boundary_color = coin.SoBaseColor()
|
self.boundary_color = coin.SoBaseColor()
|
||||||
self.boundary_coords = coin.SoGeoCoordinate()
|
self.boundary_coords = coin.SoGeoCoordinate()
|
||||||
self.boundary_lines = coin.SoLineSet()
|
self.boundary_lines = coin.SoLineSet()
|
||||||
self.boundary_style = coin.SoDrawStyle()
|
self.boundary_style = coin.SoDrawStyle()
|
||||||
self.boundary_style.style = coin.SoDrawStyle.LINES'''
|
self.boundary_style.style = coin.SoDrawStyle.LINES
|
||||||
|
|
||||||
# Boundary root.
|
# Boundary root.
|
||||||
'''boundaries = coin.SoType.fromName('SoFCSelection').createInstance()
|
boundaries = coin.SoType.fromName('SoFCSelection').createInstance()
|
||||||
boundaries.style = 'EMISSIVE_DIFFUSE'
|
boundaries.style = 'EMISSIVE_DIFFUSE'
|
||||||
boundaries.addChild(self.boundary_color)
|
boundaries.addChild(self.boundary_color)
|
||||||
boundaries.addChild(self.boundary_style)
|
boundaries.addChild(self.boundary_style)
|
||||||
boundaries.addChild(self.boundary_coords)
|
boundaries.addChild(self.boundary_coords)
|
||||||
boundaries.addChild(self.boundary_lines)'''
|
boundaries.addChild(self.boundary_lines)
|
||||||
|
|
||||||
# Major Contour features.
|
# Major Contour features.
|
||||||
'''self.major_color = coin.SoBaseColor()
|
self.major_color = coin.SoBaseColor()
|
||||||
self.major_coords = coin.SoGeoCoordinate()
|
self.major_coords = coin.SoGeoCoordinate()
|
||||||
self.major_lines = coin.SoLineSet()
|
self.major_lines = coin.SoLineSet()
|
||||||
self.major_style = coin.SoDrawStyle()
|
self.major_style = coin.SoDrawStyle()
|
||||||
self.major_style.style = coin.SoDrawStyle.LINES'''
|
self.major_style.style = coin.SoDrawStyle.LINES
|
||||||
|
|
||||||
# Major Contour root.
|
# Major Contour root.
|
||||||
'''major_contours = coin.SoSeparator()
|
major_contours = coin.SoSeparator()
|
||||||
major_contours.addChild(self.major_color)
|
major_contours.addChild(self.major_color)
|
||||||
major_contours.addChild(self.major_style)
|
major_contours.addChild(self.major_style)
|
||||||
major_contours.addChild(self.major_coords)
|
major_contours.addChild(self.major_coords)
|
||||||
major_contours.addChild(self.major_lines)'''
|
major_contours.addChild(self.major_lines)
|
||||||
|
|
||||||
# Minor Contour features.
|
# Minor Contour features.
|
||||||
'''self.minor_color = coin.SoBaseColor()
|
self.minor_color = coin.SoBaseColor()
|
||||||
self.minor_coords = coin.SoGeoCoordinate()
|
self.minor_coords = coin.SoGeoCoordinate()
|
||||||
self.minor_lines = coin.SoLineSet()
|
self.minor_lines = coin.SoLineSet()
|
||||||
self.minor_style = coin.SoDrawStyle()
|
self.minor_style = coin.SoDrawStyle()
|
||||||
self.minor_style.style = coin.SoDrawStyle.LINES'''
|
self.minor_style.style = coin.SoDrawStyle.LINES
|
||||||
|
|
||||||
# Minor Contour root.
|
# Minor Contour root.
|
||||||
'''minor_contours = coin.SoSeparator()
|
minor_contours = coin.SoSeparator()
|
||||||
minor_contours.addChild(self.minor_color)
|
minor_contours.addChild(self.minor_color)
|
||||||
minor_contours.addChild(self.minor_style)
|
minor_contours.addChild(self.minor_style)
|
||||||
minor_contours.addChild(self.minor_coords)
|
minor_contours.addChild(self.minor_coords)
|
||||||
minor_contours.addChild(self.minor_lines)'''
|
minor_contours.addChild(self.minor_lines)
|
||||||
|
|
||||||
# Highlight for selection.
|
# Highlight for selection.
|
||||||
highlight = coin.SoType.fromName('SoFCSelection').createInstance()
|
highlight = coin.SoType.fromName('SoFCSelection').createInstance()
|
||||||
@@ -596,7 +673,7 @@ class ViewProviderTerrain:
|
|||||||
highlight.addChild(mat_binding)
|
highlight.addChild(mat_binding)
|
||||||
highlight.addChild(self.geo_coords)
|
highlight.addChild(self.geo_coords)
|
||||||
highlight.addChild(self.triangles)
|
highlight.addChild(self.triangles)
|
||||||
#highlight.addChild(boundaries)
|
highlight.addChild(boundaries)
|
||||||
|
|
||||||
# Face root.
|
# Face root.
|
||||||
face = coin.SoSeparator()
|
face = coin.SoSeparator()
|
||||||
@@ -609,19 +686,19 @@ class ViewProviderTerrain:
|
|||||||
edge.addChild(self.edge_style)
|
edge.addChild(self.edge_style)
|
||||||
edge.addChild(highlight)
|
edge.addChild(highlight)
|
||||||
|
|
||||||
# Surface root.
|
# Surface root - con contour lines visibles.
|
||||||
surface_root = coin.SoSeparator()
|
surface_root = coin.SoSeparator()
|
||||||
surface_root.addChild(face)
|
surface_root.addChild(face)
|
||||||
surface_root.addChild(offset)
|
surface_root.addChild(offset)
|
||||||
surface_root.addChild(edge)
|
surface_root.addChild(edge)
|
||||||
#surface_root.addChild(major_contours)
|
surface_root.addChild(major_contours)
|
||||||
#surface_root.addChild(minor_contours)
|
surface_root.addChild(minor_contours)
|
||||||
vobj.addDisplayMode(surface_root, "Surface")
|
vobj.addDisplayMode(surface_root, "Surface")
|
||||||
|
|
||||||
# Boundary root.
|
# Boundary root.
|
||||||
#boundary_root = coin.SoSeparator()
|
boundary_root = coin.SoSeparator()
|
||||||
#boundary_root.addChild(boundaries)
|
boundary_root.addChild(boundaries)
|
||||||
#vobj.addDisplayMode(boundary_root, "Boundary")
|
vobj.addDisplayMode(boundary_root, "Boundary")
|
||||||
|
|
||||||
# Elevation/Shaded root.
|
# Elevation/Shaded root.
|
||||||
'''shaded_root = coin.SoSeparator()
|
'''shaded_root = coin.SoSeparator()
|
||||||
@@ -648,52 +725,50 @@ class ViewProviderTerrain:
|
|||||||
self.onChanged(vobj, "ShapeColor")
|
self.onChanged(vobj, "ShapeColor")
|
||||||
self.onChanged(vobj, "LineColor")
|
self.onChanged(vobj, "LineColor")
|
||||||
self.onChanged(vobj, "LineWidth")
|
self.onChanged(vobj, "LineWidth")
|
||||||
#self.onChanged(vobj, "BoundaryColor")
|
self.onChanged(vobj, "BoundaryColor")
|
||||||
#self.onChanged(vobj, "BoundaryWidth")
|
self.onChanged(vobj, "BoundaryWidth")
|
||||||
#self.onChanged(vobj, "BoundaryPattern")
|
self.onChanged(vobj, "BoundaryPattern")
|
||||||
#self.onChanged(vobj, "PatternScale")
|
self.onChanged(vobj, "PatternScale")
|
||||||
#self.onChanged(vobj, "MajorColor")
|
self.onChanged(vobj, "MajorColor")
|
||||||
#self.onChanged(vobj, "MajorWidth")
|
self.onChanged(vobj, "MajorWidth")
|
||||||
#self.onChanged(vobj, "MinorColor")
|
self.onChanged(vobj, "MinorColor")
|
||||||
#self.onChanged(vobj, "MinorWidth")
|
self.onChanged(vobj, "MinorWidth")
|
||||||
|
|
||||||
def updateData(self, obj, prop):
|
def updateData(self, obj, prop):
|
||||||
''' Update Object visuals when a data property changed. '''
|
''' Update Object visuals when a data property changed. '''
|
||||||
|
|
||||||
# Set geosystem.
|
# Set geosystem.
|
||||||
geo_system = ["UTM", FreeCAD.ActiveDocument.Site.UtmZone, "FLAT"]
|
try:
|
||||||
|
utm_zone = FreeCAD.ActiveDocument.Site.UtmZone
|
||||||
|
except:
|
||||||
|
utm_zone = "30"
|
||||||
|
geo_system = ["UTM", utm_zone, "FLAT"]
|
||||||
self.geo_coords.geoSystem.setValues(geo_system)
|
self.geo_coords.geoSystem.setValues(geo_system)
|
||||||
'''
|
|
||||||
self.boundary_coords.geoSystem.setValues(geo_system)
|
self.boundary_coords.geoSystem.setValues(geo_system)
|
||||||
self.major_coords.geoSystem.setValues(geo_system)
|
self.major_coords.geoSystem.setValues(geo_system)
|
||||||
self.minor_coords.geoSystem.setValues(geo_system)
|
self.minor_coords.geoSystem.setValues(geo_system)
|
||||||
'''
|
|
||||||
|
|
||||||
if prop == "Mesh":
|
if prop == "mesh" or prop == "Mesh":
|
||||||
if obj.mesh:
|
if obj.mesh:
|
||||||
print("Mostrar mesh")
|
|
||||||
|
|
||||||
mesh = obj.mesh
|
mesh = obj.mesh
|
||||||
vertices = [tuple(v) for v in mesh.Topology[0]]
|
try:
|
||||||
faces = []
|
vertices = [tuple(v) for v in mesh.Topology[0]]
|
||||||
for face in mesh.Topology[1]:
|
faces = []
|
||||||
faces.extend(face)
|
for face in mesh.Topology[1]:
|
||||||
faces.append(-1)
|
faces.extend(face)
|
||||||
|
faces.append(-1)
|
||||||
|
|
||||||
# Asignar a los nodos de visualización
|
# Asignar a los nodos de visualización
|
||||||
self.geo_coords.point.values = vertices # <-- ¡Clave!
|
self.geo_coords.point.values = vertices
|
||||||
self.triangles.coordIndex.values = faces # <-- ¡Clave!
|
self.triangles.coordIndex.values = faces
|
||||||
|
except Exception as e:
|
||||||
|
FreeCAD.Console.PrintError(f"Error actualizando mesh visual: {e}\n")
|
||||||
|
|
||||||
def getDisplayModes(self, vobj):
|
def getDisplayModes(self, vobj):
|
||||||
''' Return a list of display modes. '''
|
''' Return a list of display modes. '''
|
||||||
modes = ["Surface", "Boundary"]
|
return ["Surface", "Boundary", "Flat Lines", "Wireframe"]
|
||||||
|
|
||||||
return modes
|
|
||||||
|
|
||||||
def getDefaultDisplayMode(self):
|
def getDefaultDisplayMode(self):
|
||||||
'''
|
|
||||||
Return the name of the default display mode.
|
|
||||||
'''
|
|
||||||
return "Surface"
|
return "Surface"
|
||||||
|
|
||||||
def claimChildren(self):
|
def claimChildren(self):
|
||||||
@@ -736,3 +811,4 @@ class ViewProviderTerrain:
|
|||||||
|
|
||||||
if FreeCAD.GuiUp:
|
if FreeCAD.GuiUp:
|
||||||
FreeCADGui.addCommand('Terrain', _CommandTerrain())'''
|
FreeCADGui.addCommand('Terrain', _CommandTerrain())'''
|
||||||
|
|
||||||
|
|||||||
@@ -450,35 +450,18 @@ class ContourTaskPanel():
|
|||||||
starttime = datetime.now()
|
starttime = datetime.now()
|
||||||
|
|
||||||
if self.land is None:
|
if self.land is None:
|
||||||
print("No hay objetos para procesar")
|
FreeCAD.Console.PrintWarning("No hay objetos para procesar\n")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
minor = FreeCAD.Units.Quantity(self.inputMinorContourMargin.currentText()).Value
|
minor = FreeCAD.Units.Quantity(self.inputMinorContourMargin.currentText()).Value
|
||||||
mayor = FreeCAD.Units.Quantity(self.inputMayorContourMargin.currentText()).Value
|
mayor = FreeCAD.Units.Quantity(self.inputMayorContourMargin.currentText()).Value
|
||||||
|
|
||||||
i = 2
|
makeContours(
|
||||||
if i == 0:
|
self.land, minor, mayor,
|
||||||
makeContours(self.land, minor, mayor, self.MinorColor, self.MayorColor,
|
self.MinorColor, self.MayorColor,
|
||||||
self.inputMinorContourThickness.value(), self.inputMayorContourThickness.value())
|
self.inputMinorContourThickness.value(),
|
||||||
elif i == 1:
|
self.inputMayorContourThickness.value()
|
||||||
import multiprocessing
|
)
|
||||||
p = multiprocessing.Process(target=makeContours,
|
|
||||||
args=(self.land, minor, mayor,
|
|
||||||
self.MinorColor, self.MayorColor,
|
|
||||||
self.inputMinorContourThickness.value(),
|
|
||||||
self.inputMayorContourThickness.value(), ))
|
|
||||||
p.start()
|
|
||||||
p.join()
|
|
||||||
|
|
||||||
else:
|
|
||||||
import threading
|
|
||||||
hilo = threading.Thread(target = makeContours,
|
|
||||||
args = (self.land, minor, mayor,
|
|
||||||
self.MinorColor, self.MayorColor,
|
|
||||||
self.inputMinorContourThickness.value(),
|
|
||||||
self.inputMayorContourThickness.value()))
|
|
||||||
hilo.daemon = True
|
|
||||||
hilo.start()
|
|
||||||
|
|
||||||
total_time = datetime.now() - starttime
|
total_time = datetime.now() - starttime
|
||||||
print(" -- Tiempo tardado:", total_time)
|
print(" -- Tiempo tardado:", total_time)
|
||||||
@@ -569,7 +552,7 @@ class SlopeTaskPanel(_generalTaskPanel):
|
|||||||
land.ViewObject.DiffuseColor = colorlist
|
land.ViewObject.DiffuseColor = colorlist
|
||||||
|
|
||||||
# TODO: check this code:
|
# TODO: check this code:
|
||||||
elif obj.isDerivedFrom("Mesh::Feature"):
|
elif hasattr(land, 'Mesh') and land.isDerivedFrom("Mesh::Feature"):
|
||||||
fMesh = Mest2FemMesh(land)
|
fMesh = Mest2FemMesh(land)
|
||||||
import math
|
import math
|
||||||
setColors = []
|
setColors = []
|
||||||
@@ -602,10 +585,7 @@ class SlopeTaskPanel(_generalTaskPanel):
|
|||||||
print("Everything OK (", datetime.now() - starttime, ")")
|
print("Everything OK (", datetime.now() - starttime, ")")
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
# self.getPointSlope()
|
self.getPointSlope(self.ranges)
|
||||||
import threading
|
|
||||||
hilo = threading.Thread(target=self.getPointSlope(self.ranges))
|
|
||||||
hilo.start()
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Orientation Analisys: ---------------------------------------------------------------------------------
|
# Orientation Analisys: ---------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ def calculate_incenter(facet):
|
|||||||
"""Calcula el incentro usando la función nativa de FreeCAD"""
|
"""Calcula el incentro usando la función nativa de FreeCAD"""
|
||||||
try:
|
try:
|
||||||
return facet.InCircle[0] # (x, y, z)
|
return facet.InCircle[0] # (x, y, z)
|
||||||
except:
|
except (IndexError, AttributeError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user