primera subida

This commit is contained in:
2025-01-28 00:04:13 +01:00
commit a91237c3e1
577 changed files with 457418 additions and 0 deletions

803
Project/Area/PVPlantArea.py Normal file
View File

@@ -0,0 +1,803 @@
# /**********************************************************************
# * *
# * Copyright (c) 2021 Javier Braña <javier.branagutierrez@gmail.com> *
# * *
# * This program is free software; you can redistribute it and/or modify*
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307*
# * USA *
# * *
# ***********************************************************************
import FreeCAD
import Part
import PVPlantSite
import Utils.PVPlantUtils as utils
import MeshPart as mp
if FreeCAD.GuiUp:
import FreeCADGui
from DraftTools import translate
else:
# \cond
def translate(ctxt,txt):
return txt
def QT_TRANSLATE_NOOP(ctxt,txt):
return txt
# \endcond
import os
from PVPlantResources import DirIcons as DirIcons
__title__ = "PVPlant Areas"
__author__ = "Javier Braña"
__url__ = "http://www.sogos-solar.com"
import PVPlantResources
from PVPlantResources import DirIcons as DirIcons
Dir3dObjects = os.path.join(PVPlantResources.DirResources, "3dObjects")
''' Default Area: '''
def makeArea(points = None, type = 0):
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "Area")
if type == 0:
_Area(obj)
_ViewProviderArea(obj.ViewObject)
elif type == 1:
_ForbiddenArea(obj)
_ViewProviderForbiddenArea(obj.ViewObject)
if points:
obj.Points = points
return obj
class _Area:
def __init__(self, obj):
''' Initialize the Area object '''
self.Type = None
self.obj = None
def setProperties(self, obj):
pl = obj.PropertiesList
if not ("Base" in pl):
obj.addProperty("App::PropertyLink",
"Base",
"Area",
"Base wire"
).Base = None
if not ("Type" in pl):
obj.addProperty("App::PropertyString",
"Type",
"Area",
"Points that define the area"
).Type = "Area"
obj.setEditorMode("Type", 1)
self.Type = obj.Type
obj.Proxy = self
def onDocumentRestored(self, obj):
""" Method run when the document is restored """
self.setProperties(obj)
class _ViewProviderArea:
def __init__(self, vobj):
self.Object = vobj.Object
vobj.Proxy = self
def attach(self, vobj):
'''
Create Object visuals in 3D view.
'''
self.Object = vobj.Object
return
def getIcon(self):
'''
Return object treeview icon.
'''
return str(os.path.join(DirIcons, "area.svg"))
'''
def claimChildren(self):
"""
Provides object grouping
"""
return self.Object.Group
'''
def setEdit(self, vobj, mode=0):
"""
Enable edit
"""
return True
def unsetEdit(self, vobj, mode=0):
"""
Disable edit
"""
return False
def doubleClicked(self, vobj):
"""
Detect double click
"""
pass
def setupContextMenu(self, obj, menu):
"""
Context menu construction
"""
pass
def edit(self):
"""
Edit callback
"""
pass
def __getstate__(self):
"""
Save variables to file.
"""
return None
def __setstate__(self, state):
"""
Get variables from file.
"""
return None
''' Frame Area '''
def makeFramedArea(base = None, select = None):
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "FrameArea")
FrameArea(obj)
ViewProviderFrameArea(obj.ViewObject)
if base:
obj.Base = base
if select:
frames = []
for o in select:
if hasattr(o, "Proxy") and (o.Proxy.Type == "Tracker"):
if not (o in frames):
frames.append(o)
if len(frames) > 0:
print(frames)
obj.Frames = frames
try:
group = FreeCAD.ActiveDocument.FrameZones
except:
group = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", 'FrameZones')
group.Label = "FrameZones"
group.addObject(obj)
return obj
class FrameArea(_Area):
def __init__(self, obj):
_Area.__init__(self, obj)
self.setProperties(obj)
self.obj = None
def setProperties(self, obj):
_Area.setProperties(self, obj)
pl = obj.PropertiesList
if not ("Frames" in pl):
obj.addProperty("App::PropertyLinkList",
"Frames",
"Area",
"All the frames inside this area."
)
if not ("FrameNumber" in pl):
obj.addProperty("App::PropertyInteger",
"FrameNumber",
"Area",
"The number of frames inside this area."
)
obj.setEditorMode("FrameNumber", 1)
if not ("Type" in pl):
obj.addProperty("App::PropertyString",
"Type",
"Base",
"The facemaker type to use to build the profile of this object"
).Type = "FrameArea"
obj.setEditorMode("Type", 1)
self.Type = "FrameArea"
obj.Proxy = self
self.obj = obj
def onDocumentRestored(self, obj):
"""Method run when the document is restored."""
self.setProperties(obj)
def onBeforeChange(self, obj, prop):
''' '''
pass
def onChanged(self, obj, prop):
if prop == "Base":
if obj.Base.Shape is None:
obj.Shape = Part.Shape()
return
import Utils.PVPlantUtils as utils
base = obj.Base.Shape
land = PVPlantSite.get().Terrain.Mesh
vec = FreeCAD.Vector(0,0,1)
wire = utils.getProjected(base, vec)
tmp = mp.projectShapeOnMesh(wire, land, vec)
shape = Part.makeCompound([])
for section in tmp:
shape.add(Part.makePolygon(section))
obj.Shape = shape
if prop == "Frames":
lf = []
for o in obj.Frames:
if not hasattr(o, "Proxy"):
continue
if o.Proxy.Type == "Tracker":
lf.append(obj)
obj.Frames = lf
obj.FramesNumber = len(obj.Frames)
def addFrame(self, frame):
list = self.obj.Frames.copy()
list.append(frame)
self.obj.Frames = sorted(list, key=lambda x: x.Name)
def execute(self, obj):
''' execute '''
#_Area.execute(self, obj)
obj.FrameNumber = len(obj.Frames)
class ViewProviderFrameArea(_ViewProviderArea):
def __init__(self, vobj):
''' Set view properties. '''
self.Object = vobj.Object
vobj.Proxy = self
def getIcon(self):
''' Return object treeview icon '''
return str(os.path.join(DirIcons, "FrameArea.svg"))
def claimChildren(self):
""" Provides object grouping """
children = []
if self.Object.Base:
children.append(self.Object.Base)
return children
''' offsets '''
def makeOffsetArea(base = None, val=None):
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "OffsetArea")
OffsetArea(obj)
obj.Base = base
ViewProviderOffsetArea(obj.ViewObject)
if val:
obj.Distance = val
offsets = None
try:
offsetsgroup = FreeCAD.ActiveDocument.Offsets
except:
offsetsgroup = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", 'Offsets')
offsetsgroup.Label = "Offsets"
offsetsgroup.addObject(obj)
return obj
class OffsetArea(_Area):
def __init__(self, obj):
_Area.__init__(self, obj)
self.setProperties(obj)
def setProperties(self, obj):
_Area.setProperties(self, obj)
pl = obj.PropertiesList
if not ("OffsetDistance" in pl):
obj.addProperty("App::PropertyDistance",
"OffsetDistance",
"OffsetArea",
"Base wire"
)
self.Type = obj.Type = "Area_Offset"
def onDocumentRestored(self, obj):
"""Method run when the document is restored."""
self.setProperties(obj)
def execute(self, obj):
import Utils.PVPlantUtils as utils
base = obj.Base.Shape
land = PVPlantSite.get().Terrain.Mesh
vec = FreeCAD.Vector(0, 0, 1)
wire = utils.getProjected(base, vec)
wire = wire.makeOffset2D(obj.OffsetDistance.Value, 2, False, False, True)
tmp = mp.projectShapeOnMesh(wire, land, vec)
pts = []
for section in tmp:
pts.extend(section)
obj.Shape = Part.makePolygon(pts)
class ViewProviderOffsetArea(_ViewProviderArea):
def getIcon(self):
''' Return object treeview icon. '''
return str(os.path.join(DirIcons, "offset.svg"))
def claimChildren(self):
""" Provides object grouping """
children = []
if self.Object.Base:
children.append(self.Object.Base)
return children
''' Forbidden Area: '''
def makeProhibitedArea(base = None):
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "ProhibitedArea")
ProhibitedArea(obj)
ViewProviderForbiddenArea(obj.ViewObject)
if base:
obj.Base = base
try:
group = FreeCAD.ActiveDocument.Exclusion
except:
group = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup", 'Exclusion')
group.Label = "Exclusions"
group.addObject(obj)
return obj
class ProhibitedArea(OffsetArea):
def __init__(self, obj):
OffsetArea.__init__(self, obj)
self.setProperties(obj)
def setProperties(self, obj):
OffsetArea.setProperties(self, obj)
self.Type = obj.Type = "ProhibitedArea"
obj.Proxy = self
def onDocumentRestored(self, obj):
"""Method run when the document is restored."""
self.setProperties(obj)
class ViewProviderForbiddenArea(_ViewProviderArea):
def getIcon(self):
''' Return object treeview icon '''
return str(os.path.join(DirIcons, "area_forbidden.svg"))
def claimChildren(self):
""" Provides object grouping """
children = []
if self.Object.Base:
children.append(self.Object.Base)
return children
''' PV Area: '''
def makePVSubplant():
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "PVSubplant")
PVSubplant(obj)
ViewProviderPVSubplant(obj.ViewObject)
return obj
class PVSubplant:
def __init__(self, obj):
self.setProperties(obj)
self.Type = None
self.obj = None
def setProperties(self, obj):
pl = obj.PropertiesList
if not "Setup" in pl:
obj.addProperty("App::PropertyEnumeration",
"Setup",
"PVSubplant",
"The facemaker type to use to build the profile of this object"
).Setup = ["String Inverter", "Central Inverter"]
if not ("Frames" in pl):
obj.addProperty("App::PropertyLinkList",
"Frames",
"PVSubplant",
"List of frames"
)
if not ("Inverters" in pl):
obj.addProperty("App::PropertyLinkList",
"Inverters",
"PVSubplant",
"List of Inverters"
)
if not ("Cables" in pl):
obj.addProperty("App::PropertyLinkList",
"Cables",
"PVSubplant",
"List of Cables"
)
if not "TotalPVModules" in pl:
obj.addProperty("App::PropertyQuantity",
"TotalPVModules",
"PVSubplant",
"The facemaker type to use to build the profile of this object"
)
if not "TotalPowerDC" in pl:
obj.addProperty("App::PropertyQuantity",
"TotalPowerDC",
"PVSubplant",
"The facemaker type to use to build the profile of this object"
)
if not "Color" in pl:
obj.addProperty("App::PropertyColor",
"Color",
"PVSubplant",
"Color"
)
if not "Type" in pl:
obj.addProperty("App::PropertyString",
"Type",
"Base",
"The facemaker type to use to build the profile of this object"
).Type = "PVSubplant"
obj.setEditorMode("Type", 1)
self.Type = obj.Type
self.obj = obj
obj.Proxy = self
def onDocumentRestored(self, obj):
"""Method run when the document is restored."""
self.setProperties(obj)
def onChanged(self, obj, prop):
if prop == "Color":
obj.ViewObject.LineColor = obj.Color
obj.ViewObject.PointColor = obj.Color
if prop == "Setup":
if obj.Setup == "Central Inverter":
if not ("StringBoxes" in obj.PropertiesList):
obj.addProperty("App::PropertyLinkList",
"StringBoxes",
"PVSubplant",
"List of String-Boxes"
)
else:
if hasattr(obj, "StringBoxes"):
obj.removeProperty("StringBoxes")
if prop == "Frames":
import numpy as np
# 1. Dibujar contorno:
maxdist = 6000
if len(obj.Frames) > 0:
onlyframes = []
for object in obj.Frames:
if object.Name.startswith("Tracker"):
onlyframes.append(object)
obj.Frames = onlyframes
pts = []
for frame in obj.Frames:
for panel in frame.Shape.SubShapes[0].SubShapes[0].SubShapes:
zm = panel.BoundBox.ZMax
for i in range(8):
pt = panel.BoundBox.getPoint(i)
if pt.z == zm:
pts.append(pt)
import MeshTools.Triangulation as Triangulation
import MeshTools.MeshGetBoundary as mgb
m = Triangulation.Triangulate(np.array(pts), MaxlengthLE=maxdist, use3d=False)
b = mgb.get_boundary(m)
obj.Shape = b
# 2. rellenar información
power = 0
modulenum = 0
for frame in obj.Frames:
modules = frame.Setup.ModuleColumns * frame.Setup.ModuleRows
power += frame.Setup.ModulePower.Value * modules
modulenum += modules
obj.TotalPowerDC = power
obj.TotalPVModules = modulenum
obj.ViewObject.LineWidth = 5
def execute(self, obj):
''' '''
pass
class ViewProviderPVSubplant:
def __init__(self, vobj):
''' Set view properties. '''
self.Object = None
vobj.Proxy = self
def attach(self, vobj):
''' Create Object visuals in 3D view. '''
self.Object = vobj.Object
return
def getIcon(self):
''' Return object treeview icon. '''
return str(os.path.join(DirIcons, "subplant.svg"))
def claimChildren(self):
""" Provides object grouping """
children = []
if self.Object.Frames:
children.extend(self.Object.Frames)
return children
def __getstate__(self):
return None
'''def onDelete(self, feature, subelements):
try:
for obj in self.claimChildren():
obj.ViewObject.show()
except Exception as err:
FreeCAD.Console.PrintError("Error in onDelete: " + str(err))
return True
def canDragObjects(self):
return True
def canDropObjects(self):
return True
def canDragObject(self, dragged_object):
return True
def canDropObject(self, incoming_object):
return hasattr(incoming_object, 'Shape')
def dragObject(self, selfvp, dragged_object):
objs = self.Object.Objects
objs.remove(dragged_object)
self.Object.Objects = objs
def dropObject(self, selfvp, incoming_object):
self.Object.Objects = self.Object.Objects + [incoming_object]
def setEdit(self, vobj, mode=0):
"""
Enable edit
"""
return True
def unsetEdit(self, vobj, mode=0):
"""
Disable edit
"""
return False
def doubleClicked(self, vobj):
"""
Detect double click
"""
pass
def setupContextMenu(self, obj, menu):
"""
Context menu construction
"""
pass
def edit(self):
"""
Edit callback
"""
pass
def __getstate__(self):
"""
Save variables to file.
"""
return None
def __setstate__(self,state):
"""
Get variables from file.
"""
return None'''
# Comandos: -----------------------------------------------------------------------------------------------------------
class CommandDivideArea:
def GetResources(self):
return {'Pixmap': str(os.path.join(PVPlantResources.DirIcons, "area.svg")),
'Accel': "A, D",
'MenuText': "Divide Area",
'ToolTip': "Allowed Area"}
def Activated(self):
sel = FreeCADGui.Selection.getSelection()[0]
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
class CommandBoundary:
def GetResources(self):
return {'Pixmap': str(os.path.join(PVPlantResources.DirIcons, "area.svg")),
'Accel': "A, B",
'MenuText': "Area",
'ToolTip': "Allowed Area"}
def Activated(self):
sel = FreeCADGui.Selection.getSelection()[0]
obj = makeArea([ver.Point for ver in sel.Shape.Vertexes])
#taskd = _PVPlantPlacementTaskPanel()
#FreeCADGui.Control.showDialog(taskd)
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
class CommandFrameArea:
def GetResources(self):
return {'Pixmap': str(os.path.join(PVPlantResources.DirIcons, "FrameArea.svg")),
'Accel': "A, F",
'MenuText': "Frame Area",
'ToolTip': "Frame Area"}
def Activated(self):
sel = FreeCADGui.Selection.getSelection()
makeFramedArea(None, sel)
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
class CommandProhibitedArea:
def GetResources(self):
return {'Pixmap': str(os.path.join(PVPlantResources.DirIcons, "area_forbidden.svg")),
'Accel': "A, F",
'MenuText': "Prohibited Area",
'ToolTip': "Prohibited Area"}
def Activated(self):
sel = FreeCADGui.Selection.getSelection()
makeProhibitedArea(sel[0])
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
class CommandPVSubplant:
def GetResources(self):
return {'Pixmap': str(os.path.join(PVPlantResources.DirIcons, "subplant.svg")),
'Accel': "A, P",
'MenuText': "PV Subplant",
'ToolTip': "PV Subplant"}
def Activated(self):
area = makePVSubplant()
sel = FreeCADGui.Selection.getSelection()
for obj in sel:
if obj.Name[:7] == "Tracker":
frame_list = area.Frames
frame_list.append(obj)
area.Frames = frame_list
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
class CommandOffsetArea:
def GetResources(self):
return {'Pixmap': str(os.path.join(PVPlantResources.DirIcons, "offset.svg")),
'Accel': "A, O",
'MenuText': "OffsetArea",
'ToolTip': "OffsetArea"}
def Activated(self):
sel = FreeCADGui.Selection.getSelection()
base = None
if sel:
base = sel[0]
obj = makeOffsetArea(base)
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
if FreeCAD.GuiUp:
class CommandAreaGroup:
def GetCommands(self):
return tuple([#'Area',
'FrameArea',
'ForbiddenArea',
'PVSubplant',
'OffsetArea'
])
def GetResources(self):
return {'MenuText': 'Areas',
'ToolTip': 'Areas'
}
def IsActive(self):
return not FreeCAD.ActiveDocument is None
#FreeCADGui.addCommand('Area', CommandBoundary())
FreeCADGui.addCommand('FrameArea', CommandFrameArea())
FreeCADGui.addCommand('ForbiddenArea', CommandProhibitedArea())
FreeCADGui.addCommand('PVSubplant', CommandPVSubplant())
FreeCADGui.addCommand('OffsetArea', CommandOffsetArea())
FreeCADGui.addCommand('PVPlantAreas', CommandAreaGroup())

View File

@@ -0,0 +1,167 @@
# /**********************************************************************
# * *
# * Copyright (c) 2021 Javier Braña <javier.branagutierrez@gmail.com> *
# * *
# * This program is free software; you can redistribute it and/or modify*
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307*
# * USA *
# * *
# ***********************************************************************
import FreeCAD
if FreeCAD.GuiUp:
import FreeCADGui
import os
else:
# \cond
def translate(ctxt, txt):
return txt
def QT_TRANSLATE_NOOP(ctxt, txt):
return txt
# \endcond
__title__ = "PVPlant Area Utils"
__author__ = "Javier Braña"
__url__ = "http://www.sogos-solar.com"
import PVPlantResources
def splitArea(area, tool):
if (not area) or (not tool):
return None
import Part, TechDraw
import BOPTools.SplitAPI as splitter
tool = tool.Shape
if tool.BoundBox.ZMax != tool.BoundBox.ZMin:
tool = TechDraw.projectEx(tool, FreeCAD.Vector(0, 0, 1))[0]
tool = tool.extrude(FreeCAD.Vector(0, 0, 1000))
tool.Placement.Base.z -= 500
shape = area.Shape
if shape.BoundBox.ZMax != shape.BoundBox.ZMin:
shape = TechDraw.projectEx(shape, FreeCAD.Vector(0, 0, 1))[0]
face = Part.Face(Part.Wire(shape.Edges))
return splitter.slice(face, [tool, ], "Split")
class splitAreaTaskPanel:
def __init__(self):
self.area = None
self.tool = None
self.form = FreeCADGui.PySideUic.loadUi(os.path.join(PVPlantResources.__dir__, "Project", "Area", "PVPlantSplitArea.ui"))
self.form.buttonAreaSel.clicked.connect(self.addArea)
self.form.buttonToolSel.clicked.connect(self.addTool)
#self.view = FreeCADGui.ActiveDocument.ActiveView
#self.call = self.view.addEventCallback("SoEvent", self.action)
def addArea(self):
self.area = FreeCADGui.Selection.getSelection()[0]
self.form.lineArea.setText(self.area.Name)
def addTool(self):
self.tool = FreeCADGui.Selection.getSelection()[0]
self.form.lineTool.setText(self.tool.Name)
def accept(self):
import Part
self.closeForm()
results = splitArea(self.area, self.tool)
if isinstance(results, Part.Compound):
for face in results.Faces:
Part.show(face.Wire, self.area.Label + "-split")
elif isinstance(results, list):
for face in results:
Part.show(face.Wire, self.area.Label + "-split")
else:
Part.show(results)
if self.form.checkBoxDeleteTool.isChecked():
FreeCAD.ActiveDocument.removeObject(self.tool.Name)
if self.form.checkBoxDeleteArea.isChecked():
FreeCAD.ActiveDocument.removeObject(self.area.Name)
return True
def reject(self):
print(" .. Rejecting .. ")
if self.new:
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
self.closeForm()
return True
def closeForm(self):
print(" .. Closing .. ")
#self.view.removeEventCallback("SoEvent", self.call)
FreeCADGui.Control.closeDialog()
def joinAreas(areas):
if len(areas) == 0:
return None
import TechDraw
shapes = []
for area in areas:
shape = area.Shape
if shape.BoundBox.ZMax != shape.BoundBox.ZMin:
shape = TechDraw.projectEx(shape, FreeCAD.Vector(0, 0, 1))[0]
shapes.append(shape)
shape = shapes.pop()
shape.fuse(shapes)
return shape
class CommandSplitArea:
def GetResources(self):
return {'Pixmap': str(os.path.join(PVPlantResources.DirIcons, "split_area.svg")),
'Accel': "A, S",
'MenuText': "Split Area",
'ToolTip': "Split Area"}
def IsActive(self):
return (not FreeCAD.ActiveDocument is None and
not FreeCAD.ActiveDocument.findObjects(Name="ProhibitedArea") is None and
not FreeCAD.ActiveDocument.findObjects(Name="OffsetArea") is None)
def Activated(self):
self.TaskPanel = splitAreaTaskPanel()
FreeCADGui.Control.showDialog(self.TaskPanel)
return
class CommandJoinAreas:
def GetResources(self):
return {'Pixmap': str(os.path.join(PVPlantResources.DirIcons, "split_area.svg")),
'Accel': "A, J",
'MenuText': "Join Areas",
'ToolTip': "Join Areas"}
def IsActive(self):
return (not FreeCAD.ActiveDocument is None and
not FreeCAD.ActiveDocument.findObjects(Name="ProhibitedArea") is None and
not FreeCAD.ActiveDocument.findObjects(Name="OffsetArea") is None)
def Activated(self):
self.TaskPanel = splitAreaTaskPanel()
FreeCADGui.Control.showDialog(self.TaskPanel)
return
if FreeCAD.GuiUp:
FreeCADGui.addCommand('SplitArea', CommandSplitArea())
FreeCADGui.addCommand('JoinAreas', CommandJoinAreas())

View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>formSplitArea</class>
<widget class="QWidget" name="formSplitArea">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>313</width>
<height>301</height>
</rect>
</property>
<property name="windowTitle">
<string>Split Area</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Herramienta de corte</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="lineTool">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonToolSel">
<property name="text">
<string>Seleccionar</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Area</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLineEdit" name="lineArea">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="buttonAreaSel">
<property name="text">
<string>Seleccionar</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Resultado</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="checkBoxDeleteTool">
<property name="text">
<string>Borrar herramienta de corte</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxDeleteArea">
<property name="text">
<string>Borrar Area inicial</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

163
Project/ProjectSetup.py Normal file
View File

@@ -0,0 +1,163 @@
import FreeCAD
if FreeCAD.GuiUp:
import FreeCADGui
from PySide import QtGui, QtCore
import os
else:
# \cond
def translate(ctxt, txt):
return txt
def QT_TRANSLATE_NOOP(ctxt, txt):
return txt
# \endcond
__title__ = "PVPlant Project Setup"
__author__ = "Javier Braña"
__url__ = "http://www.sogos-solar.com"
from PVPlantResources import DirIcons as DirIcons
class ProjectSetupDialog(QtGui.QWidget):
'''The editmode TaskPanel to select what you want to export'''
def __init__(self):
QtGui.QWidget.__init__(self)
import os
# self.form:
self.form = FreeCADGui.PySideUic.loadUi(
os.path.join(os.path.dirname(os.path.realpath(__file__)), "ProjectSetup.ui"))
#self.form.setWindowIcon(QtGui.QIcon(os.path.join(PVPlantResources.DirIcons, "convert.svg")))
self.bcnf = FreeCADGui.UiLoader().createWidget("Gui::ColorButton")
self.bcnf.setProperty('color', QtGui.QColor(255, 126, 126))
self.bcsf = FreeCADGui.UiLoader().createWidget("Gui::ColorButton")
self.bcsf.setProperty('color', QtGui.QColor(255, 126, 0))
gridLayout = self.form.tab1.layout()
gridLayout.addWidget(self.bcnf, 2, 1)
gridLayout.addWidget(self.bcsf, 2, 2)
self.setdefaultvalues()
self.layout = QtGui.QHBoxLayout(self)
self.layout.setContentsMargins(4, 4, 4, 4)
self.layout.addWidget(self.form)
self.form.buttonAccept.clicked.connect(self.onAcceptClick)
self.form.buttonCancel.clicked.connect(self.onCancelClick)
def setdefaultvalues(self):
doc = FreeCAD.ActiveDocument
pl = doc.PropertiesList
if "MaximumTiltPositive" in pl:
self.form.editNFTL.setValue(doc.MaximumTiltPositive)
if "MaximumTiltPositiveColor" in pl:
col = QtGui.QColor()
col.setRgbF(doc.MaximumTiltPositiveColor[0], doc.MaximumTiltPositiveColor[1],
doc.MaximumTiltPositiveColor[2])
self.bcsf.setProperty('color', col)
if "MaximumTiltNegative" in pl:
self.form.editSFTL.setValue(-doc.MaximumTiltNegative)
if "MaximumTiltNegativeColor" in pl:
col = QtGui.QColor()
col.setRgbF(doc.MaximumTiltNegativeColor[0], doc.MaximumTiltNegativeColor[1],
doc.MaximumTiltNegativeColor[2])
self.bcnf.setProperty('color', col)
if "MaximumWestEastSlope" in pl:
self.form.editWETL.setValue(doc.MaximumWestEastSlope)
def onAcceptClick(self):
doc = FreeCAD.ActiveDocument
pl = doc.PropertiesList
if not ("FramesChecking" in pl):
doc.addProperty("App::PropertyBool",
"FramesChecking",
"PVPlantProject",
"All the frames inside this area."
).FramesChecking = False
doc.setEditorMode("FramesChecking", 1) # no editable
doc.setEditorMode("FramesChecking", 2) # no visible
if not ("MaximumTiltPositive" in pl):
doc.addProperty("App::PropertyAngle",
"MaximumTiltPositive",
"PVPlantProject",
"All the frames inside this area."
)
if not ("MaximumTiltPositiveColor" in pl):
doc.addProperty("App::PropertyColor",
"MaximumTiltPositiveColor",
"PVPlantProject",
"All the frames inside this area."
)
if not ("MaximumTiltNegative" in pl):
doc.addProperty("App::PropertyAngle",
"MaximumTiltNegative",
"PVPlantProject",
"All the frames inside this area."
)
if not ("MaximumTiltNegativeColor" in pl):
doc.addProperty("App::PropertyColor",
"MaximumTiltNegativeColor",
"PVPlantProject",
"All the frames inside this area."
)
if not ("MaximumWestEastSlope" in pl):
doc.addProperty("App::PropertyAngle",
"MaximumWestEastSlope",
"PVPlantProject",
"All the frames inside this area."
)
doc.MaximumTiltPositive = self.form.editNFTL.value()
col = self.bcsf.property('color')
doc.MaximumTiltPositiveColor = (col.redF(), col.greenF(), col.blueF())
doc.MaximumTiltNegative = -self.form.editSFTL.value()
col = self.bcnf.property('color')
doc.MaximumTiltNegativeColor = (col.redF(), col.greenF(), col.blueF())
doc.MaximumWestEastSlope = self.form.editWETL.value()
self.closeForm()
def onCancelClick(self):
self.closeForm()
def closeForm(self):
self.close()
class CommandProjectSetup:
def GetResources(self):
return {'Pixmap': str(os.path.join(DirIcons, "flash.svg")),
'Accel': "P, S",
'MenuText': "Project Setup",
'ToolTip': "Setup all the variable for this project"}
def Activated(self):
taskd = ProjectSetupDialog()
taskd.setParent(FreeCADGui.getMainWindow())
taskd.setWindowFlags(QtCore.Qt.Window)
taskd.show()
def IsActive(self):
if FreeCAD.ActiveDocument:
return True
else:
return False
if FreeCAD.GuiUp:
FreeCADGui.addCommand('ProjectSetup', CommandProjectSetup())

201
Project/ProjectSetup.ui Normal file
View File

@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>formProjectSetup</class>
<widget class="QDialog" name="formProjectSetup">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>485</width>
<height>384</height>
</rect>
</property>
<property name="windowTitle">
<string>Export to PVSyst</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab1">
<attribute name="title">
<string>Frame Tolerances</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<property name="spacing">
<number>9</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Maximum north-south slope:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Frame coloring:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Maximum west-east slope:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="editWETL">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="suffix">
<string> º</string>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
<property name="value">
<double>8.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QDoubleSpinBox" name="editSFTL">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="suffix">
<string> º</string>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
<property name="value">
<double>2.800000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QWidget" name="widget_2" native="true"/>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>South facing</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="editNFTL">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="suffix">
<string> º</string>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
<property name="value">
<double>5.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>North Facing</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab2">
<attribute name="title">
<string>tab2</string>
</attribute>
</widget>
<widget class="QWidget" name="tab3">
<attribute name="title">
<string>Page</string>
</attribute>
</widget>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="buttonAccept">
<property name="text">
<string>Aceptar</string>
</property>
<property name="icon">
<iconset theme="Accept">
<normaloff>../../../../../.designer/backup</normaloff>../../../../../.designer/backup</iconset>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonCancel">
<property name="text">
<string>Cancelar</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

108
Project/utils/renamer.py Normal file
View File

@@ -0,0 +1,108 @@
# /**********************************************************************
# * *
# * Copyright (c) 2021 Javier Braña <javier.branagutierrez@gmail.com> *
# * *
# * This program is free software; you can redistribute it and/or modify*
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307*
# * USA *
# * *
# ***********************************************************************
import FreeCAD
if FreeCAD.GuiUp:
import FreeCADGui, os
from PySide import QtCore
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 PVPlantResources
from PVPlantResources import DirIcons as DirIcons
def rename(objects, mask, mode=0):
'''
mode = 0/1/2/3
0: izquierda a derecha - arriba a abajo
1: arriba a abajo - izquierda a derecha
'''
# sort:
tmp = sorted(objects, key=lambda x: (x.Placement.Base.x,
x.Placement.Base.y))
for idx, obj in tmp:
obj.Name = name
class renamerTaskPanel:
def __init__(self, obj=None):
self.obj = obj
# -------------------------------------------------------------------------------------------------------------
# Module widget form
# -------------------------------------------------------------------------------------------------------------
self.formRack = FreeCADGui.PySideUic.loadUi(PVPlantResources.__dir__ + "/PVPlantFrame.ui")
self.formRack.widgetTracker.setVisible(False)
self.formRack.comboFrameType.currentIndexChanged.connect(self.selectionchange)
self.formPiling = FreeCADGui.PySideUic.loadUi(PVPlantResources.__dir__ + "/PVPlantRackFixedPiling.ui")
self.formPiling.editBreadthwaysNumOfPost.valueChanged.connect(self.editBreadthwaysNumOfPostChange)
self.formPiling.editAlongNumOfPost.valueChanged.connect(self.editAlongNumOfPostChange)
self.form = [self.formRack, self.formPiling]
def accept(self):
self.closeForm()
return True
def reject(self):
self.closeForm()
return False
def closeForm(self):
FreeCADGui.Control.closeDialog()
class _CommandRenamer:
"the Arch Building command definition"
def GetResources(self):
return {'Pixmap': str(os.path.join(DirIcons, "trackersetup.svg")),
'MenuText': QtCore.QT_TRANSLATE_NOOP("PVPlantTracker", "TrackerSetup"),
'Accel': "R, F",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PVPlanTracker",
"Creates a TrackerSetup object from setup dialog.")}
def IsActive(self):
return (not FreeCAD.ActiveDocument is None and
not FreeCAD.ActiveDocument.getObject("Site") is None)
def Activated(self):
self.TaskPanel = renamerTaskPanel()
FreeCADGui.Control.showDialog(self.TaskPanel)
return

90
Project/utils/renamer.ui Normal file
View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>formRack</class>
<widget class="QDialog" name="formRack">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>255</width>
<height>337</height>
</rect>
</property>
<property name="windowTitle">
<string>Fixed Frame:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Renombrar por sub-planta</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QComboBox" name="comboBox">
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Leyenda</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>