TclCommandPanelize.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. from ObjectCollection import *
  2. from copy import copy,deepcopy
  3. from tclCommands.TclCommand import TclCommand
  4. class TclCommandPanelize(TclCommand):
  5. """
  6. Tcl shell command to panelize 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','pan', 'panel']
  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, plot=False,
  106. autoselected=False)
  107. else:
  108. self.app.new_object("geometry", local_outname, initialize_local, plot=False, autoselected=False)
  109. currentx += lenghtx
  110. currenty += lenghty
  111. if isinstance(obj, FlatCAMExcellon):
  112. self.app.new_object("excellon", outname, initialize_excellon)
  113. else:
  114. self.app.new_object("geometry", outname, initialize_geometry)
  115. # deselect all to avoid delete selected object when run delete from shell
  116. self.app.collection.set_all_inactive()
  117. for delobj in objs:
  118. self.app.collection.set_active(delobj.options['name'])
  119. self.app.on_delete()
  120. else:
  121. return "ERROR: obj is None"
  122. return "Ok"