Files
PVPlant/Utils/polyline.py
2025-01-28 00:04:13 +01:00

380 lines
14 KiB
Python

from draftobjects.base import DraftObject
from draftutils.utils import get_param
class circle(DraftObject):
def __init__(self, obj):
''' Creates a circle object '''
super(circle, self).__init__(obj, "Circle")
self.type = 'circle'
self.components = []
def execute(self, obj):
''' Executes the circle '''
import FreeCAD as App
import DraftGeomUtils
import DraftVecUtils
center = get_param(obj, "center")
radius = get_param(obj, "radius")
if center is None:
center = App.Vector(0, 0, 0)
if radius is None:
radius = 1
center = DraftVecUtils.to_vector(center)
radius = DraftVecUtils.to_vector(radius)
circle = DraftGeomUtils.make_circle(center, radius)
self.components.append(circle)
class line(DraftObject):
def __init__(self, obj):
''' Creates a line object '''
super(line, self).__init__(obj, "Line")
self.type = 'line'
self.components = []
def execute(self, obj):
''' Executes the line '''
import FreeCAD as App
import DraftGeomUtils
import DraftVecUtils
start = get_param(obj, "start")
end = get_param(obj, "end")
if start is None:
start = App.Vector(0, 0, 0)
if end is None:
end = App.Vector(1, 1, 1)
start = DraftVecUtils.to_vector(start)
end = DraftVecUtils.to_vector(end)
line = DraftGeomUtils.make_line(start, end)
self.components.append(line)
class polyline(DraftObject):
def __init__(self, obj):
''' Creates a polyline object '''
super(Wire, self).__init__(obj, "Wire")
self.type = 'polyline'
self.components = []
def execute(self, obj):
''' Executes the polyline '''
import FreeCAD as App
import Part
V1 = App.Vector(0, 10, 0)
V2 = App.Vector(30, 10, 0)
V3 = App.Vector(30, -10, 0)
V4 = App.Vector(0, -10, 0)
VC1 = App.Vector(-10, 0, 0)
C1 = Part.Arc(V1, VC1, V4)
VC2 = App.Vector(40, 0, 0)
C2 = Part.Arc(V2, VC2, V3)
L1 = Part.LineSegment(V1, V2)
L2 = Part.LineSegment(V3, V4)
S1 = Part.Shape([C1, L1, C2, L2])
W = Part.Wire(S1.Edges)
import FreeCAD as App
import Part
class Polyline:
def __init__(self):
self.segments = []
self.setProperties(obj)
def setProperties(self, obj):
''' do something '''
def onDocumentRestored(self,obj):
self.setProperties(obj)
def add_line(self, start, end):
line_segment = Part.LineSegment(start, end)
self.segments.append(line_segment)
def add_arc(self, start, end, center, tangent=True):
if tangent:
arc = Part.ArcOfCircle(start, end, center)
else:
start_point = start - center
end_point = end - center
arc = Part.ArcOfCircle(start_point, end_point, center)
self.segments.append(arc)
def create_wire(self):
wire = Part.Wire(self.segments)
return wire
def create_shape(self):
wire = self.create_wire()
shape = Part.Shape(wire)
return shape
def create_object(self, name):
shape = self.create_shape()
obj = App.ActiveDocument.addObject("Part::Feature", name)
obj.Shape = shape
return obj
def execute(self,obj):
''' '''
class editPolyline:
def __init__(self):
import draftguitools.gui_trackers as DraftTrackers
self.objects = []
self.state = 0
self.direction = None
self.distance = 1500
self.point = None
self.tracker = DraftTrackers.wireTracker(Part.Wire(Part.makePolygon([FreeCAD.Vector(),FreeCAD.Vector(1,1,1)])))
# event callbacks
self._keyPressedCB = None
self._mouseMovedCB = None
self._mousePressedCB = None
self.view = FreeCADGui.activeDocument().activeView()
self.render_manager = FreeCADGui.ActiveDocument.ActiveView.getViewer().getSoRenderManager()
# Callbacks
self.unregister_editing_callbacks()
self.register_editing_callbacks()
# -------------------------------------------------------------------------
# SCENE EVENTS CALLBACKS
# -------------------------------------------------------------------------
def register_editing_callbacks(self):
""" Register editing callbacks (former action function) """
print("Registering callbacks")
if self._keyPressedCB is None:
self._keyPressedCB = self.view.addEventCallbackPivy(coin.SoKeyboardEvent.getClassTypeId(), self.keyPressed)
if self._mousePressedCB is None:
self._mousePressedCB = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), self.mousePressed)
if self._mouseMovedCB is None:
self._mouseMovedCB = self.view.addEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(), self.mouseMoved)
print("end Registering callbacks")
def unregister_editing_callbacks(self):
""" Remove callbacks used during editing if they exist """
print("Unregistering callbacks")
if self._keyPressedCB:
self.view.removeEventCallbackPivy(coin.SoKeyboardEvent.getClassTypeId(), self._keyPressedCB)
self._keyPressedCB = None
if self._mousePressedCB:
self.view.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), self._mousePressedCB)
self._mousePressedCB = None
if self._mouseMovedCB:
self.view.removeEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(), self._mouseMovedCB)
self._mouseMovedCB = None
print("End unregistering callbacks")
# -------------------------------------------------------------------------
# SCENE EVENT HANDLERS
# -------------------------------------------------------------------------
def keyPressed(self, event_callback):
event = event_callback.getEvent()
print(event.getKey())
if event.getState() == event.UP:
if event.getKey() == 65307:
self.quit()
elif event.getKey() == 65293:
print("ENTER")
self.state += 1
if self.state == 2:
'''print("----------------------------------------------------------------")
print(" -- objects: ")
print(self.objects)
print(" -- distance:")
print(self.distance)
print("----------------------------------------------------------------")'''
self.calculateTrenches()
self.quit()
'''elif event.getKey() == ord("q"): # or event.getKey() == ord(65307):
if self.obj:
self.obj.ViewObject.Proxy.doubleClicked(self.obj.ViewObject)
else:
self.quit()
elif event.getKey() == ord("s"):
sel = FreeCADGui.Selection.getSelectionEx()
tup = None
if len(sel) == 1:
tup = (sel[0].Object, sel[0].SubElementNames)
for i in range(len(self.selected_objects)):
if isinstance(self.selected_objects[i], MarkerOnShape):
self.selected_objects[i].sublink = tup
# FreeCAD.Console.PrintMessage("Snapped to {}\n".format(str(self.selected_objects[i].sublink)))
self.selected_objects[i].drag_start()
self.selected_objects[i].drag((0, 0, 0.))
self.selected_objects[i].drag_release()
elif (event.getKey() == 65535) or (event.getKey() == 65288): # Suppr or Backspace
# FreeCAD.Console.PrintMessage("Some objects have been deleted\n")
pts = list()
for o in self.dynamic_objects:
if isinstance(o, MarkerOnShape):
pts.append(o)
self.points = pts
self.setupInteractionSeparator()'''
def mousePressed(self, event_callback):
""" Mouse button event handler, calls: startEditing, endEditing, addPoint, delPoint """
event = event_callback.getEvent()
pos = event.getPosition().getValue()
listObjects = FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo((int(pos[0]), int(pos[1])))
if event.getButton() == event.BUTTON1: # left click
if event.getState() == coin.SoMouseButtonEvent.DOWN:
if self.state == 0:
''' Select objects '''
obj = FreeCAD.ActiveDocument.getObject(listObjects[0]['Object'])
if obj in self.objects:
self.objects.remove(obj)
else:
self.objects.append(obj)
numobjs = len(self.objects)
if numobjs == 0:
self.tracker.finalize()
elif numobjs == 1:
self.tracker.updateFromPointlist([obj.Placement.Base for obj in self.objects])
self.tracker.on()
else:
self.tracker.updateFromPointlist([obj.Placement.Base for obj in self.objects])
elif self.state == 1:
''' Select distance and direction '''
self.direction = FreeCAD.Vector(listObjects[0]['x'], listObjects[0]['y'], listObjects[0]['z'])
#self.point = None
elif event.getState() == coin.SoMouseButtonEvent.UP:
if listObjects and self.point:
if self.state == 0:
FreeCADGui.Selection.clearSelection()
for obj in listObjects:
FreeCADGui.Selection.addSelection(obj)
"""if (event.getState() == coin.SoMouseButtonEvent.DOWN) and (
event.getButton() == event.BUTTON1): # left click
print("Mouse button down and mouse button 1")
if not event.wasAltDown():
if self.editing is None:
''' do something'''
else:
self.endEditing(self.obj, self.editing)
elif event.wasAltDown(): # left click with ctrl down
self.display_tracker_menu(event)
elif (event.getState() == coin.SoMouseButtonEvent.DOWN) and (
event.getButton() == event.BUTTON2): # right click
self.display_tracker_menu(event)"""
def mouseMoved(self, event_callback):
""" Execute as callback for mouse movement. Update tracker position and update preview ghost. """
if self.state == 1:
event = event_callback.getEvent()
pos = event.getPosition().getValue()
listObjects = FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo((int(pos[0]), int(pos[1])))
print(listObjects)
point = FreeCAD.Vector(listObjects[0]['x'], listObjects[0]['y'], listObjects[0]['z'])
pts = [obj.Placement.Base for obj in self.objects]
offset = point.sub(pts[0])
self.tracker.updateFromPointlist([point.add(offset) for point in pts])
'''listObjects = FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo((int(pos[0]), int(pos[1])))
if listObjects:
# {'x': 483239.09375, 'y': 783855.8125, 'z': 797695.0, 'Document': 'Salinas_II_GRG___v3',
# 'Object': 'Wire023', 'Component': 'Edge30'}]
for obj in listObjects:
print(listObjects)
if obj.Object == self.obj.Name:
print(listObjects)
'''
def calculateTrenches(self):
if len(self.objects)>1:
import Draft
pts = [obj.Placement.Base for obj in self.objects]
vec = self.direction.sub(pts[0])
pts1 = [point.add(vec) for point in pts]
for i in range(len(pts1) - 1):
makeTrench(Draft.makeLine(pts1[i], pts1[i + 1]))
return
pts = [obj.Placement.Base for obj in FreeCADGui.Selection.getSelection()]
from sklearn.cluster import OPTICS, cluster_optics_dbscan
import numpy as np
clust = OPTICS(min_samples = 5, xi=0.05, min_cluster_size=0.05)
X = np.array(pts)
# Run the fit
clust.fit(X)
labels_050 = cluster_optics_dbscan(
reachability=clust.reachability_,
core_distances=clust.core_distances_,
ordering=clust.ordering_,
eps=0.5,
)
labels_200 = cluster_optics_dbscan(
reachability=clust.reachability_,
core_distances=clust.core_distances_,
ordering=clust.ordering_,
eps=2,
)
space = np.arange(len(X))
reachability = clust.reachability_[clust.ordering_]
labels = clust.labels_[clust.ordering_]
print("\n")
print(" Space: ", space)
print(" Reachability", reachability)
print(" Labels", labels)
return
from scipy import stats
xx = list()
yy = list()
zz = list()
for point in pts:
xx.append(point.x)
yy.append(point.y)
zz.append(point.z)
slope, intercept, r, p, std_err = stats.linregress(xx, yy)
def myfunc(val):
return slope * val + intercept
newzz = list(map(myfunc, [xx[0], xx[-1]]))
points3D = list()
points3D.append(FreeCAD.Vector(xx[0], yy[0], newzz[0]))
points3D.append(FreeCAD.Vector(xx[-1], yy[-1], newzz[1]))
def quit(self):
print("Quit")
self.tracker.finalize()
self.unregister_editing_callbacks()