Files
PVPlant/PVPlantTerrainAnalisys.py

812 lines
31 KiB
Python
Raw Permalink Normal View History

2025-01-28 00:04:13 +01:00
import Draft
import FreeCAD
import Part
if FreeCAD.GuiUp:
import FreeCADGui
from PySide import QtCore, QtGui
from PySide.QtCore import QT_TRANSLATE_NOOP
else:
# \cond
def translate(ctxt, txt):
return txt
def QT_TRANSLATE_NOOP(ctxt, txt):
return txt
# \endcond
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
import os
from PVPlantResources import DirIcons as DirIcons
2025-03-28 19:40:11 +06:00
2025-01-28 00:04:13 +01:00
def Mest2FemMesh(obj):
import Fem
fm = Fem.FemMesh()
#i = 0
#nodes = []
for mp in obj.Mesh.Points:
fm.addNode(mp.Vector.x, mp.Vector.y, mp.Vector.z)
# nodes.append(mp)
# i += 1
for mf in obj.Mesh.Facets:
fm.addFace([mf.PointIndices[0] + 1, mf.PointIndices[1] + 1, mf.PointIndices[2] + 1])
obj2 = FreeCAD.ActiveDocument.addObject("Fem::FemMeshObject")
obj2.FemMesh = fm
obj2.ViewObject.DisplayMode = "Faces"
FreeCAD.activeDocument().recompute()
return obj2
2025-03-28 19:40:11 +06:00
2025-01-28 00:04:13 +01:00
def makeContours(land, minor = 1000, mayor = 5000,
minorColor=(0.0, 0.00, 0.80), mayorColor=(0.00, 0.00, 1.00),
minorThickness = 2, mayorThickness = 5,
filter_size = 5):
if not land:
return
if land.TypeId == 'Mesh::Feature':
Contours_Mesh(land.Mesh, minor, mayor, minorColor, mayorColor, minorThickness, mayorThickness, filter_size)
else:
Contours_Part(land, minor, mayor, minorColor, mayorColor, minorThickness, mayorThickness, filter_size)
FreeCAD.ActiveDocument.recompute()
2025-03-28 19:40:11 +06:00
2025-01-28 00:04:13 +01:00
def Contours_Mesh(Mesh, minor, mayor,
minorColor, mayorColor,
minorLineWidth, mayorLineWidth,
filter_size): #filter_size de 3 a 21 y siempre impar
def calculateSection(cuts):
for inc in cuts:
CrossSections = Mesh.crossSections([((0, 0, inc), (0, 0, 1))], 0.000001)
for PointList in CrossSections[0]:
if len(PointList) > 1:
if PointList[0].sub(PointList[-1]).Length <= 10000.0:
PointList.append(PointList[0])
# 1. Smooth the points
if (len(PointList) > filter_size) and (filter_size > 0):
for a in range(len(PointList)):
x = 0
y = 0
for p in range(-filter_radius, filter_radius + 1):
point_id = a + p
if point_id < 0:
point_id = 0
if point_id >= len(PointList):
point_id = len(PointList) - 1
x += PointList[point_id].x
y += PointList[point_id].y
x /= filter_size
y /= filter_size
PointList[a].x = x
PointList[a].y = y
for a in reversed(range(len(PointList))):
x = 0
y = 0
for p in range(-filter_radius, filter_radius + 1):
point_id = a + p
if point_id < 0:
point_id = 0
if point_id >= len(PointList):
point_id = len(PointList) - 1
x += PointList[point_id].x
y += PointList[point_id].y
x /= filter_size
y /= filter_size
PointList[a].x = x
PointList[a].y = y
# 2. Make lines
#Contour = Draft.makeWire(PointList, closed=False, face=None)
#Contour.Label = str(int(inc / 1000)) + "m"
Contour = Part.makePolygon(PointList)
Part.show(Contour, str(int(inc / 1000)) + "m")
'''Contours.addObject(Contour)
if inc % mayor == 0:
Contour.ViewObject.LineWidth = mayorLineWidth
Contour.ViewObject.LineColor = mayorColor
else:
Contour.ViewObject.LineWidth = minorLineWidth
Contour.ViewObject.LineColor = minorColor'''
del Contour, PointList
del CrossSections
filter_radius = int(filter_size / 2)
try:
Contours = FreeCAD.ActiveDocument.Contours
except:
Contours = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", 'Contours')
ZMin = Mesh.BoundBox.ZMin // 10000
ZMin *= 10000
ZMax = Mesh.BoundBox.ZMax
import numpy as np
minor_array = np.arange(ZMin, ZMax, minor)
mayor_array = np.arange(ZMin, ZMax, mayor)
minor_array = np.array(list(filter(lambda x: x not in mayor_array, minor_array)))
calculateSection(minor_array)
calculateSection(mayor_array)
2025-03-28 19:40:11 +06:00
2025-01-28 00:04:13 +01:00
def Contours_Part(Terrain, minor, mayor,
minorColor, mayorColor,
minorLineWidth, mayorLineWidth,
filter_size): #filter_size de 3 a 21 y siempre impar
def calculateSection(cuts):
cnt = 0
for inc in cuts:
CrossSections = Terrain.Shape.slice(FreeCAD.Vector(0, 0, 1), inc)
for wire in CrossSections:
PointList = []
for vertex in wire.Vertexes:
PointList.append(vertex.Point)
if len(PointList) > 1:
# 1. Smooth the points
if (len(PointList) > filter_size) and (filter_size > 0):
for a in range(len(PointList)):
x = 0
y = 0
for p in range(-filter_radius, filter_radius + 1):
point_id = a + p
if point_id < 0:
point_id = 0
if point_id >= len(PointList):
point_id = len(PointList) - 1
x += PointList[point_id].x
y += PointList[point_id].y
x /= filter_size
y /= filter_size
PointList[a].x = x
PointList[a].y = y
for a in reversed(range(len(PointList))):
x = 0
y = 0
for p in range(-filter_radius, filter_radius + 1):
point_id = a + p
if point_id < 0:
point_id = 0
if point_id >= len(PointList):
point_id = len(PointList) - 1
x += PointList[point_id].x
y += PointList[point_id].y
x /= filter_size
y /= filter_size
PointList[a].x = x
PointList[a].y = y
# 2. TODO: close wire
# 3. Make lines
Contour = Draft.makeWire(PointList, closed=False, face=None, support=None)
Contour.MakeFace = False
Contour.Label = str(int(inc / 1000)) + "m"
Contours.addObject(Contour)
if inc % mayor == 0:
Contour.ViewObject.LineWidth = mayorLineWidth
Contour.ViewObject.LineColor = mayorColor
else:
Contour.ViewObject.LineWidth = minorLineWidth
Contour.ViewObject.LineColor = minorColor
cnt += 1
if cnt == 10:
return
filter_radius = int(filter_size / 2)
try:
Contours = FreeCAD.ActiveDocument.Contours
except:
Contours = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", 'Contours')
ZMin = Terrain.Shape.BoundBox.ZMin // 10000
ZMin *= 10000
ZMax = Terrain.Shape.BoundBox.ZMax
import numpy as np
minor_array = np.arange(ZMin, ZMax, minor)
mayor_array = np.arange(ZMin, ZMax, mayor)
minor_array = np.array(list(filter(lambda x: x not in mayor_array, minor_array)))
calculateSection(minor_array)
calculateSection(mayor_array)
# Base widget for task panel terrain analisys
2025-03-28 19:40:11 +06:00
2025-01-28 00:04:13 +01:00
class _generalTaskPanel:
'''The TaskPanel for Slope setup'''
def __init__(self):
self.ranges = []
self.form = FreeCADGui.PySideUic.loadUi(os.path.dirname(__file__) + "/PVPlantTerrainAnalisys.ui")
self.tableWidget = self.form.tableWidget
self.form.editSteps.valueChanged.connect(self.changeDivision)
self.tableWidget.itemChanged.connect(self.cellChanged)
def cellChanged(self, item):
if (item.column() == 1) and (item.row() != (self.tableWidget.rowCount() - 1)):
item2 = self.tableWidget.item(item.row() + 1, 0)
item2.setText(item.text())
def updateTableValues(self):
maxval = self.form.editTo.value() - self.form.editFrom.value()
ran = maxval / self.tableWidget.rowCount()
for i in range(self.tableWidget.rowCount()):
for j in range(2):
item = self.tableWidget.item(i, j)
val = ran * (i + j) + self.form.editFrom.value()
item.setText('{:.1f}'.format(val))
self.ranges[i][j] = val
#self.tableWidget.item(0, 0).setText('{:.1f}'.format(self.form.editFrom.value()))
#self.tableWidget.item(self.tableWidget.rowCount() - 1, 1).setText('{:.1f}'.format(self.form.editTo.value()))
def changeDivision(self):
self.tableWidget.blockSignals(True)
rows = self.tableWidget.rowCount()
to = self.form.editSteps.value()
if to > rows:
for i in range(0, to - rows):
self.ranges.append([0.0, 0.0, (0.0, 0.0, 0.0)])
self.createRow()
elif to < rows:
self.tableWidget.setRowCount(to)
self.ranges = self.ranges[:to]
self.updateTableValues()
self.tableWidget.blockSignals(False)
def createRow(self):
row = self.tableWidget.rowCount()
self.tableWidget.setRowCount(self.tableWidget.rowCount() + 1)
newItem = QtGui.QTableWidgetItem("item")
self.tableWidget.setItem(row, 0, newItem)
newItem.setTextAlignment(QtCore.Qt.AlignCenter)
newItem.setText("0.0")
newItem.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEditable|QtCore.Qt.ItemIsDragEnabled|
QtCore.Qt.ItemIsDropEnabled|QtCore.Qt.ItemIsUserCheckable)
newItem = QtGui.QTableWidgetItem("item")
self.tableWidget.setItem(row, 1, newItem)
newItem.setTextAlignment(QtCore.Qt.AlignCenter)
newItem.setText("0.0")
#import random
# r = random.randint(0, 255)
# g = random.randint(0, 255)
# b = random.randint(0, 255)
val = int(127 * row / (self.form.editSteps.value() / 2))
g = (127 + val) if val <= 127 else 0
r = (328 - val if val >= 127 else 0)
color = QtGui.QColor(r, g, 0)
colorPix = QtGui.QPixmap(16, 16)
colorPix.fill(color)
self.ranges[row][2] = (color.red()/255, color.green()/255, color.blue()/255)
buttonColor = QtGui.QPushButton('')
buttonColor.setIcon(QtGui.QIcon(colorPix))
buttonColor.setMaximumSize(QtCore.QSize(20, 20))
buttonColor.clicked.connect(lambda: self.selColor(buttonColor))
self.tableWidget.setCellWidget(row, 2, buttonColor)
def selColor(self, button):
color = QtGui.QColorDialog.getColor()
if color.isValid():
print("añadir color")
colorPix = QtGui.QPixmap(16, 16)
colorPix.fill(color)
button.setIcon(QtGui.QIcon(colorPix))
curentIndex = self.tableWidget.currentIndex()
self.ranges[curentIndex.row()][2] = (color.red()/255, color.green()/255, color.blue()/255)
# Contours Analisys: ---------------------------------------------------------------------------------
2025-03-28 19:40:11 +06:00
class ContourTaskPanel():
2025-01-28 00:04:13 +01:00
'''The editmode TaskPanel for contours generator'''
def __init__(self):
self.MinorColor = (0.5, 0.5, 0.5)
self.MayorColor = (0.5, 0.5, 0.5)
land = None
self.intervals = ["0.1 m", "0.5 m", "1 m", "5 m", "10 m", "50 m", "100 m", "500 m"]
self.intervalvalues = [0.1, 0.5, 1, 5, 10, 50, 100, 500]
# form:
self.form = QtGui.QWidget()
self.form.resize(800,640)
self.form.setWindowTitle("Curvas de nivel")
self.form.setWindowIcon(QtGui.QIcon(os.path.join(DirIcons, "contours.svg")))
self.grid = QtGui.QGridLayout(self.form)
# parameters
self.labelTerrain = QtGui.QLabel()
self.labelTerrain.setText("Terreno:")
self.lineEdit1 = QtGui.QLineEdit(self.form)
self.lineEdit1.setObjectName(_fromUtf8("lineEdit1"))
self.lineEdit1.readOnly = True
self.grid.addWidget(self.labelTerrain, self.grid.rowCount(), 0, 1, 1)
self.grid.addWidget(self.lineEdit1, self.grid.rowCount() - 1, 1, 1, 1)
self.buttonAdd = QtGui.QPushButton('Seleccionar Terreno')
self.buttonAdd.clicked.connect(self.add)
self.grid.addWidget(self.buttonAdd, self.grid.rowCount(), 1, 1, 1)
###----------------------
self.widgetDivisions = QtGui.QGroupBox(self.form)
self.grid.addWidget(self.widgetDivisions, self.grid.rowCount(), 0, 1, -1)
self.gridDivisions = QtGui.QGridLayout(self.widgetDivisions)
self.labelTitle1 = QtGui.QLabel()
self.labelTitle1.setText("Intervalo")
self.labelTitle2 = QtGui.QLabel()
self.labelTitle2.setText("Grosor")
self.labelTitle3 = QtGui.QLabel()
self.labelTitle3.setText("Color")
self.gridDivisions.addWidget(self.labelTitle1, self.gridDivisions.rowCount(), 1, 1, -1)
self.gridDivisions.addWidget(self.labelTitle2, self.gridDivisions.rowCount() - 1, 2, 1, -1)
self.gridDivisions.addWidget(self.labelTitle3, self.gridDivisions.rowCount() - 1, 3, 1, -1)
self.labelMinorContour = QtGui.QLabel(self.form)
self.labelMinorContour.setText("Menor:")
self.inputMinorContourMargin = QtGui.QComboBox(self.form)
self.inputMinorContourMargin.addItems(self.intervals)
self.inputMinorContourMargin.setCurrentIndex(2)
self.inputMinorContourThickness = QtGui.QSpinBox(self.form)
self.inputMinorContourThickness.setRange(1, 10)
self.inputMinorContourThickness.setValue(2)
self.gridDivisions.addWidget(self.labelMinorContour, self.gridDivisions.rowCount(), 0, 1, 1)
self.gridDivisions.addWidget(self.inputMinorContourMargin, self.gridDivisions.rowCount() - 1, 1, 1, 1)
self.gridDivisions.addWidget(self.inputMinorContourThickness, self.gridDivisions.rowCount() - 1, 2, 1, 1)
self.buttonMinorContourColor = QtGui.QPushButton('')
self.color = QtGui.QColor(128, 128, 128)
colorPix = QtGui.QPixmap(16, 16)
colorPix.fill(self.color)
self.buttonMinorContourColor.setIcon(QtGui.QIcon(colorPix))
self.buttonMinorContourColor.clicked.connect(lambda: self.selColor(self.buttonMinorContourColor))
self.gridDivisions.addWidget(self.buttonMinorContourColor, self.gridDivisions.rowCount() - 1, 3, 1, 1)
###----------------------
self.labelMayorContour = QtGui.QLabel(self.form)
self.labelMayorContour.setText("Mayor:")
self.inputMayorContourMargin = QtGui.QComboBox(self.form)
self.inputMayorContourMargin.addItems(self.intervals)
self.inputMayorContourMargin.setCurrentIndex(3)
self.inputMayorContourThickness = QtGui.QSpinBox(self.form)
self.inputMayorContourThickness.setRange(1, 10)
self.inputMayorContourThickness.setValue(5)
self.gridDivisions.addWidget(self.labelMayorContour, self.gridDivisions.rowCount(), 0, 1, 1)
self.gridDivisions.addWidget(self.inputMayorContourMargin, self.gridDivisions.rowCount() - 1, 1, 1, 1)
self.gridDivisions.addWidget(self.inputMayorContourThickness, self.gridDivisions.rowCount() - 1, 2, 1, 1)
self.buttonMayorContourColor = QtGui.QPushButton('')
self.color = QtGui.QColor(128, 128, 128)
colorPix = QtGui.QPixmap(16, 16)
colorPix.fill(self.color)
self.buttonMayorContourColor.setIcon(QtGui.QIcon(colorPix))
self.buttonMayorContourColor.clicked.connect(lambda: self.selColor(self.buttonMayorContourColor))
self.gridDivisions.addWidget(self.buttonMayorContourColor, self.gridDivisions.rowCount() - 1, 3, 1, 1)
def add(self):
sel = FreeCADGui.Selection.getSelection()
if len(sel) > 0:
self.land = sel[0]
self.lineEdit1.setText(self.land.Label)
def selColor(self, button):
color = QtGui.QColorDialog.getColor()
colorPix = QtGui.QPixmap(16, 16)
colorPix.fill(color)
button.setIcon(QtGui.QIcon(colorPix))
r = float(color.red()/255.0)
g = float(color.green()/255.0)
b = float(color.blue()/255.0)
col = (r, g, b)
if button is self.buttonMinorContourColor:
self.MinorColor = col
elif button is self.buttonMayorContourColor:
self.MayorColor = col
def accept(self):
from datetime import datetime
starttime = datetime.now()
if self.land is None:
print("No hay objetos para procesar")
return False
else:
minor = FreeCAD.Units.Quantity(self.inputMinorContourMargin.currentText()).Value
mayor = FreeCAD.Units.Quantity(self.inputMayorContourMargin.currentText()).Value
i = 2
if i == 0:
makeContours(self.land, minor, mayor, self.MinorColor, self.MayorColor,
self.inputMinorContourThickness.value(), self.inputMayorContourThickness.value())
elif i == 1:
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
print(" -- Tiempo tardado:", total_time)
FreeCADGui.Control.closeDialog()
return True
# Height Analisys: ---------------------------------------------------------------------------------
2025-03-28 19:40:11 +06:00
class HeightTaskPanel(_generalTaskPanel):
2025-01-28 00:04:13 +01:00
'''The TaskPanel for Slope setup'''
def __init__(self):
_generalTaskPanel.__init__(self)
# Initial set-up:
land = FreeCAD.ActiveDocument.Site.Terrain
self.form.editFrom.setSuffix(" m")
self.form.editFrom.setValue(land.Shape.BoundBox.ZMin / 1000)
self.form.editTo.setSuffix(" m")
self.form.editTo.setValue(land.Shape.BoundBox.ZMax / 1000)
self.form.editSteps.setValue(10)
self.form.editFrom.valueChanged.connect(self.updateTableValues)
self.form.editTo.valueChanged.connect(self.updateTableValues)
def accept(self):
land = FreeCAD.ActiveDocument.Site.Terrain
if land.isDerivedFrom("Part::Feature"):
colorlist = []
for face in land.Shape.Faces:
zz = face.CenterOfMass.z / 1000
color = (.0, .0, .0)
for i in range(1,len(self.ranges)):
if self.ranges[i][0] <= zz <= self.ranges[i][1]:
color = self.ranges[i][2]
break
colorlist.append(color)
land.ViewObject.DiffuseColor = colorlist
FreeCAD.activeDocument().recompute()
return True
# Slope Analisys: ---------------------------------------------------------------------------------
2025-03-28 19:40:11 +06:00
class SlopeTaskPanel(_generalTaskPanel):
2025-01-28 00:04:13 +01:00
'''The TaskPanel for Slope setup'''
def __init__(self):
_generalTaskPanel.__init__(self)
self.angles = self.getAngles()
# Initial set-up:
self.form.editFrom.setSuffix(" º")
self.form.editFrom.setValue(0)
self.form.editTo.setSuffix(" º")
self.form.editTo.setValue(max(self.angles))
self.form.editSteps.setValue(10)
self.form.editFrom.valueChanged.connect(self.updateTableValues)
self.form.editTo.valueChanged.connect(self.updateTableValues)
def getAngles(self):
import math
land = FreeCAD.ActiveDocument.Site.Terrain
angles = []
for face in land.Shape.Faces:
normal = face.normalAt(0, 0)
rad = normal.getAngle(FreeCAD.Vector(0, 0, 1))
angle = math.degrees(rad)
angles.append(angle)
return angles
def getPointSlope(self, ranges = None):
from datetime import datetime
starttime = datetime.now()
import math
land = FreeCAD.ActiveDocument.Site.Terrain
if land.isDerivedFrom("Part::Feature"):
colorlist = []
for face in land.Shape.Faces:
normal = face.normalAt(0, 0)
rad = normal.getAngle(FreeCAD.Vector(0, 0, 1))
angle = math.degrees(rad)
if(angle > 90):
angle -= 90
color = (1.0, 1.0, 1.0)
for i in range(0, len(ranges)):
if ranges[i][0] <= angle <= ranges[i][1]:
color = ranges[i][2]
break
colorlist.append(color)
print(len(land.Shape.Faces) == len(colorlist))
land.ViewObject.DiffuseColor = colorlist
# TODO: check this code:
elif obj.isDerivedFrom("Mesh::Feature"):
fMesh = Mest2FemMesh(land)
import math
setColors = []
i = 1
normals = land.Mesh.getPointNormals()
for normal in normals:
rad = normal.getAngle(FreeCAD.Vector(0, 0, 1))
angle = math.degrees(rad)
# Cambiar esto a la lista de colores configurable
if angle < 5:
setColors[i] = (0.0, 0.5, 0.0)
elif angle < 7.5:
setColors[i] = (0.0, 1.0, 0.5)
elif (angle < 10):
setColors[i] = (0.0, 1.0, 1.0)
elif (angle < 12.5):
setColors[i] = (0.0, 0.0, 0.5)
elif (angle < 14):
setColors[i] = (0.0, 0.0, 1.0)
elif (angle > 20):
setColors[i] = (1.0, 0.0, 0.0)
else:
setColors[i] = (1.0, 1.0, 1.0)
i += 1
fMesh.ViewObject.NodeColor = setColors
FreeCAD.activeDocument().recompute()
print("Everything OK (", datetime.now() - starttime, ")")
def accept(self):
# self.getPointSlope()
import threading
hilo = threading.Thread(target=self.getPointSlope(self.ranges))
hilo.start()
return True
# Orientation Analisys: ---------------------------------------------------------------------------------
2025-03-28 19:40:11 +06:00
class OrientationTaskPanel(_generalTaskPanel):
2025-01-28 00:04:13 +01:00
'''The TaskPanel for Orientation setup'''
def __init__(self):
_generalTaskPanel.__init__(self)
self.getAngles()
# Initial set-up:
self.form.editFrom.setSuffix(" º")
self.form.editFrom.setValue(0.0)
self.form.editTo.setSuffix(" º")
self.form.editTo.setMaximum(360.0)
self.form.editTo.setValue(360.0)
self.form.editSteps.setValue(15)
self.form.editFrom.valueChanged.connect(self.updateTableValues)
self.form.editTo.valueChanged.connect(self.updateTableValues)
def getAngles(self):
import math
land = FreeCAD.ActiveDocument.Site.Terrain
anglesx = []
anglesy = []
for face in land.Shape.Faces:
normal = face.normalAt(0, 0)
normal.z = 0
anglesx.append(math.degrees(normal.getAngle(FreeCAD.Vector(1, 0, 0))))
anglesy.append(math.degrees(normal.getAngle(FreeCAD.Vector(0, 1, 0))))
print("Min x: ", min(anglesx), " y: ", min(anglesy))
print("Max x: ", max(anglesx), " y: ", max(anglesy))
return anglesx, anglesy
def accept(self):
import math
from datetime import datetime
starttime = datetime.now()
land = FreeCAD.ActiveDocument.Site.Terrain
if land.isDerivedFrom("Part::Feature"):
colorlist = []
j = 0
minx = 99999
miny = 99999
for face in land.Shape.Faces:
normal = face.normalAt(0, 0)
normal.z = 0
anglex = math.degrees(normal.getAngle(FreeCAD.Vector(1, 0, 0)))
angley = math.degrees(normal.getAngle(FreeCAD.Vector(0, 1, 0)))
minx = min([minx, anglex])
miny = min([miny, angley])
if angley >= 90:
anglex = 360.0 - anglex
#print(anglex, " ", angley)
for i in range(1, len(self.ranges)):
if self.ranges[i][0] <= anglex <= self.ranges[i][1]:
colorlist.append(self.ranges[i][2])
break
j += 1
if j == 100:
break
land.ViewObject.DiffuseColor = colorlist
print("Angulos: ", math.degrees(minx), " - ", miny)
# TODO: check this code:
elif land.isDerivedFrom("Mesh::Feature"):
fMesh = Mest2FemMesh(land)
fMesh = Mest2FemMesh(land)
setColors = {}
i = 1
normals = land.Mesh.getPointNormals()
print(" --------- time to FEMMESH: (", datetime.now() - starttime, ")")
for normal in normals:
rad = normal.getAngle(FreeCAD.Vector(1, 1, 0))
angle = math.degrees(rad)
# Cambiar esto a la lista de colores configurable
if angle < 45:
setColors[i] = (0.0, 1.0, 0.0)
elif (angle < 90):
setColors[i] = (0.0, 1.0, 1.0)
elif (angle < 135):
setColors[i] = (0.0, 0.0, 1.0)
elif (angle <= 180):
setColors[i] = (1.0, 0.0, 1.0)
#else:
# setColors[i] = (1.0, 0.0, 0.0)
i += 1
if i== 1000:
break
fMesh.ViewObject.NodeColor = setColors
FreeCAD.activeDocument().recompute()
print("Everything OK (", datetime.now() - starttime, ")")
return True
## Commands ----------------------------------------------------------------------------------------------------------
## 1. Contours:
2025-03-28 19:40:11 +06:00
'''class _CommandContours:
2025-01-28 00:04:13 +01:00
def GetResources(self):
return {'Pixmap': str(os.path.join(DirIcons, "TerrainContours.svg")),
'Accel': "T, C",
'MenuText': 'Curvas de nivel',
'ToolTip': 'Curvas de nivel'
}
def IsActive(self):
# return not FreeCAD.ActiveDocument is None
if FreeCAD.ActiveDocument is None:
return False
return True
if FreeCADGui.Selection.getSelection() is not None:
selection = FreeCADGui.Selection.getSelection()[-1]
if selection.TypeId == 'Mesh::Feature':
return True
return False
def Activated(self):
self.TaskPanel = _ContourTaskPanel()
FreeCADGui.Control.showDialog(self.TaskPanel)
## 2. Aspect:
class _CommandSlopeAnalisys:
def GetResources(self):
return {'Pixmap': str(os.path.join(DirIcons, "TerrainSlope.svg")),
'Accel': "T, S",
'MenuText': 'Analisis de Pendiente',
'ToolTip': 'Analisis de Pendiente'
}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def Activated(self):
self.TaskPanel = _SlopeTaskPanel()
FreeCADGui.Control.showDialog(self.TaskPanel)
## 3. Height:
class _CommandHeightAnalisys:
def GetResources(self):
return {'Pixmap': str(os.path.join(DirIcons, "TerrainHeight.svg")),
'Accel': "T, H",
'MenuText': 'Analisis de Altura',
'ToolTip': 'Analisis de Altura'
}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def Activated(self):
self.TaskPanel = _HeightTaskPanel()
FreeCADGui.Control.showDialog(self.TaskPanel)
## 4. Orientation:
class _CommandOrientationAnalisys:
def GetResources(self):
return {'Pixmap': str(os.path.join(DirIcons, "TerrainOrientation.svg")),
'Accel': "T, H",
'MenuText': 'Analisis de Orientación',
'ToolTip': 'Analisis de Orientación'
}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
def Activated(self):
self.TaskPanel = _OrientationTaskPanel()
FreeCADGui.Control.showDialog(self.TaskPanel)
## 5. Commands
if FreeCAD.GuiUp:
class CommandTerrainAnalisysGroup:
def GetCommands(self):
return tuple(['Contours',
'HeightAnalisys',
'SlopeAnalisys',
'OrientationAnalisys'
])
def GetResources(self):
return { 'MenuText': QT_TRANSLATE_NOOP("",'Terrain Analisys'),
'ToolTip': QT_TRANSLATE_NOOP("",'Terrain Analisys')
}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
FreeCADGui.addCommand('Contours', _CommandContours())
FreeCADGui.addCommand('SlopeAnalisys', _CommandSlopeAnalisys())
FreeCADGui.addCommand('HeightAnalisys', _CommandHeightAnalisys())
FreeCADGui.addCommand('OrientationAnalisys', _CommandOrientationAnalisys())
2025-03-28 19:40:11 +06:00
FreeCADGui.addCommand('TerrainAnalisys', CommandTerrainAnalisysGroup())'''