Squashed commit of the following:

commit 7fda555fc0
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed May 24 17:46:25 2023 +0300

    - for all Editors now there is a shortcut key (key "C") that will toggle the cursor data in case the cursor data is in the way
    - Geometry Editor: the Path tool now has a new behavior: when key modifier SHIFT is pressed and the Grid is OFF, when the line is drawn and it is near the 0, 45 and 90 degrees, in each quadrant, then the drawn line will follow the nearest target angle (0 or 45 or 90 degrees) allowing the drawing of straight lines.

commit e5dd294576
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Fri May 19 18:18:38 2023 +0300

    - Film Tool: fixed the export to PNG to be done at correct DPI

commit a49f54d63f
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Fri May 19 13:09:08 2023 +0300

    - the selection shapes are now moved from Move Plugin to AppMain
    - Fiducials Plugin: fixed errors due of changes in the Shapely module
    - Fiducials Plugin: fixed an error where in Basic mode the soldermask opening is added incorrectly

commit ba3152e5f9
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Fri May 19 02:23:40 2023 +0300

    - CutOut Plugin - fixed the manual adding of gaps

commit 761b61668a
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed May 17 22:48:39 2023 +0300

    - Thieving Plugin: fixed errors due of changes in the Shapely module

commit dea367b185
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Tue May 16 04:34:32 2023 +0300

    - NCC Plugin: fixed the Standard method of copper clearing (both normal and with Rest machining)

commit 6719e2ef8e
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun May 14 22:14:43 2023 +0300

    - NCC Plugin - minor code refactoring

commit 5d274dd522
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun May 14 21:48:14 2023 +0300

    - Isolation Plugin, NCC Plugin and Find Optimal Plugin: fixed not finding the optimal tool diameter (the one that will isolate completely a Gerber object)

commit 1d68dea61c
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Fri May 5 22:31:18 2023 +0300

    - replaced some type hints with using the Union

commit 412872bc09
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Fri May 5 02:40:41 2023 +0300

    - fixed an erroneous opening for a Gerber file generated by KiCAD 6.0.11, due of a rectangular flash being eliminated by the global unary_union operation

commit 765d7cc05b
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Apr 15 22:15:33 2023 +0300

    - when parsing a new Gerber object, I am "preparing" each geometry added therefore making the Gerber object geometry possible faster to process

commit 6a29bcbe7c
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Apr 15 21:29:32 2023 +0300

    - some code leftovers are commented

commit b557df8fdc
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Apr 15 21:08:48 2023 +0300

    - minor fixes

commit ccc71eabc2
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Apr 15 21:03:30 2023 +0300

    - changed the shapely imports a bit according to the specifications of Shapely 2.0
    - changed the requirements.txt file to reflect the need for at least Shapely in version 2.0

commit 6f93734d3f
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Apr 8 12:43:34 2023 +0300

    - minor name changes

commit faf41d7bca
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Apr 8 12:29:45 2023 +0300

    - major change: from now on the only dimensional units available are those from ISO METRIC system

commit b446ded9ab
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Apr 8 12:10:02 2023 +0300

    - fixed some really long strings in the Geometry Editor toolbar actions
    - modified the paint and buffer icons
    - optimized the editor menu/toolbar action names

commit 72dd81848f
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed Mar 22 16:43:27 2023 +0200

    - in the toolbars now there is text under the icons (which can be turned off from the toolbar context menu)
    - the GUI state is now saved and restored through QSettings

commit 1dff9cc566
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Mon Mar 13 23:08:57 2023 +0200

    - in Tcl Commands: export_dxf and export_gerber, fixed a mistake in declaring a wrong name of a required option
    - in Tcl Command set_path added an optional parameter which allows to create a directory where path is to be set, if the directory does not exist

commit 3b3c87e953
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Mon Mar 6 16:40:49 2023 +0200

    - fixed some possible issues due of changes in version 2.0 of Shapely
    - removed the import * statement from most of the app

commit 33de5314b1
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed Mar 1 18:15:10 2023 +0200

    - in Tool Milling made sure that deleting the only tool will not crash the application
    - added a new parameter in Preferences to control the number of processes created by the Pool() - more processes better performance but also a lot of memory consumed
    - made sure that the display of messages in the Status Bar is done asap

commit 9d8852e611
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Fri Jan 20 19:23:34 2023 +0200

    - added a new method for bilinear interpolation

commit 9ce9c3cb54
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed Jan 18 18:22:33 2023 +0200

    - in Autolevelling Plugin, preventing the add of a probe point on Excellon hole checkbox is not disabled except for the Manual mode
    - in Autolevelling Plugin, the status of soem checkoxes (avoid Excellon holes and plot points) is stored between app restarts
    - in Isolation Plugin, added an convenience shortcut button to launch the Milling Plugin.

commit c85d04bc0a
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed Jan 18 01:32:28 2023 +0200

    - in Autolevelling Tool, when adding manual probe points, added an option that prevent adding a probe point within a drill hole of an Excellon object that is plotted on canvas

commit f42f05d93e
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed Jan 18 01:07:31 2023 +0200

    - in Autolevelling Tool made sure that when adding manual probe points mouse dragging with the right button is not counted as end of adding operation

commit 220157641d
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Tue Jan 17 01:02:52 2023 +0200

    - fixed the Voronoi generation in the Autolevelling Tool (removed the Foronoi package due of issues and now using the embedded functionality from Shapely)
    - fixed the enable of Levelling Tool only for CNCJob objects that were made from geometries that were segmented

commit 853b273e79
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Mon Jan 16 23:52:30 2023 +0200

    - fixed the Voronoi generation in the Autolevelling Tool (removed the Foronoi package due of issues and now using the embedded functionality from Shapely)

commit a1b6f78d78
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Mon Jan 16 13:28:50 2023 +0200

    - some PEP8 fixes

commit 6c5a468418
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Mon Jan 16 13:02:47 2023 +0200

    - fixed a decoding error in the Excellon parser

commit d6ebcef38d
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun Jan 15 22:31:11 2023 +0200

    - PEP8 changes

commit 2d0ea65f1b
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun Jan 15 15:25:20 2023 +0200

    - minor change

commit c1377d5090
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Nov 19 02:29:40 2022 +0200

    - added a 'return' button when a fatal error is encountered allowing the user to continue the work
    - fixed a crash in Milling Plugin when trying to mill slots that do not have drills in the same file

commit 22f4d92be7
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed Nov 9 20:56:39 2022 +0200

    - minor change in the requirements.txt file

commit 8b4423dc0f
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed Nov 9 19:55:59 2022 +0200

    - when changing the style for the decorations from Preferences, now change is applied immediately

commit 9ec2ee2920
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Tue Nov 8 15:59:59 2022 +0200

    - in Drilling Plugin fixed a situation when having tools with the same diameter will get them multiplied by the number of those tools

commit d1a4de676e
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun Nov 6 00:43:34 2022 +0200

    - if PikePDF module is not available then show an error but run the app (currently, for Python 3.11 is the only module not available)

commit 6509089dc4
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed Oct 19 16:59:05 2022 +0300

    - fixed an issue when exporting huge SVG files from the Film Tool by adding a fallback and using a custom XML parser with the 'huge_tree' option set

commit 2c229d8677
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed Oct 19 02:35:19 2022 +0300

    - added a hack so the Gerber files from Allegro 17.2 (which do not follow the Gerber specifications) can be loaded

commit 94901686b5
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun Oct 2 06:56:13 2022 +0300

    - really small UI change in 2-Sided Plugin

commit 56033b8bc4
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Tue Sep 27 16:45:32 2022 +0300

    - in Milling Plugin, for Excellon target, re-enabled the control over the Feedrate X-Y parameter

commit 8f774df30b
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun Sep 25 05:57:35 2022 +0300

    - small fix in ToolCutout Plugin when trying to set a checkbox state with a float value which still works in Windows but creates issues in other OS's

commit 9b08191660
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun Sep 25 05:44:43 2022 +0300

    - added a new setting in Preferences ("3D compatibility") controlled by a checkbox. If the checkbox is checked then multithreading is disabled for the 3D mode (lower performance but perhaps more compatibility, especially for Linux) - this was done from the research done by Matti Eiden on bitbucket

commit 565c839460
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Sep 10 01:50:13 2022 +0300

    - added insurance that the QThread where the ArgThread class is running, really receive the interruption request and it is finished

commit 71a3963c96
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat Sep 10 01:06:13 2022 +0300

    - hided the main UI on application quit to create a user experience of a shutdown without lag
    - added a way to terminate QThreads safely by waiting; should be much safer
    - made sure that the ArgsThread class receive the signal to stop
    - made sure that on application shutdown, all workers will quit before the actual exit

commit 3c1349a6c4
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Thu Sep 1 13:08:06 2022 +0300

    - added a new feature for Geometry export-as-SVG, the ability to export only the paths (outlines); the new feature is controlled from a new parameter in Preferences -> Geometry -> Export

commit 6eeac5312e
Merge: 419330ee 2901afd9
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Mon Aug 1 09:29:44 2022 +0000

    Merged Beta_8.995 into gerber_editor_upgrade

commit 419330ee93
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Mon Aug 1 12:27:14 2022 +0300

    - fixed some bugs in Geometry Editor in regards of Buffer Tool
    - fixed some issues in the Cutout Plugin by adding more checks
    - fixed issues when loading files by dragging in the UI (caused by recent code refactoring)

commit 4c22e52b08
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Thu May 26 00:20:43 2022 +0300

    - upgraded the UI of Region sub-tool in the Gerber Editor

commit 95066e352b
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun May 22 14:01:21 2022 +0300

    - in Gerber Editor upgraded the Simplification sub-tool GUI

commit 5298a59372
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun May 22 04:37:16 2022 +0300

    - in Gerber Editor upgraded the Track sub-tool GUI

commit 830d500d04
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun May 22 03:18:51 2022 +0300

    - in Gerber Editor upgraded the PadArray GUI

commit 9055cc1230
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sun May 22 01:40:55 2022 +0300

    - in Gerber Editor upgraded the PadAdd GUI

commit bfb3aa4118
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat May 21 02:13:47 2022 +0300

    - added properties for the mouse position and mouse clicked position (and setters) and cleaned up the code regarding this data

commit 61325b7b5f
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Sat May 21 01:25:14 2022 +0300

    - more code refactored in the appMain.py

commit 77c752701f
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Fri May 20 21:19:52 2022 +0300

    - refactored the code for the file registration and for the keywords update into its own class to make the main class smaller
    - when creating new files the file names are added to the beginning of the keywords list for the usage of Qt auto-completer

commit 5125f475eb
Merge: c3ab0b28 037a72a5
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Fri May 20 01:51:59 2022 +0000

    Merged Beta_8.995 into gerber_editor_upgrade

commit c3ab0b28b3
Merge: 93c2ab43 c0ff26db
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Thu May 19 13:25:47 2022 +0000

    Merged Beta_8.995 into gerber_editor_upgrade

commit 93c2ab43f4
Merge: 8bdaaa50 f82d4a4b
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Wed May 18 21:00:48 2022 +0000

    Merged Beta_8.995 into gerber_editor_upgrade

commit 8bdaaa5021
Merge: 1a0dfe61 04bb0857
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Tue May 17 19:55:12 2022 +0000

    Merged Beta_8.995 into gerber_editor_upgrade

commit 1a0dfe6143
Merge: 9a057a40 b09c55da
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Tue May 17 11:39:28 2022 +0000

    Merged Beta_8.995 into gerber_editor_upgrade

commit 9a057a40c5
Merge: c1a53203 3a0247e7
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Tue May 17 09:54:28 2022 +0000

    Merged Beta_8.995 into gerber_editor_upgrade

commit c1a5320315
Author: Marius Stanciu <marius.adrian@gmail.com>
Date:   Mon May 16 18:13:12 2022 +0300

    - started to lay ground for upgrading the UI in the Gerber Editor
    - fixed and upgraded the Buffer sub-tool in the Gerber Editor
    - fixed adding same aperture multiple times
This commit is contained in:
Marius Stanciu
2023-05-24 18:20:51 +03:00
parent 63071a9bae
commit cb7e69ee89
55 changed files with 0 additions and 15486 deletions

View File

View File

@@ -1,95 +0,0 @@
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
import io
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
import cProfile
import sys
def gen_data():
N = 100000
x = np.random.rand(N) * 10
y = np.random.rand(N) * 10
colors = np.random.rand(N)
area = np.pi * (15 * np.random.rand(N))**2 # 0 to 15 point radiuses
data = x, y, area, colors
return data
# @profile
def large_plot(data):
x, y, area, colors = data
fig = Figure(figsize=(10, 10), dpi=80)
axes = fig.add_axes([0.0, 0.0, 1.0, 1.0], alpha=1.0)
axes.set_frame_on(False)
axes.set_xticks([])
axes.set_yticks([])
# axes.set_xlim(0, 10)
# axes.set_ylim(0, 10)
axes.scatter(x, y, s=area, c=colors, alpha=0.5)
axes.set_xlim(0, 10)
axes.set_ylim(0, 10)
canvas = FigureCanvasAgg(fig)
canvas.draw()
# canvas = FigureCanvasQTAgg(fig)
# buf = canvas.tostring_rgb()
buf = fig.canvas.tostring_rgb()
ncols, nrows = fig.canvas.get_width_height()
img = np.fromstring(buf, dtype=np.uint8).reshape(nrows, ncols, 3)
return img
def small_plot(data):
x, y, area, colors = data
fig = Figure(figsize=(3, 3), dpi=80)
axes = fig.add_axes([0.0, 0.0, 1.0, 1.0], alpha=1.0)
axes.set_frame_on(False)
axes.set_xticks([])
axes.set_yticks([])
# axes.set_xlim(5, 6)
# axes.set_ylim(5, 6)
axes.scatter(x, y, s=area, c=colors, alpha=0.5)
axes.set_xlim(4, 7)
axes.set_ylim(4, 7)
canvas = FigureCanvasAgg(fig)
canvas.draw()
# canvas = FigureCanvasQTAgg(fig)
# buf = canvas.tostring_rgb()
buf = fig.canvas.tostring_rgb()
ncols, nrows = fig.canvas.get_width_height()
img = np.fromstring(buf, dtype=np.uint8).reshape(nrows, ncols, 3)
return img
def doit():
d = gen_data()
img = large_plot(d)
return img
if __name__ == "__main__":
d = gen_data()
if sys.argv[1] == 'large':
cProfile.runctx('large_plot(d)', None, locals())
else:
cProfile.runctx('small_plot(d)', None, locals())

View File

@@ -1,6 +0,0 @@
#!/bin/sh
echo "*** LARGE ***"
python performance.py large | egrep "(\(scatter\))|(\(draw\))|(tostring_rgb)|(fromstring)"
echo "*** SMALL ***"
python performance.py small | egrep "(\(scatter\))|(\(draw\))|(tostring_rgb)|(fromstring)"

View File

@@ -1,125 +0,0 @@
M48
INCH
T01C0.0200
T02C0.0800
T03C0.0600
T04C0.0300
T05C0.0650
T06C0.0450
T07C0.0400
T08C0.1181
T09C0.0500
%
T01
X-018204Y+015551
X-025842Y+015551
T02
X-000118Y+020629
X-000118Y+016889
X+012401Y+020629
X+012401Y+016889
X-010170Y+002440
X-010110Y+011470
X+018503Y+026574
T03
X+013060Y+010438
X+013110Y+000000
X-049015Y+002165
X+018378Y+010433
X+018317Y+000000
X-049015Y+010039
X-041141Y-000629
X-041181Y+012992
X-056496Y+012992
X-056496Y-000590
T04
X-037560Y+030490
X-036560Y+030490
X-035560Y+030490
X-034560Y+030490
X-033560Y+030490
X-032560Y+030490
X-031560Y+030490
X-030560Y+030490
X-029560Y+030490
X-028560Y+030490
X-027560Y+030490
X-026560Y+030490
X-025560Y+030490
X-024560Y+030490
X-024560Y+036490
X-025560Y+036490
X-026560Y+036490
X-027560Y+036490
X-028560Y+036490
X-029560Y+036490
X-030560Y+036490
X-031560Y+036490
X-032560Y+036490
X-033560Y+036490
X-034560Y+036490
X-035560Y+036490
X-036560Y+036490
X-037560Y+036490
X-014590Y+030810
X-013590Y+030810
X-012590Y+030810
X-011590Y+030810
X-011590Y+033810
X-012590Y+033810
X-013590Y+033810
X-014590Y+033810
X-021260Y+034680
X-020010Y+034680
X-008390Y+035840
X-008390Y+034590
X-008440Y+031870
X-008440Y+030620
T05
X-022504Y+019291
X-020354Y+019291
X-018204Y+019291
X-030142Y+019291
X-027992Y+019291
X-025842Y+019291
X-012779Y+019291
X-010629Y+019291
X-008479Y+019291
T06
X-028080Y+028230
X-030080Y+028230
X-034616Y+024409
X-039616Y+024409
X-045364Y+023346
X-045364Y+018346
X-045364Y+030157
X-045364Y+025157
X-008604Y+026983
X-013604Y+026983
X-016844Y+034107
X-016844Y+029107
T07
X-041655Y+026456
X-040655Y+026456
X-039655Y+026456
X-041640Y+022047
X-040640Y+022047
X-039640Y+022047
X-049760Y+029430
X-048760Y+029430
X-047760Y+029430
X-019220Y+037380
X-020220Y+037380
X-021220Y+037380
T08
X-024212Y+007751
X-024212Y+004011
X-035629Y+007874
X-035629Y+004133
T09
X+007086Y+030708
X+007086Y+032874
X-000787Y+031889
X-000787Y+035826
X-000787Y+027952
M30

View File

@@ -1,148 +0,0 @@
import sys
from PyQt5 import QtGui, QtWidgets
from PyQt5 import QtCore
from PyQt5.QtCore import Qt
class TitleBar(QtWidgets.QDialog):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.setWindowFlags(Qt.FramelessWindowHint)
css = """
QWidget{
Background: #AA00AA;
color:white;
font:12px bold;
font-weight:bold;
border-radius: 1px;
height: 11px;
}
QDialog{
Background-image:url('img/titlebar bg.png');
font-size:12px;
color: black;
}
QToolButton{
Background:#AA00AA;
font-size:11px;
}
QToolButton:hover{
Background: #FF00FF;
font-size:11px;
}
"""
self.setAutoFillBackground(True)
self.setBackgroundRole(QtGui.QPalette.Highlight)
self.setStyleSheet(css)
self.minimize=QtWidgets.QToolButton(self)
self.minimize.setIcon(QtGui.QIcon('img/min.png'))
self.maximize=QtWidgets.QToolButton(self);
self.maximize.setIcon(QtGui.QIcon('img/max.png'))
close=QtWidgets.QToolButton(self)
close.setIcon(QtGui.QIcon('img/close.png'))
self.minimize.setMinimumHeight(10)
close.setMinimumHeight(10)
self.maximize.setMinimumHeight(10)
label=QtWidgets.QLabel(self)
label.setText("Abracadabra")
self.setWindowTitle("Alhambra")
hbox=QtWidgets.QHBoxLayout(self)
hbox.addWidget(label)
hbox.addWidget(self.minimize)
hbox.addWidget(self.maximize)
hbox.addWidget(close)
hbox.insertStretch(1,500)
hbox.setSpacing(0)
self.setSizePolicy(QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Fixed)
self.maxNormal=False
close.clicked.connect(self.close)
self.minimize.clicked.connect(self.showSmall)
self.maximize.clicked.connect(self.showMaxRestore)
def showSmall(self):
box.showMinimized()
def showMaxRestore(self):
if(self.maxNormal):
box.showNormal()
self.maxNormal= False
self.maximize.setIcon(QtGui.QIcon('img/max.png'))
print(1)
else:
box.showMaximized()
self.maxNormal= True
print(2)
self.maximize.setIcon(QtGui.QIcon('img/max2.png'))
def close(self):
box.close()
def mousePressEvent(self,event):
if event.button() == Qt.LeftButton:
box.moving = True; box.offset = event.pos()
def mouseMoveEvent(self,event):
if box.moving: box.move(event.globalPos()-box.offset)
class Frame(QtWidgets.QFrame):
def __init__(self, parent=None):
QtWidgets.QFrame.__init__(self, parent)
self.m_mouse_down= False
self.setFrameShape(QtWidgets.QFrame.StyledPanel)
css = """
QFrame{
Background: #D700D7;
color:white;
font:13px ;
font-weight:bold;
}
"""
self.setStyleSheet(css)
self.setWindowFlags(Qt.FramelessWindowHint)
self.setMouseTracking(True)
self.m_titleBar= TitleBar(self)
self.m_content= QtWidgets.QWidget(self)
vbox=QtWidgets.QVBoxLayout(self)
vbox.addWidget(self.m_titleBar)
vbox.setContentsMargins(0, 0, 0, 0)
vbox.setSpacing(0)
layout=QtWidgets.QVBoxLayout(self)
layout.addWidget(self.m_content)
layout.setContentsMargins(5, 5, 5, 5)
layout.setSpacing(0)
vbox.addLayout(layout)
# Allows you to access the content area of the frame
# where widgets and layouts can be added
def contentWidget(self):
return self.m_content
def titleBar(self):
return self.m_titleBar
def mousePressEvent(self,event):
self.m_old_pos = event.pos()
self.m_mouse_down = event.button()== Qt.LeftButton
def mouseMoveEvent(self,event):
x=event.x()
y=event.y()
def mouseReleaseEvent(self,event):
m_mouse_down=False
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
box = Frame()
box.move(60,60)
l = QtWidgets.QVBoxLayout(box.contentWidget())
l.setContentsMargins(0, 0,0 ,0)
edit = QtWidgets.QLabel("""I would've did anything for you to show you how much I adored you
But it's over now, it's too late to save our loveJust promise me you'll think of me
Every time you look up in the sky and see a star 'cuz I'm your star.""")
l.addWidget(edit)
box.show()
app.exec_()

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +0,0 @@
G04 MADE WITH FRITZING*
G04 WWW.FRITZING.ORG*
G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
%ASAXBY*%
%FSLAX23Y23*%
%MOIN*%
%OFA0B0*%
%SFA1.0B1.0*%
%ADD10R,1.771650X1.181100*%
%ADD11C,0.008000*%
%ADD10C,0.008*%
%LNCONTOUR*%
G90*
G70*
G54D10*
G54D11*
X4Y1177D02*
X1768Y1177D01*
X1768Y4D01*
X4Y4D01*
X4Y1177D01*
D02*
G04 End of contour*
M02*

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +0,0 @@
G04 MADE WITH FRITZING*
G04 WWW.FRITZING.ORG*
G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
%ASAXBY*%
%FSLAX23Y23*%
%MOIN*%
%OFA0B0*%
%SFA1.0B1.0*%
%ADD10C,0.075000*%
%ADD11C,0.099055*%
%ADD12C,0.078740*%
%ADD13R,0.075000X0.075000*%
%ADD14C,0.024000*%
%ADD15C,0.020000*%
%LNCOPPER1*%
G90*
G70*
G54D10*
X1149Y872D03*
X1349Y872D03*
X749Y722D03*
X749Y522D03*
X1149Y522D03*
X1449Y522D03*
X1149Y422D03*
X1449Y422D03*
X1149Y322D03*
X1449Y322D03*
X1149Y222D03*
X1449Y222D03*
X949Y472D03*
X949Y72D03*
G54D11*
X749Y972D03*
X599Y972D03*
X349Y322D03*
X349Y472D03*
X349Y672D03*
X349Y822D03*
G54D10*
X699Y122D03*
X699Y322D03*
G54D12*
X699Y222D03*
X949Y972D03*
X749Y622D03*
X1049Y222D03*
X1249Y872D03*
G54D13*
X1149Y872D03*
X1149Y522D03*
G54D14*
X952Y946D02*
X1045Y249D01*
G54D15*
X776Y695D02*
X721Y695D01*
X721Y750D01*
X776Y750D01*
X776Y695D01*
D02*
X671Y150D02*
X726Y150D01*
X726Y95D01*
X671Y95D01*
X671Y150D01*
D02*
G04 End of Copper1*
M02*

View File

@@ -1,46 +0,0 @@
; NON-PLATED HOLES START AT T1
; THROUGH (PLATED) HOLES START AT T100
M48
INCH
T1C0.125984
T100C0.031496
T101C0.035000
T102C0.059055
%
T1
X001488Y010223
X001488Y001223
X016488Y001223
X016488Y010223
T100
X009488Y009723
X007488Y006223
X012488Y008723
X010488Y002223
X006988Y002223
T101
X014488Y004223
X006988Y003223
X013488Y008723
X011488Y008723
X007488Y005223
X014488Y003223
X014488Y002223
X011488Y005223
X009488Y000723
X011488Y004223
X006988Y001223
X009488Y004723
X007488Y007223
X011488Y003223
X014488Y005223
X011488Y002223
T102
X003488Y008223
X003488Y004723
X007488Y009723
X003488Y006723
X005988Y009723
X003488Y003223
T00
M30

View File

@@ -1,54 +0,0 @@
G04 MADE WITH FRITZING*
G04 WWW.FRITZING.ORG*
G04 DOUBLE SIDED*
G04 HOLES PLATED*
G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
%ASAXBY*%
%FSLAX23Y23*%
%MOIN*%
%OFA0B0*%
%SFA1.0B1.0*%
%ADD10R,0.047244X0.078740*%
%ADD11C,0.024000*%
%LNCOPPER1*%
G90*
G70*
G54D10*
X2940Y1051D03*
X2940Y941D03*
G54D11*
X2438Y839D02*
X2440Y1023D01*
D02*
X2940Y907D02*
X2941Y839D01*
D02*
X2941Y839D02*
X2438Y839D01*
D02*
X2941Y1239D02*
X2940Y1085D01*
D02*
X2438Y1239D02*
X2941Y1239D01*
D02*
X2440Y1126D02*
X2438Y1239D01*
G36*
X2418Y1064D02*
X2461Y1064D01*
X2461Y1017D01*
X2418Y1017D01*
X2418Y1064D01*
G37*
D02*
G36*
X2418Y1131D02*
X2461Y1131D01*
X2461Y1084D01*
X2418Y1084D01*
X2418Y1131D01*
G37*
D02*
G04 End of Copper1*
M02*

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +0,0 @@
# This script is for profiling Gerber.parse_lines() line by line.
# Run kernprof -l -v gerber_parsing_line_profile_1.py
import sys
sys.path.append('../../')
from flatcamParsers.ParseGerber import *
log = logging.getLogger('base2')
log.setLevel(logging.WARNING)
g = Gerber()
g.parse_file("gerber1.gbr")

View File

@@ -1,17 +0,0 @@
import cProfile
import pstats
import sys
sys.path.append('../../')
from flatcamParsers.ParseGerber import *
log = logging.getLogger('base2')
log.setLevel(logging.WARNING)
g = Gerber()
#cProfile.run('g.parse_file("gerber1.gbr")', 'gerber1_profile', sort='cumtime')
cProfile.run('g.parse_file("/home/jpcaram/flatcam_test_files/Gerbers/AVR_Transistor_Tester_silkscreen_top.GTO")',
'gerber1_profile', sort='cumtime')
p = pstats.Stats('gerber1_profile')
p.strip_dirs().sort_stats('cumulative').print_stats(.1)

View File

@@ -1,70 +0,0 @@
import sys
from PyQt5.Qt import *
from PyQt5 import QtGui, QtWidgets
class MyPopup(QWidget):
def __init__(self):
QWidget.__init__(self)
lay = QtWidgets.QVBoxLayout()
self.setLayout(lay)
lay.setContentsMargins(0, 0, 0, 0)
le = QtWidgets.QLineEdit()
le.setText("Abracadabra")
le.setReadOnly(True)
# le.setStyleSheet("QLineEdit { qproperty-frame: false }")
le.setFrame(False)
le.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# lay.addStretch()
but = QtWidgets.QPushButton("OK")
hlay = QtWidgets.QHBoxLayout()
hlay.setContentsMargins(0, 5, 5, 5)
hlay.addStretch()
hlay.addWidget(but)
lay.addWidget(le)
lay.addLayout(hlay)
# def paintEvent(self, e):
# dc = QtGui.QPainter(self)
# dc.drawLine(0, 0, 100, 100)
# dc.drawLine(100, 0, 0, 100)
class MainWindow(QMainWindow):
def __init__(self, *args):
QtWidgets.QMainWindow.__init__(self, *args)
self.cw = QtWidgets.QWidget(self)
self.setCentralWidget(self.cw)
self.btn1 = QtWidgets.QPushButton("Click me", self.cw)
self.btn1.setGeometry(QRect(0, 0, 100, 30))
self.btn1.clicked.connect(self.doit)
self.w = None
def doit(self):
print("Opening a new popup window...")
self.w = MyPopup()
self.w.setGeometry(QRect(100, 100, 400, 200))
self.w.show()
class App(QApplication):
def __init__(self, *args):
QtWidgets.QApplication.__init__(self, *args)
self.main = MainWindow()
# self.lastWindowClosed.connect(self.byebye)
self.main.show()
def byebye(self):
self.exit(0)
def main(args):
global app
app = App(args)
app.exec_()
if __name__ == "__main__":
main(sys.argv)

View File

@@ -1,34 +0,0 @@
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class MyObj():
def __init__(self):
pass
def __del__(self):
print("##### Destroyed ######")
def parse():
o = MyObj()
raise Exception("Intentional Exception")
class Example(QtWidgets.QWidget):
def __init__(self):
super(Example, self).__init__()
qbtn = QtWidgets.QPushButton('Raise', self)
qbtn.clicked.connect(parse)
self.setWindowTitle('Quit button')
self.show()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

View File

@@ -1,8 +0,0 @@
import os
os.chdir('../')
from flatcamParsers.ParseGerber import *
g = Gerber()
g.parse_file(r'C:\Users\jpcaram\Dropbox\CNC\pcbcam\test_files\PlacaReles-F_Cu.gtl')

View File

@@ -1,49 +0,0 @@
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 05 13:30:47 2014
@author: jpcaram
"""
import os
os.chdir('../')
from flatcamParsers.ParseGerber import *
from flatcamParsers.ParseExcellon import *
from matplotlib import pyplot
# Gerber. To see if the Excellon is correct
project_dir = "tests/gerber_files"
gerber_filename = project_dir + "KiCad_Squarer-F_Cu.gtl"
g = Gerber()
g.parse_file(gerber_filename)
g.create_geometry()
excellon_filename = project_dir + "KiCad_Squarer.drl"
ex = Excellon()
ex.parse_file(excellon_filename)
ex.create_geometry()
#fig = Figure()
fig = pyplot.figure()
ax = fig.add_subplot(111)
ax.set_aspect(1)
# Plot gerber
for geo in g.solid_geometry:
x, y = geo.exterior.coords.xy
pyplot.plot(x, y, 'k-')
for ints in geo.interiors:
x, y = ints.coords.xy
ax.plot(x, y, 'k-')
# Plot excellon
for geo in ex.solid_geometry:
x, y = geo.exterior.coords.xy
pyplot.plot(x, y, 'r-')
for ints in geo.interiors:
x, y = ints.coords.xy
ax.plot(x, y, 'g-')
fig.show()

View File

@@ -1,37 +0,0 @@
from camlib import *
from shapely.geometry import LineString, LinearRing
s = FlatCAMRTreeStorage()
geoms = [
LinearRing(((0.5699056603773586, 0.7216037735849057),
(0.9885849056603774, 0.7216037735849057),
(0.9885849056603774, 0.6689622641509434),
(0.5699056603773586, 0.6689622641509434),
(0.5699056603773586, 0.7216037735849057))),
LineString(((0.8684952830188680, 0.6952830188679245),
(0.8680655198743615, 0.6865349890935113),
(0.8667803692948564, 0.6778712076279851),
(0.8646522079829676, 0.6693751114229638),
(0.8645044888670096, 0.6689622641509434))),
LineString(((0.9874952830188680, 0.6952830188679245),
(0.9864925023483531, 0.6748709493942936),
(0.9856160316877274, 0.6689622641509434))),
]
for geo in geoms:
s.insert(geo)
current_pt = (0, 0)
pt, geo = s.nearest(current_pt)
while geo is not None:
print((pt, geo))
print(("OBJECTS BEFORE:", s.objects))
#geo.coords = list(geo.coords[::-1])
s.remove(geo)
print(("OBJECTS AFTER:", s.objects))
current_pt = geo.coords[-1]
pt, geo = s.nearest(current_pt)

View File

@@ -1,48 +0,0 @@
from shapely.geometry import LineString, Polygon
from shapely.ops import unary_union
from matplotlib.pyplot import plot, subplot, show, axes
from matplotlib.axes import *
from camlib import *
def plotg2(geo, solid_poly=False, color="black", linestyle='solid'):
try:
for sub_geo in geo:
plotg2(sub_geo, solid_poly=solid_poly, color=color, linestyle=linestyle)
except TypeError:
if type(geo) == Polygon:
if solid_poly:
patch = PolygonPatch(geo,
#facecolor="#BBF268",
facecolor=color,
edgecolor="#006E20",
alpha=0.5,
zorder=2)
ax = subplot(111)
ax.add_patch(patch)
else:
x, y = geo.exterior.coords.xy
plot(x, y, color=color, linestyle=linestyle)
for ints in geo.interiors:
x, y = ints.coords.xy
plot(x, y, color=color, linestyle=linestyle)
if type(geo) == LineString or type(geo) == LinearRing:
x, y = geo.coords.xy
plot(x, y, color=color, linestyle=linestyle)
if type(geo) == Point:
x, y = geo.coords.xy
plot(x, y, 'o')
if __name__ == "__main__":
p = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]])
paths = [
LineString([[0.5, 2], [2, 4.5]]),
LineString([[2, 0.5], [4.5, 2]])
]
plotg2(p, solid_poly=True)
plotg2(paths, linestyle="dashed")
show()

View File

@@ -1,24 +0,0 @@
from rtree import index as rtindex
def pt2rect(pt):
return pt[0], pt[1], pt[0], pt[1]
pts = [(0.0, 0.0), (1.0, 1.0), (0.0, 1.0)]
p = rtindex.Property()
p.buffering_capacity = 1
p.dimension = 2
rt = rtindex.Index(properties=p)
#rt = rtindex.Index()
# If interleaved is True, the coordinates must be in
# the form [xmin, ymin, ..., kmin, xmax, ymax, ..., kmax].
print((rt.interleaved))
[rt.add(0, pt2rect(pt)) for pt in pts]
print([r.bbox for r in list(rt.nearest((0, 0), 10, True))])
for pt in pts:
rt.delete(0, pt2rect(pt))
print((pt2rect(pt), [r.bbox for r in list(rt.nearest((0, 0), 10, True))]))

View File

@@ -1,34 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE svg>
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In -->
<svg xmlns="http://www.w3.org/2000/svg" width="0.402778in" xml:space="preserve" xmlns:xml="http://www.w3.org/XML/1998/namespace" x="0px" version="1.2" y="0px" height="0.527778in" viewBox="0 0 29 38" baseProfile="tiny">
<g id="copper0">
<g id="copper1">
<rect x="1.362" y="2.091" fill="none" stroke="#F7BD13" stroke-width="1.224" width="4.104" height="4.104"/>
<circle fill="none" cx="3.362" cy="4.091" stroke="#F7BD13" id="connector1pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="3.362" cy="11.29" stroke="#F7BD13" id="connector2pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="3.362" cy="18.491" stroke="#F7BD13" id="connector3pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="3.362" cy="25.69" stroke="#F7BD13" id="connector4pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="3.365" cy="32.81" stroke="#F7BD13" id="connector5pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="25.001" cy="32.821" stroke="#F7BD13" id="connector6pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="24.999" cy="25.702" stroke="#F7BD13" id="connector7pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="24.999" cy="18.503" stroke="#F7BD13" id="connector8pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="24.999" cy="11.302" stroke="#F7BD13" id="connector9pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="25.029" cy="4.077" stroke="#F7BD13" id="connector10pin" r="2.052" stroke-width="1.224"/>
</g>
<circle fill="none" cx="3.362" cy="4.091" stroke="#F7BD13" id="connector1pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="3.362" cy="11.29" stroke="#F7BD13" id="connector2pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="3.362" cy="18.491" stroke="#F7BD13" id="connector3pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="3.362" cy="25.69" stroke="#F7BD13" id="connector4pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="3.365" cy="32.81" stroke="#F7BD13" id="connector5pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="25.001" cy="32.821" stroke="#F7BD13" id="connector6pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="24.999" cy="25.702" stroke="#F7BD13" id="connector7pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="24.999" cy="18.503" stroke="#F7BD13" id="connector8pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="24.999" cy="11.302" stroke="#F7BD13" id="connector9pin" r="2.052" stroke-width="1.224"/>
<circle fill="none" cx="25.029" cy="4.077" stroke="#F7BD13" id="connector10pin" r="2.052" stroke-width="1.224"/>
</g>
<g id="silkscreen">
<rect width="28.347" x="0.024" y="0.024" height="36.851" fill="none" stroke="#FFFFFF" stroke-width="0.7087"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,468 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="50.4px" height="122.448px" viewBox="0 0 50.4 122.448" enable-background="new 0 0 50.4 122.448" xml:space="preserve">
<desc>Fritzing footprint generated by brd2svg</desc>
<g id="silkscreen">
<path fill="none" stroke="#FFFFFF" stroke-width="0.576" d="M0.288,122.136h49.824V0.288H0.288V122.136"/>
<g>
<title>element:J1</title>
<g>
<title>package:HEAD15-NOSS</title>
</g>
</g>
<g>
<title>element:J2</title>
<g>
<title>package:HEAD15-NOSS-1</title>
</g>
</g>
<g>
<title>element:U2</title>
<g>
<title>package:SSOP28</title>
</g>
</g>
<g>
<title>element:U3</title>
<g>
<title>package:SOT223</title>
</g>
</g>
</g>
<g id="copper1">
<g id="copper0">
<circle id="connector16pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="10.8" r="1.908"/>
<rect x="1.692" y="8.892" fill="none" stroke="#F7BD13" stroke-width="1.224" width="3.814" height="3.816"/>
<circle id="connector17pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="18" r="1.908"/>
<circle id="connector18pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="25.2" r="1.908"/>
<circle id="connector19pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="32.4" r="1.908"/>
<circle id="connector20pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="39.6" r="1.908"/>
<circle id="connector21pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="46.8" r="1.908"/>
<circle id="connector22pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="54" r="1.908"/>
<circle id="connector23pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="61.2" r="1.908"/>
<circle id="connector24pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="68.4" r="1.908"/>
<circle id="connector25pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="75.6" r="1.908"/>
<circle id="connector26pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="82.8" r="1.908"/>
<circle id="connector27pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="90" r="1.908"/>
<circle id="connector28pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="97.2" r="1.908"/>
<circle id="connector29pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="104.4" r="1.908"/>
<circle id="connector30pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="3.6" cy="111.6" r="1.908"/>
<circle id="connector31pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="10.8" r="1.908"/>
<circle id="connector32pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="18" r="1.908"/>
<circle id="connector33pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="25.2" r="1.908"/>
<circle id="connector34pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="32.4" r="1.908"/>
<circle id="connector35pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="39.6" r="1.908"/>
<circle id="connector36pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="46.8" r="1.908"/>
<circle id="connector37pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="54" r="1.908"/>
<circle id="connector38pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="61.2" r="1.908"/>
<circle id="connector39pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="68.4" r="1.908"/>
<circle id="connector40pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="75.6" r="1.908"/>
<circle id="connector41pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="82.8" r="1.908"/>
<circle id="connector42pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="90" r="1.908"/>
<circle id="connector43pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="97.2" r="1.908"/>
<circle id="connector44pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="104.4" r="1.908"/>
<circle id="connector45pad" fill="none" stroke="#F7BD13" stroke-width="1.224" cx="46.8" cy="111.6" r="1.908"/>
</g>
</g>
<g>
<title>layer 21</title>
<g>
<title>text:TX1</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 13.68)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -6.713867e-004 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">TX1</text>
</g>
</g>
</g>
<g>
<title>text:RX0</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 20.88)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 1.220703e-004 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">RX0</text>
</g>
</g>
</g>
<g>
<title>text:RST</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 28.008)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -7.934570e-004 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">RST</text>
</g>
</g>
</g>
<g>
<title>text:GND</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 35.208)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 0 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">GND</text>
</g>
</g>
</g>
<g>
<title>text:D2</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 41.544)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 6.103516e-005 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D2</text>
</g>
</g>
</g>
<g>
<title>text:D3</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 48.6)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -5.798340e-004 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D3</text>
</g>
</g>
</g>
<g>
<title>text:D4</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 55.872)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -6.103516e-005 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D4</text>
</g>
</g>
</g>
<g>
<title>text:D5</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 62.928)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -7.019043e-004 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D5</text>
</g>
</g>
</g>
<g>
<title>text:D6</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 70.272)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -4.577637e-004 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D6</text>
</g>
</g>
</g>
<g>
<title>text:D7</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 77.544)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 6.103516e-005 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D7</text>
</g>
</g>
</g>
<g>
<title>text:D8</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 84.6)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -5.798340e-004 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D8</text>
</g>
</g>
</g>
<g>
<title>text:D9</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 91.872)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -6.103516e-005 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D9</text>
</g>
</g>
</g>
<g>
<title>text:D10</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 100.224)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -0.0016 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D10</text>
</g>
</g>
</g>
<g>
<title>text:D11</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 107.352)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -5.493164e-004 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D11</text>
</g>
</g>
</g>
<g>
<title>text:D12</title>
<g transform="matrix(1, 0, 0, 1, 9.216, 114.552)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -0.0017 -4.272461e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D12</text>
</g>
</g>
</g>
<g>
<title>text:D13</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 114.552)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -0.0017 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">D13</text>
</g>
</g>
</g>
<g>
<title>text:3V3</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 107.28)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -2.746582e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">3V3</text>
</g>
</g>
</g>
<g>
<title>text:REF</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 100.152)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -0.0013 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">REF</text>
</g>
</g>
</g>
<g>
<title>text:A0</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 91.944)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -3.356934e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">A0</text>
</g>
</g>
</g>
<g>
<title>text:A1</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 84.672)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -8.544922e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">A1</text>
</g>
</g>
</g>
<g>
<title>text:A2</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 77.544)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 6.103516e-005 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">A2</text>
</g>
</g>
</g>
<g>
<title>text:A3</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 70.344)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -7.324219e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">A3</text>
</g>
</g>
</g>
<g>
<title>text:A4</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 63.216)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 1.831055e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">A4</text>
</g>
</g>
</g>
<g>
<title>text:A5</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 55.944)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -3.356934e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">A5</text>
</g>
</g>
</g>
<g>
<title>text:A6</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 48.744)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -0.0011 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">A6</text>
</g>
</g>
</g>
<g>
<title>text:A7</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 41.616)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -2.136230e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">A7</text>
</g>
</g>
</g>
<g>
<title>text:5V</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 34.416)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -9.765625e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">5V</text>
</g>
</g>
</g>
<g>
<title>text:RST</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 27.216)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 1.831055e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">RST</text>
</g>
</g>
</g>
<g>
<title>text:GND</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 19.8)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 1.831055e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">GND</text>
</g>
</g>
</g>
<g>
<title>text:VIN</title>
<g transform="matrix(1, 0, 0, 1, 43.488, 12.672)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -8.544922e-004 -9.460449e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="2.6726">VIN</text>
</g>
</g>
</g>
<g>
<title>text:*</title>
<g transform="matrix(1, 0, 0, 1, 7.056, 92.664)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -0.001 -5.798340e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="1.6704">*</text>
</g>
</g>
</g>
<g>
<title>text:*</title>
<g transform="matrix(1, 0, 0, 1, 7.056, 99.936)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -5.187988e-004 -5.798340e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="1.6704">*</text>
</g>
</g>
</g>
<g>
<title>text:*</title>
<g transform="matrix(1, 0, 0, 1, 7.056, 107.064)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -0.0014 -5.798340e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="1.6704">*</text>
</g>
</g>
</g>
<g>
<title>text:*</title>
<g transform="matrix(1, 0, 0, 1, 7.056, 71.064)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 -0.0014 -5.798340e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="1.6704">*</text>
</g>
</g>
</g>
<g>
<title>text:*</title>
<g transform="matrix(1, 0, 0, 1, 7.056, 63.792)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 0 -5.798340e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="1.6704">*</text>
</g>
</g>
</g>
<g>
<title>text:*</title>
<g transform="matrix(1, 0, 0, 1, 7.056, 49.464)">
<g transform="rotate(270)">
<text transform="matrix(1 0 0 1 1.220703e-004 -5.798340e-004)" fill="#FFFFFF" font-family="'OCRA'" font-size="1.6704">*</text>
</g>
</g>
</g>
<g>
<title>element:C1</title>
<g>
<title>package:CAP0805-NP</title>
</g>
</g>
<g>
<title>element:C2</title>
<g>
<title>package:TAN-A</title>
</g>
</g>
<g>
<title>element:C3</title>
<g>
<title>package:CAP0805-NP</title>
</g>
</g>
<g>
<title>element:C4</title>
<g>
<title>package:CAP0805-NP</title>
</g>
</g>
<g>
<title>element:C7</title>
<g>
<title>package:CAP0805-NP</title>
</g>
</g>
<g>
<title>element:C8</title>
<g>
<title>package:TAN-A</title>
</g>
</g>
<g>
<title>element:C9</title>
<g>
<title>package:CAP0805-NP</title>
</g>
</g>
<g>
<title>element:D1</title>
<g>
<title>package:SOD-123</title>
</g>
</g>
<g>
<title>element:J1</title>
<g>
<title>package:HEAD15-NOSS</title>
</g>
</g>
<g>
<title>element:J2</title>
<g>
<title>package:HEAD15-NOSS-1</title>
</g>
</g>
<g>
<title>element:RP1</title>
<g>
<title>package:RES4NT</title>
</g>
</g>
<g>
<title>element:RP2</title>
<g>
<title>package:RES4NT</title>
</g>
</g>
<g>
<title>element:U$4</title>
<g>
<title>package:FIDUCIAL-1X2</title>
</g>
</g>
<g>
<title>element:U$37</title>
<g>
<title>package:FIDUCIAL-1X2</title>
</g>
</g>
<g>
<title>element:U$53</title>
<g>
<title>package:FIDUCIAL-1X2</title>
</g>
</g>
<g>
<title>element:U$54</title>
<g>
<title>package:FIDUCIAL-1X2</title>
</g>
</g>
<g>
<title>element:U2</title>
<g>
<title>package:SSOP28</title>
</g>
</g>
<g>
<title>element:U3</title>
<g>
<title>package:SOT223</title>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,126 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="drawing.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="436.65332"
inkscape:cy="798.58794"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="968"
inkscape:window-height="759"
inkscape:window-x="1949"
inkscape:window-y="142"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
sodipodi:type="arc"
style="fill:none;stroke:#999999;stroke-width:0.69999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path2985"
sodipodi:cx="210.11172"
sodipodi:cy="201.81374"
sodipodi:rx="70.710678"
sodipodi:ry="70.710678"
d="m 280.8224,201.81374 a 70.710678,70.710678 0 1 1 -141.42135,0 70.710678,70.710678 0 1 1 141.42135,0 z" />
<rect
style="fill:none;stroke:#999999;stroke-width:0.69999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect2987"
width="82.832512"
height="72.73098"
x="343.45187"
y="127.06245" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 261.70701,300.10548 137.14286,-68.57143 -13.57143,104.28572 105.71429,2.85714 -232.14286,29.28572 z"
id="path2991"
inkscape:connector-curvature="0" />
<g
id="g3018"
transform="translate(-37.142857,-103.57143)">
<rect
y="222.01678"
x="508.10672"
height="72.73098"
width="82.832512"
id="rect2987-8"
style="fill:none;stroke:#999999;stroke-width:0.69999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="177.86595"
x="534.49329"
height="72.73098"
width="82.832512"
id="rect2987-4"
style="fill:none;stroke:#999999;stroke-width:0.69999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
</g>
<path
style="fill:none;stroke:#999999;stroke-width:0.69999999;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
d="M 550.71875 258.84375 L 550.71875 286 L 513.59375 286 L 513.59375 358.71875 L 596.40625 358.71875 L 596.40625 331.59375 L 633.5625 331.59375 L 633.5625 258.84375 L 550.71875 258.84375 z "
id="rect2987-5" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 276.42857,98.076465 430.71429,83.076464"
id="path3037"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 164.28571,391.64789 c 12.85715,-54.28571 55.00001,21.42858 84.28572,22.85715 29.28571,1.42857 30.71429,-14.28572 30.71429,-14.28572"
id="path3039"
inkscape:connector-curvature="0" />
<g
id="g3018-3"
transform="matrix(0.54511991,0,0,0.54511991,308.96645,74.66094)">
<rect
y="222.01678"
x="508.10672"
height="72.73098"
width="82.832512"
id="rect2987-8-5"
style="fill:none;stroke:#999999;stroke-width:1.28412116;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
<rect
y="177.86595"
x="534.49329"
height="72.73098"
width="82.832512"
id="rect2987-4-6"
style="fill:none;stroke:#999999;stroke-width:1.28412116;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1 Basic//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd'><svg baseProfile="basic" height="0.59in" id="svg" version="1.1" viewBox="0 0 67.502 42.52" width="0.94in" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px">
<g id="breadboard">
<rect fill="none" height="5.372" id="connector0pin" width="2.16" x="60.644" y="32.178"/>
<rect fill="none" height="5.309" id="connector1pin" width="2.16" x="53.496" y="5.002"/>
<rect fill="none" height="5.309" id="connector2pin" width="2.16" x="60.644" y="5.002"/>
<rect fill="none" height="5.372" id="connector3pin" width="2.159" x="53.506" y="32.178"/>
<rect fill="none" height="5.372" id="connector5pin" width="2.159" x="53.506" y="32.178"/>
<rect fill="none" height="5.372" id="connector4pin" width="2.159" x="53.506" y="32.178"/>
<rect fill="none" height="3.714" id="connector0terminal" width="2.16" x="60.644" y="33.836"/>
<rect fill="none" height="3.669" id="connector1terminal" width="2.16" x="53.496" y="5.002"/>
<rect fill="none" height="3.669" id="connector2terminal" width="2.16" x="60.644" y="5.002"/>
<rect fill="none" height="3.714" id="connector3terminal" width="2.159" x="53.506" y="33.836"/>
<rect fill="none" height="3.714" id="connector5terminal" width="2.159" x="53.506" y="33.836"/>
<rect fill="none" height="3.714" id="connector4terminal" width="2.159" x="53.506" y="33.836"/>
<g>
<polygon fill="#1F7A34" points="49.528,34.417 67.502,34.417 67.502,8.102 49.528,8.102 49.528,0 20.776,0 20.776,42.52 49.528,42.52 "/>
</g>
<g>
<g>
<path d="M30.783,4.96c0-1.988-1.609-3.598-3.598-3.598c-1.985,0-3.598,1.609-3.598,3.598 c0,1.985,1.612,3.598,3.598,3.598C29.173,8.558,30.783,6.945,30.783,4.96z" fill="#9A916C"/>
</g>
<g>
<circle cx="27.182" cy="4.96" fill="#3A3A3A" r="2.708"/>
</g>
</g>
<g>
<g>
<path d="M30.783,37.56c0-1.988-1.609-3.598-3.598-3.598c-1.985,0-3.598,1.609-3.598,3.598 c0,1.985,1.612,3.598,3.598,3.598C29.173,41.157,30.783,39.545,30.783,37.56z" fill="#9A916C"/>
</g>
<g>
<circle cx="27.182" cy="37.56" fill="#3A3A3A" r="2.708"/>
</g>
</g>
<g>
<rect fill="#898989" height="34.016" width="45.355" x="0.001" y="4.252"/>
</g>
<g>
<rect fill="#DDDDDD" height="0.743" width="45.355" x="0.001" y="4.252"/>
</g>
<g>
<rect fill="#C6C6C6" height="0.889" width="45.355" x="0.001" y="4.991"/>
</g>
<g>
<rect fill="#ADADAD" height="31.342" width="45.356" y="5.88"/>
</g>
<g>
<line fill="#919191" stroke="#4D4D4D" stroke-width="0.1" x1="34.173" x2="34.173" y1="4.252" y2="38.268"/>
</g>
<g>
<rect fill="#8C8C8C" height="5.349" width="4.667" x="52.252" y="4.961"/>
</g>
<g>
<rect fill="#8C8C8C" height="5.349" width="4.668" x="59.418" y="4.961"/>
</g>
<g>
<rect fill="#8C8C8C" height="5.349" width="4.667" x="52.252" y="32.177"/>
</g>
<g>
<rect fill="#8C8C8C" height="5.349" width="4.668" x="59.418" y="32.177"/>
</g>
<g>
<path d="M30.074,21.386l-2.64-1.524v1.134H13.468c0.515-0.416,1.008-0.965,1.493-1.505 c0.802-0.894,1.631-1.819,2.338-1.819h2.277c0.141,0.521,0.597,0.913,1.163,0.913c0.677,0,1.226-0.548,1.226-1.225 s-0.549-1.226-1.226-1.226c-0.566,0-1.022,0.392-1.163,0.914h-2.277c-0.985,0-1.868,0.984-2.803,2.026 c-0.744,0.83-1.509,1.675-2.255,1.922h-1.82c-0.185-1.02-1.073-1.794-2.145-1.794c-1.206,0-2.184,0.978-2.184,2.184 c0,1.207,0.978,2.184,2.184,2.184c1.072,0,1.96-0.774,2.145-1.794h5.196c0.746,0.247,1.511,1.093,2.254,1.922 c0.934,1.043,1.817,2.026,2.802,2.026h2.142v0.985h2.595v-2.595h-2.595v0.985h-2.142c-0.707,0-1.536-0.925-2.337-1.818 c-0.485-0.541-0.978-1.09-1.493-1.506h10.592v1.134L30.074,21.386z" fill="#4D4D4D"/>
</g>
<g>
<polyline fill="none" points="54.586,10.31 54.586,17.006 45.357,17.006 " stroke="#8C8C8C" stroke-width="1"/>
</g>
<g>
<polyline fill="none" points="61.732,10.31 61.732,19.841 45.357,19.841 " stroke="#8C8C8C" stroke-width="1"/>
</g>
<g>
<polyline fill="none" points="54.586,32.177 54.586,25.479 45.357,25.479 " stroke="#8C8C8C" stroke-width="1"/>
</g>
<g>
<polyline fill="none" points="61.732,32.177 61.732,22.646 45.357,22.646 " stroke="#8C8C8C" stroke-width="1"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,101 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="50mm"
height="50mm"
viewBox="0 0 50 50"
version="1.1"
id="svg8"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="use.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.4679048"
inkscape:cx="113.26276"
inkscape:cy="109.86475"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3834"
inkscape:window-height="2095"
inkscape:window-x="0"
inkscape:window-y="28"
inkscape:window-maximized="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-247)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 6.2421073,283.98351 c -2.4960796,-5.97466 14.6658087,-0.0283 2.7443869,-28.40936 -2.6185936,-6.23403 13.3146118,1.40862 15.4980508,1.40862"
id="path815"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc" />
<use
x="0"
y="0"
xlink:href="#path815"
id="use817"
transform="matrix(-1,0,0,1,48.96909,0)"
width="100%"
height="100%" />
<rect
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
id="rect942"
width="4.3065705"
height="4.7904549"
x="13.742314"
y="288.14493" />
<use
x="0"
y="0"
xlink:href="#rect942"
id="use944"
transform="matrix(2.4752181,0,0,1.0534789,-4.8199296,-20.27984)"
width="100%"
height="100%" />
<circle
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
id="path948"
cx="18.823099"
cy="275.70914"
r="4.5485125" />
<use
x="0"
y="0"
xlink:href="#path948"
id="use950"
transform="translate(10.50029,-10.984174)"
width="100%"
height="100%" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,331 +0,0 @@
import unittest
from flatcamParsers.ParseExcellon import Excellon
from flatcamParsers.ParseGerber import Gerber
class ExcellonNumberParseTestInch(unittest.TestCase):
# Inch base format: 00.0000
# LEADING ZEROS
# With leading zeros, when you type in a coordinate,
# the leading zeros must always be included. Trailing zeros
# are unneeded and may be left off. The CNC-7 will automatically add them.
# TRAILING ZEROS
# You must show all zeros to the right of the number and can omit
# all zeros to the left of the number. The CNC-7 will count the number
# of digits you typed and automatically fill in the missing zeros.
def test_inch_leading_6digit(self):
excellon = Excellon()
self.assertEqual(excellon.zeros, "L")
self.assertEqual(excellon.parse_number("123456"), 12.3456)
def test_inch_leading_5digit(self):
excellon = Excellon()
self.assertEqual(excellon.parse_number("12345"), 12.345)
def test_inch_leading_15digit(self):
excellon = Excellon()
self.assertEqual(excellon.parse_number("012345"), 1.2345)
def test_inch_leading_51digit(self):
excellon = Excellon()
self.assertEqual(excellon.parse_number("123450"), 12.345)
def test_inch_trailing_6digit(self):
excellon = Excellon()
excellon.zeros = "T"
self.assertEqual(excellon.parse_number("123456"), 12.3456)
def test_inch_trailing_5digit(self):
excellon = Excellon()
excellon.zeros = "T"
self.assertEqual(excellon.parse_number("12345"), 1.2345)
def test_inch_trailing_15digit(self):
excellon = Excellon()
excellon.zeros = "T"
self.assertEqual(excellon.parse_number("012345"), 1.2345)
def test_inch_trailing_51digit(self):
excellon = Excellon()
excellon.zeros = "T"
self.assertEqual(excellon.parse_number("123450"), 12.345)
class ExcellonNumberParseTestMetric(unittest.TestCase):
# Metric base format: 000.000
# LEADING ZEROS
# With leading zeros, when you type in a coordinate,
# the leading zeros must always be included. Trailing zeros
# are unneeded and may be left off. The CNC-7 will automatically add them.
# TRAILING ZEROS
# You must show all zeros to the right of the number and can omit
# all zeros to the left of the number. The CNC-7 will count the number
# of digits you typed and automatically fill in the missing zeros.
def test_inch_leading_6digit(self):
excellon = Excellon()
excellon.units = "mm"
self.assertEqual(excellon.parse_number("123456"), 123.456)
def test_inch_leading_5digit(self):
excellon = Excellon()
excellon.units = "mm"
self.assertEqual(excellon.parse_number("12345"), 123.45)
def test_inch_leading_15digit(self):
excellon = Excellon()
excellon.units = "mm"
self.assertEqual(excellon.parse_number("012345"), 12.345)
def test_inch_leading_51digit(self):
excellon = Excellon()
excellon.units = "mm"
self.assertEqual(excellon.parse_number("123450"), 123.45)
def test_inch_trailing_6digit(self):
excellon = Excellon()
excellon.units = "mm"
excellon.zeros = "T"
self.assertEqual(excellon.parse_number("123456"), 123.456)
def test_inch_trailing_5digit(self):
excellon = Excellon()
excellon.units = "mm"
excellon.zeros = "T"
self.assertEqual(excellon.parse_number("12345"), 12.345)
def test_inch_trailing_15digit(self):
excellon = Excellon()
excellon.units = "mm"
excellon.zeros = "T"
self.assertEqual(excellon.parse_number("012345"), 12.345)
def test_inch_trailing_51digit(self):
excellon = Excellon()
excellon.units = "mm"
excellon.zeros = "T"
self.assertEqual(excellon.parse_number("123450"), 123.45)
class ExcellonFormatM72Test(unittest.TestCase):
def setUp(self):
self.excellon = Excellon()
code = """
M48
M72
T1C.02362F197S550
T2C.03543F197S550
M95
T1
X9000Y11750
X30250Y10500
"""
code = code.split('\n')
self.excellon.parse_lines(code)
def test_format(self):
self.assertEqual(self.excellon.units.lower(), "in")
self.assertEqual(self.excellon.zeros, "L")
def test_coords(self):
# For X9000 add the missing 00 on the right. Then divide by 10000.
self.assertEqual(self.excellon.drills[0]["point"].coords[0], (90.0, 11.75))
self.assertEqual(self.excellon.drills[1]["point"].coords[0], (30.25, 10.5))
class ExcellonFormatM71Test(unittest.TestCase):
def setUp(self):
self.excellon = Excellon()
code = """
M48
M71
T1C.02362F197S550
T2C.03543F197S550
M95
T1
X9000Y11750
X30250Y10500
"""
code = code.split('\n')
self.excellon.parse_lines(code)
def test_format(self):
self.assertEqual(self.excellon.units.lower(), "mm")
self.assertEqual(self.excellon.zeros, "L")
def test_coords(self):
# For X9000 add the missing 00 on the right. Then divide by 10000.
self.assertEqual(self.excellon.drills[0]["point"].coords[0], (900.0, 117.5))
self.assertEqual(self.excellon.drills[1]["point"].coords[0], (302.5, 105.0))
class ExcellonFormatINCHLZTest(unittest.TestCase):
def setUp(self):
self.excellon = Excellon()
code = """
M48
INCH,LZ
T1C.02362F197S550
T2C.03543F197S550
M95
T1
X9000Y11750
X30250Y10500
"""
code = code.split('\n')
self.excellon.parse_lines(code)
def test_format(self):
self.assertEqual(self.excellon.units.lower(), "in")
self.assertEqual(self.excellon.zeros, "L")
def test_coords(self):
# For X9000 add the missing 00 on the right. Then divide by 10000.
self.assertEqual(self.excellon.drills[0]["point"].coords[0], (90.0, 11.75))
self.assertEqual(self.excellon.drills[1]["point"].coords[0], (30.25, 10.5))
class ExcellonFormatINCHTest(unittest.TestCase):
def setUp(self):
self.excellon = Excellon()
code = """
M48
INCH,LZ
T1C.02362F197S550
T2C.03543F197S550
M95
T1
X9000Y11750
X30250Y10500
"""
code = code.split('\n')
self.excellon.parse_lines(code)
def test_format(self):
self.assertEqual(self.excellon.units.lower(), "in")
self.assertEqual(self.excellon.zeros, "L")
def test_coords(self):
# For X9000 add the missing 00 on the right. Then divide by 10000.
self.assertEqual(self.excellon.drills[0]["point"].coords[0], (90.0, 11.75))
self.assertEqual(self.excellon.drills[1]["point"].coords[0], (30.25, 10.5))
class ExcellonFormatINCHTZTest(unittest.TestCase):
def setUp(self):
self.excellon = Excellon()
code = """
M48
INCH,TZ
T1C.02362F197S550
T2C.03543F197S550
M95
T1
X9000Y11750
X30250Y10500
"""
code = code.split('\n')
self.excellon.parse_lines(code)
def test_format(self):
self.assertEqual(self.excellon.units.lower(), "in")
self.assertEqual(self.excellon.zeros, "T")
def test_coords(self):
# For X9000 add the missing 00 on the right. Then divide by 10000.
self.assertEqual(self.excellon.drills[0]["point"].coords[0], (0.9, 1.175))
self.assertEqual(self.excellon.drills[1]["point"].coords[0], (3.025, 1.05))
class ExcellonFormatMETRICLZTest(unittest.TestCase):
def setUp(self):
self.excellon = Excellon()
code = """
M48
METRIC,LZ
T1C.02362F197S550
T2C.03543F197S550
M95
T1
X9000Y11750
X30250Y10500
"""
code = code.split('\n')
self.excellon.parse_lines(code)
def test_format(self):
self.assertEqual(self.excellon.units.lower(), "mm")
self.assertEqual(self.excellon.zeros, "L")
def test_coords(self):
# For X9000 add the missing 00 on the right. Then divide by 10000.
self.assertEqual(self.excellon.drills[0]["point"].coords[0], (900.0, 117.5))
self.assertEqual(self.excellon.drills[1]["point"].coords[0], (302.5, 105.0))
class ExcellonFormatMETRICTest(unittest.TestCase):
def setUp(self):
self.excellon = Excellon()
code = """
M48
METRIC,LZ
T1C.02362F197S550
T2C.03543F197S550
M95
T1
X9000Y11750
X30250Y10500
"""
code = code.split('\n')
self.excellon.parse_lines(code)
def test_format(self):
self.assertEqual(self.excellon.units.lower(), "mm")
self.assertEqual(self.excellon.zeros, "L")
def test_coords(self):
# For X9000 add the missing 00 on the right. Then divide by 10000.
self.assertEqual(self.excellon.drills[0]["point"].coords[0], (900.0, 117.5))
self.assertEqual(self.excellon.drills[1]["point"].coords[0], (302.5, 105.0))
class ExcellonFormatMETRICTZTest(unittest.TestCase):
def setUp(self):
self.excellon = Excellon()
code = """
M48
METRIC,TZ
T1C.02362F197S550
T2C.03543F197S550
M95
T1
X9000Y11750
X30250Y10500
"""
code = code.split('\n')
self.excellon.parse_lines(code)
def test_format(self):
self.assertEqual(self.excellon.units.lower(), "mm")
self.assertEqual(self.excellon.zeros, "T")
def test_coords(self):
# For X9000 add the missing 00 on the right. Then divide by 10000.
self.assertEqual(self.excellon.drills[0]["point"].coords[0], (9.0, 11.75))
self.assertEqual(self.excellon.drills[1]["point"].coords[0], (30.25, 10.5))
if __name__ == '__main__':
unittest.main()

View File

@@ -1,163 +0,0 @@
import unittest
from PyQt5 import QtGui, QtWidgets
import sys
from FlatCAMApp import App
from FlatCAMObj import FlatCAMExcellon, FlatCAMCNCjob
from flatcamGUI.ObjectUI import ExcellonObjectUI
import tempfile
import os
from time import sleep
class ExcellonFlowTestCase(unittest.TestCase):
"""
This is a top-level test covering the Excellon-to-GCode
generation workflow.
THIS IS A REQUIRED TEST FOR ANY UPDATES.
"""
filename = 'case1.drl'
def setUp(self):
self.app = QtWidgets.QApplication(sys.argv)
# Create App, keep app defaults (do not load
# user-defined defaults).
self.fc = App(user_defaults=False)
self.fc.open_excellon('tests/excellon_files/' + self.filename)
def tearDown(self):
del self.fc
del self.app
def test_flow(self):
# Names of available objects.
names = self.fc.collection.get_names()
print(names)
#--------------------------------------
# Total of 1 objects.
#--------------------------------------
self.assertEqual(len(names), 1,
"Expected 1 object, found %d" % len(names))
#--------------------------------------
# Object's name matches the file name.
#--------------------------------------
self.assertEqual(names[0], self.filename,
"Expected name == %s, got %s" % (self.filename, names[0]))
#---------------------------------------
# Get object by that name, make sure it's a FlatCAMExcellon.
#---------------------------------------
excellon_name = names[0]
excellon_obj = self.fc.collection.get_by_name(excellon_name)
self.assertTrue(isinstance(excellon_obj, FlatCAMExcellon),
"Expected FlatCAMExcellon, instead, %s is %s" %
(excellon_name, type(excellon_obj)))
#----------------------------------------
# Object's GUI matches Object's options
#----------------------------------------
# TODO: Open GUI with double-click on object.
# Opens the Object's GUI, populates it.
excellon_obj.build_ui()
for option, value in list(excellon_obj.options.items()):
try:
form_field = excellon_obj.form_fields[option]
except KeyError:
print(("**********************************************************\n"
"* WARNING: Option '{}' has no form field\n"
"**********************************************************"
"".format(option)))
continue
self.assertEqual(value, form_field.get_value(),
"Option '{}' == {} but form has {}".format(
option, value, form_field.get_value()
))
# --------------------------------------------------
# Changes in the GUI should be read in when
# running any process. Changing something here.
# --------------------------------------------------
form_field = excellon_obj.form_fields['feedrate']
value = form_field.get_value()
form_field.set_value(value * 1.1) # Increase by 10%
print(("'feedrate' == {}".format(value)))
# --------------------------------------------------
# Create GCode using all tools.
# --------------------------------------------------
assert isinstance(excellon_obj, FlatCAMExcellon) # Just for the IDE
ui = excellon_obj.ui
assert isinstance(ui, ExcellonObjectUI)
ui.tools_table.selectAll() # Select All
ui.generate_cnc_button.click() # Click
# Work is done in a separate thread and results are
# passed via events to the main event loop which is
# not running. Run only for pending events.
#
# I'm not sure why, but running it only once does
# not catch the new object. Might be a timing issue.
# http://pyqt.sourceforge.net/Docs/PyQt4/qeventloop.html#details
for _ in range(2):
sleep(0.1)
self.app.processEvents()
# ---------------------------------------------
# Check that GUI has been read in.
# ---------------------------------------------
value = excellon_obj.options['feedrate']
form_value = form_field.get_value()
self.assertEqual(value, form_value,
"Form value for '{}' == {} was not read into options"
"which has {}".format('feedrate', form_value, value))
print(("'feedrate' == {}".format(value)))
# ---------------------------------------------
# Check that only 1 object has been created.
# ---------------------------------------------
names = self.fc.collection.get_names()
self.assertEqual(len(names), 2,
"Expected 2 objects, found %d" % len(names))
# -------------------------------------------------------
# Make sure the CNCJob Object has the correct name
# -------------------------------------------------------
cncjob_name = excellon_name + "_cnc"
self.assertTrue(cncjob_name in names,
"Object named %s not found." % cncjob_name)
# -------------------------------------------------------
# Get the object make sure it's a cncjob object
# -------------------------------------------------------
cncjob_obj = self.fc.collection.get_by_name(cncjob_name)
self.assertTrue(isinstance(cncjob_obj, FlatCAMCNCjob),
"Expected a FlatCAMCNCjob, got %s" % type(cncjob_obj))
# -----------------------------------------
# Export G-Code, check output
# -----------------------------------------
assert isinstance(cncjob_obj, FlatCAMCNCjob) # For IDE
# get system temporary file(try create it and delete)
with tempfile.NamedTemporaryFile(prefix='unittest.',
suffix="." + cncjob_name + '.gcode',
delete=True) as tmp_file:
output_filename = tmp_file.name
cncjob_obj.export_gcode(output_filename)
self.assertTrue(os.path.isfile(output_filename))
os.remove(output_filename)
print(names)

View File

@@ -1,35 +0,0 @@
import unittest
import camlib
from flatcamParsers.ParseGerber import Gerber
class GerberBuffer(unittest.TestCase):
def setUp(self):
self.gerber1 = Gerber()
self.gerber1.use_buffer_for_union = True
self.gerber1.parse_file("tests/gerber_files/STM32F4-spindle.cmp")
geometry1 = self.gerber1.solid_geometry
self.geometry1_area = self.compute_area(geometry1)
self.gerber2 = Gerber()
self.gerber2.use_buffer_for_union = False
self.gerber2.parse_file("tests/gerber_files/STM32F4-spindle.cmp")
geometry2 = self.gerber2.solid_geometry
self.geometry2_area = self.compute_area (geometry2)
def compute_area(self, geometry):
area = 0
try:
for geo in geometry:
area += geo.area
# Not iterable, do the actual indexing and add.
except TypeError:
area = geometry.area
return area
def test_buffer(self):
self.assertLessEqual(abs(self.geometry2_area - self.geometry1_area), 0.000001)
if __name__ == '__main__':
unittest.main()

View File

@@ -1,190 +0,0 @@
import sys
import unittest
from PyQt5 import QtGui, QtWidgets
from FlatCAMApp import App, tclCommands
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMCNCjob
from flatcamGUI.ObjectUI import GerberObjectUI, GeometryObjectUI
from time import sleep
import os
import tempfile
class GerberFlowTestCase(unittest.TestCase):
"""
This is a top-level test covering the Gerber-to-GCode
generation workflow.
THIS IS A REQUIRED TEST FOR ANY UPDATES.
"""
filename = 'simple1.gbr'
def setUp(self):
self.app = QtWidgets.QApplication(sys.argv)
# Create App, keep app defaults (do not load
# user-defined defaults).
self.fc = App(user_defaults=False)
self.fc.open_gerber('tests/gerber_files/' + self.filename)
def tearDown(self):
del self.fc
del self.app
def test_flow(self):
# Names of available objects.
names = self.fc.collection.get_names()
print(names)
# --------------------------------------
# Total of 1 objects.
# --------------------------------------
self.assertEqual(len(names), 1,
"Expected 1 object, found %d" % len(names))
# --------------------------------------
# Object's name matches the file name.
# --------------------------------------
self.assertEqual(names[0], self.filename,
"Expected name == %s, got %s" % (self.filename, names[0]))
# ---------------------------------------
# Get object by that name, make sure it's a FlatCAMGerber.
# ---------------------------------------
gerber_name = names[0]
gerber_obj = self.fc.collection.get_by_name(gerber_name)
self.assertTrue(isinstance(gerber_obj, FlatCAMGerber),
"Expected FlatCAMGerber, instead, %s is %s" %
(gerber_name, type(gerber_obj)))
# ----------------------------------------
# Object's GUI matches Object's options
# ----------------------------------------
# TODO: Open GUI with double-click on object.
# Opens the Object's GUI, populates it.
gerber_obj.build_ui()
for option, value in list(gerber_obj.options.items()):
try:
form_field = gerber_obj.form_fields[option]
except KeyError:
print(("**********************************************************\n"
"* WARNING: Option '{}' has no form field\n"
"**********************************************************"
"".format(option)))
continue
self.assertEqual(value, form_field.get_value(),
"Option '{}' == {} but form has {}".format(
option, value, form_field.get_value()
))
# --------------------------------------------------
# Changes in the GUI should be read in when
# running any process. Changing something here.
# --------------------------------------------------
form_field = gerber_obj.form_fields['isotooldia']
value = form_field.get_value()
form_field.set_value(value * 1.1) # Increase by 10%
print(("'isotooldia' == {}".format(value)))
# --------------------------------------------------
# Create isolation routing using default values
# and by clicking on the button.
# --------------------------------------------------
# Get the object's GUI and click on "Generate Geometry" under
# "Isolation Routing"
assert isinstance(gerber_obj, FlatCAMGerber) # Just for the IDE
# Changed: UI has been build already
#gerber_obj.build_ui() # Open the object's UI.
ui = gerber_obj.ui
assert isinstance(ui, GerberObjectUI)
ui.generate_iso_button.click() # Click
# ---------------------------------------------
# Check that GUI has been read in.
# ---------------------------------------------
value = gerber_obj.options['isotooldia']
form_value = form_field.get_value()
self.assertEqual(value, form_value,
"Form value for '{}' == {} was not read into options"
"which has {}".format('isotooldia', form_value, value))
print(("'isotooldia' == {}".format(value)))
# ---------------------------------------------
# Check that only 1 object has been created.
# ---------------------------------------------
names = self.fc.collection.get_names()
self.assertEqual(len(names), 2,
"Expected 2 objects, found %d" % len(names))
# -------------------------------------------------------
# Make sure the Geometry Object has the correct name
# -------------------------------------------------------
geo_name = gerber_name + "_iso"
self.assertTrue(geo_name in names,
"Object named %s not found." % geo_name)
# -------------------------------------------------------
# Get the object make sure it's a geometry object
# -------------------------------------------------------
geo_obj = self.fc.collection.get_by_name(geo_name)
self.assertTrue(isinstance(geo_obj, FlatCAMGeometry),
"Expected a FlatCAMGeometry, got %s" % type(geo_obj))
# ------------------------------------
# Open the UI, make CNCObject
# ------------------------------------
geo_obj.build_ui()
ui = geo_obj.ui
assert isinstance(ui, GeometryObjectUI) # Just for the IDE
ui.generate_cnc_button.click() # Click
# Work is done in a separate thread and results are
# passed via events to the main event loop which is
# not running. Run only for pending events.
#
# I'm not sure why, but running it only once does
# not catch the new object. Might be a timing issue.
# http://pyqt.sourceforge.net/Docs/PyQt4/qeventloop.html#details
for _ in range(2):
sleep(0.1)
self.app.processEvents()
# ---------------------------------------------
# Check that only 1 object has been created.
# ---------------------------------------------
names = self.fc.collection.get_names()
self.assertEqual(len(names), 3,
"Expected 3 objects, found %d" % len(names))
# -------------------------------------------------------
# Make sure the CNC Job Object has the correct name
# -------------------------------------------------------
cnc_name = geo_name + "_cnc"
self.assertTrue(cnc_name in names,
"Object named %s not found." % geo_name)
# -------------------------------------------------------
# Get the object make sure it's a CNC Job object
# -------------------------------------------------------
cnc_obj = self.fc.collection.get_by_name(cnc_name)
self.assertTrue(isinstance(cnc_obj, FlatCAMCNCjob),
"Expected a FlatCAMCNCJob, got %s" % type(geo_obj))
# -----------------------------------------
# Export G-Code, check output
# -----------------------------------------
assert isinstance(cnc_obj, FlatCAMCNCjob)
output_filename = ""
# get system temporary file(try create it and delete also)
with tempfile.NamedTemporaryFile(prefix='unittest.',
suffix="." + cnc_name + '.gcode',
delete=True) as tmp_file:
output_filename = tmp_file.name
cnc_obj.export_gcode(output_filename)
self.assertTrue(os.path.isfile(output_filename))
os.remove(output_filename)
print(names)

View File

@@ -1,213 +0,0 @@
import unittest
from shapely.geometry import LineString, Polygon
from shapely.ops import unary_union
from matplotlib.pyplot import plot, subplot, show, cla, clf, xlim, ylim, title
from matplotlib.axes import *
from camlib import *
from copy import deepcopy
def mkstorage(paths):
def get_pts(o):
return [o.coords[0], o.coords[-1]]
storage = FlatCAMRTreeStorage()
storage.get_points = get_pts
for p in paths:
storage.insert(p)
return storage
def plotg2(geo, solid_poly=False, color="black", linestyle='solid'):
try:
for sub_geo in geo:
plotg2(sub_geo, solid_poly=solid_poly, color=color, linestyle=linestyle)
except TypeError:
if type(geo) == Polygon:
if solid_poly:
patch = PolygonPatch(geo,
#facecolor="#BBF268",
facecolor=color,
edgecolor="#006E20",
alpha=0.5,
zorder=2)
ax = subplot(111)
ax.add_patch(patch)
else:
x, y = geo.exterior.coords.xy
plot(x, y, color=color, linestyle=linestyle)
for ints in geo.interiors:
x, y = ints.coords.xy
plot(x, y, color=color, linestyle=linestyle)
if type(geo) == LineString or type(geo) == LinearRing:
x, y = geo.coords.xy
plot(x, y, color=color, linestyle=linestyle)
if type(geo) == Point:
x, y = geo.coords.xy
plot(x, y, 'o')
class PaintTestCase(unittest.TestCase):
# def __init__(self):
# super(PaintTestCase, self).__init__()
# self.boundary = None
# self.descr = None
def plot_summary_A(self, paths, tooldia, result, msg):
plotg2(self.boundary, solid_poly=True, color="green")
plotg2(paths, color="red")
plotg2([r.buffer(tooldia / 2) for r in result], solid_poly=True, color="blue")
plotg2(result, color="black", linestyle='dashed')
title(msg)
xlim(0, 5)
ylim(0, 5)
show()
class PaintConnectTest(PaintTestCase):
"""
Simple rectangular boundary and paths inside.
"""
def setUp(self):
self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]])
def test_jump(self):
print("Test: WALK Expected")
paths = [
LineString([[0.5, 2], [2, 4.5]]),
LineString([[2, 0.5], [4.5, 2]])
]
for p in paths:
print(p)
tooldia = 1.0
print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects())
for r in result:
print(r)
self.assertEqual(len(result), 1)
# self.plot_summary_A(paths, tooldia, result, "WALK expected.")
def test_no_jump1(self):
print("Test: FLY Expected")
paths = [
LineString([[0, 2], [2, 5]]),
LineString([[2, 0], [5, 2]])
]
for p in paths:
print(p)
tooldia = 1.0
print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects())
for r in result:
print(r)
self.assertEqual(len(result), len(paths))
# self.plot_summary_A(paths, tooldia, result, "FLY Expected")
def test_no_jump2(self):
print("Test: FLY Expected")
paths = [
LineString([[0.5, 2], [2, 4.5]]),
LineString([[2, 0.5], [4.5, 2]])
]
for p in paths:
print(p)
tooldia = 1.1
print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects())
for r in result:
print(r)
self.assertEqual(len(result), len(paths))
# self.plot_summary_A(paths, tooldia, result, "FLY Expected")
class PaintConnectTest2(PaintTestCase):
"""
Boundary with an internal cutout.
"""
def setUp(self):
self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]])
self.boundary = self.boundary.difference(
Polygon([[2, 1], [3, 1], [3, 4], [2, 4]])
)
def test_no_jump3(self):
print("TEST: No jump expected")
paths = [
LineString([[0.5, 1], [1.5, 3]]),
LineString([[4, 1], [4, 4]])
]
for p in paths:
print(p)
tooldia = 1.0
print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects())
for r in result:
print(r)
self.assertEqual(len(result), len(paths))
# self.plot_summary_A(paths, tooldia, result, "FLY Expected")
class PaintConnectTest3(PaintTestCase):
"""
Tests with linerings among elements.
"""
def setUp(self):
self.boundary = Polygon([[0, 0], [0, 5], [5, 5], [5, 0]])
print("TEST w/ LinearRings")
def test_jump2(self):
print("Test: WALK Expected")
paths = [
LineString([[0.5, 2], [2, 4.5]]),
LineString([[2, 0.5], [4.5, 2]]),
self.boundary.buffer(-0.5).exterior
]
for p in paths:
print(p)
tooldia = 1.0
print("--")
result = Geometry.paint_connect(mkstorage(deepcopy(paths)), self.boundary, tooldia)
result = list(result.get_objects())
for r in result:
print(r)
self.assertEqual(len(result), 1)
# self.plot_summary_A(paths, tooldia, result, "WALK Expected")
if __name__ == '__main__':
unittest.main()

View File

@@ -1,89 +0,0 @@
import unittest
from shapely.geometry import LineString, Polygon
from shapely.ops import unary_union
from matplotlib.pyplot import plot, subplot, show, cla, clf, xlim, ylim, title
from camlib import *
from random import random
def mkstorage(paths):
def get_pts(o):
return [o.coords[0], o.coords[-1]]
storage = FlatCAMRTreeStorage()
storage.get_points = get_pts
for p in paths:
storage.insert(p)
return storage
class PathConnectTest1(unittest.TestCase):
def setUp(self):
print("PathConnectTest1.setUp()")
pass
def test_simple_connect(self):
paths = [
LineString([[0, 0], [1, 1]]),
LineString([[1, 1], [2, 1]])
]
result = Geometry.path_connect(mkstorage(paths))
result = list(result.get_objects())
self.assertEqual(len(result), 1)
self.assertTrue(result[0].equals(LineString([[0, 0], [1, 1], [2, 1]])))
def test_interfere_connect(self):
paths = [
LineString([[0, 0], [1, 1]]),
LineString([[1, 1], [2, 1]]),
LineString([[-0.5, 0.5], [0.5, 0]])
]
result = Geometry.path_connect(mkstorage(paths))
result = list(result.get_objects())
self.assertEqual(len(result), 2)
matches = [p for p in result if p.equals(LineString([[0, 0], [1, 1], [2, 1]]))]
self.assertEqual(len(matches), 1)
def test_simple_connect_offset1(self):
for i in range(20):
offset_x = random()
offset_y = random()
paths = [
LineString([[0 + offset_x, 0 + offset_y], [1 + offset_x, 1 + offset_y]]),
LineString([[1 + offset_x, 1 + offset_y], [2 + offset_x, 1 + offset_y]])
]
result = Geometry.path_connect(mkstorage(paths))
result = list(result.get_objects())
self.assertEqual(len(result), 1)
self.assertTrue(result[0].equals(LineString([[0 + offset_x, 0 + offset_y],
[1 + offset_x, 1 + offset_y],
[2 + offset_x, 1 + offset_y]])))
def test_ring_interfere_connect(self):
print()
print("TEST STARTING ...")
paths = [
LineString([[0, 0], [1, 1]]),
LineString([[1, 1], [2, 1]]),
LinearRing([[1, 1], [2, 2], [1, 3], [0, 2]])
]
result = Geometry.path_connect(mkstorage(paths))
result = list(result.get_objects())
self.assertEqual(len(result), 2)
matches = [p for p in result if p.equals(LineString([[0, 0], [1, 1], [2, 1]]))]
self.assertEqual(len(matches), 1)
if __name__ == "__main__":
unittest.main()

View File

@@ -1,220 +0,0 @@
import sys
import unittest
from PyQt5 import QtGui, QtWidgets
from FlatCAMApp import App
from FlatCAMObj import FlatCAMGeometry, FlatCAMCNCjob
from flatcamGUI.ObjectUI import GerberObjectUI, GeometryObjectUI
from time import sleep
import os
import tempfile
from shapely.geometry import LineString, LinearRing, Polygon, MultiPolygon
class PolyPaintTestCase(unittest.TestCase):
def setUp(self):
self.app = QtWidgets.QApplication(sys.argv)
# Create App, keep app defaults (do not load
# user-defined defaults).
self.fc = App(user_defaults=False)
def tearDown(self):
for _ in range(2):
self.app.processEvents()
# NOTE: These are creating problems...
# del self.fc
# del self.app
def test_poly_paint_svg_all(self):
print("*********************************")
print("* svg_all *")
print("*********************************")
# Clear workspace
self.fc.on_file_new()
for _ in range(2):
self.app.processEvents()
# Open SVG with polygons
self.fc.import_svg('tests/svg/drawing.svg')
name = self.fc.collection.get_names()[0]
self.fc.collection.set_active(name)
geo_obj = self.fc.collection.get_by_name(name)
# Paint all polygons
geo_obj.paint_poly_all(5, 0.2, 1)
sleep(5) # Todo: Do not base it on fixed time.
for _ in range(2):
self.app.processEvents()
# New object should be available
names = self.fc.collection.get_names()
self.assertEqual(len(names), 2)
# Verify new geometry makes sense
painted = self.fc.collection.get_by_name(names[-1])
for geo in painted.solid_geometry:
# Correct Type
self.assertTrue(isinstance(geo, LineString))
# Lots of points (Should be 1000s)
self.assertGreater(len(geo.coords), 2)
def test_poly_paint_svg_click(self):
print("*********************************")
print("* svg_click *")
print("*********************************")
# Clear workspace
self.fc.on_file_new()
for _ in range(2):
self.app.processEvents()
# Open SVG with polygons
self.fc.import_svg('tests/svg/drawing.svg')
name = self.fc.collection.get_names()[0]
self.fc.collection.set_active(name)
geo_obj = self.fc.collection.get_by_name(name)
# Paint all polygons
geo_obj.paint_poly_single_click([300, 700], 5, 0.2, 1)
sleep(5)
for _ in range(2):
self.app.processEvents()
# New object should be available
names = self.fc.collection.get_names()
sleep(1)
self.assertEqual(len(names), 2)
# Verify new geometry makes sense
painted = self.fc.collection.get_by_name(names[-1])
for geo in painted.solid_geometry:
# Correct Type
self.assertTrue(isinstance(geo, LineString))
# Lots of points (Should be 1000s)
self.assertGreater(len(geo.coords), 2)
def test_poly_paint_noncopper_all(self):
print("*********************************")
print("* noncopper_all *")
print("*********************************")
# Clear workspace
self.fc.on_file_new()
for _ in range(2):
self.app.processEvents()
self.fc.open_gerber('tests/gerber_files/simple1.gbr')
sleep(1)
for _ in range(2):
self.app.processEvents()
name = self.fc.collection.get_names()[0]
gerber_obj = self.fc.collection.get_by_name(name)
self.fc.collection.set_active(name)
gerber_obj.on_generatenoncopper_button_click()
sleep(1)
for _ in range(2):
self.app.processEvents()
# New object should be available
names = self.fc.collection.get_names()
sleep(1)
self.assertEqual(len(names), 2)
geoname = "simple1.gbr_noncopper"
geo_obj = self.fc.collection.get_by_name(geoname)
self.fc.collection.set_active(geoname)
geo_obj.paint_poly_all(0.02, 0.2, 0)
sleep(5)
for _ in range(2):
self.app.processEvents()
# New object should be available
names = self.fc.collection.get_names()
sleep(1)
self.assertEqual(len(names), 3)
# Verify new geometry makes sense
painted = self.fc.collection.get_by_name(names[-1])
for geo in painted.solid_geometry:
# Correct Type
self.assertTrue(isinstance(geo, LineString))
# Lots of points (Should be 1000s)
self.assertGreater(len(geo.coords), 2)
def test_poly_paint_noncopper_click(self):
print("*********************************")
print("* noncopper_click *")
print("*********************************")
# Clear workspace
self.fc.on_file_new()
for _ in range(2):
self.app.processEvents()
self.fc.open_gerber('tests/gerber_files/simple1.gbr')
sleep(1)
for _ in range(2):
self.app.processEvents()
name = self.fc.collection.get_names()[0]
gerber_obj = self.fc.collection.get_by_name(name)
self.fc.collection.set_active(name)
gerber_obj.on_generatenoncopper_button_click()
sleep(1)
for _ in range(2):
self.app.processEvents()
# New object should be available
names = self.fc.collection.get_names()
sleep(1)
self.assertEqual(len(names), 2)
geoname = "simple1.gbr_noncopper"
geo_obj = self.fc.collection.get_by_name(geoname)
self.fc.collection.set_active(geoname)
geo_obj.paint_poly_single_click([2.7, 1.0], 0.02, 0.2, 0)
sleep(5)
for _ in range(2):
self.app.processEvents()
# New object should be available
names = self.fc.collection.get_names()
sleep(1)
self.assertEqual(len(names), 3)
# Verify new geometry makes sense
painted = self.fc.collection.get_by_name(names[-1])
for geo in painted.solid_geometry:
# Correct Type
self.assertTrue(isinstance(geo, LineString))
# Lots of points (Should be 1000s)
self.assertGreater(len(geo.coords), 2)

View File

@@ -1,127 +0,0 @@
import sys
import unittest
from PyQt5 import QtWidgets
from FlatCAMApp import App
from FlatCAMObj import FlatCAMGeometry, FlatCAMCNCjob
from flatcamGUI.ObjectUI import GerberObjectUI, GeometryObjectUI
from time import sleep
import os
import tempfile
class SVGFlowTestCase(unittest.TestCase):
def setUp(self):
self.app = QtWidgets.QApplication(sys.argv)
# Create App, keep app defaults (do not load
# user-defined defaults).
self.fc = App(user_defaults=False)
self.filename = 'drawing.svg'
def tearDown(self):
del self.fc
del self.app
def test_flow(self):
self.fc.import_svg('tests/svg/' + self.filename)
names = self.fc.collection.get_names()
print(names)
# --------------------------------------
# Total of 1 objects.
# --------------------------------------
self.assertEqual(len(names), 1, "Expected 1 object, found %d" % len(names))
# --------------------------------------
# Object's name matches the file name.
# --------------------------------------
self.assertEqual(names[0], self.filename, "Expected name == %s, got %s" % (self.filename, names[0]))
# ---------------------------------------
# Get object by that name, make sure it's a FlatCAMGerber.
# ---------------------------------------
geo_name = names[0]
geo_obj = self.fc.collection.get_by_name(geo_name)
self.assertTrue(isinstance(geo_obj, FlatCAMGeometry),
"Expected FlatCAMGeometry, instead, %s is %s" %
(geo_name, type(geo_obj)))
# ----------------------------------------
# Object's GUI matches Object's options
# ----------------------------------------
# TODO: Open GUI with double-click on object.
# Opens the Object's GUI, populates it.
geo_obj.build_ui()
for option, value in list(geo_obj.options.items()):
try:
form_field = geo_obj.form_fields[option]
except KeyError:
print(("**********************************************************\n"
"* WARNING: Option '{}' has no form field\n"
"**********************************************************"
"".format(option)))
continue
self.assertEqual(value, form_field.get_value(),
"Option '{}' == {} but form has {}".format(
option, value, form_field.get_value()
))
# ------------------------------------
# Open the UI, make CNCObject
# ------------------------------------
geo_obj.build_ui()
ui = geo_obj.ui
assert isinstance(ui, GeometryObjectUI) # Just for the IDE
ui.generate_cnc_button.click() # Click
# Work is done in a separate thread and results are
# passed via events to the main event loop which is
# not running. Run only for pending events.
#
# I'm not sure why, but running it only once does
# not catch the new object. Might be a timing issue.
# http://pyqt.sourceforge.net/Docs/PyQt4/qeventloop.html#details
for _ in range(2):
sleep(0.1)
self.app.processEvents()
# ---------------------------------------------
# Check that only 1 object has been created.
# ---------------------------------------------
names = self.fc.collection.get_names()
self.assertEqual(len(names), 2,
"Expected 2 objects, found %d" % len(names))
# -------------------------------------------------------
# Make sure the CNC Job Object has the correct name
# -------------------------------------------------------
cnc_name = geo_name + "_cnc"
self.assertTrue(cnc_name in names,
"Object named %s not found." % geo_name)
# -------------------------------------------------------
# Get the object make sure it's a CNC Job object
# -------------------------------------------------------
cnc_obj = self.fc.collection.get_by_name(cnc_name)
self.assertTrue(isinstance(cnc_obj, FlatCAMCNCjob),
"Expected a FlatCAMCNCJob, got %s" % type(geo_obj))
# -----------------------------------------
# Export G-Code, check output
# -----------------------------------------
assert isinstance(cnc_obj, FlatCAMCNCjob)
output_filename = ""
# get system temporary file(try create it and delete also)
with tempfile.NamedTemporaryFile(prefix='unittest.',
suffix="." + cnc_name + '.gcode',
delete=True) as tmp_file:
output_filename = tmp_file.name
cnc_obj.export_gcode(output_filename)
self.assertTrue(os.path.isfile(output_filename))
os.remove(output_filename)
print(names)

View File

@@ -1,18 +0,0 @@
import pkgutil
import sys
# allowed command tests (please append them alphabetically ordered)
from .test_TclCommandAddPolygon import *
from .test_TclCommandAddPolyline import *
from .test_TclCommandCncjob import *
from .test_TclCommandDrillcncjob import *
from .test_TclCommandExportGcode import *
from .test_TclCommandExteriors import *
from .test_TclCommandImportSvg import *
from .test_TclCommandInteriors import *
from .test_TclCommandIsolate import *
from .test_TclCommandNew import *
from .test_TclCommandNewGeometry import *
from .test_TclCommandOpenExcellon import *
from .test_TclCommandOpenGerber import *
from .test_TclCommandPaintPolygon import *

View File

@@ -1,18 +0,0 @@
from FlatCAMObj import FlatCAMGeometry
def test_add_polygon(self):
"""
Test add polygon into geometry
:param self:
:return:
"""
self.fc.exec_command_test('new_geometry "%s"' % self.geometry_name)
geometry_obj = self.fc.collection.get_by_name(self.geometry_name)
self.assertTrue(isinstance(geometry_obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (self.geometry_name, type(geometry_obj)))
points = '0 0 20 0 10 10 0 10'
self.fc.exec_command_test('add_polygon "%s" %s' % (self.geometry_name, points))

View File

@@ -1,18 +0,0 @@
from FlatCAMObj import FlatCAMGeometry
def test_add_polyline(self):
"""
Test add polyline into geometry
:param self:
:return:
"""
self.fc.exec_command_test('new_geometry "%s"' % self.geometry_name)
geometry_obj = self.fc.collection.get_by_name(self.geometry_name)
self.assertTrue(isinstance(geometry_obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (self.geometry_name, type(geometry_obj)))
points = '0 0 20 0 10 10 0 10 33 33'
self.fc.exec_command_test('add_polyline "%s" %s' % (self.geometry_name, points))

View File

@@ -1,17 +0,0 @@
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMObj
from .test_TclCommandIsolate import *
def test_cncjob(self):
"""
Test cncjob
:param self:
:return:
"""
# reuse isolate tests
test_isolate(self)
self.fc.exec_command_test('cncjob %s_iso -tooldia 0.5 -z_cut 0.05 -z_move 3 -feedrate 300' % self.gerber_top_name)
cam_top_obj = self.fc.collection.get_by_name(self.gerber_top_name + '_iso_cnc')
self.assertTrue(isinstance(cam_top_obj, FlatCAMObj), "Expected FlatCAMObj, instead, %s is %s"
% (self.gerber_top_name + '_iso_cnc', type(cam_top_obj)))

View File

@@ -1,18 +0,0 @@
from FlatCAMObj import FlatCAMObj
from .test_TclCommandOpenExcellon import *
def test_drillcncjob(self):
"""
Test cncjob
:param self:
:return:
"""
# reuse open excellontests
test_open_excellon(self)
self.fc.exec_command_test('drillcncjob %s -tools all -drillz 0.5 -travelz 3 -feedrate 300'
% self.excellon_name)
cam_top_obj = self.fc.collection.get_by_name(self.excellon_name + '_cnc')
self.assertTrue(isinstance(cam_top_obj, FlatCAMObj), "Expected FlatCAMObj, instead, %s is %s"
% (self.excellon_name + '_cnc', type(cam_top_obj)))

View File

@@ -1,33 +0,0 @@
import os
import tempfile
from .test_TclCommandCncjob import *
from .test_TclCommandDrillcncjob import *
def test_export_gcodecncjob(self):
"""
Test cncjob
:param self:
:return:
"""
# reuse tests
test_cncjob(self)
test_drillcncjob(self)
with tempfile.NamedTemporaryFile(prefix='unittest.', suffix="." + self.excellon_name + '.gcode', delete=True)\
as tmp_file:
output_filename = tmp_file.name
self.fc.exec_command_test('write_gcode "%s" "%s"' % (self.excellon_name + '_cnc', output_filename))
self.assertTrue(os.path.isfile(output_filename))
os.remove(output_filename)
with tempfile.NamedTemporaryFile(prefix='unittest.', suffix="." + self.gerber_top_name + '.gcode', delete=True)\
as tmp_file:
output_filename = tmp_file.name
self.fc.exec_command_test('write_gcode "%s" "%s"' % (self.gerber_top_name + '_iso_cnc', output_filename))
self.assertTrue(os.path.isfile(output_filename))
os.remove(output_filename)
# TODO check what is inside files , it should be same every time

View File

@@ -1,24 +0,0 @@
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry
def test_exteriors(self):
"""
Test exteriors
:param self:
:return:
"""
self.fc.exec_command_test('open_gerber %s/%s -outname %s'
% (self.gerber_files, self.cutout_filename, self.gerber_cutout_name))
gerber_cutout_obj = self.fc.collection.get_by_name(self.gerber_cutout_name)
self.assertTrue(isinstance(gerber_cutout_obj, FlatCAMGerber), "Expected FlatCAMGerber, instead, %s is %s"
% (self.gerber_cutout_name, type(gerber_cutout_obj)))
# exteriors interiors and delete isolated traces
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_cutout_name, self.engraver_diameter))
self.fc.exec_command_test('exteriors %s -outname %s'
% (self.gerber_cutout_name + '_iso', self.gerber_cutout_name + '_iso_exterior'))
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_iso'))
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_iso_exterior')
self.assertTrue(isinstance(obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (self.gerber_cutout_name + '_iso_exterior', type(obj)))

View File

@@ -1,60 +0,0 @@
from os import listdir
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry
def test_import_svg(self):
"""
Test all SVG files inside svg directory.
Problematic SVG files shold be put there as test reference.
:param self:
:return:
"""
file_list = listdir(self.svg_files)
for svg_file in file_list:
# import without outname
self.fc.exec_command_test('import_svg "%s/%s"' % (self.svg_files, svg_file))
obj = self.fc.collection.get_by_name(svg_file)
self.assertTrue(isinstance(obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (svg_file, type(obj)))
# import with outname
outname = '%s-%s' % (self.geometry_name, svg_file)
self.fc.exec_command_test('import_svg "%s/%s" -outname "%s"' % (self.svg_files, svg_file, outname))
obj = self.fc.collection.get_by_name(outname)
self.assertTrue(isinstance(obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (outname, type(obj)))
names = self.fc.collection.get_names()
self.assertEqual(len(names), len(file_list)*2,
"Expected %d objects, found %d" % (len(file_list)*2, len(file_list)))
def test_import_svg_as_geometry(self):
self.fc.exec_command_test('import_svg "%s/%s" -type geometry -outname "%s"'
% (self.svg_files, self.svg_filename, self.geometry_name))
obj = self.fc.collection.get_by_name(self.geometry_name)
self.assertTrue(isinstance(obj, FlatCAMGeometry) and not isinstance(obj, FlatCAMGerber),
"Expected FlatCAMGeometry, instead, %s is %s" % (self.geometry_name, type(obj)))
def test_import_svg_as_gerber(self):
self.fc.exec_command_test('import_svg "%s/%s" -type gerber -outname "%s"'
% (self.svg_files, self.svg_filename, self.gerber_name))
obj = self.fc.collection.get_by_name(self.gerber_name)
self.assertTrue(isinstance(obj, FlatCAMGerber),
"Expected FlatCAMGerber, instead, %s is %s" % (self.gerber_name, type(obj)))
self.fc.exec_command_test('isolate "%s"' % self.gerber_name)
obj = self.fc.collection.get_by_name(self.gerber_name+'_iso')
self.assertTrue(isinstance(obj, FlatCAMGeometry),
"Expected FlatCAMGeometry, instead, %s is %s" % (self.gerber_name+'_iso', type(obj)))

View File

@@ -1,24 +0,0 @@
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry
def test_interiors(self):
"""
Test interiors
:param self:
:return:
"""
self.fc.exec_command_test('open_gerber %s/%s -outname %s'
% (self.gerber_files, self.cutout_filename, self.gerber_cutout_name))
gerber_cutout_obj = self.fc.collection.get_by_name(self.gerber_cutout_name)
self.assertTrue(isinstance(gerber_cutout_obj, FlatCAMGerber), "Expected FlatCAMGerber, instead, %s is %s"
% (self.gerber_cutout_name, type(gerber_cutout_obj)))
# interiors and delete isolated traces
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_cutout_name, self.engraver_diameter))
self.fc.exec_command_test('interiors %s -outname %s'
% (self.gerber_cutout_name + '_iso', self.gerber_cutout_name + '_iso_interior'))
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_iso'))
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_iso_interior')
self.assertTrue(isinstance(obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (self.gerber_cutout_name + '_iso_interior', type(obj)))

View File

@@ -1,21 +0,0 @@
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry
def test_isolate(self):
"""
Test isolate gerber
:param self:
:return:
"""
self.fc.exec_command_test('open_gerber %s/%s -outname %s'
% (self.gerber_files, self.copper_top_filename, self.gerber_top_name))
gerber_top_obj = self.fc.collection.get_by_name(self.gerber_top_name)
self.assertTrue(isinstance(gerber_top_obj, FlatCAMGerber), "Expected FlatCAMGerber, instead, %s is %s"
% (self.gerber_top_name, type(gerber_top_obj)))
# isolate traces
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_top_name, self.engraver_diameter))
geometry_top_obj = self.fc.collection.get_by_name(self.gerber_top_name+'_iso')
self.assertTrue(isinstance(geometry_top_obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (self.gerber_top_name+'_iso', type(geometry_top_obj)))

View File

@@ -1,48 +0,0 @@
from FlatCAMObj import FlatCAMGeometry
def test_new(self):
"""
Test new project
:param self:
:return:
"""
self.fc.exec_command_test('new_geometry "%s"' % self.geometry_name)
geometry_obj = self.fc.collection.get_by_name(self.geometry_name)
self.assertTrue(isinstance(geometry_obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (self.geometry_name, type(geometry_obj)))
self.fc.exec_command_test('proc testproc {} { puts "testresult" }')
result = self.fc.exec_command_test('testproc')
self.assertEqual(result, "testresult",'testproc should return "testresult"')
self.fc.exec_command_test('set_sys units MM')
self.fc.exec_command_test('new')
# object should not exists anymore
geometry_obj = self.fc.collection.get_by_name(self.geometry_name)
self.assertIsNone(geometry_obj, "Expected object to be None, instead, %s is %s"
% (self.geometry_name, type(geometry_obj)))
# TODO after new it should delete all procedures and variables, we need to make sure "testproc" does not exists
# Test it again with same names
self.fc.exec_command_test('set_sys units MM')
self.fc.exec_command_test('new')
self.fc.exec_command_test('new_geometry "%s"' % self.geometry_name)
geometry_obj = self.fc.collection.get_by_name(self.geometry_name)
self.assertTrue(isinstance(geometry_obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (self.geometry_name, type(geometry_obj)))
self.fc.exec_command_test('set_sys units MM')
self.fc.exec_command_test('new')
# object should not exists anymore
geometry_obj = self.fc.collection.get_by_name(self.geometry_name)
self.assertIsNone(geometry_obj, "Expected object to be None, instead, %s is %s"
% (self.geometry_name, type(geometry_obj)))

View File

@@ -1,14 +0,0 @@
from FlatCAMObj import FlatCAMGeometry
def test_new_geometry(self):
"""
Test create new geometry
:param self:
:return:
"""
self.fc.exec_command_test('new_geometry "%s"' % self.geometry_name)
geometry_obj = self.fc.collection.get_by_name(self.geometry_name)
self.assertTrue(isinstance(geometry_obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (self.geometry_name, type(geometry_obj)))

View File

@@ -1,15 +0,0 @@
from FlatCAMObj import FlatCAMExcellon
def test_open_excellon(self):
"""
Test open excellon file
:param self:
:return:
"""
self.fc.exec_command_test('open_excellon %s/%s -outname %s'
% (self.gerber_files, self.excellon_filename, self.excellon_name))
excellon_obj = self.fc.collection.get_by_name(self.excellon_name)
self.assertTrue(isinstance(excellon_obj, FlatCAMExcellon), "Expected FlatCAMExcellon, instead, %s is %s"
% (self.excellon_name, type(excellon_obj)))

View File

@@ -1,25 +0,0 @@
from FlatCAMObj import FlatCAMGerber
def test_open_gerber(self):
"""
Test open gerber file
:param self:
:return:
"""
self.fc.exec_command_test('open_gerber %s/%s -outname %s'
% (self.gerber_files, self.copper_top_filename, self.gerber_top_name))
gerber_top_obj = self.fc.collection.get_by_name(self.gerber_top_name)
self.assertTrue(isinstance(gerber_top_obj, FlatCAMGerber), "Expected FlatCAMGerber, instead, %s is %s"
% (self.gerber_top_name, type(gerber_top_obj)))
self.fc.exec_command_test('open_gerber %s/%s -outname %s'
% (self.gerber_files, self.copper_bottom_filename, self.gerber_bottom_name))
gerber_bottom_obj = self.fc.collection.get_by_name(self.gerber_bottom_name)
self.assertTrue(isinstance(gerber_bottom_obj, FlatCAMGerber), "Expected FlatCAMGerber, instead, %s is %s"
% (self.gerber_bottom_name, type(gerber_bottom_obj)))
#just read with original name
self.fc.exec_command_test('open_gerber %s/%s'
% (self.gerber_files, self.copper_top_filename))

View File

@@ -1,25 +0,0 @@
from FlatCAMObj import FlatCAMGeometry
def test_paint_polygon(self):
"""
Test create paint polygon geometry
:param self:
:return:
"""
self.fc.exec_command_test('new_geometry "%s"' % self.geometry_name)
geometry_obj = self.fc.collection.get_by_name(self.geometry_name)
self.assertTrue(isinstance(geometry_obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
% (self.geometry_name, type(geometry_obj)))
points = '0 0 20 0 10 10 0 10'
self.fc.exec_command_test('add_polygon "%s" %s' % (self.geometry_name, points))
# TODO rename to paint_polygon in future oop command implementation
self.fc.exec_command_test('paint_poly "%s" 5 5 2 0.5' % (self.geometry_name))
geometry_obj = self.fc.collection.get_by_name(self.geometry_name+'_paint')
# TODO uncoment check after oop implementation, because of threading inside paint poly
#self.assertTrue(isinstance(geometry_obj, FlatCAMGeometry), "Expected FlatCAMGeometry, instead, %s is %s"
# % (self.geometry_name+'_paint', type(geometry_obj)))

View File

@@ -1,272 +0,0 @@
import sys
import unittest
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtCore import QThread
from FlatCAMApp import App
from os import listdir
from os.path import isfile
from FlatCAMObj import FlatCAMGerber, FlatCAMGeometry, FlatCAMCNCjob, FlatCAMExcellon
from flatcamGUI.ObjectUI import GerberObjectUI, GeometryObjectUI
from time import sleep
import os
import tempfile
class TclShellTest(unittest.TestCase):
svg_files = 'tests/svg'
svg_filename = 'Arduino Nano3_pcb.svg'
gerber_files = 'tests/gerber_files'
copper_bottom_filename = 'detector_copper_bottom.gbr'
copper_top_filename = 'detector_copper_top.gbr'
cutout_filename = 'detector_contour.gbr'
excellon_filename = 'detector_drill.txt'
gerber_name = "gerber"
geometry_name = "geometry"
excellon_name = "excellon"
gerber_top_name = "top"
gerber_bottom_name = "bottom"
gerber_cutout_name = "cutout"
engraver_diameter = 0.3
cutout_diameter = 3
drill_diameter = 0.8
# load test methods to split huge test file into smaller pieces
# reason for this is reuse one test window only,
# CANNOT DO THIS HERE!!!
# from tests.test_tclCommands import *
@classmethod
def setUpClass(cls):
cls.setup = True
cls.app = QtWidgets.QApplication(sys.argv)
# Create App, keep app defaults (do not load
# user-defined defaults).
cls.fc = App(user_defaults=False)
cls.fc.ui.shell_dock.show()
def setUp(self):
self.fc.exec_command_test('set_sys units MM')
self.fc.exec_command_test('new')
@classmethod
def tearDownClass(cls):
cls.fc.tcl = None
cls.app.closeAllWindows()
del cls.fc
del cls.app
pass
def test_set_get_units(self):
"""
Tests setting and getting units via the ``set_sys`` command,
and persistance after ``new`` command.
:return: None
"""
# MM
self.fc.exec_command_test('set_sys units MM')
self.fc.exec_command_test('new')
# IN
self.fc.exec_command_test('set_sys units IN')
self.fc.exec_command_test('new')
# ----------------------------------------
# Units must be IN
# ----------------------------------------
units = self.fc.exec_command_test('get_sys units')
self.assertEqual(units, "IN")
# MM
self.fc.exec_command_test('set_sys units MM')
self.fc.exec_command_test('new')
# ----------------------------------------
# Units must be MM
# ----------------------------------------
units = self.fc.exec_command_test('get_sys units')
self.assertEqual(units, "MM")
def test_gerber_flow(self):
"""
Typical workflow from Gerber to GCode.
:return: None
"""
gbr_cmd = 'open_gerber {path}/{filename} -outname {outname}'
# -----------------------------------------
# Open top layer and check for object type
# -----------------------------------------
cmd = gbr_cmd.format(
path=self.gerber_files,
filename=self.copper_top_filename,
outname=self.gerber_top_name)
self.fc.exec_command_test(cmd)
gerber_top_obj = self.fc.collection.get_by_name(self.gerber_top_name)
self.assertTrue(isinstance(gerber_top_obj, FlatCAMGerber),
"Expected FlatCAMGerber, instead, %s is %s" %
(self.gerber_top_name, type(gerber_top_obj)))
# --------------------------------------------
# Open bottom layer and check for object type
# --------------------------------------------
cmd = gbr_cmd.format(
path=self.gerber_files,
filename=self.copper_bottom_filename,
outname=self.gerber_bottom_name)
self.fc.exec_command_test(cmd)
gerber_bottom_obj = self.fc.collection.get_by_name(self.gerber_bottom_name)
self.assertTrue(isinstance(gerber_bottom_obj, FlatCAMGerber),
"Expected FlatCAMGerber, instead, %s is %s" %
(self.gerber_bottom_name, type(gerber_bottom_obj)))
# --------------------------------------------
# Open cutout layer and check for object type
# --------------------------------------------
cmd = gbr_cmd.format(
path=self.gerber_files,
filename=self.cutout_filename,
outname=self.gerber_cutout_name
)
self.fc.exec_command_test(cmd)
gerber_cutout_obj = self.fc.collection.get_by_name(self.gerber_cutout_name)
self.assertTrue(isinstance(gerber_cutout_obj, FlatCAMGerber),
"Expected FlatCAMGerber, instead, %s is %s" %
(self.gerber_cutout_name, type(gerber_cutout_obj)))
# exteriors delete and join geometries for top layer
cmd = 'isolate {objname} -dia {dia}'.format(
objname=self.gerber_cutout_name,
dia=self.engraver_diameter)
self.fc.exec_command_test(cmd)
cmd = 'exteriors {objname} -outname {outname}'.format(
objname=self.gerber_cutout_name + '_iso',
outname=self.gerber_cutout_name + '_iso_exterior')
self.fc.exec_command_test(cmd)
cmd = 'delete {objname}'.format(
objname=self.gerber_cutout_name + '_iso')
self.fc.exec_command_test(cmd)
# TODO: Check deleteb object is gone.
# --------------------------------------------
# Exteriors of cutout layer, check type
# --------------------------------------------
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_iso_exterior')
self.assertTrue(isinstance(obj, FlatCAMGeometry),
"Expected FlatCAMGeometry, instead, %s is %s" %
(self.gerber_cutout_name + '_iso_exterior', type(obj)))
# mirror bottom gerbers
self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.gerber_bottom_name, self.gerber_cutout_name))
self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.gerber_cutout_name, self.gerber_cutout_name))
# exteriors delete and join geometries for bottom layer
self.fc.exec_command_test(
'isolate %s -dia %f -outname %s' %
(self.gerber_cutout_name, self.engraver_diameter, self.gerber_cutout_name + '_bottom_iso')
)
self.fc.exec_command_test(
'exteriors %s -outname %s' %
(self.gerber_cutout_name + '_bottom_iso', self.gerber_cutout_name + '_bottom_iso_exterior')
)
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso'))
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_bottom_iso_exterior')
self.assertTrue(isinstance(obj, FlatCAMGeometry),
"Expected FlatCAMGeometry, instead, %s is %s" %
(self.gerber_cutout_name + '_bottom_iso_exterior', type(obj)))
# at this stage we should have 5 objects
names = self.fc.collection.get_names()
self.assertEqual(len(names), 5,
"Expected 5 objects, found %d" % len(names))
# isolate traces
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_top_name, self.engraver_diameter))
self.fc.exec_command_test('isolate %s -dia %f' % (self.gerber_bottom_name, self.engraver_diameter))
# join isolated geometries for top and bottom
self.fc.exec_command_test(
'join_geometries %s %s %s' %
(self.gerber_top_name + '_join_iso', self.gerber_top_name + '_iso',
self.gerber_cutout_name + '_iso_exterior')
)
self.fc.exec_command_test(
'join_geometries %s %s %s' %
(self.gerber_bottom_name + '_join_iso', self.gerber_bottom_name + '_iso',
self.gerber_cutout_name + '_bottom_iso_exterior')
)
# at this stage we should have 9 objects
names = self.fc.collection.get_names()
self.assertEqual(len(names), 9,
"Expected 9 objects, found %d" % len(names))
# clean unused isolations
self.fc.exec_command_test('delete %s' % (self.gerber_bottom_name + '_iso'))
self.fc.exec_command_test('delete %s' % (self.gerber_top_name + '_iso'))
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_iso_exterior'))
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso_exterior'))
# at this stage we should have 5 objects again
names = self.fc.collection.get_names()
self.assertEqual(len(names), 5,
"Expected 5 objects, found %d" % len(names))
# geocutout bottom test (it cuts to same object)
self.fc.exec_command_test(
'isolate %s -dia %f -outname %s' %
(self.gerber_cutout_name, self.cutout_diameter, self.gerber_cutout_name + '_bottom_iso')
)
self.fc.exec_command_test(
'exteriors %s -outname %s' %
(self.gerber_cutout_name + '_bottom_iso', self.gerber_cutout_name + '_bottom_iso_exterior')
)
self.fc.exec_command_test('delete %s' % (self.gerber_cutout_name + '_bottom_iso'))
obj = self.fc.collection.get_by_name(self.gerber_cutout_name + '_bottom_iso_exterior')
self.assertTrue(isinstance(obj, FlatCAMGeometry),
"Expected FlatCAMGeometry, instead, %s is %s" %
(self.gerber_cutout_name + '_bottom_iso_exterior', type(obj)))
self.fc.exec_command_test('geocutout %s -dia %f -gapsize 0.3 -gaps 4' %
(self.gerber_cutout_name + '_bottom_iso_exterior', self.cutout_diameter))
# at this stage we should have 6 objects
names = self.fc.collection.get_names()
self.assertEqual(len(names), 6,
"Expected 6 objects, found %d" % len(names))
# TODO: tests for tcl
def test_open_gerber(self):
self.fc.exec_command_test('open_gerber %s/%s -outname %s' %
(self.gerber_files, self.copper_top_filename, self.gerber_top_name))
gerber_top_obj = self.fc.collection.get_by_name(self.gerber_top_name)
self.assertTrue(isinstance(gerber_top_obj, FlatCAMGerber),
"Expected FlatCAMGerber, instead, %s is %s" %
(self.gerber_top_name, type(gerber_top_obj)))
def test_excellon_flow(self):
self.fc.exec_command_test('open_excellon %s/%s -outname %s' %
(self.gerber_files, self.excellon_filename, self.excellon_name))
excellon_obj = self.fc.collection.get_by_name(self.excellon_name)
self.assertTrue(isinstance(excellon_obj, FlatCAMExcellon),
"Expected FlatCAMExcellon, instead, %s is %s" %
(self.excellon_name, type(excellon_obj)))
# mirror bottom excellon
self.fc.exec_command_test('mirror %s -box %s -axis X' % (self.excellon_name, self.gerber_cutout_name))
# TODO: tests for tcl

View File

@@ -1,26 +0,0 @@
"""
Test cases for Voronoi Diagram creation.
Overall, I'm trying less to test the correctness of the result
and more to cover input cases and behavior, making sure
that we return a sane result without error or raise a useful one.
"""
import pytest
from shapely.geos import geos_version
from shapely.wkt import loads as load_wkt
from shapely.ops import voronoi_diagram
requires_geos_35 = pytest.mark.skipif(geos_version < (3, 5, 0), reason='GEOS >= 3.5.0 is required.')
@requires_geos_35
def test_from_multipoint_without_tolerace_with_floating_point_coordinates():
"""But it's fine without it."""
mp = load_wkt('MULTIPOINT (20.1273 18.7303, 26.5107 18.7303, 20.1273 23.8437, 26.5107 23.8437)')
regions = voronoi_diagram(mp)
print("Len: %d -> Regions: %s" % (len(regions), str(regions)))
print(geos_version)
test_from_multipoint_without_tolerace_with_floating_point_coordinates()

View File

@@ -1,197 +0,0 @@
# ########################################################
# # customize Title bar
# # dotpy.ir
# # iraj.jelo@gmail.com
# ########################################################
import sys
from PyQt6 import QtWidgets, QtGui
from PyQt6 import QtCore
from PyQt6.QtCore import Qt
from datetime import datetime
import traceback
class TitleBar(QtWidgets.QDialog):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
css = """
QWidget{
Background: #0000FF;
color:white;
font:12px bold;
font-weight:bold;
border-radius: 1px;
height: 11px;
}
QDialog{
Background-image:url('img/titlebar bg.png');
font-size:12px;
color: black;
}
QToolButton{
Background:#AA00AA;
font-size:11px;
}
QToolButton:hover{
Background: #FF00FF;
font-size:11px;
}
"""
self.setAutoFillBackground(True)
self.setBackgroundRole(QtGui.QPalette.ColorRole.Highlight)
self.setStyleSheet(css)
self.minimize = QtWidgets.QToolButton(self)
self.minimize.setIcon(QtGui.QIcon('img/min.png'))
self.maximize = QtWidgets.QToolButton(self)
self.maximize.setIcon(QtGui.QIcon('img/max.png'))
close = QtWidgets.QToolButton(self)
close.setIcon(QtGui.QIcon('img/close.png'))
self.minimize.setMinimumHeight(10)
close.setMinimumHeight(10)
self.maximize.setMinimumHeight(10)
label = QtWidgets.QLabel(self)
label.setText("Window Title")
self.setWindowTitle("Window Title")
hbox = QtWidgets.QHBoxLayout(self)
hbox.addWidget(label)
hbox.addWidget(self.minimize)
hbox.addWidget(self.maximize)
hbox.addWidget(close)
hbox.insertStretch(1, 500)
hbox.setSpacing(0)
self.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed)
self.maxNormal = False
close.clicked.connect(self.close)
self.minimize.clicked.connect(self.showSmall)
self.maximize.clicked.connect(self.showMaxRestore)
@staticmethod
def showSmall():
box.showMinimized()
def showMaxRestore(self):
if self.maxNormal:
box.showNormal()
self.maxNormal = False
self.maximize.setIcon(QtGui.QIcon('img/max.png'))
else:
box.showMaximized()
self.maxNormal = True
self.maximize.setIcon(QtGui.QIcon('img/max2.png'))
def close(self):
box.close()
def mousePressEvent(self, event):
if event.button() == Qt.MouseButton.LeftButton:
box.moving = True
box.offset = event.position()
if event.type() == QtCore.QEvent.Type.MouseButtonDblClick:
self.showMaxRestore()
def mouseMoveEvent(self, event):
if box.isMaximized():
self.showMaxRestore()
box.move(event.globalPosition().toPoint() - box.offset)
else:
if box.moving:
box.move(event.globalPosition().toPoint() - box.offset)
class Frame(QtWidgets.QFrame):
def __init__(self, parent=None):
QtWidgets.QFrame.__init__(self, parent)
self.m_old_pos = None
self.m_mouse_down = False
self.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
css = """
QFrame{
Background: #FFFFF0;
color:white;
font:13px ;
font-weight:bold;
}
"""
self.setStyleSheet(css)
self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
self.setMouseTracking(True)
self.m_titleBar = TitleBar(self)
self.m_content = QtWidgets.QWidget(self)
vbox = QtWidgets.QVBoxLayout(self)
vbox.addWidget(self.m_titleBar)
vbox.setContentsMargins(0, 0, 0, 0)
vbox.setSpacing(0)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.m_content)
layout.setContentsMargins(5, 5, 5, 5)
layout.setSpacing(0)
vbox.addLayout(layout)
# Allows you to access the content area of the frame
# where widgets and layouts can be added
def contentWidget(self):
return self.m_content
def titleBar(self):
return self.m_titleBar
def mousePressEvent(self, event):
self.m_old_pos = event.pos()
self.m_mouse_down = event.button() == Qt.MouseButton.LeftButton
def mouseMoveEvent(self, event):
event.position().x()
event.position().y()
def mouseReleaseEvent(self, event):
self.m_mouse_down = False
if __name__ == '__main__':
def excepthook(exc_type, exc_value, exc_tb):
msg = '%s\n' % str(datetime.today())
if exc_type != KeyboardInterrupt:
msg += "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
# show the message
try:
msgbox = QtWidgets.QMessageBox()
displayed_msg = "The application encountered a critical error and it will close.\n" \
"Please report this error to the developers."
msgbox.setText(displayed_msg)
msgbox.setDetailedText(msg)
msgbox.setWindowTitle("Critical Error")
# msgbox.setWindowIcon()
msgbox.setIcon(QtWidgets.QMessageBox.Icon.Critical)
bt_yes = msgbox.addButton("Quit", QtWidgets.QMessageBox.ButtonRole.YesRole)
msgbox.setDefaultButton(bt_yes)
# msgbox.setTextFormat(Qt.TextFormat.RichText)
msgbox.exec()
except Exception:
pass
QtWidgets.QApplication.quit()
# or QtWidgets.QApplication.exit(0)
sys.excepthook = excepthook
app = QtWidgets.QApplication(sys.argv)
box = Frame()
box.move(60, 60)
le = QtWidgets.QVBoxLayout(box.contentWidget())
le.setContentsMargins(0, 0, 0, 0)
edit = QtWidgets.QLabel("""I would've did anything for you to show you how much I adored you
But it's over now, it's too late to save our loveJust promise me you'll think of me
Every time you look up in the sky and see a star 'cuz I'm your star.""")
le.addWidget(edit)
box.show()
app.exec()

View File

@@ -1,8 +0,0 @@
# Run kernprof -l -v gerber_parsing_line_profile_1.py
import sys
sys.path.append('../../')
from camlib import *
from shapely.geometry import Polygon
poly = Polygon([(0.0, 0.0), (1.0, 0.0), (1.0, 0.5), (0.0, 0.5)])
result = Geometry.clear_polygon2(poly, 0.01)

View File

@@ -1,11 +0,0 @@
import cProfile
import pstats
from camlib import *
from shapely.geometry import Polygon
poly = Polygon([(0.0, 0.0), (1.0, 0.0), (1.0, 0.5), (0.0, 0.5)])
cProfile.run('result = Geometry.clear_polygon2(poly, 0.01)',
'toollist_minimization_profile', sort='cumtime')
p = pstats.Stats('toollist_minimization_profile')
p.sort_stats('cumulative').print_stats(.1)