updates
This commit is contained in:
@@ -141,29 +141,31 @@ def groupTrackersToTransformers(transformer_power, max_distance):
|
|||||||
|
|
||||||
for i, group in enumerate(transformer_groups):
|
for i, group in enumerate(transformer_groups):
|
||||||
# Crear la esfera que representará el CT
|
# Crear la esfera que representará el CT
|
||||||
ct_sphere = FreeCAD.ActiveDocument.addObject("Part::Sphere", f"CT_{i + 1}")
|
ct_shape = FreeCAD.ActiveDocument.addObject("Part::Box", f"CT_{i + 1}")
|
||||||
ct_sphere.Radius = 5000 # 2m de radio
|
ct_shape.Length = 6058
|
||||||
ct_sphere.Placement.Base = FreeCAD.Vector(group['center'][0], group['center'][1], 0)
|
ct_shape.Width = 2438
|
||||||
|
ct_shape.Height = 2591
|
||||||
|
ct_shape.Placement.Base = FreeCAD.Vector(group['center'][0], group['center'][1], 0)
|
||||||
|
|
||||||
# Añadir propiedades personalizadas
|
# Añadir propiedades personalizadas
|
||||||
ct_sphere.addProperty("App::PropertyLinkList", "Trackers", "CT",
|
ct_shape.addProperty("App::PropertyLinkList", "Trackers", "CT",
|
||||||
"Lista de trackers asociados a este CT")
|
"Lista de trackers asociados a este CT")
|
||||||
ct_sphere.addProperty("App::PropertyFloat", "TotalPower", "CT",
|
ct_shape.addProperty("App::PropertyFloat", "TotalPower", "CT",
|
||||||
"Potencia total del grupo (W)")
|
"Potencia total del grupo (W)")
|
||||||
ct_sphere.addProperty("App::PropertyFloat", "NominalPower", "CT",
|
ct_shape.addProperty("App::PropertyFloat", "NominalPower", "CT",
|
||||||
"Potencia nominal del transformador (W)")
|
"Potencia nominal del transformador (W)")
|
||||||
ct_sphere.addProperty("App::PropertyFloat", "Utilization", "CT",
|
ct_shape.addProperty("App::PropertyFloat", "Utilization", "CT",
|
||||||
"Porcentaje de utilización (Total/Nominal)")
|
"Porcentaje de utilización (Total/Nominal)")
|
||||||
|
|
||||||
# Establecer valores de las propiedades
|
# Establecer valores de las propiedades
|
||||||
ct_sphere.Trackers = group['trackers']
|
ct_shape.Trackers = group['trackers']
|
||||||
ct_sphere.TotalPower = group['total_power'].Value
|
ct_shape.TotalPower = group['total_power'].Value
|
||||||
ct_sphere.NominalPower = transformer_power
|
ct_shape.NominalPower = transformer_power
|
||||||
ct_sphere.Utilization = (group['total_power'].Value / transformer_power) * 100
|
ct_shape.Utilization = (group['total_power'].Value / transformer_power) * 100
|
||||||
|
|
||||||
# Configurar visualización
|
# Configurar visualización
|
||||||
# Calcular color basado en utilización (verde < 100%, amarillo < 110%, rojo > 110%)
|
# Calcular color basado en utilización (verde < 100%, amarillo < 110%, rojo > 110%)
|
||||||
utilization = ct_sphere.Utilization
|
utilization = ct_shape.Utilization
|
||||||
if utilization <= 100:
|
if utilization <= 100:
|
||||||
color = (0.0, 1.0, 0.0) # Verde
|
color = (0.0, 1.0, 0.0) # Verde
|
||||||
elif utilization <= 110:
|
elif utilization <= 110:
|
||||||
@@ -171,15 +173,15 @@ def groupTrackersToTransformers(transformer_power, max_distance):
|
|||||||
else:
|
else:
|
||||||
color = (1.0, 0.0, 0.0) # Rojo
|
color = (1.0, 0.0, 0.0) # Rojo
|
||||||
|
|
||||||
ct_sphere.ViewObject.ShapeColor = color
|
ct_shape.ViewObject.ShapeColor = color
|
||||||
ct_sphere.ViewObject.Transparency = 40 # 40% de transparencia
|
ct_shape.ViewObject.Transparency = 40 # 40% de transparencia
|
||||||
|
|
||||||
# Añadir etiqueta con información
|
# Añadir etiqueta con información
|
||||||
ct_sphere.ViewObject.DisplayMode = "Shaded"
|
ct_shape.ViewObject.DisplayMode = "Shaded"
|
||||||
ct_sphere.Label = f"CT {i + 1} ({ct_sphere.TotalPower / 1000:.1f}kW/{ct_sphere.NominalPower / 1000:.1f}kW)"
|
ct_shape.Label = f"CT {i + 1} ({ct_shape.TotalPower / 1000:.1f}kW/{ct_shape.NominalPower / 1000:.1f}kW)"
|
||||||
|
|
||||||
# Añadir al grupo principal
|
# Añadir al grupo principal
|
||||||
transformer_group.addObject(ct_sphere)
|
transformer_group.addObject(ct_shape)
|
||||||
|
|
||||||
FreeCAD.Console.PrintMessage(f"Se crearon {len(transformer_groups)} centros de transformación\n")
|
FreeCAD.Console.PrintMessage(f"Se crearon {len(transformer_groups)} centros de transformación\n")
|
||||||
onSelectGatePoint()
|
onSelectGatePoint()
|
||||||
@@ -195,7 +197,7 @@ class InternalPathCreator:
|
|||||||
self.gate_point = gate_point
|
self.gate_point = gate_point
|
||||||
self.strategy = strategy
|
self.strategy = strategy
|
||||||
self.path_width = path_width
|
self.path_width = path_width
|
||||||
self.ct_spheres = []
|
self.ct_shapes = []
|
||||||
self.ct_positions = []
|
self.ct_positions = []
|
||||||
|
|
||||||
def get_transformers(self):
|
def get_transformers(self):
|
||||||
@@ -204,13 +206,13 @@ class InternalPathCreator:
|
|||||||
FreeCAD.Console.PrintError("No se encontró el grupo 'Transformers'\n")
|
FreeCAD.Console.PrintError("No se encontró el grupo 'Transformers'\n")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.ct_spheres = transformers_group.Group
|
self.ct_shapes = transformers_group.Group
|
||||||
if not self.ct_spheres:
|
if not self.ct_shapes:
|
||||||
FreeCAD.Console.PrintWarning("No hay Centros de Transformación en el grupo\n")
|
FreeCAD.Console.PrintWarning("No hay Centros de Transformación en el grupo\n")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Obtener las posiciones de los CTs
|
# Obtener las posiciones de los CTs
|
||||||
for sphere in self.ct_spheres:
|
for sphere in self.ct_shapes:
|
||||||
base = sphere.Placement.Base
|
base = sphere.Placement.Base
|
||||||
self.ct_positions.append(FreeCAD.Vector(base.x, base.y, 0))
|
self.ct_positions.append(FreeCAD.Vector(base.x, base.y, 0))
|
||||||
return True
|
return True
|
||||||
@@ -263,6 +265,8 @@ class InternalPathCreator:
|
|||||||
y_proj = slope * x_proj + intercept
|
y_proj = slope * x_proj + intercept
|
||||||
return FreeCAD.Vector(x_proj, y_proj, 0)
|
return FreeCAD.Vector(x_proj, y_proj, 0)
|
||||||
|
|
||||||
|
# return slope * x + intercept --> desde placement
|
||||||
|
|
||||||
projected_points = [project_point(p) for p in all_points]
|
projected_points = [project_point(p) for p in all_points]
|
||||||
|
|
||||||
# Calcular distancias a lo largo de la línea
|
# Calcular distancias a lo largo de la línea
|
||||||
|
|||||||
@@ -626,6 +626,7 @@ layers = [
|
|||||||
("Available area Names", QtGui.QColor(255, 255, 255), "Continuous", "1", True),
|
("Available area Names", QtGui.QColor(255, 255, 255), "Continuous", "1", True),
|
||||||
|
|
||||||
("Areas Exclusion", QtGui.QColor(255, 85, 0), "Continuous", "1", True),
|
("Areas Exclusion", QtGui.QColor(255, 85, 0), "Continuous", "1", True),
|
||||||
|
("Areas Exclusion Offset", QtGui.QColor(255, 85, 0), "Continuous", "1", True),
|
||||||
("Areas Exclusion Name", QtGui.QColor(255, 85, 0), "Continuous", "1", True),
|
("Areas Exclusion Name", QtGui.QColor(255, 85, 0), "Continuous", "1", True),
|
||||||
("Areas Cadastral Plot", QtGui.QColor(255, 255, 255), "Continuous", "1", True),
|
("Areas Cadastral Plot", QtGui.QColor(255, 255, 255), "Continuous", "1", True),
|
||||||
("Areas Cadastral Plot Name", QtGui.QColor(255, 255, 255), "Continuous", "1", True),
|
("Areas Cadastral Plot Name", QtGui.QColor(255, 255, 255), "Continuous", "1", True),
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ class _PVPlantPlacementTaskPanel:
|
|||||||
|
|
||||||
def createFrameFromPoints(self, dataframe):
|
def createFrameFromPoints(self, dataframe):
|
||||||
from Mechanical.Frame import PVPlantFrame
|
from Mechanical.Frame import PVPlantFrame
|
||||||
try:
|
'''try:
|
||||||
MechanicalGroup = FreeCAD.ActiveDocument.Frames
|
MechanicalGroup = FreeCAD.ActiveDocument.Frames
|
||||||
except:
|
except:
|
||||||
MechanicalGroup = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", 'Frames')
|
MechanicalGroup = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", 'Frames')
|
||||||
@@ -110,14 +110,41 @@ class _PVPlantPlacementTaskPanel:
|
|||||||
FreeCAD.ActiveDocument.MechanicalGroup.addObject(MechanicalGroup)
|
FreeCAD.ActiveDocument.MechanicalGroup.addObject(MechanicalGroup)
|
||||||
|
|
||||||
if self.form.cbSubfolders.isChecked:
|
if self.form.cbSubfolders.isChecked:
|
||||||
label = "Frames-" + self.PVArea.Label
|
name = "Frames-" + self.PVArea.Label
|
||||||
if label in [obj.Label for obj in FreeCAD.ActiveDocument.Frames.Group]:
|
if name in [obj.Name for obj in FreeCAD.ActiveDocument.Frames.Group]:
|
||||||
MechanicalGroup = FreeCAD.ActiveDocument.getObject(label)[0]
|
MechanicalGroup = FreeCAD.ActiveDocument.getObject(name)[0]
|
||||||
else:
|
else:
|
||||||
group = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", label)
|
group = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", name)
|
||||||
group.Label = label
|
group.Label = name
|
||||||
MechanicalGroup.addObject(group)
|
MechanicalGroup.addObject(group)
|
||||||
MechanicalGroup = group
|
MechanicalGroup = group'''
|
||||||
|
|
||||||
|
doc = FreeCAD.ActiveDocument
|
||||||
|
|
||||||
|
# 1. Obtener o crear el grupo principal 'Frames'
|
||||||
|
main_group_name = "Frames"
|
||||||
|
main_group = doc.getObject(main_group_name)
|
||||||
|
if not main_group:
|
||||||
|
main_group = doc.addObject("App::DocumentObjectGroup", main_group_name)
|
||||||
|
main_group.Label = main_group_name
|
||||||
|
# Asumiendo que existe un grupo 'MechanicalGroup'
|
||||||
|
if hasattr(doc, 'MechanicalGroup'):
|
||||||
|
doc.MechanicalGroup.addObject(main_group)
|
||||||
|
|
||||||
|
# 2. Manejar subgrupo si es necesario
|
||||||
|
group = main_group # Grupo donde se añadirán los marcos
|
||||||
|
if self.form.cbSubfolders.isChecked(): # ¡Corregido: falta de paréntesis!
|
||||||
|
subgroup_name = f"Frames-{self.PVArea.Label}"
|
||||||
|
|
||||||
|
# Buscar subgrupo existente
|
||||||
|
subgroup = next((obj for obj in main_group.Group if obj.Name == subgroup_name), None)
|
||||||
|
|
||||||
|
if not subgroup:
|
||||||
|
subgroup = doc.addObject("App::DocumentObjectGroup", subgroup_name)
|
||||||
|
subgroup.Label = subgroup_name
|
||||||
|
main_group.addObject(subgroup)
|
||||||
|
group = subgroup
|
||||||
|
|
||||||
try:
|
try:
|
||||||
placements = dataframe["placement"].tolist()
|
placements = dataframe["placement"].tolist()
|
||||||
types = dataframe["type"].tolist()
|
types = dataframe["type"].tolist()
|
||||||
@@ -127,7 +154,7 @@ class _PVPlantPlacementTaskPanel:
|
|||||||
newrack.Label = "Tracker"
|
newrack.Label = "Tracker"
|
||||||
newrack.Visibility = False
|
newrack.Visibility = False
|
||||||
newrack.Placement = placements[idx]
|
newrack.Placement = placements[idx]
|
||||||
MechanicalGroup.addObject(newrack)
|
group.addObject(newrack)
|
||||||
frames.append(newrack)
|
frames.append(newrack)
|
||||||
except:
|
except:
|
||||||
placements = dataframe[0]
|
placements = dataframe[0]
|
||||||
@@ -138,7 +165,7 @@ class _PVPlantPlacementTaskPanel:
|
|||||||
newrack.Label = "Tracker"
|
newrack.Label = "Tracker"
|
||||||
newrack.Visibility = False
|
newrack.Visibility = False
|
||||||
newrack.Placement = idx[1]
|
newrack.Placement = idx[1]
|
||||||
MechanicalGroup.addObject(newrack)
|
groupq.addObject(newrack)
|
||||||
frames.append(newrack)
|
frames.append(newrack)
|
||||||
|
|
||||||
if self.PVArea.Name.startswith("FrameArea"):
|
if self.PVArea.Name.startswith("FrameArea"):
|
||||||
@@ -160,7 +187,7 @@ class _PVPlantPlacementTaskPanel:
|
|||||||
if exclusion_areas:
|
if exclusion_areas:
|
||||||
prohibited_faces = []
|
prohibited_faces = []
|
||||||
for obj in exclusion_areas:
|
for obj in exclusion_areas:
|
||||||
face = self.getProjected(obj.Base.Shape)
|
face = self.getProjected(obj.Shape.SubShapes[1])
|
||||||
if face.isValid():
|
if face.isValid():
|
||||||
prohibited_faces.append(face)
|
prohibited_faces.append(face)
|
||||||
self.Area = self.Area.cut(prohibited_faces)
|
self.Area = self.Area.cut(prohibited_faces)
|
||||||
@@ -474,64 +501,70 @@ class _PVPlantPlacementTaskPanel:
|
|||||||
|
|
||||||
def calculateNonAlignedArray(self):
|
def calculateNonAlignedArray(self):
|
||||||
pointsx, pointsy = self.getAligments()
|
pointsx, pointsy = self.getAligments()
|
||||||
|
if len(pointsx) == 0:
|
||||||
|
FreeCAD.Console.PrintWarning("No se encontraron alineaciones X.\n")
|
||||||
|
return []
|
||||||
|
|
||||||
footprints = []
|
footprints = []
|
||||||
for frame in self.FrameSetups:
|
for frame in self.FrameSetups:
|
||||||
xx = frame.Length.Value
|
l = frame.Length.Value
|
||||||
yy = frame.Width.Value
|
w = frame.Width.Value
|
||||||
xx_med = xx / 2
|
l_med = l / 2
|
||||||
yy_med = yy / 2
|
w_med = w / 2
|
||||||
rec = Part.makePolygon([FreeCAD.Vector(-xx_med, -yy_med, 0),
|
rec = Part.makePolygon([FreeCAD.Vector(-l_med, -w_med, 0),
|
||||||
FreeCAD.Vector(xx_med, -yy_med, 0),
|
FreeCAD.Vector( l_med, -w_med, 0),
|
||||||
FreeCAD.Vector(xx_med, yy_med, 0),
|
FreeCAD.Vector( l_med, w_med, 0),
|
||||||
FreeCAD.Vector(-xx_med, yy_med, 0),
|
FreeCAD.Vector(-l_med, w_med, 0),
|
||||||
FreeCAD.Vector(-xx_med, -yy_med, 0)])
|
FreeCAD.Vector(-l_med, -w_med, 0)])
|
||||||
rec.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), FreeCAD.Vector(0, 1, 0))
|
rec.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), FreeCAD.Vector(0, 1, 0))
|
||||||
footprints.append([frame, rec])
|
footprints.append([frame, rec])
|
||||||
ref = footprints.pop(0)
|
|
||||||
xx = ref[0].Length.Value
|
|
||||||
yy = ref[0].Width.Value
|
|
||||||
xx_med = xx / 2
|
|
||||||
yy_med = yy / 2
|
|
||||||
|
|
||||||
# variables for corridors:
|
corridor = self.form.groupCorridor.isChecked()
|
||||||
countcols = 0
|
corridor_offset = 0
|
||||||
countrows = 0
|
count = 0
|
||||||
offsetcols = 0 # ??
|
|
||||||
offsetrows = 0 # ??
|
|
||||||
valcols = FreeCAD.Units.Quantity(self.form.editColGap.text()).Value - (self.gap_col - yy)
|
|
||||||
|
|
||||||
pl = []
|
cols = []
|
||||||
for point in pointsx:
|
for x in pointsx:
|
||||||
p1 = FreeCAD.Vector(point, self.Area.BoundBox.YMax, 0.0)
|
col=[]
|
||||||
p2 = FreeCAD.Vector(point, self.Area.BoundBox.YMin, 0.0)
|
x += corridor_offset
|
||||||
|
p1 = FreeCAD.Vector(x, self.Area.BoundBox.YMax, 0.0)
|
||||||
|
p2 = FreeCAD.Vector(x, self.Area.BoundBox.YMin, 0.0)
|
||||||
line = Part.makePolygon([p1, p2])
|
line = Part.makePolygon([p1, p2])
|
||||||
|
|
||||||
inter = self.Area.section([line])
|
inter = self.Area.section([line])
|
||||||
pts = [ver.Point for ver in inter.Vertexes] # todo: sort points
|
pts = [ver.Point for ver in inter.Vertexes]
|
||||||
|
pts = sorted(pts, key=lambda p: p.y, reverse=True)
|
||||||
for i in range(0, len(pts), 2):
|
for i in range(0, len(pts), 2):
|
||||||
line = Part.LineSegment(pts[i], pts[i + 1])
|
top = pts[i]
|
||||||
if line.length() >= ref[1].BoundBox.YLength:
|
bootom = pts[i + 1]
|
||||||
y1 = pts[i].y - ref[1].BoundBox.YLength / 2
|
if top.distanceToPoint(bootom) > footprints[-1][1].BoundBox.YLength:
|
||||||
cp = ref[1].copy()
|
y1 = top.y - (footprints[-1][1].BoundBox.YLength / 2)
|
||||||
cp.Placement.Base = FreeCAD.Vector(pts[i].x, y1, 0.0)
|
cp = footprints[-1][1].copy()
|
||||||
Part.show(cp)
|
cp.Placement.Base = FreeCAD.Vector(x + footprints[-1][1].BoundBox.XLength / 2, y1, 0.0)
|
||||||
inter = cp.cut([self.Area])
|
inter = cp.cut([self.Area])
|
||||||
pts1 = [ver.Point for ver in inter.Vertexes]
|
vtx = [ver.Point for ver in inter.Vertexes]
|
||||||
if len(pts1) == 0:
|
mod = top.y
|
||||||
continue
|
if len(vtx) != 0:
|
||||||
y1 = min(pts1, key=lambda p: p.y).y
|
mod = min(vtx, key=lambda p: p.y).y
|
||||||
pointsy = np.arange(y1, pts[i + 1].y, -self.gap_row)
|
#y1 = cp.Placement.Base.y - mod
|
||||||
continue
|
|
||||||
for pointy in pointsy:
|
tmp = optimized_cut(mod - bootom.y, [ftp[1].BoundBox.YLength for ftp in footprints], 500, 'greedy')
|
||||||
cp = ref[1].copy()
|
for opt in tmp[0]:
|
||||||
cp.Placement.Base = FreeCAD.Vector(pts[i].x + ref[1].BoundBox.XLength / 2, pointy, 0.0)
|
mod -= (footprints[opt][1].BoundBox.YLength / 2)
|
||||||
cut = cp.cut([self.Area], 0)
|
pl = FreeCAD.Vector(x + footprints[opt][1].BoundBox.XLength / 2, mod, 0.0)
|
||||||
#print(y1, " - ", pointy, " - ", len(cut.Vertexes))
|
cp = footprints[opt][1].copy()
|
||||||
#if len(cut.Vertexes) == 0:
|
if self.isInside(cp, pl):
|
||||||
Part.show(cp)
|
col.append([footprints[opt][0], pl])
|
||||||
pl.append([ref[0], pointy])
|
mod -= ((footprints[opt][1].BoundBox.YLength / 2) + 500)
|
||||||
return pl
|
Part.show(cp)
|
||||||
|
|
||||||
|
if corridor and len(col) > 0:
|
||||||
|
count += 1
|
||||||
|
if count == self.form.editColCount.value():
|
||||||
|
corridor_offset += 12000
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
cols.append(cols)
|
||||||
|
return self.adjustToTerrain(cols)
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@@ -583,6 +616,115 @@ class _PVPlantPlacementTaskPanel:
|
|||||||
FreeCAD.ActiveDocument.recompute()
|
FreeCAD.ActiveDocument.recompute()
|
||||||
|
|
||||||
|
|
||||||
|
def optimized_cut(L_total, piezas, margen=0, metodo='auto'):
|
||||||
|
"""
|
||||||
|
Encuentra la combinación óptima de piezas para minimizar el desperdicio,
|
||||||
|
considerando un margen entre piezas.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
L_total (int): Longitud total del material.
|
||||||
|
piezas (list): Lista de longitudes de los patrones de corte.
|
||||||
|
margen (int): Espacio perdido entre piezas consecutivas.
|
||||||
|
metodo (str): 'dp' para programación dinámica, 'greedy' para voraz, 'auto' para selección automática.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: (piezas_seleccionadas, desperdicio)
|
||||||
|
"""
|
||||||
|
# Filtrar piezas inválidas
|
||||||
|
piezas = [p for p in piezas if 0 < p <= L_total]
|
||||||
|
if not piezas:
|
||||||
|
return [], L_total
|
||||||
|
|
||||||
|
# Transformar longitudes y longitud total con margen
|
||||||
|
longitudes_aumentadas = [p + margen for p in piezas]
|
||||||
|
L_total_aumentado = L_total + margen
|
||||||
|
|
||||||
|
# Selección automática de método
|
||||||
|
if metodo == 'auto':
|
||||||
|
if L_total_aumentado <= 10000 and len(piezas) <= 100:
|
||||||
|
metodo = 'dp'
|
||||||
|
else:
|
||||||
|
metodo = 'greedy'
|
||||||
|
|
||||||
|
if metodo == 'dp':
|
||||||
|
n = len(piezas)
|
||||||
|
dp = [0] * (L_total_aumentado + 1)
|
||||||
|
parent = [-1] * (L_total_aumentado + 1) # Almacena índices de piezas usadas
|
||||||
|
|
||||||
|
# Llenar la tabla dp y parent
|
||||||
|
for j in range(1, L_total_aumentado + 1):
|
||||||
|
for i in range(n):
|
||||||
|
p_aum = longitudes_aumentadas[i]
|
||||||
|
if p_aum <= j:
|
||||||
|
if dp[j] < dp[j - p_aum] + p_aum:
|
||||||
|
dp[j] = dp[j - p_aum] + p_aum
|
||||||
|
parent[j] = i # Guardar índice de la pieza
|
||||||
|
|
||||||
|
# Reconstruir solución desde el final
|
||||||
|
current = L_total_aumentado
|
||||||
|
seleccion_indices = []
|
||||||
|
while current > 0 and parent[current] != -1:
|
||||||
|
i = parent[current]
|
||||||
|
seleccion_indices.append(i)
|
||||||
|
current -= longitudes_aumentadas[i]
|
||||||
|
|
||||||
|
# Calcular desperdicio real
|
||||||
|
k = len(seleccion_indices)
|
||||||
|
if k == 0:
|
||||||
|
desperdicio = L_total
|
||||||
|
else:
|
||||||
|
suma_original = sum(piezas[i] for i in seleccion_indices)
|
||||||
|
desperdicio = L_total - suma_original - margen * (k - 1)
|
||||||
|
|
||||||
|
return seleccion_indices, desperdicio
|
||||||
|
|
||||||
|
elif metodo == 'greedy':
|
||||||
|
# Crear lista con índices y longitudes aumentadas
|
||||||
|
lista_con_indices = [(longitudes_aumentadas[i], i) for i in range(len(piezas))]
|
||||||
|
lista_con_indices.sort(key=lambda x: x[0], reverse=True) # Ordenar descendente
|
||||||
|
|
||||||
|
seleccion_indices = []
|
||||||
|
restante = L_total_aumentado
|
||||||
|
|
||||||
|
# Seleccionar piezas vorazmente
|
||||||
|
for p_aum, i in lista_con_indices:
|
||||||
|
while restante >= p_aum:
|
||||||
|
seleccion_indices.append(i)
|
||||||
|
restante -= p_aum
|
||||||
|
|
||||||
|
# Calcular desperdicio real
|
||||||
|
k = len(seleccion_indices)
|
||||||
|
if k == 0:
|
||||||
|
desperdicio = L_total
|
||||||
|
else:
|
||||||
|
suma_original = sum(piezas[i] for i in seleccion_indices)
|
||||||
|
desperdicio = L_total - suma_original - margen * (k - 1)
|
||||||
|
|
||||||
|
return seleccion_indices, desperdicio
|
||||||
|
|
||||||
|
|
||||||
|
# Ejemplo de uso
|
||||||
|
'''if __name__ == "__main__":
|
||||||
|
L_total = 100
|
||||||
|
piezas = [25, 35, 40, 20, 15, 30, 50]
|
||||||
|
margen = 5
|
||||||
|
|
||||||
|
print("Solución óptima con margen (programación dinámica):")
|
||||||
|
seleccion, desperd = corte_optimizado(L_total, piezas, margen, 'dp')
|
||||||
|
print(f"Piezas usadas: {seleccion}")
|
||||||
|
print(f"Margen entre piezas: {margen} cm")
|
||||||
|
print(f"Material útil: {sum(seleccion)} cm")
|
||||||
|
print(f"Espacio usado por márgenes: {(len(seleccion) - 1) * margen} cm")
|
||||||
|
print(f"Desperdicio total: {desperd} cm")
|
||||||
|
|
||||||
|
print("\nSolución aproximada con margen (algoritmo voraz):")
|
||||||
|
seleccion_g, desperd_g = corte_optimizado(L_total, piezas, margen, 'greedy')
|
||||||
|
print(f"Piezas usadas: {seleccion_g}")
|
||||||
|
print(f"Margen entre piezas: {margen} cm")
|
||||||
|
print(f"Material útil: {sum(seleccion_g)} cm")
|
||||||
|
print(f"Espacio usado por márgenes: {(len(seleccion_g) - 1) * margen} cm")
|
||||||
|
print(f"Desperdicio total: {desperd_g} cm")'''
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------
|
||||||
# function AdjustToTerrain
|
# function AdjustToTerrain
|
||||||
|
|||||||
@@ -54,30 +54,6 @@ class CommandPVPlantSite:
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
'''class CommandPVPlantGeoreferencing:
|
|
||||||
@staticmethod
|
|
||||||
def GetResources():
|
|
||||||
return {'Pixmap': str(os.path.join(DirIcons, "Location.svg")),
|
|
||||||
'Accel': "G, R",
|
|
||||||
'MenuText': QT_TRANSLATE_NOOP("Georeferencing","Georeferencing"),
|
|
||||||
'ToolTip': QT_TRANSLATE_NOOP("Georeferencing","Referenciar el lugar")}
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def IsActive():
|
|
||||||
if FreeCAD.ActiveDocument:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def Activated():
|
|
||||||
import PVPlantGeoreferencing
|
|
||||||
taskd = PVPlantGeoreferencing.MapWindow()
|
|
||||||
#taskd.setParent(FreeCADGui.getMainWindow())
|
|
||||||
#taskd.setWindowFlags(QtCore.Qt.Window)
|
|
||||||
taskd.show()#exec_()'''
|
|
||||||
|
|
||||||
|
|
||||||
class CommandProjectSetup:
|
class CommandProjectSetup:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def GetResources():
|
def GetResources():
|
||||||
|
|||||||
@@ -224,14 +224,20 @@ def getProjected(shape, direction=FreeCAD.Vector(0, 0, 1)): # Based on Draft / s
|
|||||||
return ow
|
return ow
|
||||||
|
|
||||||
|
|
||||||
def findObjects(classtype):
|
'''def findObjects(classtype):
|
||||||
objects = FreeCAD.ActiveDocument.Objects
|
objects = FreeCAD.ActiveDocument.Objects
|
||||||
objlist = list()
|
objlist = list()
|
||||||
for object in objects:
|
for object in objects:
|
||||||
if hasattr(object, "Proxy"):
|
if hasattr(object, "Proxy"):
|
||||||
if object.Proxy.Type == classtype:
|
if object.Proxy.Type == classtype:
|
||||||
objlist.append(object)
|
objlist.append(object)
|
||||||
return objlist
|
return objlist'''
|
||||||
|
|
||||||
|
def findObjects(classtype):
|
||||||
|
return [obj for obj in FreeCAD.ActiveDocument.Objects
|
||||||
|
if hasattr(obj, "Proxy")
|
||||||
|
and hasattr(obj.Proxy, "Type")
|
||||||
|
and obj.Proxy.Type == classtype]
|
||||||
|
|
||||||
def getClosePoints(sh1, angle):
|
def getClosePoints(sh1, angle):
|
||||||
'''
|
'''
|
||||||
|
|||||||
Reference in New Issue
Block a user