diff --git a/FlatCAMApp.py b/FlatCAMApp.py index fd112f8c..b4266be3 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -4936,6 +4936,14 @@ class App(QtCore.QObject): # Clear pool self.clear_pool() + #delete shapes left drawn from mark shape_collections, if any + for obj in self.collection.get_list(): + try: + obj.mark_shapes.enabled = False + obj.mark_shapes.clear(update=True) + except: + pass + # tcl needs to be reinitialized, otherwise old shell variables etc remains self.init_tcl() diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 9935cb73..fc181eaf 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -70,6 +70,8 @@ class FlatCAMObj(QtCore.QObject): # self.shapes = ShapeCollection(parent=self.app.plotcanvas.vispy_canvas.view.scene) self.shapes = self.app.plotcanvas.new_shape_group() + self.mark_shapes = self.app.plotcanvas.new_shape_collection(layers=2) + self.item = None # Link with project view item self.muted_ui = False @@ -311,6 +313,13 @@ class FlatCAMObj(QtCore.QObject): key = self.shapes.add(tolerance=self.drawing_tolerance, **kwargs) return key + def add_mark_shape(self, **kwargs): + if self.deleted: + raise ObjectDeleted() + else: + key = self.mark_shapes.add(tolerance=self.drawing_tolerance, **kwargs) + return key + @property def visible(self): return self.shapes.visible @@ -570,17 +579,17 @@ class FlatCAMGerber(FlatCAMObj, Gerber): ap_size_item = QtWidgets.QTableWidgetItem('') ap_size_item.setFlags(QtCore.Qt.ItemIsEnabled) - plot_item = FCCheckBox() - plot_item.setLayoutDirection(QtCore.Qt.RightToLeft) - if self.ui.plot_cb.isChecked(): - plot_item.setChecked(True) + mark_item = FCCheckBox() + mark_item.setLayoutDirection(QtCore.Qt.RightToLeft) + # if self.ui.aperture_table_visibility_cb.isChecked(): + # mark_item.setChecked(True) self.ui.apertures_table.setItem(self.apertures_row, 1, ap_code_item) # Aperture Code self.ui.apertures_table.setItem(self.apertures_row, 2, ap_type_item) # Aperture Type self.ui.apertures_table.setItem(self.apertures_row, 3, ap_size_item) # Aperture Dimensions self.ui.apertures_table.setItem(self.apertures_row, 4, ap_dim_item) # Aperture Dimensions - self.ui.apertures_table.setCellWidget(self.apertures_row, 5, plot_item) + self.ui.apertures_table.setCellWidget(self.apertures_row, 5, mark_item) self.apertures_row += 1 @@ -596,14 +605,14 @@ class FlatCAMGerber(FlatCAMObj, Gerber): ap_type_item = QtWidgets.QTableWidgetItem('AM') ap_type_item.setFlags(QtCore.Qt.ItemIsEnabled) - plot_item = FCCheckBox() - plot_item.setLayoutDirection(QtCore.Qt.RightToLeft) - if self.ui.plot_cb.isChecked(): - plot_item.setChecked(True) + mark_item = FCCheckBox() + mark_item.setLayoutDirection(QtCore.Qt.RightToLeft) + # if self.ui.aperture_table_visibility_cb.isChecked(): + # mark_item.setChecked(True) self.ui.apertures_table.setItem(self.apertures_row, 1, ap_code_item) # Aperture Code self.ui.apertures_table.setItem(self.apertures_row, 2, ap_type_item) # Aperture Type - self.ui.apertures_table.setCellWidget(self.apertures_row, 5, plot_item) + self.ui.apertures_table.setCellWidget(self.apertures_row, 5, mark_item) self.apertures_row += 1 @@ -634,7 +643,40 @@ class FlatCAMGerber(FlatCAMObj, Gerber): self.ui.apertures_table.setSortingEnabled(False) self.ui.apertures_table.setMinimumHeight(self.ui.apertures_table.getHeight()) - # self.ui_connect() + self.ui_connect() + + def ui_connect(self): + for row in range(self.ui.apertures_table.rowCount()): + self.ui.apertures_table.cellWidget(row, 5).clicked.connect(self.on_mark_cb_click_table) + + def ui_disconnect(self): + for row in range(self.ui.apertures_table.rowCount()): + try: + self.ui.apertures_table.cellWidget(row, 5).clicked.disconnect() + except: + pass + + def on_mark_cb_click_table(self): + self.ui_disconnect() + cw = self.sender() + cw_index = self.ui.apertures_table.indexAt(cw.pos()) + cw_row = cw_index.row() + check_row = 0 + + self.mark_shapes.clear(update=True) + for aperture in self.apertures: + # find the apertures_table row associated with the aperture + for row in range(self.ui.apertures_table.rowCount()): + if int(self.ui.apertures_table.item(row, 1).text()) == int(aperture): + check_row = row + break + + if self.ui.apertures_table.cellWidget(check_row, 5).isChecked(): + self.plot_apertures(color = '#2d4606bf', marked_aperture=aperture, visible=True) + + self.mark_shapes.redraw() + + self.ui_connect() def on_generatenoncopper_button_click(self, *args): self.app.report_usage("gerber_on_generatenoncopper_button") @@ -895,6 +937,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber): if self.muted_ui: return self.read_form_item('plot') + self.plot() def on_solid_cb_click(self, *args): if self.muted_ui: @@ -916,8 +959,19 @@ class FlatCAMGerber(FlatCAMObj, Gerber): def on_aperture_table_visibility_change(self): if self.ui.aperture_table_visibility_cb.isChecked(): self.ui.apertures_table.setVisible(True) + self.ui.scale_aperture_label.setVisible(True) + self.ui.scale_aperture_entry.setVisible(True) + self.ui.scale_aperture_button.setVisible(True) else: self.ui.apertures_table.setVisible(False) + self.ui.scale_aperture_label.setVisible(False) + self.ui.scale_aperture_entry.setVisible(False) + self.ui.scale_aperture_button.setVisible(False) + + # on hide disable all mark plots + for row in range(self.ui.apertures_table.rowCount()): + self.ui.apertures_table.cellWidget(row, 5).set_value(False) + self.mark_shapes.clear(update=True) def convert_units(self, units): """ @@ -1005,70 +1059,60 @@ class FlatCAMGerber(FlatCAMObj, Gerber): self.shapes.clear(update=True) # experimental plot() when the solid_geometry is stored in the self.apertures - # def plot_apertures(self, **kwargs): - # """ - # - # :param kwargs: color and face_color - # :return: - # """ - # - # FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + " --> FlatCAMGerber.plot()") - # - # # Does all the required setup and returns False - # # if the 'ptint' option is set to False. - # if not FlatCAMObj.plot(self): - # return - # - # if 'color' in kwargs: - # color = kwargs['color'] - # else: - # color = self.app.defaults['global_plot_line'] - # if 'face_color' in kwargs: - # face_color = kwargs['face_color'] - # else: - # face_color = self.app.defaults['global_plot_fill'] - # - # geometry = {} - # for ap in self.apertures: - # geometry[ap] = self.apertures[ap]['solid_geometry'] - # try: - # _ = iter(geometry[ap]) - # except TypeError: - # geometry[ap] = [geometry[ap]] - # - # def random_color(): - # color = np.random.rand(4) - # color[3] = 1 - # return color - # - # try: - # if self.options["solid"]: - # for geo in geometry: - # for g in geometry[geo]: - # if type(g) == Polygon or type(g) == LineString: - # self.add_shape(shape=g, color=color, - # face_color=random_color() if self.options['multicolored'] - # else face_color, visible=self.options['plot']) - # else: - # for el in g: - # self.add_shape(shape=el, color=color, - # face_color=random_color() if self.options['multicolored'] - # else face_color, visible=self.options['plot']) - # else: - # for geo in geometry: - # for g in geometry[geo]: - # if type(g) == Polygon or type(g) == LineString: - # self.add_shape(shape=g, - # color=random_color() if self.options['multicolored'] else 'black', - # visible=self.options['plot']) - # else: - # for el in g: - # self.add_shape(shape=el, - # color=random_color() if self.options['multicolored'] else 'black', - # visible=self.options['plot']) - # self.shapes.redraw() - # except (ObjectDeleted, AttributeError): - # self.shapes.clear(update=True) + def plot_apertures(self, **kwargs): + """ + + :param kwargs: color and face_color + :return: + """ + + FlatCAMApp.App.log.debug(str(inspect.stack()[1][3]) + " --> FlatCAMGerber.plot_apertures()") + + # Does all the required setup and returns False + # if the 'ptint' option is set to False. + if not FlatCAMObj.plot(self): + return + + # for marking apertures, line color and fill color are the same + if 'color' in kwargs: + color = kwargs['color'] + else: + color = self.app.defaults['global_plot_fill'] + + if 'marked_aperture' not in kwargs: + return + else: + aperture_to_plot_mark = kwargs['marked_aperture'] + if aperture_to_plot_mark is None: + return + + if 'visible' not in kwargs: + visibility = True + else: + visibility = kwargs['visible'] + + geometry = {} + for ap in self.apertures: + geometry[int(ap)] = self.apertures[ap]['solid_geometry'] + try: + _ = iter(geometry[int(ap)]) + except TypeError: + geometry[int(ap)] = [geometry[int(ap)]] + + try: + if aperture_to_plot_mark in self.apertures: + for geo in geometry[int(aperture_to_plot_mark)]: + if type(geo) == Polygon or type(geo) == LineString: + self.add_mark_shape(shape=geo, color=color, + face_color=color, visible=visibility) + else: + for el in geo: + self.add_mark_shape(shape=el, color=color, + face_color=color, visible=visibility) + + self.mark_shapes.redraw() + except (ObjectDeleted, AttributeError): + self.mark_shapes.clear(update=True) def serialize(self): return { @@ -4383,6 +4427,7 @@ class FlatCAMGeometry(FlatCAMObj, Geometry): self.tools[tool]['solid_geometry'] = scale_recursion(self.tools[tool]['solid_geometry']) else: self.solid_geometry=scale_recursion(self.solid_geometry) + self.app.inform.emit("[success]Geometry Scale done.") def offset(self, vect): diff --git a/ObjectUI.py b/ObjectUI.py index f8d38493..760b0551 100644 --- a/ObjectUI.py +++ b/ObjectUI.py @@ -127,6 +127,8 @@ class GerberObjectUI(ObjectUI): self.custom_box.addLayout(grid0) self.plot_options_label = QtWidgets.QLabel("Plot Options:") + self.plot_options_label.setFixedWidth(90) + grid0.addWidget(self.plot_options_label, 0, 0) # Solid CB @@ -158,10 +160,12 @@ class GerberObjectUI(ObjectUI): self.custom_box.addLayout(hlay_plot) #### Gerber Apertures #### - self.apertures_table_label = QtWidgets.QLabel('Apertures Table') + self.apertures_table_label = QtWidgets.QLabel('Apertures') self.apertures_table_label.setToolTip( - "Apertures in this Gerber object." + "Apertures Table containining this Gerber object apertures." ) + self.apertures_table_label.setFixedWidth(90) + hlay_plot.addWidget(self.apertures_table_label) # Aperture Table Visibility CB @@ -181,7 +185,7 @@ class GerberObjectUI(ObjectUI): self.custom_box.addWidget(self.apertures_table) self.apertures_table.setColumnCount(6) - self.apertures_table.setHorizontalHeaderLabels(['#', 'Code', 'Type', 'Size', 'Dim', 'P']) + self.apertures_table.setHorizontalHeaderLabels(['#', 'Code', 'Type', 'Size', 'Dim', 'M']) self.apertures_table.setSortingEnabled(False) self.apertures_table.horizontalHeaderItem(0).setToolTip( @@ -197,16 +201,40 @@ class GerberObjectUI(ObjectUI): " - (width, height) for R, O type.\n" " - (dia, nVertices) for P type") self.apertures_table.horizontalHeaderItem(5).setToolTip( - "Toggle display of the aperture instances.") + "Mark the aperture instances on canvas.") + # self.apertures_table.setColumnHidden(5, True) + + #### Aperture Scale #### + self.scale_aperture_grid = QtWidgets.QGridLayout() + self.custom_box.addLayout(self.scale_aperture_grid) + + # Factor + self.scale_aperture_label = QtWidgets.QLabel('Factor:') + self.scale_aperture_label.setToolTip( + "Change the size of the selected apertures.\n" + "Factor by which to multiply\n" + "geometric features of this object." + ) + self.scale_aperture_label.setFixedWidth(90) + self.scale_aperture_grid.addWidget(self.scale_aperture_label, 0, 0) + + self.scale_aperture_entry = FloatEntry2() + self.scale_aperture_entry.set_value(1.0) + self.scale_aperture_grid.addWidget(self.scale_aperture_entry, 0, 1) + + # Scale Button + self.scale_aperture_button = QtWidgets.QPushButton('Scale') + self.scale_aperture_button.setToolTip( + "Perform scaling operation." + ) + self.scale_aperture_button.setFixedWidth(40) + self.scale_aperture_grid.addWidget(self.scale_aperture_button, 0, 2) # start with apertures table hidden self.apertures_table.setVisible(False) - - # hide the plot column. for now I can't plot individually the apertures without making the plot really ugly - self.apertures_table.setColumnHidden(5, True) - # - # self.empty_label = QtWidgets.QLabel('') - # self.custom_box.addWidget(self.empty_label) + self.scale_aperture_label.setVisible(False) + self.scale_aperture_entry.setVisible(False) + self.scale_aperture_button.setVisible(False) # Isolation Routing self.isolation_routing_label = QtWidgets.QLabel("Isolation Routing:") @@ -226,6 +254,7 @@ class GerberObjectUI(ObjectUI): "feature, use a negative value for\n" "this parameter." ) + tdlabel.setFixedWidth(90) grid1.addWidget(tdlabel, 0, 0) self.iso_tool_dia_entry = LengthEntry() grid1.addWidget(self.iso_tool_dia_entry, 0, 1) @@ -235,6 +264,7 @@ class GerberObjectUI(ObjectUI): "Width of the isolation gap in\n" "number (integer) of tool widths." ) + passlabel.setFixedWidth(90) grid1.addWidget(passlabel, 1, 0) self.iso_width_entry = IntEntry() grid1.addWidget(self.iso_width_entry, 1, 1) @@ -245,6 +275,7 @@ class GerberObjectUI(ObjectUI): "Example:\n" "A value here of 0.25 means an overlap of 25% from the tool diameter found above." ) + overlabel.setFixedWidth(90) grid1.addWidget(overlabel, 2, 0) self.iso_overlap_entry = FloatEntry() grid1.addWidget(self.iso_overlap_entry, 2, 1) @@ -295,6 +326,15 @@ class GerberObjectUI(ObjectUI): hlay_1 = QtWidgets.QHBoxLayout() self.custom_box.addLayout(hlay_1) + self.generate_iso_button = QtWidgets.QPushButton('FULL Geo') + self.generate_iso_button.setToolTip( + "Create the Geometry Object\n" + "for isolation routing. It contains both\n" + "the interiors and exteriors geometry." + ) + self.generate_iso_button.setFixedWidth(90) + hlay_1.addWidget(self.generate_iso_button) + hlay_1.addStretch() self.generate_ext_iso_button = QtWidgets.QPushButton('Ext Geo') @@ -303,7 +343,7 @@ class GerberObjectUI(ObjectUI): "for isolation routing containing\n" "only the exteriors geometry." ) - self.generate_ext_iso_button.setFixedWidth(60) + # self.generate_ext_iso_button.setFixedWidth(60) hlay_1.addWidget(self.generate_ext_iso_button) self.generate_int_iso_button = QtWidgets.QPushButton('Int Geo') @@ -312,18 +352,9 @@ class GerberObjectUI(ObjectUI): "for isolation routing containing\n" "only the interiors geometry." ) - self.generate_int_iso_button.setFixedWidth(60) + # self.generate_int_iso_button.setFixedWidth(60) hlay_1.addWidget(self.generate_int_iso_button) - self.generate_iso_button = QtWidgets.QPushButton('FULL Geo') - self.generate_iso_button.setToolTip( - "Create the Geometry Object\n" - "for isolation routing. It contains both\n" - "the interiors and exteriors geometry." - ) - self.generate_iso_button.setFixedWidth(80) - hlay_1.addWidget(self.generate_iso_button) - # when the follow checkbox is checked then the exteriors and interiors isolation generation buttons # are disabled as is doesn't make sense to have them enabled due of the nature of "follow" self.ois_iso = OptionalInputSection(self.follow_cb, @@ -333,11 +364,12 @@ class GerberObjectUI(ObjectUI): self.custom_box.addLayout(grid2) ## Clear non-copper regions - self.clearcopper_label = QtWidgets.QLabel("Clear non-copper:") + self.clearcopper_label = QtWidgets.QLabel("Clear N-copper:") self.clearcopper_label.setToolTip( "Create a Geometry object with\n" "toolpaths to cut all non-copper regions." ) + self.clearcopper_label.setFixedWidth(90) grid2.addWidget(self.clearcopper_label, 0, 0) self.generate_ncc_button = QtWidgets.QPushButton('NCC Tool') @@ -385,15 +417,17 @@ class GerberObjectUI(ObjectUI): "objects with this minimum\n" "distance." ) + bmlabel.setFixedWidth(90) grid4.addWidget(bmlabel, 0, 0) self.noncopper_margin_entry = LengthEntry() grid4.addWidget(self.noncopper_margin_entry, 0, 1) # Rounded corners - self.noncopper_rounded_cb = FCCheckBox(label="Rounded corners") + self.noncopper_rounded_cb = FCCheckBox(label="Rounded Geo") self.noncopper_rounded_cb.setToolTip( "Resulting geometry will have rounded corners." ) + self.noncopper_rounded_cb.setFixedWidth(90) grid4.addWidget(self.noncopper_rounded_cb, 1, 0) self.generate_noncopper_button = QtWidgets.QPushButton('Generate Geo') @@ -415,17 +449,19 @@ class GerberObjectUI(ObjectUI): "Distance of the edges of the box\n" "to the nearest polygon." ) + bbmargin.setFixedWidth(90) grid5.addWidget(bbmargin, 0, 0) self.bbmargin_entry = LengthEntry() grid5.addWidget(self.bbmargin_entry, 0, 1) - self.bbrounded_cb = FCCheckBox(label="Rounded corners") + self.bbrounded_cb = FCCheckBox(label="Rounded Geo") self.bbrounded_cb.setToolTip( "If the bounding box is \n" "to have rounded corners\n" "their radius is equal to\n" "the margin." ) + self.bbrounded_cb.setFixedWidth(90) grid5.addWidget(self.bbrounded_cb, 1, 0) self.generate_bb_button = QtWidgets.QPushButton('Generate Geo') diff --git a/PlotCanvas.py b/PlotCanvas.py index e0f2e75f..41f43d79 100644 --- a/PlotCanvas.py +++ b/PlotCanvas.py @@ -165,7 +165,9 @@ class PlotCanvas(QtCore.QObject): """ self.vispy_canvas.view.camera.zoom(factor, center) - def new_shape_group(self): + def new_shape_group(self, shape_collection=None): + if shape_collection: + return ShapeGroup(shape_collection) return ShapeGroup(self.shape_collection) def new_shape_collection(self, **kwargs): diff --git a/README.md b/README.md index 18eb9576..c8e92c4b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing. ================================================= +25.02.2019 + +- fixed the Gerber object UI layout +- added ability to mark individual apertures in Gerber file using the Gerber Aperture Table + 24.02.2019 - fixed a small bug in the Tool Solder Paste: the App don't take into consideration pads already filled with solder paste. diff --git a/camlib.py b/camlib.py index f2f2abb5..842fc405 100644 --- a/camlib.py +++ b/camlib.py @@ -1858,7 +1858,8 @@ class Gerber (Geometry): +-----------+-----------------------------------+ | others | Depend on ``type`` | +-----------+-----------------------------------+ - + | solid_geometry | (list) | + +-----------+-----------------------------------+ * ``aperture_macros`` (dictionary): Are predefined geometrical structures that can be instantiated with different parameters in an aperture definition. See ``apertures`` above. The key is the name of the macro, @@ -1921,9 +1922,7 @@ class Gerber (Geometry): 'size':float, 'width':float, 'height':float, - 'light_solid_geometry': [], - 'dark_solid_geometry': [], - 'buff_solid_geometry': [], + 'solid_geometry': [], 'follow_geometry': [], } } @@ -2247,6 +2246,11 @@ class Gerber (Geometry): geo = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4)) if not geo.is_empty: poly_buffer.append(geo) + try: + self.apertures[current_aperture]['solid_geometry'].append(geo) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(geo) path = [path[-1]] @@ -2411,6 +2415,11 @@ class Gerber (Geometry): int(self.steps_per_circle)) if not flash.is_empty: poly_buffer.append(flash) + try: + self.apertures[current_aperture]['solid_geometry'].append(flash) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(flash) except IndexError: log.warning("Line %d: %s -> Nothing there to flash!" % (line_num, gline)) @@ -2448,6 +2457,11 @@ class Gerber (Geometry): geo = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4)) if not geo.is_empty: poly_buffer.append(geo) + try: + self.apertures[last_path_aperture]['solid_geometry'].append(geo) + except KeyError: + self.apertures[last_path_aperture]['solid_geometry'] = [] + self.apertures[last_path_aperture]['solid_geometry'].append(geo) path = [path[-1]] @@ -2468,6 +2482,11 @@ class Gerber (Geometry): geo = LineString(path).buffer(width/1.999, int(self.steps_per_circle / 4)) if not geo.is_empty: poly_buffer.append(geo) + try: + self.apertures[current_aperture]['solid_geometry'].append(geo) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(geo) path = [path[-1]] @@ -2485,6 +2504,11 @@ class Gerber (Geometry): if not geo.is_empty: follow_buffer.append(geo) poly_buffer.append(geo) + try: + self.apertures[current_aperture]['solid_geometry'].append(geo) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(geo) continue # Only one path defines region? @@ -2514,6 +2538,11 @@ class Gerber (Geometry): if not region.is_empty: poly_buffer.append(region) + try: + self.apertures[current_aperture]['solid_geometry'].append(region) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(region) path = [[current_x, current_y]] # Start new path continue @@ -2584,6 +2613,11 @@ class Gerber (Geometry): geo = shply_box(minx, miny, maxx, maxy) poly_buffer.append(geo) + try: + self.apertures[current_aperture]['solid_geometry'].append(geo) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(geo) except: pass last_path_aperture = current_aperture @@ -2633,6 +2667,11 @@ class Gerber (Geometry): poly_buffer.append(geo) except: poly_buffer.append(geo) + try: + self.apertures[current_aperture]['solid_geometry'].append(geo) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(geo) # if linear_x or linear_y are None, ignore those if linear_x is not None and linear_y is not None: @@ -2665,8 +2704,18 @@ class Gerber (Geometry): try: if self.apertures[current_aperture]["type"] != 'R': poly_buffer.append(geo) + try: + self.apertures[current_aperture]['solid_geometry'].append(geo) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(geo) except: poly_buffer.append(geo) + try: + self.apertures[current_aperture]['solid_geometry'].append(geo) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(geo) # Reset path starting point path = [[linear_x, linear_y]] @@ -2684,6 +2733,11 @@ class Gerber (Geometry): ) if not flash.is_empty: poly_buffer.append(flash) + try: + self.apertures[current_aperture]['solid_geometry'].append(flash) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(flash) # maybe those lines are not exactly needed but it is easier to read the program as those coordinates # are used in case that circular interpolation is encountered within the Gerber file @@ -2773,6 +2827,11 @@ class Gerber (Geometry): buffered = LineString(path).buffer(width / 1.999, int(self.steps_per_circle)) if not buffered.is_empty: poly_buffer.append(buffered) + try: + self.apertures[current_aperture]['solid_geometry'].append(buffered) + except KeyError: + self.apertures[current_aperture]['solid_geometry'] = [] + self.apertures[current_aperture]['solid_geometry'].append(buffered) current_x = circular_x current_y = circular_y @@ -2900,6 +2959,11 @@ class Gerber (Geometry): geo = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4)) if not geo.is_empty: poly_buffer.append(geo) + try: + self.apertures[last_path_aperture]['solid_geometry'].append(geo) + except KeyError: + self.apertures[last_path_aperture]['solid_geometry'] = [] + self.apertures[last_path_aperture]['solid_geometry'].append(geo) # --- Apply buffer --- @@ -3110,6 +3174,7 @@ class Gerber (Geometry): :type factor: float :rtype : None """ + log.debug("camlib.Gerber.scale()") try: xfactor = float(xfactor) @@ -3143,6 +3208,14 @@ class Gerber (Geometry): yfactor, origin=(px, py)) self.solid_geometry = scale_geom(self.solid_geometry) + + # we need to scale the geometry stored in the Gerber apertures, too + try: + for apid in self.apertures: + self.apertures[apid]['solid_geometry'] = scale_geom(self.apertures[apid]['solid_geometry']) + except Exception as e: + log.debug('FlatCAMGeometry.scale() --> %s' % str(e)) + self.app.inform.emit("[success]Gerber Scale done.") ## solid_geometry ???