kopia lustrzana https://github.com/hdacosta400/intelligent-textiles
[V1] Custom routing for combination of wires
users now have the option to add "interpolation wires" when combining wire groujps, which creates custom routing wires. Logic needs to be refined a bit more to be more robust, also need to add line intersection/pitch detection to invalidate user inputs.main
rodzic
d9b2fb0c58
commit
ce3e56a5ee
Plik binarny nie jest wyświetlany.
|
@ -63,17 +63,19 @@ class CombineGridsWorker():
|
|||
'''
|
||||
Wires in the same grid are currently disjoint from each other
|
||||
Need to group them together so they get connected together
|
||||
|
||||
Need to fix this for when wire groups are angled (Same x/y won't apply)
|
||||
'''
|
||||
wire_groups = {}
|
||||
# if self.is_horizontal_connection: # wires will have same x
|
||||
for w in wires:
|
||||
points = [p for p in w.path.end_points]
|
||||
p = points[0]
|
||||
for w_points in wires:
|
||||
# points = [p for p in w.path.end_points]
|
||||
p = w_points[0]
|
||||
key = p.x if self.is_horizontal_connection else p.y
|
||||
if key not in wire_groups:
|
||||
wire_groups[key] = [points]
|
||||
wire_groups[key] = [w_points]
|
||||
else:
|
||||
wire_groups[key].append(points)
|
||||
wire_groups[key].append(w_points)
|
||||
for k in wire_groups:
|
||||
if self.is_horizontal_connection: # sort wires from top to bottom
|
||||
wire_groups[k] = sorted(wire_groups[k], key=lambda w:-w[0].y)
|
||||
|
@ -84,39 +86,147 @@ class CombineGridsWorker():
|
|||
return wire_groups
|
||||
|
||||
|
||||
def connect_wires(self, wire_groups_dict):
|
||||
def connect_wires(self, wire_groups_dict, interp_wires=None, interp_dict=None, interp_start_indices=None):
|
||||
start_points = sorted(list(wire_groups_dict.keys()))
|
||||
wire_groups = [wire_groups_dict[k] for k in start_points]
|
||||
wire_lens = [len(w) for w in wire_groups]
|
||||
wire_indices = [0 for _ in range(len(wire_groups))] # starting indices
|
||||
inkex.errormsg("interp start indices:{}".format(interp_start_indices))
|
||||
while wire_indices != wire_lens:
|
||||
joint_wire_points = []
|
||||
for i in range(len(wire_indices)):
|
||||
wire_idx = wire_indices[i]
|
||||
max_idx = wire_lens[i]
|
||||
if wire_idx != max_idx:
|
||||
joint_wire_points.extend(wire_groups[i][wire_idx])
|
||||
wire_indices[i] += 1
|
||||
interp_done = False # FIX THIS to better determine when to add interpolation wires!
|
||||
for wire_group_idx, curr_wire_idx in enumerate(wire_indices):
|
||||
max_idx = wire_lens[wire_group_idx]
|
||||
if curr_wire_idx != max_idx:
|
||||
current_wire = wire_groups[wire_group_idx][curr_wire_idx]
|
||||
joint_wire_points.extend([[p.x, p.y] for p in current_wire])
|
||||
wire_indices[wire_group_idx] += 1
|
||||
if interp_wires is not None and not interp_done: # add custom routes if inputted by user
|
||||
if curr_wire_idx == 0: joint_wire_points.extend([[p.x,p.y] for p in interp_wires[0]])
|
||||
elif curr_wire_idx == max_idx - 1: joint_wire_points.extend([[p.x,p.y] for p in interp_wires[1]])
|
||||
else:
|
||||
interp_points = self.add_interpolation_points(curr_wire_idx, interp_wires, interp_dict)
|
||||
joint_wire_points.extend(interp_points)
|
||||
interp_done = True
|
||||
|
||||
joint_wire_points = ['{},{}'.format(p.x,p.y) for p in joint_wire_points]
|
||||
joint_wire_points = ['{},{}'.format(p[0],p[1]) for p in joint_wire_points]
|
||||
self.create_path(joint_wire_points, is_horizontal=self.is_horizontal_connection)
|
||||
|
||||
def segment_line(self, line, num_points):
|
||||
'''
|
||||
Breaks line into num_points equal parts
|
||||
returns array of points
|
||||
|
||||
line: A shapely.LineString object (interpolation along line can be done manually but this is easier)
|
||||
'''
|
||||
points = []
|
||||
def parameterize_line(t):
|
||||
x_t = line[0][0] + (line[1][0] - line[0][0]) * t
|
||||
y_t = line[0][1] + (line[1][1] - line[0][1]) * t
|
||||
return x_t, y_t
|
||||
|
||||
segment_length = 1 / (num_points + 1)
|
||||
for i in range(1 ,num_points+2): # adjust from 0 to n+1 bc we cant put in 0 to the parameterized line equation
|
||||
x, y = parameterize_line(i * segment_length)
|
||||
points.append([x,y])
|
||||
inkex.errormsg("what are points:{},{}".format(points, len(points)))
|
||||
return points
|
||||
|
||||
def generate_interpolation_points(self, interpolation_wires, num_wires):
|
||||
interp_dict = {}
|
||||
for i in range(len(interpolation_wires) - 1):
|
||||
# exclude parts of interp wire that connect to sensor wire
|
||||
wire1 = interpolation_wires[i]
|
||||
wire2 = interpolation_wires[i+1]
|
||||
for j in range(1, len(wire1) - 1):
|
||||
x1, y1 = wire1[j].x, wire1[j].y
|
||||
x2, y2 = wire2[j].x, wire2[j].y
|
||||
line = [[x1, y1], [x2, y2]]
|
||||
interp_dict[(x1, y1, x2, y2)] = [[x1, y1]]
|
||||
# FOR NOW, assume interp wires are placed @ top and bottommost wire
|
||||
# need to account for these points already placed by subtracting 2
|
||||
# in future, user may only want custom wiring for SOME wires and default for others
|
||||
# in this case, need to add additional detection mechanisms to see where they are
|
||||
interp_points = self.segment_line(line, num_wires - 2)
|
||||
interp_dict[(x1, y1, x2, y2)].extend(interp_points)
|
||||
points = ['{},{}'.format(p[0],p[1]) for p in line]
|
||||
# self.create_path(points, False)
|
||||
return interp_dict
|
||||
|
||||
def calculate_interp_wire_group(self, wire_groups_dict, interpolation_wires):
|
||||
start_points = sorted(list(wire_groups_dict.keys()))
|
||||
interp_start_indices = []
|
||||
for sp in start_points:
|
||||
for wire_idx, wire in enumerate(wire_groups_dict[sp]):
|
||||
# assumption that interpolation wire starts at END of a wire
|
||||
for w in interpolation_wires:
|
||||
if wire[-1].x == w[0][0] and wire[-1].y == w[0][1]:
|
||||
interp_start_indices.append((sp,wire_idx))
|
||||
|
||||
return interp_start_indices
|
||||
|
||||
def connect_custom_wires(self, wire_groups_dict, interpolation_wires):
|
||||
# how many wires are grouped together???
|
||||
num_wires = len(wire_groups_dict[list(wire_groups_dict.keys())[0]])
|
||||
interp_dict = self.generate_interpolation_points(interpolation_wires, num_wires)
|
||||
|
||||
# determine the wiregroups where the interpolation wires start
|
||||
interp_start_indices = self.calculate_interp_wire_group(wire_groups_dict, interpolation_wires)
|
||||
self.connect_wires(wire_groups_dict, interpolation_wires, interp_dict, interp_start_indices)
|
||||
|
||||
|
||||
def add_interpolation_points(self, wire_idx, interpolation_wires, interpolation_dict):
|
||||
'''
|
||||
Generates list of interpolation points to add to current wire
|
||||
FOR NOW ASSUMING TWO INTERPOLATION WIRES
|
||||
'''
|
||||
wire1, wire2 = interpolation_wires
|
||||
intermediate_points = []
|
||||
for i in range(1, len(wire1) - 1):
|
||||
x1, y1 = wire1[i].x, wire1[i].y
|
||||
xn, yn = wire2[i].x , wire2[i].y
|
||||
interpolation_points = interpolation_dict[(x1,y1,xn,yn)]
|
||||
intermediate_points.append(interpolation_points[wire_idx])
|
||||
return intermediate_points
|
||||
|
||||
|
||||
|
||||
def run(self):
|
||||
|
||||
connector_pins = []
|
||||
wires = []
|
||||
interpolation_wires = [] # for custom combination routing
|
||||
for elem in self.svg.get_selected():
|
||||
if type(elem) == PathElement: #connector
|
||||
points = [p for p in elem.path.end_points]
|
||||
if len(points) == 4:
|
||||
connector_bbox = elem.bounding_box()
|
||||
connector_pins.append(elem)
|
||||
# if len(points) == 4: # figure out differnt condition for this
|
||||
# connector_bbox = elem.bounding_box()
|
||||
# connector_pins.append(elem)
|
||||
if len(points) > 2:
|
||||
interpolation_wires.append(points)
|
||||
else:
|
||||
wires.append(elem)
|
||||
wires.append(points)
|
||||
|
||||
|
||||
wire_groups = self.group_wires(wires)
|
||||
self.connect_wires(wire_groups)
|
||||
if len(interpolation_wires) == 0:
|
||||
self.connect_wires(wire_groups)
|
||||
else: #custom connection
|
||||
if len(interpolation_wires) > 2: # may not need to be the case in the future
|
||||
inkex.errormsg("only create two custom routes for interpolation")
|
||||
return
|
||||
else:
|
||||
# check lens of interpolation wires to make sure they are the same
|
||||
len_wire = len(interpolation_wires[0])
|
||||
same_length = all([len(w) == len_wire for w in interpolation_wires])
|
||||
if not same_length:
|
||||
inkex.errormsg("interpolation wires have the same number of points")
|
||||
return
|
||||
if self.is_horizontal_connection:
|
||||
interpolation_wires = sorted(interpolation_wires, key=lambda w:-w[0].y)
|
||||
else:
|
||||
interpolation_wires = sorted(interpolation_wires, key=lambda w:w[0].x)
|
||||
self.connect_custom_wires(wire_groups, interpolation_wires)
|
||||
|
||||
# remove old wires
|
||||
for elem in self.svg.get_selected(): elem.getparent().remove(elem)
|
||||
|
@ -129,13 +239,11 @@ class CombineGridsWorker():
|
|||
|
||||
color = "red" if is_horizontal else "blue"
|
||||
path_str = ' '.join(points)
|
||||
inkex.errormsg("points:{}".format(path_str))
|
||||
path = inkex.Polyline(attrib={
|
||||
'id': "wire_segment",
|
||||
'points': path_str,
|
||||
})
|
||||
|
||||
inkex.errormsg("input points:{}".format(points))
|
||||
line_attribs = {
|
||||
'style' : "stroke: %s; stroke-width: 0.4; fill: none; stroke-dasharray:0.4,0.4" % color,
|
||||
'd': str(path.get_path())
|
||||
|
|
Ładowanie…
Reference in New Issue