Files
PVPlant/Civil/Trench/TrenchOperators.py
2025-01-28 00:04:13 +01:00

201 lines
7.0 KiB
Python

def getcenter(lEdges, r):
import math
rndEdges = lEdges[0:2]
rndEdges = Part.__sortEdges__(rndEdges)
lVertexes = rndEdges[0].Vertexes + [rndEdges[1].Vertexes[-1]]
U1 = lVertexes[0].Point.sub(lVertexes[1].Point)
U1.normalize()
U2 = lVertexes[2].Point.sub(lVertexes[1].Point)
U2.normalize()
alpha = U1.getAngle(U2)
# Edges have same direction
'''if (round(alpha, 0) == 0) or (round(alpha - math.pi, 0) == 0):
pt1 = FreeCAD.Vector(U1)
x = pt1.x
pt1.x = pt1.y
pt1.y = -x
return rndEdges
pointsDirection = lineSelected.discretize(Number=500) # discretize the path line first selection
v = pointsDirection[0].sub(pointsDirection[1]) # avec vecteurs 1 et 2 (direction debut ligne)
r = App.Rotation(App.Vector(0, 0, 1), v)'''
dToCenter = r / math.sin(alpha / 2.0)
# dToTangent = (dToCenter ** 2 - r ** 2) ** 0.5
dirVect = U2.add(U1)
dirVect.normalize()
dirVect.scale(dToCenter, dToCenter, dToCenter)
pt1 = lVertexes[1].Point.add(dirVect)
pt2 = -1 * pt1
pt2.z = pt1.z
print(pt1, " - ", pt2)
return [pt1, pt2]
# from DRAFT
def split_wire(wire, newPoint, edgeIndex):
import Draft
wire1Points = []
wire2Points = []
print("New Point: ", newPoint)
print("edgeIndex: ", edgeIndex)
for index, point in enumerate(wire.Points):
print("index: ", index, " - point: ", point)
if index == edgeIndex:
wire1Points.append(point)
wire1Points.append(wire.Placement.inverse().multVec(newPoint))
wire2Points.append(newPoint)
# wire2Points.append(wire.Placement.multVec(point))
elif index < edgeIndex:
wire1Points.append(point)
elif index > edgeIndex:
wire2Points.append(wire.Placement.multVec(point))
if len(wire1Points) == 1:
wire1Points.insert(0, wire.Points[0])
if len(wire2Points) == 1:
wire2Points.appen(wire.Points[-1])
wire.Points = wire1Points
wire2 = Draft.makeWire(wire2Points, placement=wire.Placement)
FreeCAD.ActiveDocument.recompute()
wires = [wire, wire2]
return sorted(wires, key=lambda obj: obj.Length, reverse=True)
def SplitTrench(trench, point):
if not trench or not point:
return None
import Part
wire = trench.Base
vertex = Part.Vertex(point)
'''Find the minimum distance to another shape:
- distToShape(shape) -> (dist, vectors, infos) dist is the minimum distance, in mm (float value).
vectors is a list of pairs of App.Vector. Each pair corresponds to solution.
Example:
[(Vector (2.0, -1.0, 2.0), Vector (2.0, 0.0, 2.0)), (Vector (2.0,-1.0, 2.0), Vector (2.0, -1.0, 3.0))]
- First vector is a point on self, second vector is a point on s.
infos contains additional info on the solutions. It is a list of tuples: (topo1, index1, params1, topo2, index2, params2)
- topo1, topo2 are strings identifying type of BREP element: 'Vertex', 'Edge', or 'Face'.
- index1, index2 are indexes of the elements (zero-based).
- params1, params2 are parameters of internal space of the elements. For vertices, params is None.
For edges, params is one float, u. For faces, params is a tuple (u,v).
(719762.0578530617,
[(Vector (225057.375, 783988.625, 715062.875), Vector (306961.4605149741, 778138.3688035253, 0.0))],
[('Vertex', 0, None, 'Edge', 0, 79697.52668425611)])
'''
(dist, vectors, infos) = vertex.distToShape(wire.Shape)
if not dist:
return None
Location = FreeCAD.Vector(vectors[0][1])
if not Location:
return None
Normal = None
edind = 0
if infos[0][3] == 'Vertex':
vec = Location.sub(point)
Normal = FreeCAD.Vector(vec[1], -vec[0], vec[2])
edind = int(infos[0][4]) - 1
elif infos[0][3] == 'Edge':
ed = wire.Shape.Edges[int(dist[2][0][4])]
Normal = ed.Vertexes[1].Point.sub(ed.Vertexes[0].Point)
edind = int(infos[0][4])
wires = split_wire(wire, Location, edind)
trench.Base = wires[0]
trench1 = makeTrench(wire[1])
return Location, [trench, trench1], node
def JoinTrench(trench1, trench2):
if not trench1 or not trench2:
return None
class CommandSplitTrench: # V1:
"""Gui command for the Line tool."""
def GetResources(self):
"""Set icon, menu and tooltip."""
return {'Pixmap': str(os.path.join(DirIcons, "trench.svg")),
'MenuText': "Trench",
'Accel': "C, T",
'ToolTip': "Creates a Trench object from setup dialog."}
def IsActive(self):
return (not (FreeCAD.ActiveDocument is None) and
not (FreeCAD.ActiveDocument.getObject("Trench") is None))
def Activated(self):
"""Execute when the command is called."""
sel = FreeCADGui.Selection.getSelection()
done = False
if len(sel) > 0:
import Draft
for obj in sel:
if Draft.getType(obj) == "Wire":
FreeCAD.ActiveDocument.openTransaction("Create Trench")
makeTrench(obj)
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
done = True
break
if not done:
taskd = TrenchTaskPanel()
if taskd:
FreeCADGui.Control.showDialog(taskd)
else:
print(" No ha sido posible crear el formulario")
class CommandJoinTrench: # V1:
"""Gui command for the Line tool."""
def GetResources(self):
"""Set icon, menu and tooltip."""
return {'Pixmap': str(os.path.join(DirIcons, "trenchsplit.svg")),
'MenuText': "Semi-Automatic Trench Generator",
'Accel': "T, S",
'ToolTip': "Creates a Trench object from setup dialog."}
def IsActive(self):
return (not (FreeCAD.ActiveDocument is None) and
not (FreeCAD.ActiveDocument.getObject("Trench") is None))
def Activated(self):
"""Execute when the command is called."""
semi = semiAutomaticTrench()
if FreeCAD.GuiUp:
class CommandTrenchGroup:
def GetCommands(self):
return tuple(['PVPlantSplitTrench',
'PVPlantJoinTrench',
])
def GetResources(self):
return {'MenuText': 'Trench operations',
'ToolTip': 'Trench operations'
}
def IsActive(self):
active = not (FreeCAD.ActiveDocument is None)
terrain = not (FreeCAD.ActiveDocument.getObject("Terrain") is None)
active = active and terrain
if terrain:
active = active and not (FreeCAD.ActiveDocument.getObject("Terrain").Mesh is None)
return active
FreeCADGui.addCommand('PVPlantTrench', CommandTrench())
FreeCADGui.addCommand('PVPlantSemiAutomaticTrench', CommandSemiAutomaticTrench())
FreeCADGui.addCommand('Trenches', CommandTrenchGroup())