2021-11-17 23:11:03 +00:00
|
|
|
from .base import InkstitchExtension
|
|
|
|
import sys
|
|
|
|
from base64 import b64decode
|
|
|
|
from argparse import ArgumentParser, REMAINDER
|
|
|
|
|
|
|
|
import appdirs
|
|
|
|
import inkex
|
2021-11-18 01:48:48 +00:00
|
|
|
from inkex import Line, Rectangle, Path, Polyline, PathElement
|
2021-11-17 23:11:03 +00:00
|
|
|
import wx
|
|
|
|
import wx.adv
|
|
|
|
from lxml import etree
|
|
|
|
|
2021-11-18 01:48:48 +00:00
|
|
|
from .create_grid import BoundingBoxMetadata
|
2021-11-17 23:11:03 +00:00
|
|
|
|
2021-11-18 01:48:48 +00:00
|
|
|
class CombineGridsFrame(wx.Frame):
|
|
|
|
DEFAULT_FONT = "small_font"
|
|
|
|
def __init__(self, shape1, shape2, svg, *args, **kwargs):
|
|
|
|
if sys.platform.startswith('win32'):
|
|
|
|
import locale
|
|
|
|
locale.setlocale(locale.LC_ALL, "C")
|
|
|
|
lc = wx.Locale()
|
|
|
|
lc.Init(wx.LANGUAGE_DEFAULT)
|
|
|
|
pass
|
2021-11-17 23:11:03 +00:00
|
|
|
|
2021-12-02 22:20:40 +00:00
|
|
|
class Connector():
|
|
|
|
'''
|
|
|
|
Object to represent connector of wires
|
|
|
|
'''
|
|
|
|
def __init__(self, connector_points, bbox):
|
|
|
|
self.connector_points = connector_points # all coords where wires need to route to
|
|
|
|
self.open_wire_idx = 0 # idx of next available wire
|
|
|
|
self.bbox = bbox
|
|
|
|
inkex.errormsg("num connectors:{}".format(len(self.connector_points)))
|
|
|
|
def has_available_wires(self):
|
|
|
|
return self.open_wire_idx <= len(self.connector_points) - 4 # every connector is 4 points
|
|
|
|
def connect_wire(self):
|
|
|
|
if self.has_available_wires():
|
|
|
|
points = self.connector_points[self.open_wire_idx:self.open_wire_idx + 4]
|
|
|
|
self.open_wire_idx += 2
|
|
|
|
return points
|
|
|
|
else:
|
|
|
|
inkex.errormsg("connector has no more open connections. Decrease the number of wires!")
|
|
|
|
return None
|
|
|
|
|
2021-11-17 23:11:03 +00:00
|
|
|
class CombineGrids(InkstitchExtension):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.cancelled = False
|
|
|
|
InkstitchExtension.__init__(self, *args, **kwargs)
|
2021-11-18 01:48:48 +00:00
|
|
|
self.arg_parser.add_argument("--alignment")
|
|
|
|
args, _ = self.arg_parser.parse_known_args()
|
2021-12-02 22:20:40 +00:00
|
|
|
self.is_horizontal_connection = True if args.alignment == "1" else False
|
|
|
|
inkex.errormsg(self.is_horizontal_connection)
|
2021-11-18 01:48:48 +00:00
|
|
|
self.wires = []
|
2021-12-02 22:20:40 +00:00
|
|
|
self.connector = None
|
2021-11-17 23:11:03 +00:00
|
|
|
def cancel(self):
|
|
|
|
self.cancelled = True
|
2021-12-02 22:20:40 +00:00
|
|
|
|
|
|
|
def get_points(self, line):
|
|
|
|
# return [p for p in line.path.end_points]
|
|
|
|
return line.points
|
|
|
|
|
|
|
|
def check_horizontal_wire_directions(self, num_left_wires, num_right_wires):
|
|
|
|
'''
|
|
|
|
Checks that the wires can be connected in such a way that union
|
|
|
|
goes in the SAME direction (so that they can be hooked up to connectors later)
|
|
|
|
'''
|
|
|
|
if num_left_wires < num_right_wires and num_left_wires % 2 == 0:
|
|
|
|
return False
|
|
|
|
if num_right_wires < num_left_wires and num_right_wires % 2 == 1:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2021-11-18 01:48:48 +00:00
|
|
|
def connect_horizontally(self):
|
2021-12-02 22:20:40 +00:00
|
|
|
rect1,rect2 = self.wires[0].bbox, self.wires[1].bbox
|
|
|
|
left_wire = None
|
|
|
|
right_wire = None
|
2021-11-18 01:48:48 +00:00
|
|
|
if rect1.left < rect2.left:
|
2021-12-03 15:21:21 +00:00
|
|
|
left_wire, right_wire = self.wires
|
2021-11-18 01:48:48 +00:00
|
|
|
else:
|
2021-12-03 15:21:21 +00:00
|
|
|
right_wire, left_wire = self.wires
|
|
|
|
|
2021-12-02 22:20:40 +00:00
|
|
|
self.union_wires(left_wire, right_wire, True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def union_wires(self, min_wire, max_wire, is_horizontal):
|
|
|
|
min_wire_points = self.get_points(min_wire)
|
|
|
|
max_wire_points = self.get_points(max_wire)
|
|
|
|
|
|
|
|
min_multiplier = min_wire.get_num_wire_joins(is_horizontal)
|
|
|
|
max_multiplier = max_wire.get_num_wire_joins(is_horizontal)
|
|
|
|
|
|
|
|
inkex.errormsg("mult:{}, {}".format(min_multiplier, max_multiplier))
|
|
|
|
|
|
|
|
min_wire_idx = 2 * min_multiplier
|
|
|
|
max_wire_idx = 0
|
|
|
|
min_points = ['{},{}'.format(p.x,p.y) for p in min_wire_points[0: min_wire_idx]]
|
|
|
|
union_wire_points = []
|
|
|
|
union_wire_points.extend(min_points)
|
|
|
|
|
|
|
|
while min_wire_idx != len(min_wire_points): # leave hanging wire
|
|
|
|
# 4 points on max wire constitutes a wrap around from one wire path to the next
|
|
|
|
# this will not always be true as one may need to connect multiple shapes together in sets of two
|
|
|
|
max_wire_splice_length = min(4 * max_multiplier, len(max_wire_points) - max_wire_idx)
|
|
|
|
inkex.errormsg("max wire idx:{}".format(max_wire_idx))
|
|
|
|
max_points = ['{},{}'.format(p.x,p.y) for p in max_wire_points[max_wire_idx: max_wire_idx + max_wire_splice_length]]
|
|
|
|
union_wire_points.extend(max_points)
|
|
|
|
max_wire_idx += max_wire_splice_length
|
|
|
|
inkex.errormsg("max wire idx:{}".format(max_wire_idx))
|
|
|
|
|
|
|
|
inkex.errormsg("min wire idx:{}".format(min_wire_idx))
|
|
|
|
min_wire_splice_length = min(4 * min_multiplier, len(min_wire_points) - min_wire_idx)
|
|
|
|
min_points = ['{},{}'.format(p.x,p.y) for p in min_wire_points[min_wire_idx: min_wire_idx + min_wire_splice_length]]
|
|
|
|
union_wire_points.extend(min_points)
|
|
|
|
min_wire_idx += min_wire_splice_length
|
|
|
|
inkex.errormsg("min wire idx:{}".format(min_wire_idx))
|
|
|
|
|
|
|
|
max_points = ['{},{}'.format(p.x,p.y) for p in max_wire_points[max_wire_idx: len(max_wire_points)]]
|
2021-12-03 15:21:21 +00:00
|
|
|
inkex.errormsg("idx of right wire: {}:{}".format(max_wire_idx,len(max_wire_points)))
|
2021-12-02 22:20:40 +00:00
|
|
|
union_wire_points.extend(max_points)
|
|
|
|
# done unionizing the wires
|
2021-12-03 15:21:21 +00:00
|
|
|
# remove old wires (.wire is used to access the actual svg element within the object)
|
2021-12-02 22:20:40 +00:00
|
|
|
min_wire.wire.getparent().remove(min_wire.wire)
|
|
|
|
max_wire.wire.getparent().remove(max_wire.wire)
|
|
|
|
|
|
|
|
# add new combined one
|
|
|
|
inkex.errormsg(union_wire_points)
|
|
|
|
self.create_path(union_wire_points, is_horizontal)
|
|
|
|
|
|
|
|
def create_path(self, points, is_horizontal):
|
|
|
|
'''
|
|
|
|
Creates a wire segment path given all of the points sequentially
|
|
|
|
'''
|
|
|
|
color = "red" if is_horizontal else "blue"
|
|
|
|
path_str = ' '.join(points)
|
|
|
|
path = inkex.Polyline(attrib={
|
|
|
|
'id': "wire_segment",
|
|
|
|
'style': "stroke: %s; stroke-width: 0.4; fill: none; stroke-dasharray:0.4,0.4" % color,
|
|
|
|
'points': path_str,
|
|
|
|
})
|
|
|
|
self.svg.get_current_layer().append(path)
|
|
|
|
|
2021-11-17 23:11:03 +00:00
|
|
|
def effect(self):
|
2021-12-02 22:20:40 +00:00
|
|
|
connector_points = []
|
|
|
|
connector_bbox = None
|
2021-11-18 01:48:48 +00:00
|
|
|
for elem in self.svg.get_selected():
|
|
|
|
# inkex.errormsg("things selected:{}".format(len(self.svg.get_selected())))
|
|
|
|
inkex.errormsg("type of elem:{}".format(type(elem)))
|
|
|
|
# have to separate shapes and wires here!
|
|
|
|
if type(elem) == Polyline:
|
2021-12-02 22:20:40 +00:00
|
|
|
# self.wires.append(elem)
|
|
|
|
# self.wire_rectangles.append(elem.bounding_box())
|
|
|
|
|
|
|
|
#V2
|
|
|
|
wire = Wire(elem)
|
|
|
|
self.wires.append(wire)
|
|
|
|
|
|
|
|
# elif type(elem) == PathElement: #connector
|
|
|
|
# self.wire_rectangles.append(elem.bounding_box())
|
|
|
|
# connector_bbox = elem.bbox()
|
|
|
|
# points = self.get_points(elem)
|
|
|
|
# for p in points:
|
|
|
|
# connector_points.append(p)
|
|
|
|
|
|
|
|
self.connector = Connector(connector_points, connector_bbox)
|
|
|
|
|
2021-11-18 01:48:48 +00:00
|
|
|
if len(self.wires) != 2:
|
2021-12-02 22:20:40 +00:00
|
|
|
inkex.errormsg(len(self.wires))
|
2021-11-18 01:48:48 +00:00
|
|
|
inkex.errormsg("Please select only two wires to combine!")
|
|
|
|
return
|
|
|
|
if self.is_horizontal_connection:
|
2021-12-02 22:20:40 +00:00
|
|
|
self.connect_horizontally()
|
2021-12-03 15:21:21 +00:00
|
|
|
|
2021-12-02 22:20:40 +00:00
|
|
|
class Wire:
|
2021-12-03 15:21:21 +00:00
|
|
|
#TODO: move this into a util class
|
2021-12-02 22:20:40 +00:00
|
|
|
def __init__(self, wire):
|
|
|
|
self.wire = wire
|
|
|
|
self.points = [p for p in self.wire.path.end_points]
|
|
|
|
self.bbox = self.wire.bounding_box()
|
2021-12-03 15:21:21 +00:00
|
|
|
|
2021-12-02 22:20:40 +00:00
|
|
|
def get_num_wire_joins(self, is_horizontal):
|
|
|
|
'''
|
|
|
|
Determines how many wires were horizontally joined together to create the current wire object
|
2021-11-18 01:48:48 +00:00
|
|
|
|
2021-12-02 22:20:40 +00:00
|
|
|
The default is 1
|
|
|
|
'''
|
|
|
|
point_counter = 1
|
|
|
|
for i in range(len(self.points) - 1):
|
|
|
|
p1 = self.points[i]
|
|
|
|
p2 = self.points[i+1]
|
|
|
|
inkex.errormsg("points:{},{}".format(p1,p2))
|
|
|
|
if (is_horizontal and p1.x == p2.x) or (not is_horizontal and p1.y == p2.y):
|
|
|
|
inkex.errormsg("coming in here")
|
|
|
|
return point_counter // 2
|
|
|
|
else:
|
|
|
|
inkex.errormsg("adding 1!")
|
|
|
|
point_counter += 1
|
|
|
|
# should never get here?
|
|
|
|
return None
|
2021-12-03 15:21:21 +00:00
|
|
|
'''
|
|
|
|
Determine how many points of connection a wire has on each side (left right for horizontal case / top bottom for vertical case)
|
|
|
|
'''
|
|
|
|
def get_num_left_endpoints(self):
|
|
|
|
left_side = self.bbox.left
|
|
|
|
return sum([1 for p in self.points if p.x == left_side])
|
|
|
|
|
|
|
|
def get_num_right_endpoints(self):
|
|
|
|
right_side = self.bbox.right
|
|
|
|
return sum([1 for p in self.points if p.x == right_side])
|
2021-11-17 23:11:03 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
inkex.errormsg(sys.argv[1:])
|
|
|
|
parser = ArgumentParser()
|
|
|
|
parser.add_argument("--horizontal_wires")
|
|
|
|
parser.add_argument("--vertical_wires")
|
|
|
|
parser.add_argument('args', nargs=REMAINDER)
|
|
|
|
args, _ = parser.parse_known_args()
|
|
|
|
inkex.errormsg("args:{}".format(args))
|
2021-12-02 22:20:40 +00:00
|
|
|
CombineGrids().run()
|