TclCommandPanelize.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. from ObjectCollection import *
  2. from copy import copy,deepcopy
  3. import TclCommand
  4. class TclCommandPanelize(TclCommand.TclCommand):
  5. """
  6. Tcl shell command to pannelize an object.
  7. example:
  8. """
  9. # List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
  10. aliases = ['panelize']
  11. # Dictionary of types from Tcl command, needs to be ordered
  12. arg_names = collections.OrderedDict([
  13. ('name', str),
  14. ])
  15. # Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
  16. option_types = collections.OrderedDict([
  17. ('rows', int),
  18. ('columns', int),
  19. ('spacing_columns', float),
  20. ('spacing_rows', float),
  21. ('box', str),
  22. ('outname', str)
  23. ])
  24. # array of mandatory options for current Tcl command: required = {'name','outname'}
  25. required = ['name', 'rows', 'columns']
  26. # structured help for current command, args needs to be ordered
  27. help = {
  28. 'main': 'Rectangular panelizing.',
  29. 'args': collections.OrderedDict([
  30. ('name', 'Name of the object to panelize.'),
  31. ('box', 'Name of object which acts as box (cutout for example.)'
  32. 'for cutout boundary. Object from name is used if not specified.'),
  33. ('spacing_columns', 'Spacing between columns.'),
  34. ('spacing_rows', 'Spacing between rows.'),
  35. ('columns', 'Number of columns.'),
  36. ('rows', 'Number of rows;'),
  37. ('outname', 'Name of the new geometry object.')
  38. ]),
  39. 'examples': []
  40. }
  41. def execute(self, args, unnamed_args):
  42. """
  43. :param args:
  44. :param unnamed_args:
  45. :return:
  46. """
  47. name = args['name']
  48. # Get source object.
  49. try:
  50. obj = self.app.collection.get_by_name(str(name))
  51. except:
  52. return "Could not retrieve object: %s" % name
  53. if obj is None:
  54. return "Object not found: %s" % name
  55. if 'box' in args:
  56. boxname = args['box']
  57. try:
  58. box = self.app.collection.get_by_name(boxname)
  59. except:
  60. return "Could not retrieve object: %s" % name
  61. else:
  62. box = obj
  63. if 'columns' not in args or 'rows' not in args:
  64. return "ERROR: Specify -columns and -rows"
  65. if 'outname' in args:
  66. outname = args['outname']
  67. else:
  68. outname = name + '_panelized'
  69. if 'spacing_columns' in args:
  70. spacing_columns = args['spacing_columns']
  71. else:
  72. spacing_columns = 5
  73. if 'spacing_rows' in args:
  74. spacing_rows = args['spacing_rows']
  75. else:
  76. spacing_rows = 5
  77. xmin, ymin, xmax, ymax = box.bounds()
  78. lenghtx = xmax - xmin + spacing_columns
  79. lenghty = ymax - ymin + spacing_rows
  80. currenty = 0
  81. def initialize_local(obj_init, app):
  82. obj_init.solid_geometry = obj.solid_geometry
  83. obj_init.offset([float(currentx), float(currenty)]),
  84. objs.append(obj_init)
  85. def initialize_local_excellon(obj_init, app):
  86. obj_init.tools = obj.tools
  87. # drills are offset, so they need to be deep copied
  88. obj_init.drills = deepcopy(obj.drills)
  89. obj_init.offset([float(currentx), float(currenty)])
  90. obj_init.create_geometry()
  91. objs.append(obj_init)
  92. def initialize_geometry(obj_init, app):
  93. FlatCAMGeometry.merge(objs, obj_init)
  94. def initialize_excellon(obj_init, app):
  95. # merge expects tools to exist in the target object
  96. obj_init.tools = obj.tools.copy()
  97. FlatCAMExcellon.merge(objs, obj_init)
  98. objs = []
  99. if obj is not None:
  100. for row in range(args['rows']):
  101. currentx = 0
  102. for col in range(args['columns']):
  103. local_outname = outname + ".tmp." + str(col) + "." + str(row)
  104. if isinstance(obj, FlatCAMExcellon):
  105. self.app.new_object("excellon", local_outname, initialize_local_excellon)
  106. else:
  107. self.app.new_object("geometry", local_outname, initialize_local)
  108. currentx += lenghtx
  109. currenty += lenghty
  110. if isinstance(obj, FlatCAMExcellon):
  111. self.app.new_object("excellon", outname, initialize_excellon)
  112. else:
  113. self.app.new_object("geometry", outname, initialize_geometry)
  114. # deselect all to avoid delete selected object when run delete from shell
  115. self.app.collection.set_all_inactive()
  116. for delobj in objs:
  117. self.app.collection.set_active(delobj.options['name'])
  118. self.app.on_delete()
  119. else:
  120. return "ERROR: obj is None"
  121. return "Ok"