Merged in marius_stanciu/flatcam_beta/Beta (pull request #272)
Beta - improvements
|
@ -1940,6 +1940,10 @@ class App(QtCore.QObject):
|
||||||
|
|
||||||
self.ui.popmenu_properties.triggered.connect(self.obj_properties)
|
self.ui.popmenu_properties.triggered.connect(self.obj_properties)
|
||||||
|
|
||||||
|
# Project Context Menu -> Color Setting
|
||||||
|
for act in self.ui.menuprojectcolor.actions():
|
||||||
|
act.triggered.connect(self.on_set_color_action_triggered)
|
||||||
|
|
||||||
# Preferences Plot Area TAB
|
# Preferences Plot Area TAB
|
||||||
self.ui.pref_save_button.clicked.connect(lambda: self.on_save_button(save_to_file=True))
|
self.ui.pref_save_button.clicked.connect(lambda: self.on_save_button(save_to_file=True))
|
||||||
self.ui.pref_apply_button.clicked.connect(lambda: self.on_save_button(save_to_file=False))
|
self.ui.pref_apply_button.clicked.connect(lambda: self.on_save_button(save_to_file=False))
|
||||||
|
@ -2024,7 +2028,7 @@ class App(QtCore.QObject):
|
||||||
self.ui.general_defaults_form.general_gui_group.proj_color_dis_button.clicked.connect(
|
self.ui.general_defaults_form.general_gui_group.proj_color_dis_button.clicked.connect(
|
||||||
self.on_proj_color_dis_button)
|
self.on_proj_color_dis_button)
|
||||||
|
|
||||||
# ############################# workspace setting signals #####################
|
# ############################# Workspace Setting Signals #####################
|
||||||
self.ui.general_defaults_form.general_gui_group.wk_cb.currentIndexChanged.connect(self.on_workspace_modified)
|
self.ui.general_defaults_form.general_gui_group.wk_cb.currentIndexChanged.connect(self.on_workspace_modified)
|
||||||
self.ui.general_defaults_form.general_gui_group.wk_orientation_radio.activated_custom.connect(
|
self.ui.general_defaults_form.general_gui_group.wk_orientation_radio.activated_custom.connect(
|
||||||
self.on_workspace_modified
|
self.on_workspace_modified
|
||||||
|
@ -4731,7 +4735,7 @@ class App(QtCore.QObject):
|
||||||
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % " "), 2, 3)
|
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % " "), 2, 3)
|
||||||
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "German"), 3, 0)
|
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "German"), 3, 0)
|
||||||
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Marius Stanciu (Google-Tr)"), 3, 1)
|
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Marius Stanciu (Google-Tr)"), 3, 1)
|
||||||
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Jens Karstedt, @detlefeckardt"), 3, 2)
|
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Jens Karstedt, Detlef Eckardt"), 3, 2)
|
||||||
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % " "), 3, 3)
|
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % " "), 3, 3)
|
||||||
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Romanian"), 4, 0)
|
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Romanian"), 4, 0)
|
||||||
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Marius Stanciu"), 4, 1)
|
self.translator_grid_lay.addWidget(QtWidgets.QLabel('%s' % "Marius Stanciu"), 4, 1)
|
||||||
|
@ -8443,16 +8447,16 @@ class App(QtCore.QObject):
|
||||||
def populate_cmenu_grids(self):
|
def populate_cmenu_grids(self):
|
||||||
units = self.defaults['units'].lower()
|
units = self.defaults['units'].lower()
|
||||||
|
|
||||||
|
for act in self.ui.cmenu_gridmenu.actions():
|
||||||
|
act.triggered.disconnect()
|
||||||
self.ui.cmenu_gridmenu.clear()
|
self.ui.cmenu_gridmenu.clear()
|
||||||
|
|
||||||
sorted_list = sorted(self.defaults["global_grid_context_menu"][str(units)])
|
sorted_list = sorted(self.defaults["global_grid_context_menu"][str(units)])
|
||||||
|
|
||||||
grid_toggle = self.ui.cmenu_gridmenu.addAction(QtGui.QIcon(self.resource_location + '/grid32_menu.png'),
|
grid_toggle = self.ui.cmenu_gridmenu.addAction(QtGui.QIcon(self.resource_location + '/grid32_menu.png'),
|
||||||
_("Grid On/Off"))
|
_("Grid On/Off"))
|
||||||
grid_toggle.setCheckable(True)
|
grid_toggle.setCheckable(True)
|
||||||
if self.grid_status() == True:
|
grid_toggle.setChecked(True) if self.grid_status() else grid_toggle.setChecked(False)
|
||||||
grid_toggle.setChecked(True)
|
|
||||||
else:
|
|
||||||
grid_toggle.setChecked(False)
|
|
||||||
|
|
||||||
self.ui.cmenu_gridmenu.addSeparator()
|
self.ui.cmenu_gridmenu.addSeparator()
|
||||||
for grid in sorted_list:
|
for grid in sorted_list:
|
||||||
|
@ -12356,6 +12360,59 @@ class App(QtCore.QObject):
|
||||||
# Clear pool to free memory
|
# Clear pool to free memory
|
||||||
self.clear_pool()
|
self.clear_pool()
|
||||||
|
|
||||||
|
def on_set_color_action_triggered(self):
|
||||||
|
new_color = self.defaults['global_plot_fill']
|
||||||
|
act_name = self.sender().text().lower()
|
||||||
|
|
||||||
|
sel_obj = self.collection.get_active()
|
||||||
|
|
||||||
|
if act_name == 'red':
|
||||||
|
new_color = '#FF0000' + \
|
||||||
|
str(hex(self.ui.general_defaults_form.general_gui_group.pf_color_alpha_slider.value())[2:])
|
||||||
|
if act_name == 'blue':
|
||||||
|
new_color = '#0000FF' + \
|
||||||
|
str(hex(self.ui.general_defaults_form.general_gui_group.pf_color_alpha_slider.value())[2:])
|
||||||
|
if act_name == 'yellow':
|
||||||
|
new_color = '#FFDF00' + \
|
||||||
|
str(hex(self.ui.general_defaults_form.general_gui_group.pf_color_alpha_slider.value())[2:])
|
||||||
|
if act_name == 'green':
|
||||||
|
new_color = '#00FF00' + \
|
||||||
|
str(hex(self.ui.general_defaults_form.general_gui_group.pf_color_alpha_slider.value())[2:])
|
||||||
|
if act_name == 'violet':
|
||||||
|
new_color = '#FF00FF' + \
|
||||||
|
str(hex(self.ui.general_defaults_form.general_gui_group.pf_color_alpha_slider.value())[2:])
|
||||||
|
if act_name == 'brown':
|
||||||
|
new_color = '#A52A2A' + \
|
||||||
|
str(hex(self.ui.general_defaults_form.general_gui_group.pf_color_alpha_slider.value())[2:])
|
||||||
|
|
||||||
|
if act_name == 'custom':
|
||||||
|
new_color = QtGui.QColor(self.defaults['global_plot_fill'][:7])
|
||||||
|
c_dialog = QtWidgets.QColorDialog()
|
||||||
|
plot_fill_color = c_dialog.getColor(initial=new_color)
|
||||||
|
|
||||||
|
if plot_fill_color.isValid() is False:
|
||||||
|
return
|
||||||
|
|
||||||
|
new_color = str(plot_fill_color.name()) + \
|
||||||
|
str(hex(self.ui.general_defaults_form.general_gui_group.pf_color_alpha_slider.value())[2:])
|
||||||
|
|
||||||
|
if self.is_legacy is False:
|
||||||
|
new_line_color = new_color[:-2]
|
||||||
|
sel_obj.fill_color = new_color
|
||||||
|
sel_obj.outline_color = new_line_color
|
||||||
|
|
||||||
|
sel_obj.shapes.redraw(
|
||||||
|
update_colors=(new_color, new_line_color)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
new_line_color = new_color
|
||||||
|
|
||||||
|
sel_obj.fill_color = new_color
|
||||||
|
sel_obj.outline_color = new_line_color
|
||||||
|
sel_obj.shapes.redraw(
|
||||||
|
update_colors=(new_color, new_line_color)
|
||||||
|
)
|
||||||
|
|
||||||
def on_grid_snap_triggered(self, state):
|
def on_grid_snap_triggered(self, state):
|
||||||
if state:
|
if state:
|
||||||
self.ui.snap_infobar_label.setPixmap(QtGui.QPixmap(self.resource_location + '/snap_filled_16.png'))
|
self.ui.snap_infobar_label.setPixmap(QtGui.QPixmap(self.resource_location + '/snap_filled_16.png'))
|
||||||
|
|
|
@ -15,7 +15,9 @@ from shapely.geometry import Point, Polygon, MultiPolygon, MultiLineString, Line
|
||||||
from shapely.ops import cascaded_union
|
from shapely.ops import cascaded_union
|
||||||
import shapely.affinity as affinity
|
import shapely.affinity as affinity
|
||||||
|
|
||||||
from copy import deepcopy, copy
|
from copy import deepcopy
|
||||||
|
from copy import copy
|
||||||
|
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
import traceback
|
import traceback
|
||||||
import inspect # TODO: For debugging only.
|
import inspect # TODO: For debugging only.
|
||||||
|
@ -30,6 +32,8 @@ from flatcamParsers.ParseGerber import Gerber
|
||||||
from camlib import Geometry, CNCjob
|
from camlib import Geometry, CNCjob
|
||||||
import FlatCAMApp
|
import FlatCAMApp
|
||||||
|
|
||||||
|
from flatcamGUI.VisPyVisuals import ShapeCollection
|
||||||
|
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
import os, sys, itertools
|
import os, sys, itertools
|
||||||
import ezdxf
|
import ezdxf
|
||||||
|
@ -104,6 +108,7 @@ class FlatCAMObj(QtCore.QObject):
|
||||||
|
|
||||||
if self.app.is_legacy is False:
|
if self.app.is_legacy is False:
|
||||||
self.shapes = self.app.plotcanvas.new_shape_group()
|
self.shapes = self.app.plotcanvas.new_shape_group()
|
||||||
|
# self.shapes = ShapeCollection(parent=self.app.plotcanvas.view.scene, pool=self.app.pool, layers=2)
|
||||||
else:
|
else:
|
||||||
self.shapes = ShapeCollectionLegacy(obj=self, app=self.app, name=name)
|
self.shapes = ShapeCollectionLegacy(obj=self, app=self.app, name=name)
|
||||||
|
|
||||||
|
@ -649,10 +654,13 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
|
|
||||||
self.units_found = self.app.defaults['units']
|
self.units_found = self.app.defaults['units']
|
||||||
|
|
||||||
|
self.fill_color = self.app.defaults['global_plot_fill']
|
||||||
|
self.outline_color = self.app.defaults['global_plot_line']
|
||||||
|
|
||||||
# Attributes to be included in serialization
|
# Attributes to be included in serialization
|
||||||
# Always append to it because it carries contents
|
# Always append to it because it carries contents
|
||||||
# from predecessors.
|
# from predecessors.
|
||||||
self.ser_attrs += ['options', 'kind']
|
self.ser_attrs += ['options', 'kind', 'fill_color', 'outline_color']
|
||||||
|
|
||||||
def set_ui(self, ui):
|
def set_ui(self, ui):
|
||||||
"""
|
"""
|
||||||
|
@ -736,6 +744,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
self.ui.aperture_table_visibility_cb.hide()
|
self.ui.aperture_table_visibility_cb.hide()
|
||||||
self.ui.milling_type_label.hide()
|
self.ui.milling_type_label.hide()
|
||||||
self.ui.milling_type_radio.hide()
|
self.ui.milling_type_radio.hide()
|
||||||
|
self.ui.iso_type_label.hide()
|
||||||
self.ui.iso_type_radio.hide()
|
self.ui.iso_type_radio.hide()
|
||||||
|
|
||||||
self.ui.follow_cb.hide()
|
self.ui.follow_cb.hide()
|
||||||
|
@ -1665,12 +1674,12 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
if 'color' in kwargs:
|
if 'color' in kwargs:
|
||||||
color = kwargs['color']
|
color = kwargs['color']
|
||||||
else:
|
else:
|
||||||
color = self.app.defaults['global_plot_line']
|
color = self.outline_color
|
||||||
|
|
||||||
if 'face_color' in kwargs:
|
if 'face_color' in kwargs:
|
||||||
face_color = kwargs['face_color']
|
face_color = kwargs['face_color']
|
||||||
else:
|
else:
|
||||||
face_color = self.app.defaults['global_plot_fill']
|
face_color = self.fill_color
|
||||||
|
|
||||||
if 'visible' not in kwargs:
|
if 'visible' not in kwargs:
|
||||||
visible = self.options['plot']
|
visible = self.options['plot']
|
||||||
|
@ -1740,7 +1749,10 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
||||||
for el in g:
|
for el in g:
|
||||||
self.add_shape(shape=el, color=random_color() if self.options['multicolored'] else 'black',
|
self.add_shape(shape=el, color=random_color() if self.options['multicolored'] else 'black',
|
||||||
visible=visible)
|
visible=visible)
|
||||||
self.shapes.redraw()
|
self.shapes.redraw(
|
||||||
|
# update_colors=(self.fill_color, self.outline_color),
|
||||||
|
# indexes=self.app.plotcanvas.shape_collection.data.keys()
|
||||||
|
)
|
||||||
except (ObjectDeleted, AttributeError):
|
except (ObjectDeleted, AttributeError):
|
||||||
self.shapes.clear(update=True)
|
self.shapes.clear(update=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -3763,6 +3775,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
||||||
self.ui.name_entry.set_value(self.options['name'])
|
self.ui.name_entry.set_value(self.options['name'])
|
||||||
self.ui_connect()
|
self.ui_connect()
|
||||||
|
|
||||||
|
self.ui.e_cut_entry.setDisabled(False) if self.ui.extracut_cb.get_value() else \
|
||||||
|
self.ui.e_cut_entry.setDisabled(True)
|
||||||
|
|
||||||
def set_ui(self, ui):
|
def set_ui(self, ui):
|
||||||
FlatCAMObj.set_ui(self, ui)
|
FlatCAMObj.set_ui(self, ui)
|
||||||
|
|
||||||
|
@ -3939,7 +3954,9 @@ class FlatCAMGeometry(FlatCAMObj, Geometry):
|
||||||
else:
|
else:
|
||||||
self.ui.level.setText('<span style="color:red;"><b>%s</b></span>' % _('Advanced'))
|
self.ui.level.setText('<span style="color:red;"><b>%s</b></span>' % _('Advanced'))
|
||||||
|
|
||||||
self.ui.e_cut_entry.setDisabled(True)
|
self.ui.e_cut_entry.setDisabled(False) if self.app.defaults['geometry_extracut'] else \
|
||||||
|
self.ui.e_cut_entry.setDisabled(True)
|
||||||
|
self.ui.extracut_cb.toggled.connect(lambda state: self.ui.e_cut_entry.setDisabled(not state))
|
||||||
|
|
||||||
self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click)
|
self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click)
|
||||||
self.ui.generate_cnc_button.clicked.connect(self.on_generatecnc_button_click)
|
self.ui.generate_cnc_button.clicked.connect(self.on_generatecnc_button_click)
|
||||||
|
|
|
@ -321,6 +321,7 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
||||||
sel = len(self.view.selectedIndexes()) > 0
|
sel = len(self.view.selectedIndexes()) > 0
|
||||||
self.app.ui.menuprojectenable.setEnabled(sel)
|
self.app.ui.menuprojectenable.setEnabled(sel)
|
||||||
self.app.ui.menuprojectdisable.setEnabled(sel)
|
self.app.ui.menuprojectdisable.setEnabled(sel)
|
||||||
|
self.app.ui.menuprojectcolor.setEnabled(sel)
|
||||||
self.app.ui.menuprojectviewsource.setEnabled(sel)
|
self.app.ui.menuprojectviewsource.setEnabled(sel)
|
||||||
|
|
||||||
self.app.ui.menuprojectcopy.setEnabled(sel)
|
self.app.ui.menuprojectcopy.setEnabled(sel)
|
||||||
|
@ -334,8 +335,12 @@ class ObjectCollection(QtCore.QAbstractItemModel):
|
||||||
self.app.ui.menuprojectedit.setVisible(True)
|
self.app.ui.menuprojectedit.setVisible(True)
|
||||||
self.app.ui.menuprojectsave.setVisible(True)
|
self.app.ui.menuprojectsave.setVisible(True)
|
||||||
self.app.ui.menuprojectviewsource.setVisible(True)
|
self.app.ui.menuprojectviewsource.setVisible(True)
|
||||||
|
self.app.ui.menuprojectcolor.setEnabled(False)
|
||||||
|
|
||||||
for obj in self.get_selected():
|
for obj in self.get_selected():
|
||||||
|
if type(obj) == FlatCAMGerber:
|
||||||
|
self.app.ui.menuprojectcolor.setEnabled(True)
|
||||||
|
|
||||||
if type(obj) != FlatCAMGeometry:
|
if type(obj) != FlatCAMGeometry:
|
||||||
self.app.ui.menuprojectgeneratecnc.setVisible(False)
|
self.app.ui.menuprojectgeneratecnc.setVisible(False)
|
||||||
if type(obj) != FlatCAMGeometry and type(obj) != FlatCAMExcellon and type(obj) != FlatCAMGerber:
|
if type(obj) != FlatCAMGeometry and type(obj) != FlatCAMExcellon and type(obj) != FlatCAMGerber:
|
||||||
|
|
13
README.md
|
@ -9,12 +9,25 @@ CAD program, and create G-Code for Isolation routing.
|
||||||
|
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
|
22.12.2019
|
||||||
|
|
||||||
|
- added a new option for the Gerber objects: on the project context menu now can be chosen a color for the selected Gerber object
|
||||||
|
- fixed issue in Gerber UI where a label was not hidden when in Basic mode
|
||||||
|
- added the color parameters of the objects to the serializable attributes
|
||||||
|
- fixed Gerber object color set for Legacy(2D) graphic engine; glitch on the OpenGL(3D) graphic engine
|
||||||
|
- fixed the above mentioned glitch in the OpenGL(3D) graphic engine when an Gerber object has been set with a color
|
||||||
|
|
||||||
|
21.12.2019
|
||||||
|
|
||||||
|
- fixed a typo in Distance Tool
|
||||||
|
|
||||||
20.12.2019
|
20.12.2019
|
||||||
|
|
||||||
- fixed a rare issue in the generation of non-copper-region geometry started from the Gerber Object UI (selected tab)
|
- fixed a rare issue in the generation of non-copper-region geometry started from the Gerber Object UI (selected tab)
|
||||||
- Print function is now printing a PDF file for a selection of objects in the colors from canvas
|
- Print function is now printing a PDF file for a selection of objects in the colors from canvas
|
||||||
- added an icon in the infobar that will show more clearly the status of the grid snapping
|
- added an icon in the infobar that will show more clearly the status of the grid snapping
|
||||||
- in Geometry Object UI (selected tab) when a tool type is changed from no matter what to V-shape, the cut_z value is saved and when the tool type is changed back to something different than V-shape, this saved cut-z value is restored
|
- in Geometry Object UI (selected tab) when a tool type is changed from no matter what to V-shape, the cut_z value is saved and when the tool type is changed back to something different than V-shape, this saved cut-z value is restored
|
||||||
|
- fixed re-cut length entry not staying disabled when the re-cut cb is not checked
|
||||||
|
|
||||||
19.12.2019
|
19.12.2019
|
||||||
|
|
||||||
|
|
|
@ -634,11 +634,39 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
|
||||||
# ########################## Project Tab Context Menu # ##################
|
# ########################## Project Tab Context Menu # ##################
|
||||||
# ########################################################################
|
# ########################################################################
|
||||||
self.menuproject = QtWidgets.QMenu()
|
self.menuproject = QtWidgets.QMenu()
|
||||||
|
|
||||||
self.menuprojectenable = self.menuproject.addAction(
|
self.menuprojectenable = self.menuproject.addAction(
|
||||||
QtGui.QIcon(self.app.resource_location + '/replot32.png'), _('Enable Plot'))
|
QtGui.QIcon(self.app.resource_location + '/replot32.png'), _('Enable Plot'))
|
||||||
self.menuprojectdisable = self.menuproject.addAction(
|
self.menuprojectdisable = self.menuproject.addAction(
|
||||||
QtGui.QIcon(self.app.resource_location + '/clear_plot32.png'), _('Disable Plot'))
|
QtGui.QIcon(self.app.resource_location + '/clear_plot32.png'), _('Disable Plot'))
|
||||||
self.menuproject.addSeparator()
|
self.menuproject.addSeparator()
|
||||||
|
|
||||||
|
self.menuprojectcolor = self.menuproject.addMenu(
|
||||||
|
QtGui.QIcon(self.app.resource_location + '/set_color32.png'), _('Set Color'))
|
||||||
|
|
||||||
|
self.menuproject_red = self.menuprojectcolor.addAction(
|
||||||
|
QtGui.QIcon(self.app.resource_location + '/red32.png'), _('Red'))
|
||||||
|
|
||||||
|
self.menuproject_blue = self.menuprojectcolor.addAction(
|
||||||
|
QtGui.QIcon(self.app.resource_location + '/blue32.png'), _('Blue'))
|
||||||
|
|
||||||
|
self.menuproject_yellow = self.menuprojectcolor.addAction(
|
||||||
|
QtGui.QIcon(self.app.resource_location + '/yellow32.png'), _('Yellow'))
|
||||||
|
|
||||||
|
self.menuproject_green = self.menuprojectcolor.addAction(
|
||||||
|
QtGui.QIcon(self.app.resource_location + '/green32.png'), _('Green'))
|
||||||
|
|
||||||
|
self.menuproject_violet = self.menuprojectcolor.addAction(
|
||||||
|
QtGui.QIcon(self.app.resource_location + '/violet32.png'), _('Violet'))
|
||||||
|
|
||||||
|
self.menuproject_brown = self.menuprojectcolor.addAction(
|
||||||
|
QtGui.QIcon(self.app.resource_location + '/brown32.png'), _('Brown'))
|
||||||
|
|
||||||
|
self.menuproject_custom = self.menuprojectcolor.addAction(
|
||||||
|
QtGui.QIcon(self.app.resource_location + '/set_color32.png'), _('Custom'))
|
||||||
|
|
||||||
|
self.menuproject.addSeparator()
|
||||||
|
|
||||||
self.menuprojectgeneratecnc = self.menuproject.addAction(
|
self.menuprojectgeneratecnc = self.menuproject.addAction(
|
||||||
QtGui.QIcon(self.app.resource_location + '/cnc32.png'), _('Generate CNC'))
|
QtGui.QIcon(self.app.resource_location + '/cnc32.png'), _('Generate CNC'))
|
||||||
self.menuprojectviewsource = self.menuproject.addAction(
|
self.menuprojectviewsource = self.menuproject.addAction(
|
||||||
|
|
|
@ -1577,7 +1577,7 @@ class GeometryObjectUI(ObjectUI):
|
||||||
self.cncfeedrate_rapid_entry.hide()
|
self.cncfeedrate_rapid_entry.hide()
|
||||||
|
|
||||||
# Cut over 1st point in path
|
# Cut over 1st point in path
|
||||||
self.extracut_cb = FCCheckBox('%s' % _('Re-cut'))
|
self.extracut_cb = FCCheckBox('%s:' % _('Re-cut'))
|
||||||
self.extracut_cb.setToolTip(
|
self.extracut_cb.setToolTip(
|
||||||
_("In order to remove possible\n"
|
_("In order to remove possible\n"
|
||||||
"copper leftovers where first cut\n"
|
"copper leftovers where first cut\n"
|
||||||
|
@ -1599,8 +1599,6 @@ class GeometryObjectUI(ObjectUI):
|
||||||
self.grid3.addWidget(self.extracut_cb, 13, 0)
|
self.grid3.addWidget(self.extracut_cb, 13, 0)
|
||||||
self.grid3.addWidget(self.e_cut_entry, 13, 1)
|
self.grid3.addWidget(self.e_cut_entry, 13, 1)
|
||||||
|
|
||||||
self.ois_e_cut = OptionalInputSection(self.extracut_cb, [self.e_cut_entry])
|
|
||||||
|
|
||||||
# Spindlespeed
|
# Spindlespeed
|
||||||
spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed'))
|
spdlabel = QtWidgets.QLabel('%s:' % _('Spindle speed'))
|
||||||
spdlabel.setToolTip(
|
spdlabel.setToolTip(
|
||||||
|
|
|
@ -1033,7 +1033,7 @@ class ShapeCollectionLegacy:
|
||||||
if update is True:
|
if update is True:
|
||||||
self.redraw()
|
self.redraw()
|
||||||
|
|
||||||
def redraw(self):
|
def redraw(self, update_colors=None):
|
||||||
"""
|
"""
|
||||||
This draw the shapes in the shapes collection, on canvas
|
This draw the shapes in the shapes collection, on canvas
|
||||||
|
|
||||||
|
@ -1087,7 +1087,6 @@ class ShapeCollectionLegacy:
|
||||||
self.axes.plot(x, y, local_shapes[element]['color'],
|
self.axes.plot(x, y, local_shapes[element]['color'],
|
||||||
linestyle='-',
|
linestyle='-',
|
||||||
linewidth=local_shapes[element]['linewidth'])
|
linewidth=local_shapes[element]['linewidth'])
|
||||||
|
|
||||||
elif obj_type == 'gerber':
|
elif obj_type == 'gerber':
|
||||||
if self.obj.options["multicolored"]:
|
if self.obj.options["multicolored"]:
|
||||||
linespec = '-'
|
linespec = '-'
|
||||||
|
@ -1095,16 +1094,25 @@ class ShapeCollectionLegacy:
|
||||||
linespec = 'k-'
|
linespec = 'k-'
|
||||||
|
|
||||||
if self.obj.options["solid"]:
|
if self.obj.options["solid"]:
|
||||||
|
if update_colors:
|
||||||
|
gerber_fill_color = update_colors[0]
|
||||||
|
gerber_outline_color = update_colors[1]
|
||||||
|
else:
|
||||||
|
gerber_fill_color = local_shapes[element]['face_color']
|
||||||
|
gerber_outline_color = local_shapes[element]['color']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
patch = PolygonPatch(local_shapes[element]['shape'],
|
patch = PolygonPatch(local_shapes[element]['shape'],
|
||||||
facecolor=local_shapes[element]['face_color'],
|
facecolor=gerber_fill_color,
|
||||||
edgecolor=local_shapes[element]['color'],
|
edgecolor=gerber_outline_color,
|
||||||
alpha=local_shapes[element]['alpha'],
|
alpha=local_shapes[element]['alpha'],
|
||||||
zorder=2)
|
zorder=2)
|
||||||
self.axes.add_patch(patch)
|
self.axes.add_patch(patch)
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
FlatCAMApp.App.log.warning("A geometry component was not a polygon:")
|
FlatCAMApp.App.log.warning("A geometry component was not a polygon:")
|
||||||
FlatCAMApp.App.log.warning(str(element))
|
FlatCAMApp.App.log.warning(str(element))
|
||||||
|
except Exception as e:
|
||||||
|
FlatCAMApp.App.log.debug("PlotCanvasLegacy.ShepeCollectionLegacy.redraw() --> %s" % str(e))
|
||||||
else:
|
else:
|
||||||
x, y = local_shapes[element]['shape'].exterior.xy
|
x, y = local_shapes[element]['shape'].exterior.xy
|
||||||
self.axes.plot(x, y, linespec)
|
self.axes.plot(x, y, linespec)
|
||||||
|
|
|
@ -17,10 +17,9 @@ from flatcamGUI.VisPyTesselators import GLUTess
|
||||||
|
|
||||||
|
|
||||||
class FlatCAMLineVisual(LineVisual):
|
class FlatCAMLineVisual(LineVisual):
|
||||||
def __init__(self, pos=None, color=(0.5, 0.5, 0.5, 1), width=1, connect='strip',
|
def __init__(self, pos=None, color=(0.5, 0.5, 0.5, 1), width=1, connect='strip', method='gl', antialias=False):
|
||||||
method='gl', antialias=False):
|
LineVisual.__init__(self, pos=pos, color=color, width=width, connect=connect,
|
||||||
LineVisual.__init__(self, pos=None, color=(0.5, 0.5, 0.5, 1), width=1, connect='strip',
|
method=method, antialias=True)
|
||||||
method='gl', antialias=True)
|
|
||||||
|
|
||||||
def clear_data(self):
|
def clear_data(self):
|
||||||
self._bounds = None
|
self._bounds = None
|
||||||
|
@ -158,11 +157,14 @@ class ShapeGroup(object):
|
||||||
if update:
|
if update:
|
||||||
self._collection.redraw([]) # Skip waiting results
|
self._collection.redraw([]) # Skip waiting results
|
||||||
|
|
||||||
def redraw(self):
|
def redraw(self, update_colors=None):
|
||||||
"""
|
"""
|
||||||
Redraws shape collection
|
Redraws shape collection
|
||||||
"""
|
"""
|
||||||
self._collection.redraw(self._indexes)
|
if update_colors:
|
||||||
|
self._collection.redraw(self._indexes, update_colors=update_colors)
|
||||||
|
else:
|
||||||
|
self._collection.redraw(self._indexes)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def visible(self):
|
def visible(self):
|
||||||
|
@ -228,9 +230,9 @@ class ShapeCollectionVisual(CompoundVisual):
|
||||||
pass
|
pass
|
||||||
m.set_gl_state(polygon_offset_fill=True, polygon_offset=(1, 1), cull_face=False)
|
m.set_gl_state(polygon_offset_fill=True, polygon_offset=(1, 1), cull_face=False)
|
||||||
|
|
||||||
for l in self._lines:
|
for lne in self._lines:
|
||||||
pass
|
pass
|
||||||
l.set_gl_state(blend=True)
|
lne.set_gl_state(blend=True)
|
||||||
|
|
||||||
self.freeze()
|
self.freeze()
|
||||||
|
|
||||||
|
@ -245,6 +247,8 @@ class ShapeCollectionVisual(CompoundVisual):
|
||||||
Line/edge color
|
Line/edge color
|
||||||
:param face_color: str, tuple
|
:param face_color: str, tuple
|
||||||
Polygon face color
|
Polygon face color
|
||||||
|
:param alpha: str
|
||||||
|
Polygon transparency
|
||||||
:param visible: bool
|
:param visible: bool
|
||||||
Shape visibility
|
Shape visibility
|
||||||
:param update: bool
|
:param update: bool
|
||||||
|
@ -271,11 +275,11 @@ class ShapeCollectionVisual(CompoundVisual):
|
||||||
# Add data to process pool if pool exists
|
# Add data to process pool if pool exists
|
||||||
try:
|
try:
|
||||||
self.results[key] = self.pool.map_async(_update_shape_buffers, [self.data[key]])
|
self.results[key] = self.pool.map_async(_update_shape_buffers, [self.data[key]])
|
||||||
except Exception as e:
|
except Exception:
|
||||||
self.data[key] = _update_shape_buffers(self.data[key])
|
self.data[key] = _update_shape_buffers(self.data[key])
|
||||||
|
|
||||||
if update:
|
if update:
|
||||||
self.redraw() # redraw() waits for pool process end
|
self.redraw() # redraw() waits for pool process end
|
||||||
|
|
||||||
return key
|
return key
|
||||||
|
|
||||||
|
@ -309,6 +313,131 @@ class ShapeCollectionVisual(CompoundVisual):
|
||||||
if update:
|
if update:
|
||||||
self.__update()
|
self.__update()
|
||||||
|
|
||||||
|
def update_color(self, new_mesh_color=None, new_line_color=None, indexes=None):
|
||||||
|
if (new_mesh_color is None or new_mesh_color == '') and (new_line_color is None or new_line_color == ''):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not self.data:
|
||||||
|
return
|
||||||
|
|
||||||
|
mesh_colors = [[] for _ in range(0, len(self._meshes))] # Face colors
|
||||||
|
line_colors = [[] for _ in range(0, len(self._meshes))] # Line colors
|
||||||
|
line_pts = [[] for _ in range(0, len(self._lines))] # Vertices for line
|
||||||
|
|
||||||
|
# Lock sub-visuals updates
|
||||||
|
self.update_lock.acquire(True)
|
||||||
|
# Merge shapes buffers
|
||||||
|
|
||||||
|
if indexes is None:
|
||||||
|
for k, data in list(self.data.items()):
|
||||||
|
if data['visible'] and 'line_pts' in data:
|
||||||
|
if new_mesh_color and new_mesh_color != '':
|
||||||
|
dim_mesh_tris = (len(data['mesh_tris']) // 3)
|
||||||
|
if dim_mesh_tris != 0:
|
||||||
|
try:
|
||||||
|
mesh_colors[data['layer']] += [Color(new_mesh_color).rgba] * dim_mesh_tris
|
||||||
|
self.data[k]['face_color'] = new_mesh_color
|
||||||
|
|
||||||
|
new_temp = list()
|
||||||
|
for i in range(len(data['mesh_colors'])):
|
||||||
|
new_temp.append(Color(new_mesh_color).rgba)
|
||||||
|
data['mesh_colors'] = new_temp
|
||||||
|
except Exception as e:
|
||||||
|
print("VisPyVisuals.ShapeCollectionVisual.update_color(). "
|
||||||
|
"Create mesh colors --> Data error. %s" % str(e))
|
||||||
|
|
||||||
|
if new_line_color and new_line_color != '':
|
||||||
|
dim_line_pts = (len(data['line_pts']))
|
||||||
|
if dim_line_pts != 0:
|
||||||
|
try:
|
||||||
|
line_pts[data['layer']] += data['line_pts']
|
||||||
|
line_colors[data['layer']] += [Color(new_line_color).rgba] * dim_line_pts
|
||||||
|
self.data[k]['color'] = new_line_color
|
||||||
|
|
||||||
|
new_temp = list()
|
||||||
|
for i in range(len(data['line_colors'])):
|
||||||
|
new_temp.append(Color(new_line_color).rgba)
|
||||||
|
data['line_colors'] = new_temp
|
||||||
|
except Exception as e:
|
||||||
|
print("VisPyVisuals.ShapeCollectionVisual.update_color(). "
|
||||||
|
"Create line colors --> Data error. %s" % str(e))
|
||||||
|
else:
|
||||||
|
for k, data in list(self.data.items()):
|
||||||
|
if data['visible'] and 'line_pts' in data:
|
||||||
|
dim_mesh_tris = (len(data['mesh_tris']) // 3)
|
||||||
|
dim_line_pts = (len(data['line_pts']))
|
||||||
|
|
||||||
|
if k in indexes:
|
||||||
|
if new_mesh_color and new_mesh_color != '':
|
||||||
|
if dim_mesh_tris != 0:
|
||||||
|
try:
|
||||||
|
mesh_colors[data['layer']] += [Color(new_mesh_color).rgba] * dim_mesh_tris
|
||||||
|
self.data[k]['face_color'] = new_mesh_color
|
||||||
|
|
||||||
|
new_temp = list()
|
||||||
|
for i in range(len(data['mesh_colors'])):
|
||||||
|
new_temp.append(Color(new_mesh_color).rgba)
|
||||||
|
data['mesh_colors'] = new_temp
|
||||||
|
except Exception as e:
|
||||||
|
print("VisPyVisuals.ShapeCollectionVisual.update_color(). "
|
||||||
|
"Create mesh colors --> Data error. %s" % str(e))
|
||||||
|
if new_line_color and new_line_color != '':
|
||||||
|
if dim_line_pts != 0:
|
||||||
|
try:
|
||||||
|
line_pts[data['layer']] += data['line_pts']
|
||||||
|
line_colors[data['layer']] += [Color(new_line_color).rgba] * dim_line_pts
|
||||||
|
self.data[k]['color'] = new_line_color
|
||||||
|
|
||||||
|
new_temp = list()
|
||||||
|
for i in range(len(data['line_colors'])):
|
||||||
|
new_temp.append(Color(new_line_color).rgba)
|
||||||
|
data['line_colors'] = new_temp
|
||||||
|
except Exception as e:
|
||||||
|
print("VisPyVisuals.ShapeCollectionVisual.update_color(). "
|
||||||
|
"Create line colors --> Data error. %s" % str(e))
|
||||||
|
else:
|
||||||
|
if dim_mesh_tris != 0:
|
||||||
|
try:
|
||||||
|
mesh_colors[data['layer']] += [Color(data['face_color']).rgba] * dim_mesh_tris
|
||||||
|
except Exception as e:
|
||||||
|
print("VisPyVisuals.ShapeCollectionVisual.update_color(). "
|
||||||
|
"Create mesh colors --> Data error. %s" % str(e))
|
||||||
|
|
||||||
|
if dim_line_pts != 0:
|
||||||
|
try:
|
||||||
|
line_pts[data['layer']] += data['line_pts']
|
||||||
|
line_colors[data['layer']] += [Color(data['color']).rgba] * dim_line_pts
|
||||||
|
except Exception as e:
|
||||||
|
print("VisPyVisuals.ShapeCollectionVisual.update_color(). "
|
||||||
|
"Create line colors --> Data error. %s" % str(e))
|
||||||
|
|
||||||
|
# Updating meshes
|
||||||
|
if new_mesh_color and new_mesh_color != '':
|
||||||
|
for i, mesh in enumerate(self._meshes):
|
||||||
|
if mesh_colors[i]:
|
||||||
|
try:
|
||||||
|
mesh._meshdata.set_face_colors(colors=np.asarray(mesh_colors[i]))
|
||||||
|
mesh.mesh_data_changed()
|
||||||
|
except Exception as e:
|
||||||
|
print("VisPyVisuals.ShapeCollectionVisual.update_color(). "
|
||||||
|
"Apply mesh colors --> Data error. %s" % str(e))
|
||||||
|
|
||||||
|
# Updating lines
|
||||||
|
if new_line_color and new_line_color != '':
|
||||||
|
for i, line in enumerate(self._lines):
|
||||||
|
if len(line_pts[i]) > 0:
|
||||||
|
try:
|
||||||
|
line._color = np.asarray(line_colors[i])
|
||||||
|
line._changed['color'] = True
|
||||||
|
line.update()
|
||||||
|
except Exception as e:
|
||||||
|
print("VisPyVisuals.ShapeCollectionVisual.update_color(). "
|
||||||
|
"Apply line colors --> Data error. %s" % str(e))
|
||||||
|
else:
|
||||||
|
line.clear_data()
|
||||||
|
|
||||||
|
self.update_lock.release()
|
||||||
|
|
||||||
def __update(self):
|
def __update(self):
|
||||||
"""
|
"""
|
||||||
Merges internal buffers, sets data to visuals, redraws collection on scene
|
Merges internal buffers, sets data to visuals, redraws collection on scene
|
||||||
|
@ -328,20 +457,23 @@ class ShapeCollectionVisual(CompoundVisual):
|
||||||
try:
|
try:
|
||||||
line_pts[data['layer']] += data['line_pts']
|
line_pts[data['layer']] += data['line_pts']
|
||||||
line_colors[data['layer']] += data['line_colors']
|
line_colors[data['layer']] += data['line_colors']
|
||||||
mesh_tris[data['layer']] += [x + len(mesh_vertices[data['layer']])
|
|
||||||
for x in data['mesh_tris']]
|
|
||||||
|
|
||||||
|
mesh_tris[data['layer']] += [x + len(mesh_vertices[data['layer']]) for x in data['mesh_tris']]
|
||||||
mesh_vertices[data['layer']] += data['mesh_vertices']
|
mesh_vertices[data['layer']] += data['mesh_vertices']
|
||||||
mesh_colors[data['layer']] += data['mesh_colors']
|
mesh_colors[data['layer']] += data['mesh_colors']
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Data error", e)
|
print("VisPyVisuals.ShapeCollectionVisual._update() --> Data error. %s" % str(e))
|
||||||
|
|
||||||
# Updating meshes
|
# Updating meshes
|
||||||
for i, mesh in enumerate(self._meshes):
|
for i, mesh in enumerate(self._meshes):
|
||||||
if len(mesh_vertices[i]) > 0:
|
if len(mesh_vertices[i]) > 0:
|
||||||
set_state(polygon_offset_fill=False)
|
set_state(polygon_offset_fill=False)
|
||||||
mesh.set_data(np.asarray(mesh_vertices[i]), np.asarray(mesh_tris[i], dtype=np.uint32)
|
faces_array = np.asarray(mesh_tris[i], dtype=np.uint32)
|
||||||
.reshape((-1, 3)), face_colors=np.asarray(mesh_colors[i]))
|
mesh.set_data(
|
||||||
|
vertices=np.asarray(mesh_vertices[i]),
|
||||||
|
faces=faces_array.reshape((-1, 3)),
|
||||||
|
face_colors=np.asarray(mesh_colors[i])
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
mesh.set_data()
|
mesh.set_data()
|
||||||
|
|
||||||
|
@ -350,17 +482,20 @@ class ShapeCollectionVisual(CompoundVisual):
|
||||||
# Updating lines
|
# Updating lines
|
||||||
for i, line in enumerate(self._lines):
|
for i, line in enumerate(self._lines):
|
||||||
if len(line_pts[i]) > 0:
|
if len(line_pts[i]) > 0:
|
||||||
line.set_data(np.asarray(line_pts[i]), np.asarray(line_colors[i]), self._line_width, 'segments')
|
line.set_data(
|
||||||
|
pos=np.asarray(line_pts[i]),
|
||||||
|
color=np.asarray(line_colors[i]),
|
||||||
|
width=self._line_width,
|
||||||
|
connect='segments')
|
||||||
else:
|
else:
|
||||||
line.clear_data()
|
line.clear_data()
|
||||||
|
|
||||||
line._bounds_changed()
|
line._bounds_changed()
|
||||||
|
|
||||||
self._bounds_changed()
|
self._bounds_changed()
|
||||||
|
|
||||||
self.update_lock.release()
|
self.update_lock.release()
|
||||||
|
|
||||||
def redraw(self, indexes=None):
|
def redraw(self, indexes=None, update_colors=None):
|
||||||
"""
|
"""
|
||||||
Redraws collection
|
Redraws collection
|
||||||
:param indexes: list
|
:param indexes: list
|
||||||
|
@ -369,19 +504,30 @@ class ShapeCollectionVisual(CompoundVisual):
|
||||||
# Only one thread can update data
|
# Only one thread can update data
|
||||||
self.results_lock.acquire(True)
|
self.results_lock.acquire(True)
|
||||||
|
|
||||||
for i in list(self.data.copy().keys()) if not indexes else indexes:
|
for i in list(self.data.keys()) if not indexes else indexes:
|
||||||
if i in list(self.results.copy().keys()):
|
if i in list(self.results.keys()):
|
||||||
try:
|
try:
|
||||||
self.results[i].wait() # Wait for process results
|
self.results[i].wait() # Wait for process results
|
||||||
if i in self.data:
|
if i in self.data:
|
||||||
self.data[i] = self.results[i].get()[0] # Store translated data
|
self.data[i] = self.results[i].get()[0] # Store translated data
|
||||||
del self.results[i]
|
del self.results[i]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e, indexes)
|
print("VisPyVisuals.ShapeCollectionVisual.redraw() --> Data error = %s. Indexes = %s" %
|
||||||
|
(str(e), str(indexes)))
|
||||||
|
|
||||||
self.results_lock.release()
|
self.results_lock.release()
|
||||||
|
|
||||||
self.__update()
|
if update_colors is None:
|
||||||
|
self.__update()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
self.update_color(
|
||||||
|
new_mesh_color=update_colors[0],
|
||||||
|
new_line_color=update_colors[1],
|
||||||
|
indexes=indexes
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
print("VisPyVisuals.ShapeCollectionVisual.redraw() --> Update colors error = %s." % str(e))
|
||||||
|
|
||||||
def lock_updates(self):
|
def lock_updates(self):
|
||||||
self.update_lock.acquire(True)
|
self.update_lock.acquire(True)
|
||||||
|
@ -489,7 +635,7 @@ class TextCollectionVisual(TextVisual):
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
|
||||||
# Prepare data for translation
|
# Prepare data for translation
|
||||||
self.data[key] = {'text': text, 'pos': pos, 'visible': visible,'font_size': font_size, 'color': color}
|
self.data[key] = {'text': text, 'pos': pos, 'visible': visible, 'font_size': font_size, 'color': color}
|
||||||
|
|
||||||
if update:
|
if update:
|
||||||
self.redraw()
|
self.redraw()
|
||||||
|
@ -537,7 +683,7 @@ class TextCollectionVisual(TextVisual):
|
||||||
font_s = data['font_size']
|
font_s = data['font_size']
|
||||||
color = data['color']
|
color = data['color']
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Data error", e)
|
print("VisPyVisuals.TextCollectionVisual._update() --> Data error. %s" % str(e))
|
||||||
|
|
||||||
# Updating text
|
# Updating text
|
||||||
if len(labels) > 0:
|
if len(labels) > 0:
|
||||||
|
|
|
@ -349,7 +349,7 @@ class Distance(FlatCAMTool):
|
||||||
d = math.sqrt(dx ** 2 + dy ** 2)
|
d = math.sqrt(dx ** 2 + dy ** 2)
|
||||||
self.stop_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1]))
|
self.stop_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1]))
|
||||||
|
|
||||||
self.app.inform.emit("{tx1}: {tx2} D(x) = {d_x} | D(y) = {d_y} | (tx3} = {d_z}".format(
|
self.app.inform.emit("{tx1}: {tx2} D(x) = {d_x} | D(y) = {d_y} | {tx3} = {d_z}".format(
|
||||||
tx1=_("MEASURING"),
|
tx1=_("MEASURING"),
|
||||||
tx2=_("Result"),
|
tx2=_("Result"),
|
||||||
tx3=_("Distance"),
|
tx3=_("Distance"),
|
||||||
|
|
After Width: | Height: | Size: 459 B |
After Width: | Height: | Size: 470 B |
After Width: | Height: | Size: 459 B |
After Width: | Height: | Size: 459 B |
After Width: | Height: | Size: 703 B |
After Width: | Height: | Size: 848 B |
After Width: | Height: | Size: 459 B |
After Width: | Height: | Size: 459 B |