Merged in marius_stanciu/flatcam_beta/Beta (pull request #272)

Beta - improvements
This commit is contained in:
Marius Stanciu 2019-12-22 23:03:12 +00:00
commit 00e7519ed4
17 changed files with 316 additions and 44 deletions

View File

@ -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'))

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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(

View File

@ -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(

View File

@ -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)

View File

@ -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:

View File

@ -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"),

BIN
share/blue32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

BIN
share/brown32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

BIN
share/green32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

BIN
share/red32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

BIN
share/set_color16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

BIN
share/set_color32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

BIN
share/violet32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

BIN
share/yellow32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B