From 66bd61305fa5f1a29f26c0a9dedf271f3d02b41c Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 14 Dec 2020 17:29:36 +0200 Subject: [PATCH] - added new functionality: centering in origin for a selection of objects - for all centering functionality, now if the moved object is of 'geometry' kind it will have the source_file attribute updated with DXF code --- CHANGELOG.md | 5 ++ appGUI/MainGUI.py | 8 ++ app_Main.py | 81 +++++++++++++++++- .../resources/dark_resources/origin3_32.png | Bin 0 -> 771 bytes assets/resources/origin3_32.png | Bin 0 -> 798 bytes 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 assets/resources/dark_resources/origin3_32.png create mode 100644 assets/resources/origin3_32.png diff --git a/CHANGELOG.md b/CHANGELOG.md index cceb1224..15b38d92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ CHANGELOG for FlatCAM beta ================================================= +14.12.2020 + +- added new functionality: centering in origin for a selection of objects +- for all centering functionality, now if the moved object is of 'geometry' kind it will have the source_file attribute updated with DXF code + 13.12.2020 - GCode Editor - fixed the issue with the editor toolbar buttons not being updated like for the other editors diff --git a/appGUI/MainGUI.py b/appGUI/MainGUI.py index 09a4d35d..52694996 100644 --- a/appGUI/MainGUI.py +++ b/appGUI/MainGUI.py @@ -431,6 +431,9 @@ class MainGUI(QtWidgets.QMainWindow): self.menuedit_move2origin = self.menuedit.addAction( QtGui.QIcon(self.app.resource_location + '/origin2_16.png'), '%s\t%s' % (_('Move to Origin'), _('Shift+O'))) + self.menuedit_center_in_origin = self.menuedit.addAction( + QtGui.QIcon(self.app.resource_location + '/origin3_32.png'), + '%s\t%s' % (_('Center to Origin'), '')) self.menueditjump = self.menuedit.addAction( QtGui.QIcon(self.app.resource_location + '/jump_to16.png'), @@ -1022,6 +1025,8 @@ class MainGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/origin32.png'), _('Set Origin')) self.move2origin_btn = self.toolbaredit.addAction( QtGui.QIcon(self.app.resource_location + '/origin2_32.png'), _('Move to Origin')) + self.center_in_origin_btn = self.toolbaredit.addAction( + QtGui.QIcon(self.app.resource_location + '/origin3_32.png'), _('Center to Origin')) self.jmp_btn = self.toolbaredit.addAction( QtGui.QIcon(self.app.resource_location + '/jump_to16.png'), _('Jump to Location')) @@ -2235,6 +2240,9 @@ class MainGUI(QtWidgets.QMainWindow): QtGui.QIcon(self.app.resource_location + '/origin32.png'), _('Set Origin')) self.move2origin_btn = self.toolbaredit.addAction( QtGui.QIcon(self.app.resource_location + '/origin2_32.png'), _('Move to Origin')) + self.center_in_origin_btn = self.toolbaredit.addAction( + QtGui.QIcon(self.app.resource_location + '/origin3_32.png'), _('Center to Origin')) + self.jmp_btn = self.toolbaredit.addAction( QtGui.QIcon(self.app.resource_location + '/jump_to16.png'), _('Jump to Location')) self.locate_btn = self.toolbaredit.addAction( diff --git a/app_Main.py b/app_Main.py index 4eed11af..1765be8a 100644 --- a/app_Main.py +++ b/app_Main.py @@ -2082,6 +2082,7 @@ class App(QtCore.QObject): self.ui.menueditorigin.triggered.connect(self.on_set_origin) self.ui.menuedit_move2origin.triggered.connect(self.on_move2origin) + self.ui.menuedit_center_in_origin.triggered.connect(self.on_center_in_origin) self.ui.menueditjump.triggered.connect(self.on_jump_to) self.ui.menueditlocate.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active())) @@ -2262,6 +2263,7 @@ class App(QtCore.QObject): self.ui.distance_min_btn.triggered.connect(lambda: self.distance_min_tool.run(toggle=True)) self.ui.origin_btn.triggered.connect(self.on_set_origin) self.ui.move2origin_btn.triggered.connect(self.on_move2origin) + self.ui.center_in_origin_btn.triggered.connect(self.on_center_in_origin) self.ui.jmp_btn.triggered.connect(self.on_jump_to) self.ui.locate_btn.triggered.connect(lambda: self.on_locate(obj=self.collection.get_active())) @@ -4982,7 +4984,9 @@ class App(QtCore.QObject): elif obj.kind == 'excellon': obj.source_file = self.f_handlers.export_excellon( obj_name=out_name, filename=None, local_use=obj, use_thread=False) - + elif obj.kind == 'geometry': + obj.source_file = self.f_handlers.export_dxf( + obj_name=out_name, filename=None, local_use=obj, use_thread=False) if noplot_sig is False: self.replot_signal.emit([]) @@ -5062,6 +5066,7 @@ class App(QtCore.QObject): for obj in obj_list: obj.plot() + self.plotcanvas.fit_view() for obj in obj_list: out_name = obj.options["name"] @@ -5072,6 +5077,80 @@ class App(QtCore.QObject): elif obj.kind == 'excellon': obj.source_file = self.f_handlers.export_excellon( obj_name=out_name, filename=None, local_use=obj, use_thread=False) + elif obj.kind == 'geometry': + obj.source_file = self.f_handlers.export_dxf( + obj_name=out_name, filename=None, local_use=obj, use_thread=False) + self.inform.emit('[success] %s...' % _('Origin set')) + + if use_thread is True: + self.worker_task.emit({'fcn': worker_task, 'params': []}) + else: + worker_task() + self.should_we_save = True + + def on_center_in_origin(self, use_thread=True): + """ + Move selected objects to be centered in origin. + :param use_thread: Control if to use threaded operation. Boolean. + :return: + """ + + def worker_task(): + with self.proc_container.new(_("Centering in Origin...")): + obj_list = self.collection.get_selected() + + if not obj_list: + self.inform.emit('[ERROR_NOTCL] %s' % _("Failed. No object(s) selected...")) + return + + xminlist = [] + yminlist = [] + xmaxlist = [] + ymaxlist = [] + + # first get a bounding box to fit all + for obj in obj_list: + xmin, ymin, xmax, ymax = obj.bounds() + xminlist.append(xmin) + yminlist.append(ymin) + xmaxlist.append(xmax) + ymaxlist.append(ymax) + + # get the minimum x,y for all objects selected + x0 = min(xminlist) + y0 = min(yminlist) + x1 = max(xmaxlist) + y1 = max(ymaxlist) + cx = (x1 - x0) / 2 + x0 + cy = (y1 - y0) / 2 + y0 + + for obj in obj_list: + obj.offset((-cx, -cy)) + self.app_obj.object_changed.emit(obj) + + # Update the object bounding box options + a, b, c, d = obj.bounds() + obj.options['xmin'] = a + obj.options['ymin'] = b + obj.options['xmax'] = c + obj.options['ymax'] = d + + for obj in obj_list: + obj.plot() + self.plotcanvas.fit_view() + + for obj in obj_list: + out_name = obj.options["name"] + + if obj.kind == 'gerber': + obj.source_file = self.f_handlers.export_gerber( + obj_name=out_name, filename=None, local_use=obj, use_thread=False) + elif obj.kind == 'excellon': + obj.source_file = self.f_handlers.export_excellon( + obj_name=out_name, filename=None, local_use=obj, use_thread=False) + elif obj.kind == 'geometry': + obj.source_file = self.f_handlers.export_dxf( + obj_name=out_name, filename=None, local_use=obj, use_thread=False) self.inform.emit('[success] %s...' % _('Origin set')) diff --git a/assets/resources/dark_resources/origin3_32.png b/assets/resources/dark_resources/origin3_32.png new file mode 100644 index 0000000000000000000000000000000000000000..bc6c8360c1e75c3ee5fcad423b145ed1f268ad61 GIT binary patch literal 771 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jPK-BC>eK@{oCO|{#S9F5 zM?jcysy3fAQ1DxTPlzj!{*MEE{`?t-4Aq2zR=j@w8fe_7PoLhteG4)7)vH(U-@iw; z1E}WBn>Rplpn4z)c4uGYem=3 z)rCokJghxMG~;Z^$s8bTSs2=MT9aSW-LGj(!ibd!TftNXMsTv7{mG-MLxVH(jZS~GIW8CE|A@0dThpcT zh{zIu)tQMRnv+=_d0uDf#d8>mn8xzHj9Tf_w&sJ>(-qIW(!Yqf`Ks?;@+s9tI$&?2 z(9eYr5;wmL3~8x>%PSo4akh>jSYZTx$PQb;GlhtOK9(-b%>XX1!_Qs;jS-B<`&Izd(6q z)#9hpPkv@eUwW&jwqeK@{oCO|{#S9F5 zM?jcysy3fAPythbPlzi}a)g6_e#iC!gCMLV$S;^7cDA&`KAFaw|G$5_(ZJF4^;E7R zBU9dKi4%7NgYO^TD=5Ut%C=wlLA_?kmoqsZpV=2EOMdHkVHY=Z&!%^iJ)efAzEZhX zbp2din3TxF+Ji^g?}-=wxVrO`SQ0S2gFRgwLn`J>4SreFWFXO_kkz9R7GUF$`|(KF z6}hbZtzYeK-TGcXb&<2e!hq%X`!`I!d-5F{!-M(49CHK=&dfKFezHU1_3^etf)cJ8 zT*-T;tIZRbl&(23aY=}k@`plm{q*8Wb!W%GRPps9-YF-HmIriw&iUAsw=gv1lIlcl z#wdnWTdgL>pGdxuk#Ob8T)l@&+;uM$^>xJD`oOi7m%A*fVsfh{&qPM23x{HFY!3Jk zwdumywL2dOFL`nI<4t*Te`(Z@b0_D2zy61zLSBXciR#*DP#X4h^>bP0l+XkKGx6~h literal 0 HcmV?d00001