Creating a new workbench for photovoltaic

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
JavierBrana
Posts: 31
Joined: Thu Sep 06, 2018 5:43 pm

Re: Creating a new workbench for photovoltaic

Post by JavierBrana »

HakanSeven12 wrote: Sun Aug 01, 2021 7:20 am Still you didn't send me a test file :)
https://mega.nz/file/KvpGSarI#H0mAi_DxJ ... FpnJJVirvc
HakanSeven12 wrote: Sun Aug 01, 2021 7:20 am if you want to save them to object you need to add a string property to object. Then you can create a dictionary to save your settings and convert it to string and add it to your new property. When you want to set this color again use 'eval' to convert it to dictionary.
Good idea. I will think about that.
User avatar
HakanSeven12
Veteran
Posts: 1481
Joined: Wed Feb 06, 2019 10:30 pm

Re: Creating a new workbench for photovoltaic

Post by HakanSeven12 »

I made some improvement for pads. Take a look: http://forum.freecadweb.org/viewtopic.p ... &start=570
User avatar
ebrahim raeyat
Posts: 621
Joined: Sun Sep 09, 2018 7:00 pm
Location: Iran
Contact:

Re: Creating a new workbench for photovoltaic

Post by ebrahim raeyat »

HakanSeven12 wrote: Sun Aug 01, 2021 7:20 am Still you didn't send me a test file :) if you want to save them to object you need to add a string property to object. Then you can create a dictionary to save your settings and convert it to string and add it to your new property. When you want to set this color again use 'eval' to convert it to dictionary.
for storing a dictionary in an object, you can use "App::PropertyMap" properties.
User avatar
HakanSeven12
Veteran
Posts: 1481
Joined: Wed Feb 06, 2019 10:30 pm

Re: Creating a new workbench for photovoltaic

Post by HakanSeven12 »

I didn't know that. Thank for trick :) I will try.
User avatar
HakanSeven12
Veteran
Posts: 1481
Joined: Wed Feb 06, 2019 10:30 pm

Re: Creating a new workbench for photovoltaic

Post by HakanSeven12 »

My dictionary has dictionaries in it. So that property dont works for me :)
JavierBrana
Posts: 31
Joined: Thu Sep 06, 2018 5:43 pm

Re: Creating a new workbench for photovoltaic

Post by JavierBrana »

Nice work NakanSeven12!! I am checking your code when I have a moment.

For my side, I stopped this part and I am focus on the electrical and mechanical parts. For now, them are a little more urgent than civil. But soon I will come back to this part too.

My progress:
  • better construction of trackers
  • faster positioning of frames
  • positioning of frames aligned or following the shape of the boundaries of the land
  • Striming configuration and drawing
  • working on cable and wiring
  • reports of the mechanical part and export them to xmlx
User avatar
HakanSeven12
Veteran
Posts: 1481
Joined: Wed Feb 06, 2019 10:30 pm

Re: Creating a new workbench for photovoltaic

Post by HakanSeven12 »

JavierBrana
Posts: 31
Joined: Thu Sep 06, 2018 5:43 pm

Re: Creating a new workbench for photovoltaic

Post by JavierBrana »

Any alternative option to "makeParallelProjection"?. It is very expensive talking about time. It takes arround 3 second one operation and in some commands "makeParallelProjection" is called more than 1.000 times so you can guess it takes a long of time. I tried with extrude and (cut or common) but it is the same time more or less.
User avatar
HakanSeven12
Veteran
Posts: 1481
Joined: Wed Feb 06, 2019 10:30 pm

Re: Creating a new workbench for photovoltaic

Post by HakanSeven12 »

Why are you using this? What is the process?
JavierBrana
Posts: 31
Joined: Thu Sep 06, 2018 5:43 pm

Re: Creating a new workbench for photovoltaic

Post by JavierBrana »

There are serveral processes:

In this function y adjust a frame to the terrain. The solution I found was get the extreme points and project a line to the terrain. Thanks to this porjection I get a line from the first point to the last point. At the same time I get the base and angle:

Code: Select all

    def adjustToTerrain(self, cols, width):
        dist = 2000
        terrain = PVPlantSite.get().Terrain.Shape
        placements = []
        for col in cols:
            groups = []
            groups.append([col[0]])
            for i in range(1, len(col) - 1):
                group = groups[-1]
                l = (col[i].sub(group[-1])).Length
                l -= width
                if l <= dist:
                    group.append(col[i])
                else:
                    groups.append([col[i]])
            for group in groups:
                points = []
                vec1 = FreeCAD.Vector(self.Dir)
                vec1.Length = width / 2
                if len(group) == 1:
                    points.append(group[0].sub(vec1))
                    points.append(group[0].add(vec1))
                elif len(group) > 1:
                    points.append(group[0].sub(vec1))
                    for ind in range(0, len(group) - 1):
                        points.append((group[ind].add(vec1) + group[ind + 1].sub(vec1)) / 2)
                    points.append(group[-1].add(vec1))
                points3D = []
                for ind in range(len(points) - 1):
                    line = Part.LineSegment(points[ind], points[ind + 1])
                    [b]tmp = terrain.makeParallelProjection(line.toShape(), FreeCAD.Vector(0, 0, 1))[/b]
                    if len(tmp.Vertexes) > 0:
                        if ind == 0:
                            points3D.append(tmp.Vertexes[0].Point)
                        points3D.append(tmp.Vertexes[-1].Point)

                Draft.makeWire(points3D)

                for ind in range(0, len(points3D) - 1):
                    pl = FreeCAD.Placement()
                    vec = points3D[ind] - points3D[ind + 1]
                    pl.Base = FreeCAD.Vector(group[ind])
                    p = (points3D[ind] + points3D[ind + 1]) / 2
                    pl.Base.z = p.z
                    pl.Rotation = FreeCAD.Rotation(FreeCAD.Vector(-1, 0, 0), vec)
                    placements.append(pl)
        return placements
Other is this, where I calcule the eartwork. Once the frame is adjust to the terrain, I project the axis and I compare this profile with the axis:

Code: Select all

def calculateEarthWorks(trackerPath, Terrain, offsetup=200, offsetdown=200):
    Cuts = None
    Fills = None
    newPath = None

    limitTop = makeOffset(trackerPath, offsetup)
    limitBottom = makeOffset(trackerPath, -offsetdown)

    points3D = []
    [b]tmp_pts = Terrain.Shape.makeParallelProjection(trackerPath.Shape.Wires[0], FreeCAD.Vector(0, 0, 1))[/b]
    points3D = [ver.Point for ver in tmp_pts.Vertexes]
    points3D = sorted(points3D, key=lambda k: k.y, reverse=True)
    terrainProfile = Part.makePolygon(points3D)
    #Part.show(terrainProfile)

    sectionTop = terrainProfile.section(limitTop)
    crossTopPoints = VertexesToPoints(sectionTop.Vertexes)
    cutPoints, PointList = getCuts(crossTopPoints, points3D)

    Cuts = []
    for i in cutPoints:
        Cuts.extend(i)
    sectionBottom = terrainProfile.section(limitBottom)
    crossBottomPoints = VertexesToPoints(sectionBottom.Vertexes)
    fillPoints, PointList = getCuts(crossBottomPoints, PointList)

    Fills = []
    for i in fillPoints:
        Fills.extend(i)
    PointList = sorted(PointList, key=lambda k: k.y, reverse=(trackerPath.Shape.Vertexes[-1].Point.y <
                                                              trackerPath.Shape.Vertexes[0].Point.y))
    #newPath = Draft.makeWire(PointList, closed=False, face=None)
    #newPath.Label = trackerPath.Label + "_NewPath"

    return Cuts, Fills, newPath
Last edited by JavierBrana on Thu Jan 13, 2022 12:01 pm, edited 2 times in total.
Post Reply