- added a new option for the Gerber objects: on the project context menu now can be chosen a color for the selected Gerber object

This commit is contained in:
Marius Stanciu 2019-12-22 06:52:45 +02:00 committed by Marius
parent 73d41816d6
commit 612666d01a
14 changed files with 251 additions and 32 deletions

View File

@ -1940,6 +1940,10 @@ class App(QtCore.QObject):
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
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))
@ -2024,7 +2028,7 @@ class App(QtCore.QObject):
self.ui.general_defaults_form.general_gui_group.proj_color_dis_button.clicked.connect(
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_orientation_radio.activated_custom.connect(
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' % "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' % "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' % "Romanian"), 4, 0)
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):
units = self.defaults['units'].lower()
for act in self.ui.cmenu_gridmenu.actions():
act.triggered.disconnect()
self.ui.cmenu_gridmenu.clear()
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 On/Off"))
grid_toggle.setCheckable(True)
if self.grid_status() == True:
grid_toggle.setChecked(True)
else:
grid_toggle.setChecked(False)
grid_toggle.setChecked(True) if self.grid_status() else grid_toggle.setChecked(False)
self.ui.cmenu_gridmenu.addSeparator()
for grid in sorted_list:
@ -12356,6 +12360,50 @@ class App(QtCore.QObject):
# Clear pool to free memory
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:])
new_line_color = new_color[:-2]
sel_obj.shapes.redraw(
update_colors=(new_color, new_line_color)
)
sel_obj.fill_color = new_color
sel_obj.outline_color = new_line_color
def on_grid_snap_triggered(self, state):
if state:
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
import shapely.affinity as affinity
from copy import deepcopy, copy
from copy import deepcopy
from copy import copy
from io import StringIO
import traceback
import inspect # TODO: For debugging only.
@ -30,6 +32,8 @@ from flatcamParsers.ParseGerber import Gerber
from camlib import Geometry, CNCjob
import FlatCAMApp
from flatcamGUI.VisPyVisuals import ShapeCollection
import tkinter as tk
import os, sys, itertools
import ezdxf
@ -104,9 +108,13 @@ class FlatCAMObj(QtCore.QObject):
if self.app.is_legacy is False:
self.shapes = self.app.plotcanvas.new_shape_group()
# self.shapes = ShapeCollection(parent=self.app.plotcanvas.view.scene, pool=self.app.pool, layers=2)
else:
self.shapes = ShapeCollectionLegacy(obj=self, app=self.app, name=name)
self.fill_color = self.app.defaults['global_plot_fill']
self.outline_color = self.app.defaults['global_plot_line']
self.mark_shapes = dict()
self.item = None # Link with project view item
@ -1665,12 +1673,12 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
if 'color' in kwargs:
color = kwargs['color']
else:
color = self.app.defaults['global_plot_line']
color = self.outline_color
if 'face_color' in kwargs:
face_color = kwargs['face_color']
else:
face_color = self.app.defaults['global_plot_fill']
face_color = self.fill_color
if 'visible' not in kwargs:
visible = self.options['plot']
@ -1740,7 +1748,10 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
for el in g:
self.add_shape(shape=el, color=random_color() if self.options['multicolored'] else 'black',
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):
self.shapes.clear(update=True)
except Exception as e:

View File

@ -321,6 +321,7 @@ class ObjectCollection(QtCore.QAbstractItemModel):
sel = len(self.view.selectedIndexes()) > 0
self.app.ui.menuprojectenable.setEnabled(sel)
self.app.ui.menuprojectdisable.setEnabled(sel)
self.app.ui.menuprojectcolor.setEnabled(sel)
self.app.ui.menuprojectviewsource.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.menuprojectsave.setVisible(True)
self.app.ui.menuprojectviewsource.setVisible(True)
self.app.ui.menuprojectcolor.setEnabled(False)
for obj in self.get_selected():
if type(obj) == FlatCAMGerber:
self.app.ui.menuprojectcolor.setEnabled(True)
if type(obj) != FlatCAMGeometry:
self.app.ui.menuprojectgeneratecnc.setVisible(False)
if type(obj) != FlatCAMGeometry and type(obj) != FlatCAMExcellon and type(obj) != FlatCAMGerber:

View File

@ -9,6 +9,10 @@ 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
21.12.2019
- fixed a typo in Distance Tool

View File

@ -634,11 +634,39 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
# ########################## Project Tab Context Menu # ##################
# ########################################################################
self.menuproject = QtWidgets.QMenu()
self.menuprojectenable = self.menuproject.addAction(
QtGui.QIcon(self.app.resource_location + '/replot32.png'), _('Enable Plot'))
self.menuprojectdisable = self.menuproject.addAction(
QtGui.QIcon(self.app.resource_location + '/clear_plot32.png'), _('Disable Plot'))
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(
QtGui.QIcon(self.app.resource_location + '/cnc32.png'), _('Generate CNC'))
self.menuprojectviewsource = self.menuproject.addAction(

View File

@ -17,10 +17,9 @@ from flatcamGUI.VisPyTesselators import GLUTess
class FlatCAMLineVisual(LineVisual):
def __init__(self, pos=None, color=(0.5, 0.5, 0.5, 1), width=1, connect='strip',
method='gl', antialias=False):
LineVisual.__init__(self, pos=None, color=(0.5, 0.5, 0.5, 1), width=1, connect='strip',
method='gl', antialias=True)
def __init__(self, pos=None, color=(0.5, 0.5, 0.5, 1), width=1, connect='strip', method='gl', antialias=False):
LineVisual.__init__(self, pos=pos, color=color, width=width, connect=connect,
method=method, antialias=True)
def clear_data(self):
self._bounds = None
@ -158,11 +157,14 @@ class ShapeGroup(object):
if update:
self._collection.redraw([]) # Skip waiting results
def redraw(self):
def redraw(self, update_colors=None):
"""
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
def visible(self):
@ -228,9 +230,9 @@ class ShapeCollectionVisual(CompoundVisual):
pass
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
l.set_gl_state(blend=True)
lne.set_gl_state(blend=True)
self.freeze()
@ -245,6 +247,8 @@ class ShapeCollectionVisual(CompoundVisual):
Line/edge color
:param face_color: str, tuple
Polygon face color
:param alpha: str
Polygon transparency
:param visible: bool
Shape visibility
:param update: bool
@ -271,11 +275,11 @@ class ShapeCollectionVisual(CompoundVisual):
# Add data to process pool if pool exists
try:
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])
if update:
self.redraw() # redraw() waits for pool process end
self.redraw() # redraw() waits for pool process end
return key
@ -309,6 +313,108 @@ class ShapeCollectionVisual(CompoundVisual):
if 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 data in self.data.values():
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
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
except Exception as e:
print("VisPyVisuals.ShapeCollectionVisual.update_color(). "
"Create line colors --> Data error. %s" % str(e))
else:
for k, data in 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
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
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):
"""
Merges internal buffers, sets data to visuals, redraws collection on scene
@ -328,20 +434,23 @@ class ShapeCollectionVisual(CompoundVisual):
try:
line_pts[data['layer']] += data['line_pts']
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_colors[data['layer']] += data['mesh_colors']
except Exception as e:
print("Data error", e)
print("VisPyVisuals.ShapeCollectionVisual._update() --> Data error. %s" % str(e))
# Updating meshes
for i, mesh in enumerate(self._meshes):
if len(mesh_vertices[i]) > 0:
set_state(polygon_offset_fill=False)
mesh.set_data(np.asarray(mesh_vertices[i]), np.asarray(mesh_tris[i], dtype=np.uint32)
.reshape((-1, 3)), face_colors=np.asarray(mesh_colors[i]))
faces_array = np.asarray(mesh_tris[i], dtype=np.uint32)
mesh.set_data(
vertices=np.asarray(mesh_vertices[i]),
faces=faces_array.reshape((-1, 3)),
face_colors=np.asarray(mesh_colors[i])
)
else:
mesh.set_data()
@ -350,17 +459,20 @@ class ShapeCollectionVisual(CompoundVisual):
# Updating lines
for i, line in enumerate(self._lines):
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:
line.clear_data()
line._bounds_changed()
self._bounds_changed()
self.update_lock.release()
def redraw(self, indexes=None):
def redraw(self, indexes=None, update_colors=None):
"""
Redraws collection
:param indexes: list
@ -377,11 +489,22 @@ class ShapeCollectionVisual(CompoundVisual):
self.data[i] = self.results[i].get()[0] # Store translated data
del self.results[i]
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.__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):
self.update_lock.acquire(True)
@ -489,7 +612,7 @@ class TextCollectionVisual(TextVisual):
self.lock.release()
# 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:
self.redraw()
@ -537,7 +660,7 @@ class TextCollectionVisual(TextVisual):
font_s = data['font_size']
color = data['color']
except Exception as e:
print("Data error", e)
print("VisPyVisuals.TextCollectionVisual._update() --> Data error. %s" % str(e))
# Updating text
if len(labels) > 0:

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