├── .git_filters ├── rcs-keywords.clean └── rcs-keywords.smudge ├── .gitattributes ├── .gitignore ├── README Keyword Substitution ├── doc ├── 2-1-23-28 copy.pdf ├── 2-1-23-28.pdf ├── DAC05OffsetPolygon.pdf ├── DXF2GCODE_Beschreibung_b02_tkinter.doc ├── DXF2GCODE_Beschreibung_v01.doc ├── DXF2GCODE_Zusammenhänge_der_Skripts.doc ├── LKH_REPORT.pdf ├── TSPchapter.pdf ├── [31] CAD-01-UncutFreePocketing.pdf ├── acad_dxf2010.pdf ├── arcinterpolation.pdf ├── dxf2002.pdf ├── dxf2ble10b10.zip ├── eurocg08-slides.pdf ├── liu2007_line_arc_offset[1].pdf └── mscthesis.pdf ├── dxf ├── 1.dxf ├── 132_2000.dxf ├── 132_R14.dxf ├── 1997.DXF ├── 1997_simplified.dxf ├── 1997_simplified_doppelte_linien.dxf ├── 2.dxf ├── 2010-06-13 test.dxf ├── 2010-06-13_test_kor.dxf ├── 2011-08-09_test.dxf ├── 2013-11-08_test.dxf ├── 3.dxf ├── ADLER.DXF ├── AFluegel Rippen b2 0201.dxf ├── ATT00079.dxf ├── Blocktest.JPG ├── Blocktest.dxf ├── Bogen_Ellipsen_Polylinien_Block.dxf ├── BreakExample.dxf ├── BreakExample_Circle.dxf ├── DEMO.DXF ├── DRAAK.dxf ├── DXF_132_-.dxf ├── Drawing2.dxf ├── Ellipsenbögen_Block_gedreht.JPG ├── Ellipsenbögen_Block_gedreht.dxf ├── Ellipsenbögen_Block_kopiert.JPG ├── Ellipsenbögen_Block_kopiert.dxf ├── Ellipsenbögen_Block_radial_60_Grad.JPG ├── Ellipsenbögen_Block_radial_60_Grad.dxf ├── Ellipsenbögen_einfach.JPG ├── Ellipsenbögen_einfach.dxf ├── FLH-001.dxf ├── Flügel Rippen sp2 0201.dxf ├── Frontplatte_Texte_aufgebrochen.dxf ├── Hardcopy.pdf ├── IFluegel Rippen b2 0201 a.ngc ├── IFluegel Rippen b2 0201 b.ngc ├── IFluegel Rippen b2 0201.dxf ├── Inkspace_dxf_export_kreis_splines.dxf ├── Kurve_Polylinien.dxf ├── Kurven1-14.dxf ├── LinieBlock.JPG ├── LinieBlock1-Meines.JPG ├── LinieBlock1Turbocad.JPG ├── Linieblock.dxf ├── Linieblock1.dxf ├── Lueftergitter_R14.dxf ├── Polylinie.dxf ├── SchlittenBack.dxf ├── Schlüssel_Andi.dxf ├── Schlüssel_Andi.jpg ├── Spline_Problem.dxf ├── Spriale14.dxf ├── Stir_1.dxf ├── Teile.dxf ├── Turbocad_12.5.dxf ├── UAP_212718.dxf ├── beispiel_wordart.doc ├── beispiel_wordart.pdf ├── deformed_spline.png ├── erin.dxf ├── erin7.ngc ├── ferrari.dxf ├── foobar.dxf ├── fräsen_test_02 2004.dxf ├── lines_through_cutting_depth1.dat ├── lines_through_cutting_depth2.png ├── no_problem_with_arc_alone.dxf ├── numbers.dxf ├── owl01.dxf ├── print.pdf ├── print.ps ├── problem_with_arc_and_problem_with_G41-G42_auto_switch.dxf ├── problem_with_arc_and_problem_with_G41-G42_auto_switch_red.dxf ├── problem_with_arc_in_block.dxf ├── problem_with_arc_in_blockqcad.dxf ├── probleme.dxf ├── pstoedit_test.pdf ├── pumpenteile.dxf ├── qcad_test_Elements_zero.dxf ├── rib_test.dxf ├── sector.dxf ├── test.dxf ├── test1.dxf ├── toe_test.dxf └── vdr_Fraeskontur_Fraesermitte.dxf ├── links └── DXF2GCODE Webpage.URL ├── python_examples ├── Ellipse_BiArc │ ├── BIARC_TEST.py │ ├── clsBiArc.py │ ├── clsEllipse.py │ ├── clsGeometrie.py │ └── test.bat ├── Ellipse_fitting_by_Biarc_curves.py ├── FloatCanvasDemo.py ├── GridDemo.py ├── Kegelstump_Abwicklung_2dxf.py ├── NURBS_fitting_by_Biarc_curves.py ├── NURBS_fitting_by_Biarc_curves_wx.py ├── Offset │ ├── Pairwise_offset_algorithm.py │ └── euclid.py ├── canvas_sample.py ├── customtreectrl.py ├── gtk │ ├── animationrotation.py │ ├── filesel.py │ ├── make_exe.py │ ├── polyline_hit_inside.py │ └── pygtkcanvas-1.0 │ │ ├── LICENSE │ │ ├── README │ │ ├── __init__.py │ │ ├── canvas.py │ │ ├── canvasitem.py │ │ ├── canvaslayer.py │ │ ├── canvasmath.py │ │ ├── example.py │ │ ├── image1.png │ │ ├── image2.jpeg │ │ ├── pygtkcanvas-design.dia │ │ └── pygtkcanvas.geany ├── make_exe.py ├── menu_test.py ├── progressbar.py ├── qt │ ├── Starte_mein_gui.py │ ├── Starte_mein_gui.spec │ ├── context_menu.py │ ├── demo.py │ ├── demo.ui │ ├── diagramscene.py │ ├── diagramscene.pyw │ ├── diagramscene.qrc │ ├── diagramscene_rc.py │ ├── filedialog.py │ ├── graphicscene_test.py │ ├── images │ │ ├── background1.png │ │ ├── background2.png │ │ ├── background3.png │ │ ├── background4.png │ │ ├── bold.png │ │ ├── bringtofront.png │ │ ├── delete.png │ │ ├── floodfill.png │ │ ├── italic.png │ │ ├── linecolor.png │ │ ├── linepointer.png │ │ ├── pointer.png │ │ ├── sendtoback.png │ │ ├── textpointer.png │ │ └── underline.png │ ├── make_exe.py │ ├── make_py_uic.py │ ├── mein_test.py │ └── warnStarte_mein_gui.txt ├── travelling_salesman_problem_2.py └── treewidget.py └── source ├── COPYING ├── core ├── __init__.py ├── arcgeo.py ├── boundingbox.py ├── breakgeo.py ├── customgcode.py ├── entitycontent.py ├── holegeo.py ├── intersect.py ├── layercontent.py ├── linegeo.py ├── point.py ├── point3d.py ├── project.py ├── shape.py ├── shapeoffset.py └── stmove.py ├── dxf2gcode.py ├── dxf2gcode.ui ├── dxf2gcode_images.qrc ├── dxf2gcode_images4_rc.py ├── dxf2gcode_images5_rc.py ├── dxf2gcode_ui4.py ├── dxf2gcode_ui5.py ├── dxfimport ├── __init__.py ├── biarc.py ├── classes.py ├── geoent_arc.py ├── geoent_circle.py ├── geoent_ellipse.py ├── geoent_insert.py ├── geoent_line.py ├── geoent_lwpolyline.py ├── geoent_point.py ├── geoent_polyline.py ├── geoent_spline.py ├── importer.py └── spline_convert.py ├── globals ├── __init__.py ├── config.py ├── configobj │ ├── PKG-INFO │ ├── __init__.py │ ├── _version.py │ ├── configobj.py │ ├── setup.py │ └── validate.py ├── constants.py ├── d2gexceptions.py ├── globals.py ├── logger.py └── six.py ├── gui ├── __init__.py ├── aboutdialog.py ├── arrow.py ├── canvas.py ├── canvas2d.py ├── canvas3d.py ├── configwindow.py ├── messagebox.py ├── popupdialog.py ├── routetext.py ├── treehandling.py ├── treeview.py └── wpzero.py ├── i18n ├── dxf2gcode_de_DE.qm ├── dxf2gcode_de_DE.ts ├── dxf2gcode_fr.qm ├── dxf2gcode_fr.ts ├── dxf2gcode_ru.qm └── dxf2gcode_ru.ts ├── images ├── DXF2GCODE-001.ico ├── blocks.png ├── collapse-all.png ├── custom.png ├── delete.png ├── dxf2gcode_logo.png ├── expand-all.png ├── go-down.png ├── go-up.png ├── layer.png ├── list-add.png ├── list-remove.png └── shape.png ├── make_exe.py ├── make_py_uic.py ├── make_tr.py ├── postpro ├── __init__.py ├── breaks.py ├── postprocessor.py ├── postprocessorconfig.py └── tspoptimisation.py └── setup.py /.git_filters/rcs-keywords.clean: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -p 2 | # 3 | # @brief Git filter to implement rcs keyword expansion as seen in cvs and svn. 4 | # @author Martin Turon 5 | # 6 | # Copyright (c) 2009-2011 Turon Technologies, Inc. All rights reserved. 7 | 8 | s/\$Id[^\$]*\$/\$Id\$/; 9 | s/\$Date[^\$]*\$/\$Date\$/; 10 | s/\$Author[^\$]*\$/\$Author\$/; 11 | s/\$Source[^\$]*\$/\$Source\$/; 12 | s/\$File[^\$]*\$/\$File\$/; 13 | s/\$Revision[^\$]*\$/\$Revision\$/; 14 | -------------------------------------------------------------------------------- /.git_filters/rcs-keywords.smudge: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # @brief Git filter to implement rcs keyword expansion as seen in cvs and svn. 4 | # @author Martin Turon 5 | # 6 | # Usage: 7 | # .git_filter/rcs-keywords.smudge file_path < file_contents 8 | # 9 | # To add keyword expansion: 10 | # /.gitattributes - *.c filter=rcs-keywords 11 | # /.git_filters/rcs-keywords.smudge - copy this file to project 12 | # /.git_filters/rcs-keywords.clean - copy companion to project 13 | # ~/.gitconfig - add [filter] lines below 14 | # 15 | # [filter "rcs-keywords"] 16 | # clean = .git_filters/rcs-keywords.clean 17 | # smudge = .git_filters/rcs-keywords.smudge %f 18 | # 19 | # Copyright (c) 2009-2011 Turon Technologies, Inc. All rights reserved. 20 | 21 | $path = shift; 22 | $path =~ /.*\/(.*)/; 23 | $filename = $1; 24 | 25 | if (0 == length($filename)) { 26 | $filename = $path; 27 | } 28 | 29 | # Need to grab filename and to use git log for this to be accurate. 30 | $rev = `git log -- | head -n 3`; 31 | $rev =~ /^Author:\s*(.*)\s*$/m; 32 | $author = $1; 33 | $author =~ /\s*(.*)\s*<.*/; 34 | $name = $1; 35 | $rev =~ /^Date:\s*(.*)\s*$/m; 36 | $date = $1; 37 | $rev =~ /^commit (.*)$/m; 38 | $ident = $1; 39 | 40 | while () { 41 | s/\$Date[^\$]*\$/\$Date: $date \$/; 42 | s/\$Author[^\$]*\$/\$Author: $author \$/; 43 | s/\$Id[^\$]*\$/\$Id: $filename | $date | $name \$/; 44 | s/\$File[^\$]*\$/\$File: $filename \$/; 45 | s/\$Source[^\$]*\$/\$Source: $path \$/; 46 | s/\$Revision[^\$]*\$/\$Revision: $ident \$/; 47 | } continue { 48 | print or die "-p destination: $!\n"; 49 | } 50 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # .gitattributes 2 | # Map file extensions to git filters 3 | 4 | constants.py filter=rcs-keywords 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | dist/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | 47 | logfile.txt 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | 56 | # Sphinx documentation 57 | docs/_build/ 58 | 59 | # PyBuilder 60 | target/ 61 | 62 | # Config files 63 | *.cfg 64 | 65 | # Eclipse Project stuff 66 | /.project 67 | /.pydevproject 68 | 69 | # PyCharm stuff 70 | .idea/ -------------------------------------------------------------------------------- /README Keyword Substitution: -------------------------------------------------------------------------------- 1 | # It proves to be very useful to show the user what version he/she is running in the about dialog 2 | # therefore, the easiest solution to achieve this is to use keyword substitution. 3 | 4 | # To add keyword substitution: 5 | # either, execute the following Git commands: 6 | 7 | $ git config filter.rcs-keywords.clean '.git_filters/rcs-keywords.clean' 8 | $ git config filter.rcs-keywords.smudge '.git_filters/rcs-keywords.smudge %f' 9 | 10 | # or add the following to ~/.gitconfig: 11 | 12 | [filter "rcs-keywords"] 13 | clean = .git_filters/rcs-keywords.clean 14 | smudge = .git_filters/rcs-keywords.smudge %f 15 | -------------------------------------------------------------------------------- /doc/2-1-23-28 copy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/2-1-23-28 copy.pdf -------------------------------------------------------------------------------- /doc/2-1-23-28.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/2-1-23-28.pdf -------------------------------------------------------------------------------- /doc/DAC05OffsetPolygon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/DAC05OffsetPolygon.pdf -------------------------------------------------------------------------------- /doc/DXF2GCODE_Beschreibung_b02_tkinter.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/DXF2GCODE_Beschreibung_b02_tkinter.doc -------------------------------------------------------------------------------- /doc/DXF2GCODE_Beschreibung_v01.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/DXF2GCODE_Beschreibung_v01.doc -------------------------------------------------------------------------------- /doc/DXF2GCODE_Zusammenhänge_der_Skripts.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/DXF2GCODE_Zusammenhänge_der_Skripts.doc -------------------------------------------------------------------------------- /doc/LKH_REPORT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/LKH_REPORT.pdf -------------------------------------------------------------------------------- /doc/TSPchapter.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/TSPchapter.pdf -------------------------------------------------------------------------------- /doc/[31] CAD-01-UncutFreePocketing.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/[31] CAD-01-UncutFreePocketing.pdf -------------------------------------------------------------------------------- /doc/acad_dxf2010.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/acad_dxf2010.pdf -------------------------------------------------------------------------------- /doc/arcinterpolation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/arcinterpolation.pdf -------------------------------------------------------------------------------- /doc/dxf2002.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/dxf2002.pdf -------------------------------------------------------------------------------- /doc/dxf2ble10b10.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/dxf2ble10b10.zip -------------------------------------------------------------------------------- /doc/eurocg08-slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/eurocg08-slides.pdf -------------------------------------------------------------------------------- /doc/liu2007_line_arc_offset[1].pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/liu2007_line_arc_offset[1].pdf -------------------------------------------------------------------------------- /doc/mscthesis.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/doc/mscthesis.pdf -------------------------------------------------------------------------------- /dxf/AFluegel Rippen b2 0201.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/AFluegel Rippen b2 0201.dxf -------------------------------------------------------------------------------- /dxf/Blocktest.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Blocktest.JPG -------------------------------------------------------------------------------- /dxf/Drawing2.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Drawing2.dxf -------------------------------------------------------------------------------- /dxf/Ellipsenbögen_Block_gedreht.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Ellipsenbögen_Block_gedreht.JPG -------------------------------------------------------------------------------- /dxf/Ellipsenbögen_Block_kopiert.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Ellipsenbögen_Block_kopiert.JPG -------------------------------------------------------------------------------- /dxf/Ellipsenbögen_Block_radial_60_Grad.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Ellipsenbögen_Block_radial_60_Grad.JPG -------------------------------------------------------------------------------- /dxf/Ellipsenbögen_einfach.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Ellipsenbögen_einfach.JPG -------------------------------------------------------------------------------- /dxf/FLH-001.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/FLH-001.dxf -------------------------------------------------------------------------------- /dxf/Flügel Rippen sp2 0201.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Flügel Rippen sp2 0201.dxf -------------------------------------------------------------------------------- /dxf/Hardcopy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Hardcopy.pdf -------------------------------------------------------------------------------- /dxf/IFluegel Rippen b2 0201 a.ngc: -------------------------------------------------------------------------------- 1 | (Generated with: dxf2gcode_b02, Version: TKINTER Beta 02, Date: 2010-03-30) 2 | (Time: Sun Apr 25 09:39:59 2010) 3 | (Created from file: C:/Dokumente und Einstellungen/llihab1/Eigene Dateien/Hauber/allg/hauber/Fliegen/Modellfliegen/marabu/Fräsen/Balsaholz/Fluegel/Baustand 02/IFluegel Rippen b2 0201.dxf) 4 | G21 (Unit in mm) 5 | G90 (Absolute distance mode) 6 | G64 P0.01 (Exact Path 0.001 tol.) 7 | G17 8 | G40 (Cancel diameter comp.) 9 | G49 (Cancel length comp.) 10 | T1M6 (Tool change to T1) 11 | M8 (Coolant flood on) 12 | S5000M03 (Spindle 5000rpm cw) 13 | G0 Z 5.000 14 | G0 X 27.180 Y 33.643 15 | G0 Z 2.000 16 | F150 17 | G1 Z -2.500 18 | F400 19 | G42 20 | G1 X 27.321 Y 33.219 21 | G2 X 26.473 Y 33.219 I -0.424 J 0.424 22 | G2 X 30.008 Y 36.754 I 1.768 J 1.768 23 | G2 X 26.473 Y 33.219 I -1.768 J -1.768 24 | G1 Z 2.000 25 | G0 Z 5.000 26 | G40 27 | G0 X 27.197 Y 54.393 28 | G0 Z 2.000 29 | F150 30 | G1 Z -2.500 31 | F400 32 | G42 33 | G1 X 27.338 Y 53.969 34 | G2 X 26.490 Y 53.969 I -0.424 J 0.424 35 | G2 X 30.025 Y 57.505 I 1.768 J 1.768 36 | G2 X 26.490 Y 53.969 I -1.768 J -1.768 37 | G1 Z 2.000 38 | G0 Z 5.000 39 | G40 40 | G0 X 25.734 Y 76.130 41 | G0 Z 2.000 42 | F150 43 | G1 Z -2.500 44 | F400 45 | G42 46 | G1 X 25.876 Y 75.706 47 | G2 X 25.027 Y 75.706 I -0.424 J 0.424 48 | G2 X 28.563 Y 79.241 I 1.768 J 1.768 49 | G2 X 25.027 Y 75.706 I -1.768 J -1.768 50 | G1 Z 2.000 51 | G0 Z 5.000 52 | G40 53 | G0 X 74.288 Y 81.693 54 | G0 Z 2.000 55 | F150 56 | G1 Z -2.500 57 | F400 58 | G42 59 | G1 X 74.429 Y 81.269 60 | G2 X 73.580 Y 81.269 I -0.424 J 0.424 61 | G2 X 77.151 Y 84.840 I 1.785 J 1.785 62 | G2 X 73.580 Y 81.269 I -1.785 J -1.785 63 | G1 Z 2.000 64 | G0 Z 5.000 65 | G40 66 | G0 X 178.470 Y 62.091 67 | G0 Z 2.000 68 | F150 69 | G1 Z -2.500 70 | F400 71 | G42 72 | G1 X 178.611 Y 61.667 73 | G2 X 177.763 Y 61.667 I -0.424 J 0.424 74 | G2 X 181.298 Y 65.202 I 1.768 J 1.768 75 | G2 X 177.763 Y 61.667 I -1.768 J -1.768 76 | G1 Z 2.000 77 | G0 Z 5.000 78 | G40 79 | G0 X 180.984 Y 82.150 80 | G0 Z 2.000 81 | F150 82 | G1 Z -2.500 83 | F400 84 | G42 85 | G1 X 181.126 Y 81.726 86 | G2 X 180.277 Y 81.726 I -0.424 J 0.424 87 | G2 X 183.813 Y 85.262 I 1.768 J 1.768 88 | G2 X 180.277 Y 81.726 I -1.768 J -1.768 89 | G1 Z 2.000 90 | G0 Z 5.000 91 | G40 92 | G0 X 229.782 Y 67.864 93 | G0 Z 2.000 94 | F150 95 | G1 Z -2.500 96 | F400 97 | G42 98 | G1 X 229.923 Y 67.440 99 | G2 X 229.075 Y 67.440 I -0.424 J 0.424 100 | G2 X 232.964 Y 71.329 I 1.945 J 1.945 101 | G2 X 229.075 Y 67.440 I -1.945 J -1.945 102 | G1 Z 2.000 103 | G0 Z 5.000 104 | G40 105 | G0 X 233.428 Y 88.200 106 | G0 Z 2.000 107 | F150 108 | G1 Z -2.500 109 | F400 110 | G42 111 | G1 X 233.570 Y 87.776 112 | G2 X 232.721 Y 87.776 I -0.424 J 0.424 113 | G2 X 236.292 Y 91.347 I 1.785 J 1.785 114 | G2 X 232.721 Y 87.776 I -1.785 J -1.785 115 | G1 Z 2.000 116 | G0 Z 5.000 117 | G40 118 | G0 X 346.555 Y 82.796 119 | G0 Z 2.000 120 | F150 121 | G1 Z -2.500 122 | F400 123 | G42 124 | G1 X 346.697 Y 82.372 125 | G2 X 345.848 Y 82.372 I -0.424 J 0.424 126 | G2 X 349.384 Y 85.908 I 1.768 J 1.768 127 | G2 X 345.848 Y 82.372 I -1.768 J -1.768 128 | G1 Z 2.000 129 | G0 Z 5.000 130 | G40 131 | G0 X 346.107 Y 61.942 132 | G0 Z 2.000 133 | F150 134 | G1 Z -2.500 135 | F400 136 | G42 137 | G1 X 346.249 Y 61.518 138 | G2 X 345.400 Y 61.518 I -0.424 J 0.424 139 | G2 X 348.936 Y 65.054 I 1.768 J 1.768 140 | G2 X 345.400 Y 61.518 I -1.768 J -1.768 141 | G1 Z 2.000 142 | G0 Z 5.000 143 | G40 144 | G0 X 346.468 Y 37.709 145 | G0 Z 2.000 146 | F150 147 | G1 Z -2.500 148 | F400 149 | G42 150 | G1 X 346.609 Y 37.284 151 | G2 X 345.760 Y 37.284 I -0.424 J 0.424 152 | G2 X 349.296 Y 40.820 I 1.768 J 1.768 153 | G2 X 345.760 Y 37.284 I -1.768 J -1.768 154 | G1 Z 2.000 155 | G0 Z 5.000 156 | G40 157 | G0 X 347.437 Y 12.867 158 | G0 Z 2.000 159 | F150 160 | G1 Z -2.500 161 | F400 162 | G42 163 | G1 X 347.578 Y 12.442 164 | G2 X 346.730 Y 12.442 I -0.424 J 0.424 165 | G2 X 350.265 Y 15.978 I 1.768 J 1.768 166 | G2 X 346.730 Y 12.442 I -1.768 J -1.768 167 | G1 Z 2.000 168 | G0 Z 5.000 169 | G40 170 | G0 X 231.942 Y 40.859 171 | G0 Z 2.000 172 | F150 173 | G1 Z -2.500 174 | F400 175 | G42 176 | G1 X 232.083 Y 40.434 177 | G2 X 231.235 Y 40.434 I -0.424 J 0.424 178 | G2 X 235.124 Y 44.323 I 1.945 J 1.945 179 | G2 X 231.235 Y 40.434 I -1.945 J -1.945 180 | G1 Z 2.000 181 | G0 Z 5.000 182 | G40 183 | G0 X 227.233 Y 19.172 184 | G0 Z 2.000 185 | F150 186 | G1 Z -2.500 187 | F400 188 | G42 189 | G1 X 227.374 Y 18.748 190 | G2 X 226.526 Y 18.748 I -0.424 J 0.424 191 | G2 X 230.415 Y 22.637 I 1.945 J 1.945 192 | G2 X 226.526 Y 18.748 I -1.945 J -1.945 193 | G1 Z 2.000 194 | G0 Z 5.000 195 | G40 196 | G0 X 181.603 Y 35.205 197 | G0 Z 2.000 198 | F150 199 | G1 Z -2.500 200 | F400 201 | G42 202 | G1 X 181.744 Y 34.781 203 | G2 X 180.896 Y 34.781 I -0.424 J 0.424 204 | G2 X 184.431 Y 38.316 I 1.768 J 1.768 205 | G2 X 180.896 Y 34.781 I -1.768 J -1.768 206 | G1 Z 2.000 207 | G0 Z 5.000 208 | G40 209 | G0 X 177.866 Y 13.647 210 | G0 Z 2.000 211 | F150 212 | G1 Z -2.500 213 | F400 214 | G42 215 | G1 X 178.007 Y 13.222 216 | G2 X 177.159 Y 13.222 I -0.424 J 0.424 217 | G2 X 180.694 Y 16.758 I 1.768 J 1.768 218 | G2 X 177.159 Y 13.222 I -1.768 J -1.768 219 | G1 Z 2.000 220 | G0 Z 5.000 221 | G40 222 | G0 X 26.670 Y 13.392 223 | G0 Z 2.000 224 | F150 225 | G1 Z -2.500 226 | F400 227 | G42 228 | G1 X 26.812 Y 12.968 229 | G2 X 25.963 Y 12.968 I -0.424 J 0.424 230 | G2 X 29.499 Y 16.503 I 1.768 J 1.768 231 | G2 X 25.963 Y 12.968 I -1.768 J -1.768 232 | G1 Z 2.000 233 | G0 Z 5.000 234 | G40 235 | G0 X 0.000 Y 0.000 236 | M9 (Coolant off) 237 | M5 (Spindle off) 238 | M2 (Prgram end) -------------------------------------------------------------------------------- /dxf/IFluegel Rippen b2 0201.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/IFluegel Rippen b2 0201.dxf -------------------------------------------------------------------------------- /dxf/Inkspace_dxf_export_kreis_splines.dxf: -------------------------------------------------------------------------------- 1 | 999 2 | DXF created by Inkscape 3 | 0 4 | SECTION 5 | 2 6 | ENTITIES 7 | 0 8 | SPLINE 9 | 5 10 | 43 11 | 8 12 | 0 13 | 62 14 | 256 15 | 370 16 | -1 17 | 6 18 | ByLayer 19 | 100 20 | AcDbEntity 21 | 100 22 | AcDbSpline 23 | 70 24 | 8 25 | 71 26 | 3 27 | 72 28 | 8 29 | 73 30 | 4 31 | 74 32 | 0 33 | 40 34 | 0 35 | 40 36 | 0 37 | 40 38 | 0 39 | 40 40 | 0 41 | 40 42 | 1 43 | 40 44 | 1 45 | 40 46 | 1 47 | 40 48 | 1 49 | 10 50 | 31.447619 51 | 20 52 | 67.733340 53 | 30 54 | 0 55 | 10 56 | 37.777750 57 | 20 58 | 70.921991 59 | 30 60 | 0 61 | 10 62 | 44.842151 63 | 20 64 | 69.719998 65 | 30 66 | 0 67 | 10 68 | 51.606348 69 | 20 70 | 67.733340 71 | 30 72 | 0 73 | 0 74 | SPLINE 75 | 5 76 | 43 77 | 8 78 | 0 79 | 62 80 | 256 81 | 370 82 | -1 83 | 6 84 | ByLayer 85 | 100 86 | AcDbEntity 87 | 100 88 | AcDbSpline 89 | 70 90 | 8 91 | 71 92 | 3 93 | 72 94 | 8 95 | 73 96 | 4 97 | 74 98 | 0 99 | 40 100 | 0 101 | 40 102 | 0 103 | 40 104 | 0 105 | 40 106 | 0 107 | 40 108 | 1 109 | 40 110 | 1 111 | 40 112 | 1 113 | 40 114 | 1 115 | 10 116 | 51.606348 117 | 20 118 | 67.733340 119 | 30 120 | 0 121 | 10 122 | 58.370546 123 | 20 124 | 65.746682 125 | 30 126 | 0 127 | 10 128 | 70.111846 129 | 20 130 | 59.596741 131 | 30 132 | 0 133 | 10 134 | 74.184126 135 | 20 136 | 53.219052 137 | 30 138 | 0 139 | 0 140 | SPLINE 141 | 5 142 | 43 143 | 8 144 | 0 145 | 62 146 | 256 147 | 370 148 | -1 149 | 6 150 | ByLayer 151 | 100 152 | AcDbEntity 153 | 100 154 | AcDbSpline 155 | 70 156 | 8 157 | 71 158 | 3 159 | 72 160 | 8 161 | 73 162 | 4 163 | 74 164 | 0 165 | 40 166 | 0 167 | 40 168 | 0 169 | 40 170 | 0 171 | 40 172 | 0 173 | 40 174 | 1 175 | 40 176 | 1 177 | 40 178 | 1 179 | 40 180 | 1 181 | 10 182 | 74.184126 183 | 20 184 | 53.219052 185 | 30 186 | 0 187 | 10 188 | 78.256407 189 | 20 190 | 46.841366 191 | 30 192 | 0 193 | 10 194 | 79.099893 195 | 20 196 | 35.804753 197 | 30 198 | 0 199 | 10 200 | 77.409525 201 | 20 202 | 29.834926 203 | 30 204 | 0 205 | 0 206 | SPLINE 207 | 5 208 | 43 209 | 8 210 | 0 211 | 62 212 | 256 213 | 370 214 | -1 215 | 6 216 | ByLayer 217 | 100 218 | AcDbEntity 219 | 100 220 | AcDbSpline 221 | 70 222 | 8 223 | 71 224 | 3 225 | 72 226 | 8 227 | 73 228 | 4 229 | 74 230 | 0 231 | 40 232 | 0 233 | 40 234 | 0 235 | 40 236 | 0 237 | 40 238 | 0 239 | 40 240 | 1 241 | 40 242 | 1 243 | 40 244 | 1 245 | 40 246 | 1 247 | 10 248 | 77.409525 249 | 20 250 | 29.834926 251 | 30 252 | 0 253 | 10 254 | 75.719155 255 | 20 256 | 23.865102 257 | 30 258 | 0 259 | 10 260 | 73.610953 261 | 20 262 | 20.496342 263 | 30 264 | 0 265 | 10 266 | 66.120637 267 | 20 268 | 16.126989 269 | 30 270 | 0 271 | 0 272 | SPLINE 273 | 5 274 | 43 275 | 8 276 | 0 277 | 62 278 | 256 279 | 370 280 | -1 281 | 6 282 | ByLayer 283 | 100 284 | AcDbEntity 285 | 100 286 | AcDbSpline 287 | 70 288 | 8 289 | 71 290 | 3 291 | 72 292 | 8 293 | 73 294 | 4 295 | 74 296 | 0 297 | 40 298 | 0 299 | 40 300 | 0 301 | 40 302 | 0 303 | 40 304 | 0 305 | 40 306 | 1 307 | 40 308 | 1 309 | 40 310 | 1 311 | 40 312 | 1 313 | 10 314 | 66.120637 315 | 20 316 | 16.126989 317 | 30 318 | 0 319 | 10 320 | 58.630320 321 | 20 322 | 11.757633 323 | 30 324 | 0 325 | 10 326 | 45.323546 327 | 20 328 | 2.312163 329 | 30 330 | 0 331 | 10 332 | 27.415873 333 | 20 334 | 13.707930 335 | 30 336 | 0 337 | 0 338 | SPLINE 339 | 5 340 | 43 341 | 8 342 | 0 343 | 62 344 | 256 345 | 370 346 | -1 347 | 6 348 | ByLayer 349 | 100 350 | AcDbEntity 351 | 100 352 | AcDbSpline 353 | 70 354 | 8 355 | 71 356 | 3 357 | 72 358 | 8 359 | 73 360 | 4 361 | 74 362 | 0 363 | 40 364 | 0 365 | 40 366 | 0 367 | 40 368 | 0 369 | 40 370 | 0 371 | 40 372 | 1 373 | 40 374 | 1 375 | 40 376 | 1 377 | 40 378 | 1 379 | 10 380 | 27.415873 381 | 20 382 | 13.707930 383 | 30 384 | 0 385 | 10 386 | 9.508201 387 | 20 388 | 25.103702 389 | 30 390 | 0 391 | 10 392 | 14.038074 393 | 20 394 | 36.820282 395 | 30 396 | 0 397 | 10 398 | 15.320635 399 | 20 400 | 45.961911 401 | 30 402 | 0 403 | 0 404 | SPLINE 405 | 5 406 | 43 407 | 8 408 | 0 409 | 62 410 | 256 411 | 370 412 | -1 413 | 6 414 | ByLayer 415 | 100 416 | AcDbEntity 417 | 100 418 | AcDbSpline 419 | 70 420 | 8 421 | 71 422 | 3 423 | 72 424 | 8 425 | 73 426 | 4 427 | 74 428 | 0 429 | 40 430 | 0 431 | 40 432 | 0 433 | 40 434 | 0 435 | 40 436 | 0 437 | 40 438 | 1 439 | 40 440 | 1 441 | 40 442 | 1 443 | 40 444 | 1 445 | 10 446 | 15.320635 447 | 20 448 | 45.961911 449 | 30 450 | 0 451 | 10 452 | 16.603196 453 | 20 454 | 55.103540 455 | 30 456 | 0 457 | 10 458 | 25.117487 459 | 20 460 | 64.544689 461 | 30 462 | 0 463 | 10 464 | 31.447619 465 | 20 466 | 67.733340 467 | 30 468 | 0 469 | 0 470 | LINE 471 | 8 472 | 2 473 | 62 474 | 4 475 | 10 476 | 31.447619 477 | 20 478 | 67.733340 479 | 30 480 | 0 481 | 11 482 | 31.447619 483 | 21 484 | 67.733340 485 | 31 486 | 0 487 | 0 488 | ENDSEC 489 | 0 490 | EOF 491 | 492 | -------------------------------------------------------------------------------- /dxf/LinieBlock.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/LinieBlock.JPG -------------------------------------------------------------------------------- /dxf/LinieBlock1-Meines.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/LinieBlock1-Meines.JPG -------------------------------------------------------------------------------- /dxf/LinieBlock1Turbocad.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/LinieBlock1Turbocad.JPG -------------------------------------------------------------------------------- /dxf/Schlüssel_Andi.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Schlüssel_Andi.dxf -------------------------------------------------------------------------------- /dxf/Schlüssel_Andi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/Schlüssel_Andi.jpg -------------------------------------------------------------------------------- /dxf/Spline_Problem.dxf: -------------------------------------------------------------------------------- 1 | 0 2 | SECTION 3 | 2 4 | ENTITIES 5 | 0 6 | SPLINE 7 | 8 8 | 0 9 | 62 10 | 7 11 | 210 12 | 0.0 13 | 220 14 | 0.0 15 | 230 16 | 1.0 17 | 70 18 | 8 19 | 71 20 | 5 21 | 72 22 | 15 23 | 73 24 | 9 25 | 74 26 | 0 27 | 42 28 | 0.0 29 | 43 30 | 0.0 31 | 40 32 | 0.2960716011585239 33 | 40 34 | 0.2960716011585239 35 | 40 36 | 0.2960716011585239 37 | 40 38 | 0.2960716011585239 39 | 40 40 | 0.2960716011585239 41 | 40 42 | 0.2960716011585239 43 | 40 44 | 1.6062952070777794 45 | 40 46 | 1.6062952070777794 47 | 40 48 | 1.6062952070777794 49 | 40 50 | 3.2645918963599247 51 | 40 52 | 3.2645918963599247 53 | 40 54 | 3.2645918963599247 55 | 40 56 | 3.2645918963599247 57 | 40 58 | 3.2645918963599247 59 | 40 60 | 3.2645918963599247 61 | 10 62 | 121.09966679259503 63 | 20 64 | 76.381201705220676 65 | 30 66 | 0.0 67 | 10 68 | 121.07130091929682 69 | 20 70 | 76.112062323237495 71 | 30 72 | 0.0 73 | 10 74 | 121.01596396413595 75 | 20 76 | 75.854818935882179 77 | 30 78 | 0.0 79 | 10 80 | 120.9337369057566 81 | 20 82 | 75.609495682694771 83 | 30 84 | 0.0 85 | 10 86 | 120.68750998502378 87 | 20 88 | 75.08098045958657 89 | 30 90 | 0.0 91 | 10 92 | 120.31774104417886 93 | 20 94 | 74.617973420667496 95 | 30 96 | 0.0 97 | 10 98 | 120.077457479202 99 | 20 100 | 74.38120837456222 101 | 30 102 | 0.0 103 | 10 104 | 119.81327498839786 105 | 20 106 | 74.169254479215283 107 | 30 108 | 0.0 109 | 10 110 | 119.53223325674307 111 | 20 112 | 73.984210247874302 113 | 30 114 | 0.0 115 | 0 116 | ENDSEC 117 | 0 118 | EOF 119 | -------------------------------------------------------------------------------- /dxf/UAP_212718.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/UAP_212718.dxf -------------------------------------------------------------------------------- /dxf/beispiel_wordart.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/beispiel_wordart.doc -------------------------------------------------------------------------------- /dxf/beispiel_wordart.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/beispiel_wordart.pdf -------------------------------------------------------------------------------- /dxf/deformed_spline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/deformed_spline.png -------------------------------------------------------------------------------- /dxf/foobar.dxf: -------------------------------------------------------------------------------- 1 | 0 2 | SECTION 3 | 2 4 | BLOCKS 5 | 0 6 | ENDSEC 7 | 0 8 | SECTION 9 | 2 10 | ENTITIES 11 | 0 12 | LINE 13 | 8 14 | 0 15 | 10 16 | -25 17 | 11 18 | 25 19 | 20 20 | 50 21 | 21 22 | 50 23 | 0 24 | LINE 25 | 8 26 | 0 27 | 10 28 | 25 29 | 11 30 | 0 31 | 20 32 | 50 33 | 21 34 | -50 35 | 0 36 | LINE 37 | 8 38 | 0 39 | 10 40 | 0 41 | 11 42 | -25 43 | 20 44 | -50 45 | 21 46 | 50 47 | 0 48 | LINE 49 | 8 50 | 0 51 | 10 52 | -5 53 | 11 54 | -4.619 55 | 20 56 | 0 57 | 21 58 | 1.913 59 | 0 60 | LINE 61 | 8 62 | 0 63 | 10 64 | -4.619 65 | 11 66 | -4.074 67 | 20 68 | 1.913 69 | 21 70 | 2.73 71 | 0 72 | LINE 73 | 8 74 | 0 75 | 10 76 | -4.074 77 | 11 78 | -3.536 79 | 20 80 | 2.73 81 | 21 82 | 3.536 83 | 0 84 | LINE 85 | 8 86 | 0 87 | 10 88 | -3.536 89 | 11 90 | -1.913 91 | 20 92 | 3.536 93 | 21 94 | 4.619 95 | 0 96 | LINE 97 | 8 98 | 0 99 | 10 100 | -1.913 101 | 11 102 | -1.43 103 | 20 104 | 4.619 105 | 21 106 | 4.716 107 | 0 108 | LINE 109 | 8 110 | 0 111 | 10 112 | -1.43 113 | 11 114 | 0 115 | 20 116 | 4.716 117 | 21 118 | 5 119 | 0 120 | LINE 121 | 8 122 | 0 123 | 10 124 | 0 125 | 11 126 | 1.43 127 | 20 128 | 5 129 | 21 130 | 4.716 131 | 0 132 | LINE 133 | 8 134 | 0 135 | 10 136 | 1.43 137 | 11 138 | 1.913 139 | 20 140 | 4.716 141 | 21 142 | 4.619 143 | 0 144 | LINE 145 | 8 146 | 0 147 | 10 148 | 1.913 149 | 11 150 | 3.536 151 | 20 152 | 4.619 153 | 21 154 | 3.536 155 | 0 156 | LINE 157 | 8 158 | 0 159 | 10 160 | 3.536 161 | 11 162 | 4.074 163 | 20 164 | 3.536 165 | 21 166 | 2.73 167 | 0 168 | LINE 169 | 8 170 | 0 171 | 10 172 | 4.074 173 | 11 174 | 4.619 175 | 20 176 | 2.73 177 | 21 178 | 1.913 179 | 0 180 | LINE 181 | 8 182 | 0 183 | 10 184 | 4.619 185 | 11 186 | 5 187 | 20 188 | 1.913 189 | 21 190 | 0 191 | 0 192 | LINE 193 | 8 194 | 0 195 | 10 196 | 5 197 | 11 198 | 4.619 199 | 20 200 | 0 201 | 21 202 | -1.913 203 | 0 204 | LINE 205 | 8 206 | 0 207 | 10 208 | 4.619 209 | 11 210 | 3.597 211 | 20 212 | -1.913 213 | 21 214 | -3.444 215 | 0 216 | LINE 217 | 8 218 | 0 219 | 10 220 | 3.597 221 | 11 222 | 3.536 223 | 20 224 | -3.444 225 | 21 226 | -3.536 227 | 0 228 | LINE 229 | 8 230 | 0 231 | 10 232 | 3.536 233 | 11 234 | 1.913 235 | 20 236 | -3.536 237 | 21 238 | -4.619 239 | 0 240 | LINE 241 | 8 242 | 0 243 | 10 244 | 1.913 245 | 11 246 | 1.182 247 | 20 248 | -4.619 249 | 21 250 | -4.765 251 | 0 252 | LINE 253 | 8 254 | 0 255 | 10 256 | 1.182 257 | 11 258 | 0 259 | 20 260 | -4.765 261 | 21 262 | -5 263 | 0 264 | LINE 265 | 8 266 | 0 267 | 10 268 | 0 269 | 11 270 | -1.182 271 | 20 272 | -5 273 | 21 274 | -4.765 275 | 0 276 | LINE 277 | 8 278 | 0 279 | 10 280 | -1.182 281 | 11 282 | -1.913 283 | 20 284 | -4.765 285 | 21 286 | -4.619 287 | 0 288 | LINE 289 | 8 290 | 0 291 | 10 292 | -1.913 293 | 11 294 | -3.536 295 | 20 296 | -4.619 297 | 21 298 | -3.536 299 | 0 300 | LINE 301 | 8 302 | 0 303 | 10 304 | -3.536 305 | 11 306 | -3.597 307 | 20 308 | -3.536 309 | 21 310 | -3.444 311 | 0 312 | LINE 313 | 8 314 | 0 315 | 10 316 | -3.597 317 | 11 318 | -4.619 319 | 20 320 | -3.444 321 | 21 322 | -1.913 323 | 0 324 | LINE 325 | 8 326 | 0 327 | 10 328 | -4.619 329 | 11 330 | -5 331 | 20 332 | -1.913 333 | 21 334 | 0 335 | 0 336 | ENDSEC 337 | 0 338 | SECTION 339 | 2 340 | OBJECTS 341 | 0 342 | DICTIONARY 343 | 0 344 | ENDSEC 345 | 0 346 | EOF 347 | -------------------------------------------------------------------------------- /dxf/fräsen_test_02 2004.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/fräsen_test_02 2004.dxf -------------------------------------------------------------------------------- /dxf/lines_through_cutting_depth1.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/lines_through_cutting_depth1.dat -------------------------------------------------------------------------------- /dxf/lines_through_cutting_depth2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/lines_through_cutting_depth2.png -------------------------------------------------------------------------------- /dxf/print.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/print.pdf -------------------------------------------------------------------------------- /dxf/pstoedit_test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/pstoedit_test.pdf -------------------------------------------------------------------------------- /dxf/rib_test.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/rib_test.dxf -------------------------------------------------------------------------------- /dxf/toe_test.dxf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/dxf/toe_test.dxf -------------------------------------------------------------------------------- /links/DXF2GCODE Webpage.URL: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://www.christian-kohloeffel.homepage.t-online.de/dxf2gocde.html#mozTocId700862 3 | -------------------------------------------------------------------------------- /python_examples/Ellipse_BiArc/BIARC_TEST.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/Ellipse_BiArc/BIARC_TEST.py -------------------------------------------------------------------------------- /python_examples/Ellipse_BiArc/clsBiArc.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/Ellipse_BiArc/clsBiArc.py -------------------------------------------------------------------------------- /python_examples/Ellipse_BiArc/clsEllipse.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/Ellipse_BiArc/clsEllipse.py -------------------------------------------------------------------------------- /python_examples/Ellipse_BiArc/clsGeometrie.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/Ellipse_BiArc/clsGeometrie.py -------------------------------------------------------------------------------- /python_examples/Ellipse_BiArc/test.bat: -------------------------------------------------------------------------------- 1 | python BIARC_TEST.py 2 | @pause -------------------------------------------------------------------------------- /python_examples/Ellipse_fitting_by_Biarc_curves.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/Ellipse_fitting_by_Biarc_curves.py -------------------------------------------------------------------------------- /python_examples/GridDemo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.4 2 | 3 | """ 4 | A simple demo to show how to do grids 5 | 6 | """ 7 | 8 | import wx 9 | 10 | 11 | try: 12 | # See if there is a local copy 13 | import sys 14 | sys.path.append("../") 15 | from floatcanvas import NavCanvas, FloatCanvas 16 | except ImportError: 17 | from wx.lib.floatcanvas import NavCanvas, FloatCanvas 18 | 19 | class DrawFrame(wx.Frame): 20 | 21 | """ 22 | A frame used for the FloatCanvas Demo 23 | 24 | """ 25 | 26 | def __init__(self, *args, **kwargs): 27 | wx.Frame.__init__(self, *args, **kwargs) 28 | 29 | self.CreateStatusBar() 30 | 31 | # Add the Canvas 32 | Canvas = NavCanvas.NavCanvas(self,-1, 33 | size = (500,500), 34 | ProjectionFun = None, 35 | Debug = 0, 36 | BackgroundColor = "DARK SLATE BLUE", 37 | ).Canvas 38 | 39 | 40 | Point = (45,40) 41 | Box = Canvas.AddCircle(Point, 42 | Diameter = 10, 43 | FillColor = "Black", 44 | LineColor = "Red", 45 | LineWidth = 6) 46 | 47 | # Crosses: 48 | Grid = FloatCanvas.DotGrid( Spacing=(1, .5), Size=2, Color="Cyan", Cross=True, CrossThickness=2) 49 | #Dots: 50 | #Grid = FloatCanvas.DotGrid( (0.5, 1), Size=3, Color="Red") 51 | 52 | Canvas.GridUnder = Grid 53 | #Canvas.GridOver = Grid 54 | 55 | FloatCanvas.EVT_MOTION(Canvas, self.OnMove ) 56 | 57 | self.Show() 58 | Canvas.ZoomToBB() 59 | 60 | def OnMove(self, event): 61 | """ 62 | Updates the status bar with the world coordinates 63 | 64 | """ 65 | self.SetStatusText("%.2f, %.2f"%tuple(event.Coords)) 66 | 67 | 68 | 69 | app = wx.App(False) # true to get its own output window. 70 | F = DrawFrame(None, title="FloatCanvas Demo App", size=(700,700) ) 71 | app.MainLoop() 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /python_examples/Kegelstump_Abwicklung_2dxf.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/Kegelstump_Abwicklung_2dxf.py -------------------------------------------------------------------------------- /python_examples/NURBS_fitting_by_Biarc_curves.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/NURBS_fitting_by_Biarc_curves.py -------------------------------------------------------------------------------- /python_examples/NURBS_fitting_by_Biarc_curves_wx.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/NURBS_fitting_by_Biarc_curves_wx.py -------------------------------------------------------------------------------- /python_examples/Offset/Pairwise_offset_algorithm.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/Offset/Pairwise_offset_algorithm.py -------------------------------------------------------------------------------- /python_examples/canvas_sample.py: -------------------------------------------------------------------------------- 1 | import wx, sys, time, threading 2 | from wx.lib.floatcanvas.FloatCanvas import FloatCanvas 3 | from wx.lib.floatcanvas.GUIMode import GUIMove 4 | 5 | 6 | myEVT_PRINT = wx.NewEventType() 7 | EVT_PRINT = wx.PyEventBinder(myEVT_PRINT, 1) 8 | class PrintEvent(wx.PyCommandEvent): 9 | def __init__(self,message): 10 | wx.PyCommandEvent.__init__(self, myEVT_PRINT, wx.ID_ANY) 11 | self._message = message 12 | 13 | def GetMessage(self): 14 | return self._message 15 | 16 | 17 | class Renderer: 18 | def __init__(self,parent): 19 | self.parent = parent 20 | self.requests = [] 21 | self.counter = 0 22 | self.running = True 23 | threading.Thread(target=self.render).start() 24 | 25 | def MakeRequest(self): 26 | self.requests.append(None) 27 | 28 | def render(self): 29 | while self.running: 30 | if self.requests: 31 | request = self.requests.pop(0) 32 | # Make the CPU work 33 | for i in range(100000): pass 34 | self.counter += 1 35 | wx.PostEvent(self.parent.log,PrintEvent("%s\n"%self.counter)) 36 | else: 37 | time.sleep(.01) 38 | 39 | 40 | class MyTextCtrl(wx.TextCtrl): 41 | def __init__(self,parent): 42 | wx.TextCtrl.__init__(self,parent,-1,style = wx.TE_MULTILINE) 43 | sys.stdout = self 44 | self.Bind(EVT_PRINT, self.OnPrint) 45 | 46 | def OnPrint(self,e): 47 | self.AppendText(e.GetMessage()) 48 | 49 | 50 | class MyCanvas(FloatCanvas): 51 | def __init__(self, parent): 52 | self.parent = parent 53 | FloatCanvas.__init__(self, parent, BackgroundColor="BLACK") 54 | self.circles = [] 55 | self.GUIMode = GUICustom(self) 56 | 57 | def UpdateCircles(self, coord): 58 | self.RemoveObjects(self.circles) 59 | self.circles = [] 60 | for i in range(25): 61 | self.circles.append(self.AddCircle((coord[0]+i%5*5,coord[1]+i), 62 | Diameter=10,LineColor="White")) 63 | 64 | class GUICustom(GUIMove): 65 | def OnLeftDown(self,e): 66 | self.starttime = time.time() 67 | 68 | def OnLeftUp(self,e): 69 | return 70 | 71 | def OnMove(self,e): 72 | if e.LeftIsDown() and e.Dragging(): 73 | # Uncomment these lines to see the fix 74 | ## t = time.time() 75 | ## if t - self.starttime < .05: 76 | ## return 77 | ## self.starttime = t 78 | self.Canvas.UpdateCircles(self.Canvas.PixelToWorld(e.GetPosition())) 79 | self.Canvas.parent.renderer.MakeRequest() 80 | self.Canvas.Draw() 81 | 82 | 83 | class TestFrame(wx.Frame): 84 | def __init__(self,parent,id): 85 | wx.Frame.__init__(self,parent,id,"Test App") 86 | self.renderer = Renderer(self) 87 | self.log = MyTextCtrl(self) 88 | self.Canvas = MyCanvas(self) 89 | 90 | sizer = wx.BoxSizer() 91 | sizer.Add(self.Canvas,3,wx.EXPAND) 92 | sizer.Add(self.log,1,wx.EXPAND) 93 | self.SetSizer(sizer) 94 | 95 | self.Bind(wx.EVT_CLOSE,self.OnExit) 96 | self.Show(True) 97 | 98 | def OnExit(self,e): 99 | self.renderer.running = False 100 | self.Destroy() 101 | 102 | app = wx.App() 103 | frame = TestFrame(None,wx.ID_ANY) 104 | app.MainLoop() 105 | -------------------------------------------------------------------------------- /python_examples/customtreectrl.py: -------------------------------------------------------------------------------- 1 | import wx, wx.lib.customtreectrl as CT 2 | 3 | class MainWindow(wx.Frame): 4 | def __init__(self, parent, id, title): 5 | wx.Frame.__init__(self,parent,wx.ID_ANY, title, size=(600, 600), pos=(200, 200)) 6 | 7 | self.splitter_window = wx.SplitterWindow(self, -1, style=wx.SP_3D|wx.SP_BORDER) 8 | self.splitter_window.SetMinimumPaneSize(20) 9 | self.left_panel = wx.Panel(self.splitter_window, -1) 10 | self.right_panel = wx.Panel(self.splitter_window, -1) 11 | 12 | self.tree = CT.CustomTreeCtrl(self.left_panel, 1002, pos=(0, 0), 13 | style=wx.TR_DEFAULT_STYLE | 14 | wx.TR_HAS_VARIABLE_ROW_HEIGHT | 15 | wx.TR_HAS_BUTTONS | 16 | wx.TR_FULL_ROW_HIGHLIGHT | 17 | wx.TR_MULTIPLE | 18 | wx.TR_EDIT_LABELS) 19 | self.root = self.tree.AddRoot("Root Item") 20 | 21 | offset_lists = ["Clearance Reports", "Other Offsets"] 22 | offset_list_combo_box = wx.ComboBox(self.right_panel, -1, choices=offset_lists) 23 | 24 | #Sizers 25 | offset_sizer = wx.BoxSizer(wx.VERTICAL) 26 | offset_sizer.Add(offset_list_combo_box, 0, wx.EXPAND) 27 | vbox = wx.BoxSizer(wx.VERTICAL) 28 | vbox.Add(self.tree, 1, wx.EXPAND) 29 | self.left_panel.SetSizer(vbox) 30 | vbox2 = wx.BoxSizer(wx.VERTICAL) 31 | vbox2.Add(offset_sizer, 1, wx.EXPAND) 32 | self.right_panel.SetSizer(vbox2) 33 | main_sizer = wx.BoxSizer(wx.HORIZONTAL) 34 | self.splitter_window.SplitVertically(self.left_panel, self.right_panel) 35 | main_sizer.Add(self.splitter_window, 1, wx.EXPAND) 36 | self.SetSizer(main_sizer) 37 | 38 | self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndLabelEdit) 39 | self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnBeginLabelEdit) 40 | self.Bind(wx.EVT_KEY_DOWN, self.enterpressed) 41 | self.tree.Bind(wx.EVT_KEY_DOWN, self.enterpressed) 42 | self.Bind(wx.EVT_KEY_DOWN, self.enterpressed, self.tree) 43 | self.Bind(wx.EVT_COMMAND_ENTER, self.enterpressed) 44 | self.Bind(wx.EVT_TEXT_ENTER, self.enterpressed) 45 | 46 | self.Show(True) 47 | 48 | def OnBeginLabelEdit(self, event): 49 | pass 50 | def OnEndLabelEdit(self, event): 51 | text = self.tree.GetEditControl().GetValue() 52 | item_being_edited = self.tree.GetSelection() 53 | self.tree.SetItemText(item_being_edited, text) 54 | def enterpressed(self, event): 55 | print "pressed enter" 56 | 57 | app = wx.PySimpleApp() 58 | frame = MainWindow(None, -1, "Test") 59 | app.MainLoop() -------------------------------------------------------------------------------- /python_examples/gtk/filesel.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # example filesel.py 4 | 5 | import pygtk 6 | pygtk.require('2.0') 7 | import gtk 8 | 9 | class FileSelectionExample: 10 | # Get the selected filename and print it to the console 11 | def file_ok_sel(self, w): 12 | print "%s" % self.filew.get_filename() 13 | 14 | def destroy(self, widget): 15 | gtk.main_quit() 16 | 17 | def __init__(self): 18 | # Create a new file selection widget 19 | self.filew = gtk.FileSelection("File selection") 20 | 21 | self.filew.connect("destroy", self.destroy) 22 | # Connect the ok_button to file_ok_sel method 23 | self.filew.ok_button.connect("clicked", self.file_ok_sel) 24 | 25 | # Connect the cancel_button to destroy the widget 26 | self.filew.cancel_button.connect("clicked", 27 | lambda w: self.filew.destroy()) 28 | 29 | # Lets set the filename, as if this were a save dialog, 30 | # and we are giving a default filename 31 | self.filew.set_filename("penguin.png") 32 | 33 | self.filew.show() 34 | 35 | def main(): 36 | gtk.main() 37 | return 0 38 | 39 | if __name__ == "__main__": 40 | FileSelectionExample() 41 | main() 42 | -------------------------------------------------------------------------------- /python_examples/gtk/make_exe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os, sys 4 | import subprocess 5 | 6 | pyinpfad = "C:\Python26\pyinstaller-1.4" 7 | 8 | pyt = "C:/Python26/pythonw.exe" 9 | filepfad= os.path.realpath(os.path.dirname(sys.argv[0])) 10 | exemakepfad=filepfad 11 | file = "animationrotation" 12 | icon= "%s/DXF2GCODE-001.ico" %filepfad 13 | 14 | options=("--onefile --noconsole --upx --tk") #--icon=%s" %icon) 15 | print options 16 | 17 | #Verzwichniss wechseln 18 | exemakepfad = unicode( exemakepfad, "utf-8" ) 19 | os.chdir(exemakepfad.encode( "utf-8" )) 20 | 21 | 22 | cmd=("%s %s\Makespec.py %s %s/%s.py" %(pyt,pyinpfad,options,filepfad,file)) 23 | print cmd 24 | retcode=subprocess.call(cmd) 25 | 26 | cmd=("%s %s\Build.py %s\%s.spec" %(pyt,pyinpfad,exemakepfad,file)) 27 | print cmd 28 | retcode=subprocess.call(cmd) 29 | 30 | print "\n!!!!!!!Bitmaps und Languagues Ordner nicht vergessen!!!!!!" 31 | print "\nFertig" -------------------------------------------------------------------------------- /python_examples/gtk/polyline_hit_inside.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | ## hittest Copyright (C) 2007 Donn.C.Ingle 4 | ## 5 | ## Contact: donn.ingle@gmail.com - I hope this email lasts. 6 | ## 7 | ## This program is free software; you can redistribute it and/or modify 8 | ## it under the terms of the GNU General Public License as published by 9 | ## the Free Software Foundation; either version 2 of the License, or 10 | ## ( at your option ) any later version. 11 | ## 12 | ## This program is distributed in the hope that it will be useful, 13 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | ## GNU General Public License for more details. 16 | ## 17 | ## You should have received a copy of the GNU General Public License 18 | ## along with this program; if not, write to the Free Software 19 | ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | ## 21 | 22 | import pygtk 23 | #pygtk.require('2.0') 24 | import gtk 25 | import gobject 26 | import cairo 27 | from gtk import gdk 28 | 29 | # Create a GTK+ widget on which we will draw using Cairo 30 | class Screen(gtk.DrawingArea): 31 | 32 | # Draw in response to an expose-event 33 | __gsignals__ = { "expose-event": "override" } 34 | 35 | def __init__(self): 36 | super(Screen,self).__init__() 37 | # gtk.Widget signals 38 | self.connect("button_press_event", self.button_press) 39 | self.connect("button_release_event", self.button_release) 40 | self.connect("motion_notify_event", self.motion_notify) 41 | # More GTK voodoo : unmask events 42 | self.add_events(gdk.BUTTON_PRESS_MASK | 43 | gdk.BUTTON_RELEASE_MASK | 44 | gdk.POINTER_MOTION_MASK) 45 | 46 | # Handle the expose-event by drawing 47 | def do_expose_event(self, event): 48 | 49 | # Create the cairo context 50 | cr = self.window.cairo_create() 51 | self.hitpath = None #Is set later 52 | 53 | # Restrict Cairo to the exposed area; avoid extra work 54 | cr.rectangle(event.area.x, event.area.y, 55 | event.area.width, event.area.height) 56 | cr.clip() 57 | 58 | self.draw(cr, *self.window.get_size()) 59 | 60 | def makeHitPath(self,cairopath): 61 | ## Make a simpler list of tuples 62 | 63 | ## Internally, a cairo path looks like this: 64 | ## (0, (10.0, 10.0)) 65 | ## (1, (60.0, 10.0)) 66 | ## (1, (60.0, 60.0)) 67 | ## (1, (35.0, 60.0)) 68 | ## (1, (35.0, 35.0)) 69 | ## (1, (10.0, 35.0)) 70 | ## (1, (10.0, 60.0)) 71 | ## (1, (-40.0, 60.0)) 72 | ## (3, ()) #want to ignore this one 73 | ## (0, (10.0, 10.0)) 74 | 75 | self.hitpath = [] 76 | for sub in cairopath: 77 | if sub[1]: #kick out the close path () empty tuple 78 | self.hitpath.append(sub[1]) #list of tuples 79 | 80 | def draw(self, cr, width, height): 81 | # Fill the background with gray 82 | cr.set_source_rgb(0.5, 0.5, 0.5) 83 | cr.rectangle(0, 0, width, height) 84 | cr.fill() 85 | 86 | def hitTest(self,*p): 87 | ## Code lifted from http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/ 88 | ## converted to Python. I won't pretend I grok it at all, just glad it works! 89 | ## Not sure how well it works yet, it might have edge flaws. 90 | px = p[0] 91 | py = p[1] 92 | counter = i = xinters = 0 93 | p1 = p2 = () 94 | 95 | p1 = self.hitpath[0] 96 | N = len(self.hitpath) 97 | 98 | # Mathemagic loop-de-loop 99 | for i in range(0,N): 100 | p2 = self.hitpath[i % N] 101 | if py > min( p1[1] , p2[1] ): 102 | if py <= max( p1[1], p2[1] ): 103 | if px <= max( p1[0], p2[0] ): 104 | if p1[1] != p2[1]: 105 | xinters = ( py - p1[1] ) * ( p2[0] - p1[0] ) / ( p2[1] - p1[1] ) + p1[0] 106 | if p1[0] == p2[0] or px <= xinters: counter += 1 107 | p1 = p2 108 | 109 | if counter % 2 == 0: 110 | return "outside" 111 | return "inside" 112 | 113 | def button_press(self,widget,event): 114 | pass 115 | def button_release(self,widget,event): 116 | pass 117 | def motion_notify(self,widget,event): 118 | pass 119 | 120 | # GTK mumbo-jumbo to show the widget in a window and quit when it's closed 121 | def run(Widget): 122 | window = gtk.Window() 123 | window.connect("delete-event", gtk.main_quit) 124 | widget = Widget() 125 | widget.show() 126 | window.add(widget) 127 | window.present() 128 | gtk.main() 129 | 130 | class Shapes(Screen): 131 | #Override the press event 132 | def button_press(self,widget,event): 133 | print self.hitTest(event.x, event.y) 134 | 135 | def draw(self, cr, width, height): 136 | x = y = 10 137 | sx = sy = 50 138 | cr.move_to(x,y) 139 | cr.line_to(x+sx,y) 140 | cr.line_to(x+sx,y+sy) 141 | cr.line_to(x+(sx/2),y+sy) 142 | cr.line_to(x+(sx/2),y+(sy/2)) 143 | cr.line_to(x,y+(sy/2)) 144 | cr.line_to(x,y+sy) 145 | cr.line_to(x-sx,y+sy) 146 | cr.close_path() 147 | cr.set_source_rgb(1,0,0) 148 | 149 | self.makeHitPath(cr.copy_path_flat()) #record the path to use as a hit area. 150 | 151 | cr.fill() #consumes the path, so get it before the fill 152 | 153 | 154 | run(Shapes) 155 | -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008, 2009, Marko Tasic 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | * Neither the name of the Marko Tasic nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/gtk/pygtkcanvas-1.0/README -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/__init__.py: -------------------------------------------------------------------------------- 1 | from canvas import * 2 | from canvaslayer import * 3 | from canvasitem import * 4 | -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/canvaslayer.py: -------------------------------------------------------------------------------- 1 | __all__ = ['CanvasLayer'] 2 | 3 | class CanvasLayer(list): 4 | def __init__(self): 5 | self.visible = True 6 | 7 | def set_visible(self, visible): 8 | self.visible = visible 9 | 10 | def get_visible(self): 11 | return self.visible 12 | 13 | def clear(self): 14 | del self[:] 15 | 16 | def move_all(self, dx, dy): 17 | for item in self: 18 | item.move(dx, dy) 19 | 20 | def scale_all(self, xc, yc, xs, ys): 21 | for item in self: 22 | item.scale(xc, yc, xs, ys) 23 | 24 | def find_above(self, item): 25 | index = self.index(item) 26 | if index < len(self) - 1: 27 | return self[index + 1] 28 | else: 29 | return None 30 | 31 | def find_all_above(self, item): 32 | index = self.index(item) 33 | if index < len(self) - 1: 34 | return self[index + 1:] 35 | else: 36 | return [] 37 | 38 | def find_below(self, item): 39 | index = self.index(item) 40 | if index > 0: 41 | return self[index - 1] 42 | else: 43 | return None 44 | 45 | def find_all_below(self, item): 46 | index = self.index(item) 47 | if index > 0: 48 | return self[:index - 1] 49 | else: 50 | return [] 51 | 52 | def find_visible(self, x0, y0, x1, y1): 53 | l = [] 54 | for item in self: 55 | _x0, _y0, _x1, _y1 = item.get_bbox() 56 | if y1 < _y0: continue 57 | if y0 > _y1: continue 58 | if x1 < _x0: continue 59 | if x0 > _x1: continue 60 | l.append(item) 61 | 62 | return l 63 | 64 | def find_closest(self, x, y, halo=0, start=None, end=None): 65 | x0, y0, x1, y1 = x - halo, y - halo, x + halo, y + halo 66 | start_index = self.index(start) if start else 0 67 | end_index = self.index(end) if end else len(self) 68 | l = [] 69 | 70 | for item in self[start_index:end_index]: 71 | _x0, _y0, _x1, _y1 = item.get_bbox() 72 | if (x0<=_x0<=x1 or x0<=_x1<=x1) and (y0<=_y0<=y1 or y0<=_y1<=y1): 73 | l.append(item) 74 | 75 | return l 76 | 77 | def find_enclosed(self, x0, y0, x1, y1): 78 | l = [] 79 | for item in self: 80 | _x0, _y0, _x1, _y1 = item.get_bbox() 81 | if x0<=_x0 and y0<=_y0 and x1>=_x1 and y1>=_y1: 82 | l.append(item) 83 | 84 | return l 85 | 86 | def find_overlapping(self, x0, y0, x1, y1): 87 | l = [] 88 | for item in self: 89 | _x0, _y0, _x1, _y1 = item.get_bbox() 90 | if (x0<=_x0<=x1 or x0<=_x1<=x1) and (y0<=_y0<=y1 or y0<=_y1<=y1): 91 | l.append(item) 92 | 93 | return l 94 | -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/canvasmath.py: -------------------------------------------------------------------------------- 1 | __all__ = ['dist2d', 'inline2d', 'inrect2d', 'inoval2d', 'inarc2d', 2 | 'intext2d', 'inpolygon2d', 'collision_rect_rect2d', 3 | 'image_rgba_to_argb', 'image_argb_to_rgba', 'image_rgba_to_bgra', 4 | 'cairo_image_surface_from_image', 'cairo_image_surface_from_filename'] 5 | 6 | from math import fabs, sqrt, cos, sin, pi, copysign 7 | import array 8 | import Image 9 | import cairo 10 | 11 | def dist2d(x0, y0, x1, y1): 12 | dx = x0 - x1 13 | dy = y0 - y1 14 | return sqrt(dx * dx + dy * dy) 15 | 16 | def inline2d(points, x, y, tolerance=2): 17 | x0, y0, x1, y1 = points 18 | dx = x1 - x0 19 | dy = y1 - y0 20 | px = x - x0 21 | py = y - y0 22 | segment_len = sqrt(dx * dx + dy * dy) 23 | 24 | if segment_len < 1E-6: 25 | dist = sqrt(px * px + py * py) 26 | else: 27 | half_len = segment_len / 2 28 | newx = abs((px * dx + py * dy) / segment_len - half_len) 29 | newy = abs(-px * dy + py * dx) / segment_len 30 | 31 | if newx > half_len: 32 | newx = newx - half_len 33 | dist = sqrt(newx * newx + newy * newy) 34 | else: 35 | dist = newy 36 | 37 | return True if dist<=tolerance else False 38 | 39 | def inrect2d(points, x, y, filled=False, tolerance=2): 40 | x0, y0, x1, y1 = points 41 | 42 | if x0>x1: 43 | x0, x1 = x1, x0 44 | if y0>y1: 45 | y0, y1 = y1, y0 46 | 47 | if filled: 48 | return True if x0<=x<=x1 and y0<=y<=y1 else False 49 | else: 50 | if x0-tolerance<=x<=x0+tolerance or x1-tolerance<=x<=x1+tolerance: 51 | return True if y0<=y<=y1 else False 52 | elif y0-tolerance<=y<=y0+tolerance or y1-tolerance<=y<=y1+tolerance: 53 | return True if x0<=x<=x1 else False 54 | 55 | def inoval2d(points, x, y, filled=False, tolerance=2): 56 | x0, y0, x1, y1 = points 57 | if x0 > x1: 58 | x0, x1 = x1, x0 59 | if y0 > y1: 60 | y0, y1 = y1, y0 61 | 62 | xc = (x0 + x1) / 2 63 | yc = (y0 + y1) / 2 64 | xr0 = xc - x0 65 | yr0 = yc - y0 66 | r0 = xr0 if xr0>yr0 else yr0 67 | 68 | xr1 = xc - x 69 | yr1 = yc - y 70 | r1 = sqrt(xr1*xr1 + yr1*yr1) 71 | 72 | if filled: 73 | return True if r0>=r1 else False 74 | else: 75 | return True if r0-tolerance<=r1<=r0+tolerance else False 76 | 77 | def inarc2d(points, x, y, start=0, extent=360, filled=False, tolerance=2): 78 | return inoval2d(points, x, y, filled, tolerance) 79 | 80 | def intext2d(points, x, y, filled=True, tolerance=0): 81 | return inrect2d(points, x, y, filled, tolerance) 82 | 83 | def inpolygon2d(poly, x, y, tolerance=2): 84 | inside = False 85 | npoints = len(poly) 86 | 87 | # 3-points, 2-axes(x,y) 88 | if npoints < 3 * 2: 89 | return False 90 | 91 | xold = poly[-2] 92 | yold = poly[-1] 93 | 94 | for i in xrange(0, npoints, 2): 95 | xnew = poly[i] 96 | ynew = poly[i+1] 97 | 98 | if xnew > xold: 99 | x0 = xold 100 | y0 = yold 101 | x1 = xnew 102 | y1 = ynew 103 | else: 104 | x0 = xnew 105 | y0 = ynew 106 | x1 = xold 107 | y1 = yold 108 | 109 | if (xnew < x) == (x <= xold) and (y-y0)*(x1-x0) < (y1-y0)*(x-x0): 110 | inside = not inside 111 | 112 | xold = xnew 113 | yold = ynew 114 | 115 | return inside 116 | 117 | #def matmul(a, b): 118 | # return [[sum(i*j for i, j in zip(row, col)) for col in zip(*b)] for row in a] 119 | 120 | def collision_rect_rect2d(left1, top1, right1, bottom1, left2, top2, right2, bottom2): 121 | if bottom1 < top2: return False 122 | if top1 > bottom2: return False 123 | if right1 < left2: return False 124 | if left1 > right2: return False 125 | return True 126 | 127 | def image_rgba_to_argb(str_buf): 128 | byte_buf = array.array("B", str_buf) 129 | num_quads = len(byte_buf)/4 130 | 131 | for i in xrange(num_quads): 132 | alpha = byte_buf[i*4 + 3] 133 | byte_buf[i*4 + 3] = byte_buf[i*4 + 2] 134 | byte_buf[i*4 + 2] = byte_buf[i*4 + 1] 135 | byte_buf[i*4 + 1] = byte_buf[i*4 + 0] 136 | byte_buf[i*4 + 0] = alpha 137 | 138 | return byte_buf.tostring() 139 | 140 | def image_argb_to_rgba(str_buf): 141 | byte_buf = array.array("B", str_buf) 142 | num_quads = len(byte_buf)/4 143 | 144 | for i in xrange(num_quads): 145 | alpha = byte_buf[i*4 + 0] 146 | byte_buf[i*4 + 0] = byte_buf[i*4 + 1] 147 | byte_buf[i*4 + 1] = byte_buf[i*4 + 2] 148 | byte_buf[i*4 + 2] = byte_buf[i*4 + 3] 149 | byte_buf[i*4 + 3] = alpha 150 | 151 | return byte_buf.tostring() 152 | 153 | def image_rgba_to_bgra(str_buf): 154 | byte_buf = array.array("B", str_buf) 155 | num_quads = len(byte_buf) / 4 156 | 157 | for i in xrange(num_quads): 158 | i40 = i * 4 159 | i42 = i40 + 2 160 | r = byte_buf[i40] 161 | b = byte_buf[i42] 162 | byte_buf[i40] = b 163 | byte_buf[i42] = r 164 | 165 | return byte_buf.tostring() 166 | 167 | def cairo_image_surface_from_image(image): 168 | if image.mode != 'RGBA': 169 | image = image.convert('RGBA') 170 | 171 | width, height = image.size 172 | stride = cairo.ImageSurface.format_stride_for_width( 173 | cairo.FORMAT_ARGB32, width) 174 | 175 | image_buffer = array.array('c') 176 | image_buffer.fromstring( 177 | image_rgba_to_bgra( 178 | image.tostring())) 179 | 180 | cairo_image = cairo.ImageSurface.create_for_data( 181 | image_buffer, cairo.FORMAT_ARGB32, width, height, stride) 182 | 183 | return cairo_image 184 | 185 | def cairo_image_surface_from_filename(filename): 186 | image = Image.open(filename) 187 | cairo_image = cairo_image_surface_from_image(image) 188 | return cairo_image 189 | -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/example.py: -------------------------------------------------------------------------------- 1 | import pygtk 2 | pygtk.require('2.0') 3 | import gtk 4 | from random import randrange, random 5 | 6 | from canvas import Canvas 7 | from canvaslayer import CanvasLayer 8 | from canvasitem import * 9 | 10 | class Window: 11 | def __init__(self): 12 | self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) 13 | self.window.connect("delete-event", self.delete_event_cb) 14 | self.window.connect("destroy", self.destroy_cb) 15 | self.window.set_border_width(0) 16 | self.window.set_size_request(800, 600) 17 | self.window.show() 18 | 19 | self.canvas = Canvas() 20 | self.canvas.set_background((0,0,0)) 21 | self.canvas.set_foreground((0,0,0)) 22 | self.canvas.set_flags(gtk.HAS_FOCUS|gtk.CAN_FOCUS) 23 | self.canvas.grab_focus() 24 | 25 | self.layer1 = CanvasLayer() 26 | self.layer2 = CanvasLayer() 27 | self.canvas.append(self.layer1) 28 | self.canvas.append(self.layer2) 29 | self.canvas.show() 30 | self.window.add(self.canvas) 31 | 32 | for n in xrange(100): 33 | o = CanvasRect(self.layer1, 100, 100, 200, 200, filled=True) 34 | o.scale(random(), random(), random(), random()) 35 | o.move(randrange(1000), randrange(1000)) 36 | o.connect('button-press-event', self.button_press_event_cb) 37 | o.connect('motion-notify-event', self.motion_notify_event_cb) 38 | o.connect('button-release-event', self.button_release_event_cb) 39 | 40 | for n in xrange(100): 41 | g = CanvasGroup(self.layer2, fg=(0,0,1)) 42 | o = CanvasLine(g, 0, 0, 100, 100) 43 | print(dir(o)) 44 | o = CanvasRect(g, 0, 100, 100, 200, filled=True, fg=(0.5, 0.3,0.4),bg=(1, 0.3,0.4)) 45 | o = CanvasOval(g, 0, 200, 100, 300, fg=(0.5, 1,0.3)) 46 | o = CanvasArc(g, 0, 300, 100, 400, start=0, extent=180) 47 | o = CanvasText(g, 0, 400, text='Hello') 48 | o = CanvasLine(g, 100, 0, 200, 100) 49 | o = CanvasRect(g, 100, 100, 200, 200, filled=True, outline=True) 50 | o = CanvasOval(g, 100, 200, 200, 300, filled=True) 51 | o = CanvasArc(g, 100, 300, 200, 400, start=90, extent=270, filled=True) 52 | o = CanvasText(g, 100, 400, text='World') 53 | g.scale(random(), random(), random(), random()) 54 | g.move(randrange(1000), randrange(1000)) 55 | g.connect('button-press-event', self.button_press_event_cb) 56 | g.connect('motion-notify-event', self.motion_notify_event_cb) 57 | g.connect('button-release-event', self.button_release_event_cb) 58 | 59 | # o = CanvasImage(self.layer1, 0, 0, filename='image2.jpeg') 60 | # o.connect('button-press-event', self.button_press_event_cb) 61 | # o.connect('motion-notify-event', self.motion_notify_event_cb) 62 | # o.connect('button-release-event', self.button_release_event_cb) 63 | 64 | # o = CanvasImage(self.layer1, 100, 100, filename='image1.png') 65 | # o.connect('button-press-event', self.button_press_event_cb) 66 | # o.connect('motion-notify-event', self.motion_notify_event_cb) 67 | # o.connect('button-release-event', self.button_release_event_cb) 68 | 69 | # o = CanvasFunc(self.layer1, target=self.canvas_func1, args=(), kw={}) 70 | 71 | self.canvas_button = None 72 | self.item = None 73 | self.item_prev_x = None 74 | self.item_prev_y = None 75 | self.item_button = None 76 | 77 | self.window.connect('key-press-event', self.window_key_press_event_cb) 78 | self.window.connect('key-release-event', self.window_key_release_event_cb) 79 | self.canvas.connect('button-press-event', self.canvas_button_press_event_cb) 80 | self.canvas.connect('motion-notify-event', self.canvas_motion_notify_event_cb) 81 | self.canvas.connect('button-release-event', self.canvas_button_release_event_cb) 82 | self.canvas.connect('scroll-event', self.canvas_scroll_event_cb) 83 | 84 | def delete_event_cb(self, widget, event, data=None): 85 | return False 86 | 87 | def destroy_cb(self, widget, data=None): 88 | gtk.main_quit() 89 | 90 | def main(self): 91 | gtk.main() 92 | 93 | def button_press_event_cb(self, widget, item, event): 94 | self.item = item 95 | self.item_prev_x = event.x 96 | self.item_prev_y = event.y 97 | self.item_button = event.button 98 | 99 | def motion_notify_event_cb(self, widget, item, event): 100 | if self.item_button == 1: 101 | dx = event.x - self.item_prev_x 102 | dy = event.y - self.item_prev_y 103 | self.item.move(dx, dy) 104 | self.item_prev_x = event.x 105 | self.item_prev_y = event.y 106 | 107 | def button_release_event_cb(self, widget, item, signal_id): 108 | self.item_button = None 109 | 110 | def canvas_button_press_event_cb(self, widget, event): 111 | self.canvas_button = event.button 112 | if self.canvas_button == 2: 113 | self.canvas_prev_x = event.x 114 | self.canvas_prev_y = event.y 115 | 116 | def canvas_motion_notify_event_cb(self, widget, event): 117 | if self.canvas_button == 2: 118 | dx = event.x - self.canvas_prev_x 119 | dy = event.y - self.canvas_prev_y 120 | self.canvas.move_all(dx, dy) 121 | self.canvas_prev_x = event.x 122 | self.canvas_prev_y = event.y 123 | 124 | def canvas_button_release_event_cb(self, widget, signal_id): 125 | self.canvas_button = None 126 | 127 | def canvas_scroll_event_cb(self, widget, event): 128 | if event.direction == gtk.gdk.SCROLL_UP: 129 | self.canvas.scale_all(event.x, event.y, 1.2, 1.2) 130 | elif event.direction == gtk.gdk.SCROLL_DOWN: 131 | self.canvas.scale_all(event.x, event.y, 1/1.2, 1/1.2) 132 | 133 | def window_key_press_event_cb(self, widget, event): 134 | print widget, event 135 | 136 | def window_key_release_event_cb(self, widget, event): 137 | print widget, event 138 | 139 | def canvas_func1(self, *args, **kw): 140 | self.canvas.draw_image(0, 0, xs=1.0, ys=1.0, filename='image2.jpeg') 141 | self.canvas.draw_line(0, 0, 100, 100) 142 | self.canvas.draw_rect(0, 100, 100, 200) 143 | self.canvas.draw_oval(0, 200, 100, 300) 144 | self.canvas.draw_arc(0, 300, 100, 400) 145 | self.canvas.draw_text(0, 400, "Hello World") 146 | 147 | if __name__ == "__main__": 148 | win = Window() 149 | win.main() 150 | -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/gtk/pygtkcanvas-1.0/image1.png -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/image2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/gtk/pygtkcanvas-1.0/image2.jpeg -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/pygtkcanvas-design.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/gtk/pygtkcanvas-1.0/pygtkcanvas-design.dia -------------------------------------------------------------------------------- /python_examples/gtk/pygtkcanvas-1.0/pygtkcanvas.geany: -------------------------------------------------------------------------------- 1 | 2 | [project] 3 | name=pygtkcanvas 4 | base_path=/home/mtasic/projects/pygtkcanvas/ 5 | make_in_base_path=false 6 | description= 7 | run_cmd= 8 | 9 | [files] 10 | current_page=0 11 | FILE_NAME_0=438;Python;0;16;1;1;0;/home/mtasic/projects/pygtkcanvas//example.py;0 12 | FILE_NAME_1=115;Python;0;16;1;1;0;/home/mtasic/projects/pygtkcanvas/canvas.py;0 13 | FILE_NAME_2=72;Python;0;16;1;1;0;/home/mtasic/projects/pygtkcanvas/canvaslayer.py;0 14 | FILE_NAME_3=159;Python;0;16;1;1;0;/home/mtasic/projects/pygtkcanvas//canvasitem.py;0 15 | FILE_NAME_4=260;Python;0;16;1;1;0;/home/mtasic/projects/pygtkcanvas/canvasmath.py;0 16 | 17 | [indentation] 18 | indent_width=4 19 | indent_type=1 20 | indent_hard_tab_width=8 21 | detect_indent=false 22 | indent_mode=2 23 | -------------------------------------------------------------------------------- /python_examples/make_exe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os, sys 4 | import subprocess 5 | 6 | pyinpfad = "D:\pyinstaller" 7 | exemakepfad = "D:/dxf2gcode_exe_tkinter" 8 | pyt = "C:/Python25/pythonw.exe" 9 | filepfad= os.path.realpath(os.path.dirname(sys.argv[0])) 10 | icon= "" 11 | file = "NURBS_fitting_by_Biarc_curves_wx" 12 | 13 | 14 | options=("--onefile --noconsol --upx --tk --icon=%s" %icon) 15 | print options 16 | 17 | #Verzwichniss wechseln 18 | exemakepfad = unicode( exemakepfad, "utf-8" ) 19 | os.chdir(exemakepfad.encode( "utf-8" )) 20 | 21 | 22 | cmd=("%s %s\Makespec.py %s %s/%s.py" %(pyt,pyinpfad,options,filepfad,file)) 23 | print cmd 24 | retcode=subprocess.call(cmd) 25 | 26 | cmd=("%s %s\Build.py %s\%s.spec" %(pyt,pyinpfad,exemakepfad,file)) 27 | print cmd 28 | retcode=subprocess.call(cmd) 29 | 30 | print "\n!!!!!!!Bitmaps und Languagues Ordner nicht vergessen!!!!!!" 31 | print "\nFertig" -------------------------------------------------------------------------------- /python_examples/menu_test.py: -------------------------------------------------------------------------------- 1 | ''' 2 | dynamic cascaded submenus 3 | 4 | Created on 25.11.2009 5 | 6 | @author: mah 7 | ''' 8 | 9 | from Tkinter import * 10 | import pprint 11 | 12 | # http://www.astro.washington.edu/users/rowen/TkinterSummary.html#CallbackShims 13 | class SimpleCallback: 14 | """Create a callback shim. Based on code by Scott David Daniels 15 | (which also handles keyword arguments). 16 | """ 17 | def __init__(self, callback, *firstArgs): 18 | self.__callback = callback 19 | self.__firstArgs = firstArgs 20 | 21 | def __call__(self, *args): 22 | return self.__callback (*(self.__firstArgs + args)) 23 | 24 | 25 | def apply_export(inst): 26 | print "export ",inst 27 | 28 | def apply_delete(inst): 29 | if inst in instances: 30 | instances.remove(inst) 31 | rebuild_menu() 32 | print "delete ",inst 33 | 34 | def add_instance(tag): 35 | global counter 36 | counter += 1 37 | name = "%s-%d" %(tag,counter) 38 | print "add %s" % (name) 39 | instances.append(name) 40 | rebuild_menu() 41 | 42 | 43 | def rebuild_menu(): 44 | 45 | dyn_menu = Menu(menu) 46 | dyn_menu.add_command(label="single entry") 47 | dyn_menu.add_separator() 48 | print instances 49 | print dir(menu) 50 | print dir(Menu) 51 | for i in range(len(instances)): 52 | print i 53 | name = instances[i] 54 | sm= Menu(dyn_menu) 55 | sm.add_command(label = "export shape with %s" %(name),command=SimpleCallback(apply_export,name)) 56 | sm.add_command(label = "close %s" %(name),command=SimpleCallback(apply_delete,name)) 57 | dyn_menu.add_cascade(label=name,menu=sm) 58 | menu.entryconfigure(3,label="Apply", menu=dyn_menu) 59 | 60 | def dump(arg): 61 | print "instances:" 62 | pp.pprint(instances) 63 | 64 | 65 | pp = pprint.PrettyPrinter(indent=4) 66 | 67 | 68 | counter = 0 69 | entries = ['good','bad','ugly'] 70 | dyn_menu = None 71 | instances = [] 72 | 73 | root=Tk() 74 | menu = Menu(root) 75 | root.config(menu=menu) 76 | 77 | list_menu = Menu(menu) 78 | list_menu.add_command(label="show instances",command=SimpleCallback(dump,1)) 79 | menu.add_cascade(label="Dump", menu=list_menu) 80 | 81 | 82 | create_menu = Menu(menu) 83 | for k in entries: 84 | create_menu.add_command(label=k,command=SimpleCallback(add_instance,k)) 85 | menu.add_cascade(label="Create", menu=create_menu) 86 | 87 | menu.add_cascade(label="Apply") 88 | menu.entryconfigure(3,label="Sowas", menu=dyn_menu) 89 | #rebuild_menu() 90 | root.mainloop() 91 | -------------------------------------------------------------------------------- /python_examples/progressbar.py: -------------------------------------------------------------------------------- 1 | 2 | from PyQt4 import QtCore, QtGui 3 | import time 4 | from PyQt4.QtGui import QApplication 5 | import sys 6 | 7 | 8 | # http://stackoverflow.com/questions/19442443/busy-indication-with-pyqt-progress-bar 9 | class MyCustomWidget(QtGui.QWidget): 10 | 11 | def __init__(self, parent=None): 12 | super(MyCustomWidget, self).__init__(parent) 13 | layout = QtGui.QVBoxLayout(self) 14 | self.setWindowFlags(QtCore.Qt.FramelessWindowHint) 15 | #self.setAttribute(QtCore.Qt.WA_TranslucentBackground) 16 | 17 | self.progressBar = QtGui.QProgressBar(self) 18 | self.progressBar.setRange(0,100) 19 | button = QtGui.QPushButton("Start", self) 20 | layout.addWidget(self.progressBar) 21 | layout.addWidget(button) 22 | 23 | button.clicked.connect(self.onStart) 24 | 25 | self.myLongTask = TaskThread() 26 | print(self.myLongTask.result) 27 | self.myLongTask.notifyProgress.connect(self.onProgress) 28 | self.myLongTask.done.connect(self.finPBar) 29 | 30 | def finPBar(self, object): 31 | print(object.result) 32 | 33 | def onStart(self): 34 | self.myLongTask.start() 35 | 36 | def onProgress(self, i): 37 | self.progressBar.setValue(i) 38 | 39 | 40 | class TaskThread(QtCore.QThread): 41 | notifyProgress = QtCore.pyqtSignal(int) 42 | done = QtCore.pyqtSignal(object) 43 | 44 | def __init__(self): 45 | super(TaskThread, self).__init__() 46 | self.result = "No" 47 | 48 | def run(self): 49 | for i in range(101): 50 | self.notifyProgress.emit(i) 51 | time.sleep(0.1) 52 | self.result = "success" 53 | self.done.emit(self) 54 | 55 | 56 | if __name__ == "__main__" : 57 | app = QApplication(sys.argv) 58 | tester = MyCustomWidget() 59 | tester.show() 60 | sys.exit(app.exec_()) 61 | -------------------------------------------------------------------------------- /python_examples/qt/Starte_mein_gui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """The user interface for our app""" 4 | 5 | import os,sys 6 | 7 | # Import Qt modules 8 | from PyQt4 import QtCore,QtGui 9 | 10 | # Import the compiled UI module 11 | from mein_test import Ui_MainWindow 12 | 13 | # Create a class for our main window 14 | class Main(QtGui.QMainWindow): 15 | def __init__(self): 16 | QtGui.QMainWindow.__init__(self) 17 | 18 | # This is always the same 19 | self.ui=Ui_MainWindow() 20 | self.ui.setupUi(self) 21 | 22 | self.createActions() 23 | 24 | self.myGraphicsScene=myGraphicsScene() 25 | self.myGraphicsScene.addLine() 26 | 27 | self.ui.mygraphicsView.setScene(self.myGraphicsScene) 28 | self.ui.mygraphicsView.show() 29 | 30 | def createActions(self): 31 | 32 | 33 | self.ui.actionExit.triggered.connect(self.close) 34 | 35 | self.ui.actionLoad_File.triggered.connect(self.showDialog) 36 | 37 | self.ui.actionAbout.triggered.connect(self.about) 38 | 39 | 40 | def showDialog(self): 41 | filename = QtGui.QFileDialog.getOpenFileName(self, 'Open file', 42 | 'E:') 43 | 44 | 45 | def about(self): 46 | QtGui.QMessageBox.about(self, "About Diagram Scene", 47 | "The Diagram Scene example shows use of the graphics framework.") 48 | 49 | class myGraphicsScene(QtGui.QGraphicsScene): 50 | def __init__(self): 51 | QtGui.QGraphicsScene.__init__(self) 52 | self.setSceneRect(0,-600,800,500) 53 | 54 | def addLine(self): 55 | l=myLineItem(QtCore.QLineF(0,0,2000,-200)) 56 | self.addItem(l) 57 | 58 | class myLineItem(QtGui.QGraphicsLineItem): 59 | def __init__(self,line): 60 | QtGui.QGraphicsLineItem.__init__(self,line) 61 | def paint(self, painter, options, widget): 62 | print "Painting" 63 | QtGui.QGraphicsLineItem.paint(self, painter,options,widget) 64 | #self.setPen(QPen(Qt.red)) 65 | 66 | 67 | 68 | def main(): 69 | # Again, this is boilerplate, it's going to be the same on 70 | # almost every app you write 71 | app = QtGui.QApplication(sys.argv) 72 | window=Main() 73 | window.show() 74 | 75 | 76 | # It's exec_ because exec is a reserved word in Python 77 | sys.exit(app.exec_()) 78 | 79 | 80 | if __name__ == "__main__": 81 | main() 82 | 83 | -------------------------------------------------------------------------------- /python_examples/qt/Starte_mein_gui.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python -*- 2 | a = Analysis([os.path.join(HOMEPATH,'support\\_mountzlib.py'), os.path.join(HOMEPATH,'support\\useUnicode.py'), 'D:\\Eclipse_Workspace\\DXF2GCODE\\trunk\\python_examples\\qt/Starte_mein_gui.py'], 3 | pathex=['D:\\Eclipse_Workspace\\DXF2GCODE\\trunk\\python_examples\\qt']) 4 | pyz = PYZ(a.pure) 5 | exe = EXE( pyz, 6 | a.scripts, 7 | a.binaries, 8 | a.zipfiles, 9 | a.datas, 10 | name=os.path.join('dist', 'Starte_mein_gui.exe'), 11 | debug=False, 12 | strip=False, 13 | upx=True, 14 | console=False ) 15 | -------------------------------------------------------------------------------- /python_examples/qt/context_menu.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | from PyQt4.QtCore import Qt 5 | from PyQt4.QtGui import * 6 | 7 | class TableWidget(QTableWidget): 8 | 9 | def __init__(self, parent = None): 10 | 11 | QTableWidget.__init__(self, parent) 12 | self.setContextMenuPolicy(Qt.ActionsContextMenu) 13 | 14 | quitAction = QAction("Quit", self) 15 | quitAction.triggered.connect(qApp.quit) 16 | 17 | quitAction2 = QAction("Quit", self) 18 | quitAction2.triggered.connect(qApp.quit) 19 | 20 | self.addAction(quitAction) 21 | self.addAction(quitAction2) 22 | 23 | 24 | app = QApplication([]) 25 | tableWidget = TableWidget() 26 | tableWidget.show() 27 | sys.exit(app.exec_()) 28 | -------------------------------------------------------------------------------- /python_examples/qt/demo.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'demo.ui' 4 | # 5 | # Created: Wed Nov 24 21:16:23 2010 6 | # by: PyQt4 UI code generator 4.5.4 7 | # 8 | # WARNING! All changes made in this file will be lost! 9 | 10 | from PyQt4 import QtCore, QtGui 11 | 12 | class Ui_DemoDialog(object): 13 | def setupUi(self, DemoDialog): 14 | DemoDialog.setObjectName("DemoDialog") 15 | DemoDialog.resize(473, 439) 16 | self.gridlayout = QtGui.QGridLayout(DemoDialog) 17 | self.gridlayout.setMargin(9) 18 | self.gridlayout.setSpacing(6) 19 | self.gridlayout.setObjectName("gridlayout") 20 | self.vboxlayout = QtGui.QVBoxLayout() 21 | self.vboxlayout.setSpacing(6) 22 | self.vboxlayout.setMargin(0) 23 | self.vboxlayout.setObjectName("vboxlayout") 24 | self.button1 = QtGui.QPushButton(DemoDialog) 25 | self.button1.setObjectName("button1") 26 | self.vboxlayout.addWidget(self.button1) 27 | self.button2 = QtGui.QPushButton(DemoDialog) 28 | self.button2.setObjectName("button2") 29 | self.vboxlayout.addWidget(self.button2) 30 | self.gridlayout.addLayout(self.vboxlayout, 1, 0, 1, 1) 31 | self.hboxlayout = QtGui.QHBoxLayout() 32 | self.hboxlayout.setSpacing(6) 33 | self.hboxlayout.setMargin(0) 34 | self.hboxlayout.setObjectName("hboxlayout") 35 | spacerItem = QtGui.QSpacerItem(131, 31, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) 36 | self.hboxlayout.addItem(spacerItem) 37 | self.okButton = QtGui.QPushButton(DemoDialog) 38 | self.okButton.setObjectName("okButton") 39 | self.hboxlayout.addWidget(self.okButton) 40 | self.gridlayout.addLayout(self.hboxlayout, 3, 0, 1, 3) 41 | spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) 42 | self.gridlayout.addItem(spacerItem1, 2, 0, 1, 1) 43 | spacerItem2 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) 44 | self.gridlayout.addItem(spacerItem2, 0, 0, 1, 1) 45 | self.list = QtGui.QListWidget(DemoDialog) 46 | self.list.setObjectName("list") 47 | self.gridlayout.addWidget(self.list, 0, 2, 3, 1) 48 | self.graphicsView = QtGui.QGraphicsView(DemoDialog) 49 | self.graphicsView.setObjectName("graphicsView") 50 | self.gridlayout.addWidget(self.graphicsView, 0, 1, 3, 1) 51 | 52 | self.retranslateUi(DemoDialog) 53 | QtCore.QObject.connect(self.okButton, QtCore.SIGNAL("clicked()"), DemoDialog.accept) 54 | QtCore.QObject.connect(self.button2, QtCore.SIGNAL("clicked()"), self.list.clear) 55 | QtCore.QMetaObject.connectSlotsByName(DemoDialog) 56 | 57 | def retranslateUi(self, DemoDialog): 58 | DemoDialog.setWindowTitle(QtGui.QApplication.translate("DemoDialog", "PyUIC4 Demo Dialog", None, QtGui.QApplication.UnicodeUTF8)) 59 | self.button1.setText(QtGui.QApplication.translate("DemoDialog", "Add items", None, QtGui.QApplication.UnicodeUTF8)) 60 | self.button2.setText(QtGui.QApplication.translate("DemoDialog", "Clear list", None, QtGui.QApplication.UnicodeUTF8)) 61 | self.okButton.setText(QtGui.QApplication.translate("DemoDialog", "OK", None, QtGui.QApplication.UnicodeUTF8)) 62 | 63 | -------------------------------------------------------------------------------- /python_examples/qt/demo.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DemoDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 473 10 | 439 11 | 12 | 13 | 14 | PyUIC4 Demo Dialog 15 | 16 | 17 | 18 | 9 19 | 20 | 21 | 6 22 | 23 | 24 | 25 | 26 | 6 27 | 28 | 29 | 0 30 | 31 | 32 | 33 | 34 | Add items 35 | 36 | 37 | 38 | 39 | 40 | 41 | Clear list 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 6 51 | 52 | 53 | 0 54 | 55 | 56 | 57 | 58 | Qt::Horizontal 59 | 60 | 61 | 62 | 131 63 | 31 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | OK 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | Qt::Vertical 81 | 82 | 83 | 84 | 20 85 | 40 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | Qt::Vertical 94 | 95 | 96 | 97 | 20 98 | 40 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | okButton 115 | clicked() 116 | DemoDialog 117 | accept() 118 | 119 | 120 | 369 121 | 256 122 | 123 | 124 | 96 125 | 254 126 | 127 | 128 | 129 | 130 | button2 131 | clicked() 132 | list 133 | clear() 134 | 135 | 136 | 92 137 | 112 138 | 139 | 140 | 279 141 | 123 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /python_examples/qt/diagramscene.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/pointer.png 4 | images/linepointer.png 5 | images/textpointer.png 6 | images/bold.png 7 | images/italic.png 8 | images/underline.png 9 | images/floodfill.png 10 | images/bringtofront.png 11 | images/delete.png 12 | images/sendtoback.png 13 | images/linecolor.png 14 | images/background1.png 15 | images/background2.png 16 | images/background3.png 17 | images/background4.png 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /python_examples/qt/filedialog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # openfiledialog.py 4 | 5 | import sys 6 | from PyQt4 import QtGui 7 | from PyQt4 import QtCore 8 | 9 | 10 | class OpenFile(QtGui.QMainWindow): 11 | def __init__(self, parent=None): 12 | QtGui.QMainWindow.__init__(self, parent) 13 | 14 | self.setGeometry(300, 300, 350, 300) 15 | self.setWindowTitle('OpenFile') 16 | 17 | self.textEdit = QtGui.QTextEdit() 18 | self.setCentralWidget(self.textEdit) 19 | self.statusBar() 20 | 21 | self._label = QtGui.QLabel("Einkaufszaehler") 22 | self.statusBar().addPermanentWidget(self._label) 23 | self.statusBar().addPermanentWidget(self._label) 24 | 25 | self._label.setText("BLA2") 26 | 27 | self.setFocus() 28 | 29 | openFile = QtGui.QAction(QtGui.QIcon('open.png'), 'Open', self) 30 | openFile.setShortcut('Ctrl+O') 31 | openFile.setStatusTip('Open new File') 32 | self.connect(openFile, QtCore.SIGNAL('triggered()'), self.showDialog) 33 | 34 | menubar = self.menuBar() 35 | fileMenu = menubar.addMenu('&File') 36 | fileMenu.addAction(openFile) 37 | 38 | def showDialog(self): 39 | filename = QtGui.QFileDialog.getOpenFileName(self, 'Open file', 40 | '/home') 41 | fname = open(filename) 42 | data = fname.read() 43 | self.textEdit.setText(data) 44 | 45 | app = QtGui.QApplication(sys.argv) 46 | fd = OpenFile() 47 | fd.show() 48 | app.exec_() 49 | 50 | -------------------------------------------------------------------------------- /python_examples/qt/graphicscene_test.py: -------------------------------------------------------------------------------- 1 | from PyQt4.QtGui import * 2 | from PyQt4.QtCore import * 3 | import sys 4 | class myLineItem(QGraphicsLineItem): 5 | def __init__(self,line): 6 | QGraphicsLineItem.__init__(self,line) 7 | def paint(self, painter, options, widget): 8 | print "Painting" 9 | QGraphicsLineItem.paint(self, painter,options,widget) 10 | #self.setPen(QPen(Qt.red)) 11 | app=QApplication(sys.argv) 12 | scene=QGraphicsScene() 13 | l=myLineItem(QLineF(-20,0,20,2000)) 14 | 15 | 16 | 17 | scene.addItem(l) 18 | 19 | view= QGraphicsView(scene) 20 | view.show(); 21 | scene.setSceneRect(0,0,800,600) 22 | app.exec_() 23 | 24 | -------------------------------------------------------------------------------- /python_examples/qt/images/background1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/background1.png -------------------------------------------------------------------------------- /python_examples/qt/images/background2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/background2.png -------------------------------------------------------------------------------- /python_examples/qt/images/background3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/background3.png -------------------------------------------------------------------------------- /python_examples/qt/images/background4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/background4.png -------------------------------------------------------------------------------- /python_examples/qt/images/bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/bold.png -------------------------------------------------------------------------------- /python_examples/qt/images/bringtofront.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/bringtofront.png -------------------------------------------------------------------------------- /python_examples/qt/images/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/delete.png -------------------------------------------------------------------------------- /python_examples/qt/images/floodfill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/floodfill.png -------------------------------------------------------------------------------- /python_examples/qt/images/italic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/italic.png -------------------------------------------------------------------------------- /python_examples/qt/images/linecolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/linecolor.png -------------------------------------------------------------------------------- /python_examples/qt/images/linepointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/linepointer.png -------------------------------------------------------------------------------- /python_examples/qt/images/pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/pointer.png -------------------------------------------------------------------------------- /python_examples/qt/images/sendtoback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/sendtoback.png -------------------------------------------------------------------------------- /python_examples/qt/images/textpointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/textpointer.png -------------------------------------------------------------------------------- /python_examples/qt/images/underline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/qt/images/underline.png -------------------------------------------------------------------------------- /python_examples/qt/make_exe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os, sys 4 | import subprocess 5 | 6 | pyinpfad = "C:\Python26\pyinstaller-1.4" 7 | 8 | pyt = "C:/Python26/pythonw.exe" 9 | filepfad= os.path.realpath(os.path.dirname(sys.argv[0])) 10 | exemakepfad=filepfad 11 | file = "Starte_mein_gui" 12 | icon= "%s/DXF2GCODE-001.ico" %filepfad 13 | 14 | #options=("--onefile --noconsole --upx --icon=%s" %icon) 15 | options=("--onefile --noconsole --upx") 16 | print options 17 | 18 | #Verzwichniss wechseln 19 | exemakepfad = unicode( exemakepfad, "utf-8" ) 20 | os.chdir(exemakepfad.encode( "utf-8" )) 21 | 22 | 23 | cmd=("%s %s\Makespec.py %s %s/%s.py" %(pyt,pyinpfad,options,filepfad,file)) 24 | print cmd 25 | retcode=subprocess.call(cmd) 26 | 27 | cmd=("%s %s\Build.py %s\%s.spec" %(pyt,pyinpfad,exemakepfad,file)) 28 | print cmd 29 | retcode=subprocess.call(cmd) 30 | 31 | print "\n!!!!!!!Bitmaps und Languagues Ordner nicht vergessen!!!!!!" 32 | print "\nFertig" -------------------------------------------------------------------------------- /python_examples/qt/make_py_uic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os, sys 4 | import subprocess 5 | 6 | pyt = "C:/Python26/pythonw.exe" 7 | 8 | uicpfad = "C:\Python26\Lib\site-packages\PyQt4\uic" 9 | filepfad= os.path.realpath(os.path.dirname(sys.argv[0])) 10 | 11 | uifile = "mein_test.ui" 12 | ergfile= "mein_test.py" 13 | 14 | 15 | options=("-o") 16 | #print options 17 | 18 | 19 | cmd=("%s %s\pyuic.py %s %s %s" %(pyt,uicpfad,uifile,options,ergfile)) 20 | print cmd 21 | retcode=subprocess.call(cmd) 22 | -------------------------------------------------------------------------------- /python_examples/travelling_salesman_problem_2.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/python_examples/travelling_salesman_problem_2.py -------------------------------------------------------------------------------- /python_examples/treewidget.py: -------------------------------------------------------------------------------- 1 | from PyQt5.QtCore import ( 2 | QAbstractItemModel, 3 | QModelIndex, 4 | Qt, 5 | QVariant 6 | ) 7 | 8 | from PyQt5.QtWidgets import QApplication, QTreeView 9 | 10 | class TreeItem(object): 11 | def __init__(self, content, parentItem): 12 | self.content = content 13 | self.parentItem = parentItem 14 | self.childItems = [] 15 | 16 | def appendChild(self, item): 17 | self.childItems.append(item) 18 | 19 | def child(self, row): 20 | return self.childItems[row] 21 | 22 | def childCount(self): 23 | return len(self.childItems) 24 | 25 | def columnCount(self): 26 | return 1 27 | 28 | def data(self, column): 29 | if self.content != None and column == 0: 30 | return QVariant(self.content) 31 | 32 | return QVariant() 33 | 34 | def parent(self): 35 | return self.parentItem 36 | 37 | def row(self): 38 | if self.parentItem: 39 | return self.parentItem.childItems.index(self) 40 | return 0 41 | 42 | class NodeTree(QAbstractItemModel): 43 | def __init__(self,parent,data) : 44 | super(NodeTree,self).__init__(parent) 45 | self.rootItem = TreeItem(None, None) 46 | self.parents = {0 : self.rootItem} 47 | self.setupModelData(self.rootItem, data) 48 | 49 | def setupModelData(self, root, data): 50 | for el in data: 51 | if isinstance(el, list): 52 | item = TreeItem("Node", root) 53 | self.setupModelData(item, el) 54 | else: 55 | item = TreeItem(el, root) 56 | root.appendChild(item) 57 | 58 | def rowCount(self, parent = QModelIndex()): 59 | if parent.column() > 0: 60 | return 0 61 | if not parent.isValid(): 62 | p_Item = self.rootItem 63 | else: 64 | p_Item = parent.internalPointer() 65 | return p_Item.childCount() 66 | 67 | def columnCount(self, parent = QModelIndex()): 68 | return 1 69 | 70 | def data(self, index, role): 71 | if not index.isValid(): 72 | return QVariant() 73 | 74 | item = index.internalPointer() 75 | if role == Qt.DisplayRole: 76 | return item.data(index.column()) 77 | if role == Qt.UserRole: 78 | if item: 79 | return item.content 80 | 81 | return QVariant() 82 | 83 | def headerData(self, column, orientation, role): 84 | if (orientation == Qt.Horizontal and 85 | role == Qt.DisplayRole): 86 | return QVariant("Content") 87 | 88 | return QVariant() 89 | 90 | def index(self, row, column, parent): 91 | if not self.hasIndex(row, column, parent): 92 | return QModelIndex() 93 | 94 | if not parent.isValid(): 95 | parentItem = self.rootItem 96 | else: 97 | parentItem = parent.internalPointer() 98 | 99 | childItem = parentItem.child(row) 100 | if childItem: 101 | return self.createIndex(row, column, childItem) 102 | else: 103 | return QModelIndex() 104 | 105 | def parent(self, index): 106 | if not index.isValid(): 107 | return QModelIndex() 108 | 109 | childItem = index.internalPointer() 110 | if not childItem: 111 | return QModelIndex() 112 | 113 | parentItem = childItem.parent() 114 | 115 | if parentItem == self.rootItem: 116 | return QModelIndex() 117 | 118 | return self.createIndex(parentItem.row(), 0, parentItem) 119 | 120 | if __name__ == "__main__" : 121 | # http://blog.mathieu-leplatre.info/filesystem-watch-with-pyqt4.html 122 | import sys 123 | 124 | app = QApplication(sys.argv) 125 | TreeView = QTreeView() 126 | TreeModel = NodeTree(TreeView, [['A',['a',1]],['C','D'],['E','F']]) 127 | TreeView.setModel(TreeModel) 128 | TreeView.show() 129 | app.exec_() 130 | -------------------------------------------------------------------------------- /source/core/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /source/core/boundingbox.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohl�ffel 7 | # Vinzenz Schulz 8 | # Jean-Paul Schouwstra 9 | # 10 | # This file is part of DXF2GCODE. 11 | # 12 | # DXF2GCODE is free software: you can redistribute it and/or modify 13 | # it under the terms of the GNU General Public License as published by 14 | # the Free Software Foundation, either version 3 of the License, or 15 | # (at your option) any later version. 16 | # 17 | # DXF2GCODE is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | # GNU General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU General Public License 23 | # along with DXF2GCODE. If not, see . 24 | # 25 | ############################################################################ 26 | 27 | from __future__ import absolute_import 28 | from __future__ import division 29 | 30 | from math import sqrt, sin, cos, atan2 31 | from copy import deepcopy 32 | 33 | from core.point import Point 34 | 35 | import logging 36 | logger = logging.getLogger("core.boundingbox") 37 | 38 | eps=-1e-12 39 | 40 | class BoundingBox: 41 | """ 42 | Bounding Box Class. This is the standard class which provides all std. 43 | Bounding Box methods. 44 | """ 45 | def __init__(self, Ps=Point(0, 0), Pe=Point(0, 0), hdl=[]): 46 | """ 47 | Standard method to initialize the class 48 | """ 49 | 50 | self.Ps = Ps 51 | self.Pe = Pe 52 | 53 | 54 | def __str__(self): 55 | """ 56 | Standard method to print the object 57 | @return: A string 58 | """ 59 | s = ("\nPs : %s" % (self.Ps)) + \ 60 | ("\nPe : %s" % (self.Pe)) 61 | return s 62 | 63 | def joinBB(self, other): 64 | """ 65 | Joins two Bounding Box Classes and returns the new one 66 | @param other: The 2nd Bounding Box 67 | @return: Returns the joined Bounding Box Class 68 | """ 69 | 70 | if type(self.Ps) == type(None) or type(self.Pe) == type(None): 71 | return BoundingBox(deepcopy(other.Ps), deepcopy(other.Pe)) 72 | 73 | xmin = min(self.Ps.x, other.Ps.x) 74 | xmax = max(self.Pe.x, other.Pe.x) 75 | ymin = min(self.Ps.y, other.Ps.y) 76 | ymax = max(self.Pe.y, other.Pe.y) 77 | 78 | return BoundingBox(Ps=Point(xmin, ymin), Pe=Point(xmax, ymax)) 79 | 80 | def hasintersection(self, other=None, tol=eps): 81 | """ 82 | Checks if the two bounding boxes have an intersection 83 | @param other: The 2nd Bounding Box 84 | @return: Returns true or false 85 | """ 86 | if isinstance(other, Point): 87 | return self.pointisinBB(other, tol) 88 | elif isinstance(other, BoundingBox): 89 | x_inter_pos = (self.Pe.x + tol > other.Ps.x) and \ 90 | (self.Ps.x - tol < other.Pe.x) 91 | y_inter_pos = (self.Pe.y + tol > other.Ps.y) and \ 92 | (self.Ps.y - tol < other.Pe.y) 93 | 94 | return x_inter_pos and y_inter_pos 95 | else: 96 | logger.warning("Unsupported Instance: %s" % other.type) 97 | 98 | def iscontained(self, other): 99 | """ 100 | Checks if self Bounding Box is contained in Boundingbox of other 101 | @param other: The 2nd Bounding Box 102 | @return: Returns true or false 103 | """ 104 | return other.Ps.x < self.Ps.x and self.Pe.x < other.Pe.x and\ 105 | other.Ps.y < self.Ps.y and self.Pe.y < other.Pe.y 106 | 107 | 108 | def pointisinBB(self, Point=Point(), tol=eps): 109 | """ 110 | Checks if the Point is within the bounding box 111 | @param Point: The Point which shall be ckecke 112 | @return: Returns true or false 113 | """ 114 | x_inter_pos = (self.Pe.x + tol > Point.x) and \ 115 | (self.Ps.x - tol < Point.x) 116 | y_inter_pos = (self.Pe.y + tol > Point.y) and \ 117 | (self.Ps.y - tol < Point.y) 118 | return x_inter_pos and y_inter_pos 119 | -------------------------------------------------------------------------------- /source/core/breakgeo.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*-# -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2014-2015 6 | # Robert Lichtenberger 7 | # Wojciech Nycz 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | from __future__ import absolute_import 27 | 28 | from copy import deepcopy 29 | 30 | from core.linegeo import LineGeo 31 | 32 | 33 | class BreakGeo(LineGeo): 34 | """ 35 | BreakGeo interrupts another geometry item by changing the Z-Position. 36 | """ 37 | def __init__(self, Ps, Pe, height, xyfeed, zfeed): 38 | LineGeo.__init__(self, Ps, Pe) 39 | 40 | self.height = height 41 | self.xyfeed = xyfeed 42 | self.zfeed = zfeed 43 | 44 | def __deepcopy__(self, memo): 45 | return BreakGeo(deepcopy(self.Ps, memo), 46 | deepcopy(self.Pe, memo), 47 | deepcopy(self.height, memo), 48 | deepcopy(self.xyfeed, memo), 49 | deepcopy(self.zfeed, memo)) 50 | 51 | def __str__(self): 52 | """ 53 | Standard method to print the object 54 | @return: A string 55 | """ 56 | return "\nBreakGeo" +\ 57 | "\nPs: %s" % self.Ps +\ 58 | "\nPe: %s" % self.Pe +\ 59 | "\nheight: %0.5f" % self.height 60 | 61 | def save_v1(self): 62 | """ 63 | Standard method to print the object 64 | @return: A string 65 | """ 66 | return "\nBreakGeo" +\ 67 | "\nPs: %s" % self.Ps.save_v1() +\ 68 | "\nPe: %s" % self.Pe.save_v1() +\ 69 | "\nheight: %0.5f" % self.height 70 | 71 | def Write_GCode(self, PostPro): 72 | """ 73 | Writes the GCODE for a Break. 74 | @param PostPro: The PostProcessor instance to be used 75 | @return: Returns the string to be written to file. 76 | """ 77 | oldZ = PostPro.ze 78 | oldFeed = PostPro.feed 79 | if self.height <= oldZ: 80 | return ( 81 | LineGeo.Write_GCode(self, PostPro) 82 | ) 83 | else: 84 | return ( 85 | PostPro.chg_feed_rate(self.zfeed) + 86 | PostPro.lin_pol_z(self.height) + 87 | PostPro.chg_feed_rate(self.xyfeed) + 88 | LineGeo.Write_GCode(self, PostPro) + 89 | PostPro.chg_feed_rate(self.zfeed) + 90 | PostPro.lin_pol_z(oldZ) + 91 | PostPro.chg_feed_rate(oldFeed) 92 | ) 93 | -------------------------------------------------------------------------------- /source/core/customgcode.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2012-2015 6 | # Xavier Izard 7 | # 8 | # This file is part of DXF2GCODE. 9 | # 10 | # DXF2GCODE is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # DXF2GCODE is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with DXF2GCODE. If not, see . 22 | # 23 | ############################################################################ 24 | 25 | 26 | class CustomGCode(object): 27 | """ 28 | This class contains a "custom gcode" object. Custom GCode objects are part 29 | of a layer (layercontent.py) and are used to insert custom GCode into the 30 | generated file. 31 | Custom GCodes are defined in the config file 32 | 33 | @purpose: store user defined GCode 34 | """ 35 | def __init__(self, name, nr, gcode, parentLayer): 36 | """ 37 | Standard method to initialize the class 38 | @param name: the name of the GCode, as defined in the config file 39 | @param gcode: the user defined gcode 40 | @param parent: The parent layer Class of the shape 41 | """ 42 | self.name = name 43 | self.nr = nr 44 | self.gcode = gcode 45 | self.parentLayer = parentLayer 46 | self.disabled = False 47 | self.send_to_TSP = False # Never optimize path for CustomGCode 48 | 49 | def __str__(self): 50 | """ 51 | Standard method to print the object 52 | @return: A string 53 | """ 54 | return "\nCustomGCode" +\ 55 | "\nname: %s" % self.name +\ 56 | "\nnr: %i" % self.nr +\ 57 | "\ngcode: %s" % self.gcode 58 | 59 | def setDisable(self, flag=False): 60 | """ 61 | Function to modify the disable property 62 | @param flag: The flag to enable or disable Selection 63 | """ 64 | self.disabled = flag 65 | 66 | def isDisabled(self): 67 | """ 68 | Returns the state of self.disabled 69 | """ 70 | return self.disabled 71 | 72 | def Write_GCode(self, PostPro): 73 | """ 74 | This method returns the string to be exported for this custom gcode 75 | @param PostPro: this is the Postprocessor class including the methods to export 76 | """ 77 | return self.gcode 78 | -------------------------------------------------------------------------------- /source/core/entitycontent.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohlöffel 7 | # Vinzenz Schulz 8 | # Jean-Paul Schouwstra 9 | # 10 | # This file is part of DXF2GCODE. 11 | # 12 | # DXF2GCODE is free software: you can redistribute it and/or modify 13 | # it under the terms of the GNU General Public License as published by 14 | # the Free Software Foundation, either version 3 of the License, or 15 | # (at your option) any later version. 16 | # 17 | # DXF2GCODE is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | # GNU General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU General Public License 23 | # along with DXF2GCODE. If not, see . 24 | # 25 | ############################################################################ 26 | 27 | 28 | class EntityContent(object): 29 | def __init__(self, nr, name, parent, p0, pb, sca, rot): 30 | """ 31 | @param p0: The Starting Point to plot (Default x=0 and y=0) 32 | @param bp: The Base Point to insert the geometry and base for rotation 33 | (Default is also x=0 and y=0) 34 | @param sca: The scale of the basis function (default =1) 35 | @param rot: The rotation of the geometries around base (default =0) 36 | """ 37 | self.nr = nr 38 | self.name = name 39 | self.parent = parent 40 | self.children = [] 41 | self.p0 = p0 42 | self.pb = pb 43 | self.sca = sca 44 | self.rot = rot 45 | 46 | def __str__(self): 47 | return "\nEntityContent" +\ 48 | "\nnr : %i" % self.nr +\ 49 | "\nname: %s" % self.name +\ 50 | "\nchildren: %s" % self.children +\ 51 | "\np0: %s" % self.p0 +\ 52 | "\npb: %s" % self.pb +\ 53 | "\nsca: %s" % self.sca +\ 54 | "\nrot: %s" % self.rot 55 | 56 | def append(self, child): 57 | self.children.append(child) 58 | -------------------------------------------------------------------------------- /source/core/holegeo.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2014-2015 6 | # Robert Lichtenberger 7 | # Jean-Paul Schouwstra 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | from __future__ import absolute_import 27 | from __future__ import division 28 | 29 | from copy import deepcopy 30 | from math import pi 31 | 32 | from core.point import Point 33 | from core.boundingbox import BoundingBox 34 | 35 | 36 | class HoleGeo(object): 37 | """ 38 | HoleGeo represents drilling holes. 39 | """ 40 | def __init__(self, Ps): 41 | """ 42 | Standard Method to initialise the HoleGeo 43 | """ 44 | self.Ps = Ps 45 | self.length = -1 46 | 47 | self.abs_geo = None 48 | 49 | def __deepcopy__(self, memo): 50 | return HoleGeo(deepcopy(self.Ps, memo)) 51 | 52 | def __str__(self): 53 | """ 54 | Standard method to print the object 55 | @return: A string 56 | """ 57 | return "\nHoleGeo at (%s) " % self.Ps 58 | 59 | def save_v1(self): 60 | return "\nHoleGeo at (%s) " % self.Ps.save_v1() 61 | 62 | def calc_bounding_box(self, radius = 1): 63 | """ 64 | Calculated the BoundingBox of the geometry and saves it into self.BB 65 | @param radius: The Radius of the HoleGeo to be used for BoundingBox 66 | """ 67 | 68 | Ps = Point(x = self.Ps.x - radius, y = self.Ps.y - radius) 69 | Pe = Point(x = self.Ps.x + radius, y = self.Ps.y + radius) 70 | 71 | self.BB = BoundingBox(Ps = Ps, Pe = Pe) 72 | 73 | def reverse(self): 74 | """ 75 | Reverses the direction. 76 | """ 77 | pass 78 | 79 | def make_abs_geo(self, parent=None): 80 | """ 81 | Generates the absolute geometry based on itself and the parent. This 82 | is done for rotating and scaling purposes 83 | """ 84 | Ps = self.Ps.rot_sca_abs(parent=parent) 85 | 86 | self.abs_geo = HoleGeo(Ps) 87 | 88 | def get_start_end_points(self, start_point, angles=None): 89 | if angles is None: 90 | return self.Ps 91 | elif angles: 92 | return self.Ps, 0 93 | else: 94 | return self.Ps, Point(0, -1) if start_point else Point(0, -1) 95 | 96 | def make_path(self, caller, drawHorLine): 97 | 98 | 99 | radius = caller.parentLayer.tool_diameter / 2 100 | self.calc_bounding_box(radius = radius) 101 | 102 | segments = 30 103 | Ps = self.Ps.get_arc_point(0, radius) 104 | 105 | for i in range(1, segments + 1): 106 | ang = i * 2 * pi / segments 107 | Pe = self.Ps.get_arc_point(ang, radius) 108 | drawHorLine(caller, Ps, Pe) 109 | Ps = Pe 110 | 111 | def isHit(self, caller, xy, tol): 112 | tol2 = tol**2 113 | radius = caller.parentLayer.getToolRadius() 114 | segments = 30 115 | Ps = self.Ps.get_arc_point(0, radius) 116 | for i in range(1, segments + 1): 117 | ang = i * 2 * pi / segments 118 | Pe = self.Ps.get_arc_point(ang, radius) 119 | if xy.distance2_to_line(Ps, Pe) <= tol2: 120 | return True 121 | Ps = Pe 122 | return False 123 | 124 | def Write_GCode(self, PostPro): 125 | """ 126 | Writes the GCODE for a Hole. 127 | @param PostPro: The PostProcessor instance to be used 128 | @return: Returns the string to be written to a file. 129 | """ 130 | return PostPro.make_print_str("(Drilled hole)%nl") 131 | -------------------------------------------------------------------------------- /source/core/intersect.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # 3 | # Copyright (C) 2015 4 | # Jean-Paul Schouwstra 5 | # 6 | # This file is part of DXF2GCODE. 7 | # 8 | # DXF2GCODE is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # DXF2GCODE is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with DXF2GCODE. If not, see . 20 | # 21 | ############################################################################ 22 | 23 | from __future__ import absolute_import 24 | from __future__ import division 25 | 26 | from math import sqrt 27 | 28 | from core.linegeo import LineGeo 29 | from core.arcgeo import ArcGeo 30 | from core.point import Point 31 | 32 | 33 | class Intersect(object): 34 | @staticmethod 35 | def get_intersection_point(prv_geo, geo): 36 | intersection = None 37 | if isinstance(prv_geo, LineGeo) and isinstance(geo, LineGeo): 38 | intersection = Intersect.line_line_intersection(prv_geo, geo) 39 | elif isinstance(prv_geo, LineGeo) and isinstance(geo, ArcGeo): 40 | intersection = Intersect.line_arc_intersection(prv_geo, geo, prv_geo.Pe) 41 | elif isinstance(prv_geo, ArcGeo) and isinstance(geo, LineGeo): 42 | intersection = Intersect.line_arc_intersection(geo, prv_geo, prv_geo.Pe) 43 | elif isinstance(prv_geo, ArcGeo) and isinstance(geo, ArcGeo): 44 | intersection = Intersect.arc_arc_intersection(geo, prv_geo, prv_geo.Pe) 45 | return intersection 46 | 47 | @staticmethod 48 | def point_belongs_to_line(point, line): 49 | linex = sorted([line.Ps.x, line.Pe.x]) 50 | liney = sorted([line.Ps.y, line.Pe.y]) 51 | return (linex[0] - 1e-8 <= point.x <= linex[1] + 1e-8 and 52 | liney[0] - 1e-8 <= point.y <= liney[1] + 1e-8) 53 | 54 | @staticmethod 55 | def point_belongs_to_arc(point, arc): 56 | ang = arc.dif_ang(arc.Ps, point, arc.ext) 57 | return (arc.ext + 1e-8 >= ang >= -1e-8 if arc.ext > 0 else 58 | arc.ext - 1e-8 <= ang <= 1e-8) 59 | 60 | @staticmethod 61 | def line_line_intersection(line1, line2): 62 | # based on 63 | # http://stackoverflow.com/questions/20677795/find-the-point-of-intersecting-lines 64 | xydiff1 = line1.Ps - line1.Pe 65 | xydiff2 = line2.Ps - line2.Pe 66 | xdiff = (xydiff1.x, xydiff2.x) 67 | ydiff = (xydiff1.y, xydiff2.y) 68 | 69 | det = lambda a, b: a[0] * b[1] - a[1] * b[0] 70 | 71 | div = det(xdiff, ydiff) 72 | if div != 0: 73 | d = (det((line1.Ps.x, line1.Ps.y), (line1.Pe.x, line1.Pe.y)), 74 | det((line2.Ps.x, line2.Ps.y), (line2.Pe.x, line2.Pe.y))) 75 | 76 | point = Point(det(d, xdiff) / div, 77 | det(d, ydiff) / div) 78 | 79 | if Intersect.point_belongs_to_line(point, line1) and Intersect.point_belongs_to_line(point, line2): 80 | return point 81 | return None 82 | 83 | @staticmethod 84 | def line_arc_intersection(line, arc, refpoint): 85 | # based on 86 | # http://stackoverflow.com/questions/13053061/circle-line-intersection-points 87 | baX = line.Pe.x - line.Ps.x 88 | baY = line.Pe.y - line.Ps.y 89 | caX = arc.O.x - line.Ps.x 90 | caY = arc.O.y - line.Ps.y 91 | 92 | a = baX * baX + baY * baY 93 | bBy2 = baX * caX + baY * caY 94 | c = caX * caX + caY * caY - arc.r * arc.r 95 | 96 | if a == 0: 97 | return None 98 | 99 | pBy2 = bBy2 / a 100 | q = c / a 101 | 102 | disc = pBy2 * pBy2 - q 103 | if disc > 0: 104 | tmpSqrt = sqrt(disc) 105 | abScalingFactor1 = -pBy2 + tmpSqrt 106 | abScalingFactor2 = -pBy2 - tmpSqrt 107 | 108 | p1 = Point(line.Ps.x - baX * abScalingFactor1, 109 | line.Ps.y - baY * abScalingFactor1) 110 | p2 = Point(line.Ps.x - baX * abScalingFactor2, 111 | line.Ps.y - baY * abScalingFactor2) 112 | 113 | intersections = [] 114 | if Intersect.point_belongs_to_arc(p1, arc) and Intersect.point_belongs_to_line(p1, line): 115 | intersections.append(p1) 116 | if Intersect.point_belongs_to_arc(p2, arc) and Intersect.point_belongs_to_line(p2, line): 117 | intersections.append(p2) 118 | intersections.sort(key=lambda x: (refpoint - x).length_squared()) 119 | if len(intersections) > 0: 120 | return intersections[0] 121 | return None 122 | 123 | @staticmethod 124 | def arc_arc_intersection(arc1, arc2, refpoint): 125 | # based on 126 | # http://stackoverflow.com/questions/3349125/circle-circle-intersection-points 127 | d = arc1.O.distance(arc2.O) 128 | 129 | if d > (arc1.r + arc2.r): # there are no solutions, the circles are separate 130 | return None 131 | elif d + 1e-5 < abs(arc1.r - arc2.r): # there are no solutions because one circle is contained within the other 132 | return None 133 | elif d == 0: # then the circles are coincident and there are an infinite number of solutions 134 | return None 135 | else: 136 | a = (arc1.r**2 - arc2.r**2 + d**2) / (2 * d) 137 | if arc1.r**2 - a**2 < 0: 138 | return None 139 | h = sqrt(arc1.r**2 - a**2) 140 | P2 = arc1.O + a * (arc2.O - arc1.O) / d 141 | 142 | p1 = Point(P2.x + h * (arc2.O.y - arc1.O.y) / d, 143 | P2.y - h * (arc2.O.x - arc1.O.x) / d) 144 | p2 = Point(P2.x - h * (arc2.O.y - arc1.O.y) / d, 145 | P2.y + h * (arc2.O.x - arc1.O.x) / d) 146 | 147 | intersections = [] 148 | if Intersect.point_belongs_to_arc(p1, arc1) and Intersect.point_belongs_to_arc(p1, arc2): 149 | intersections.append(p1) 150 | if Intersect.point_belongs_to_arc(p2, arc1) and Intersect.point_belongs_to_arc(p2, arc2): 151 | intersections.append(p2) 152 | intersections.sort(key=lambda x: (refpoint - x).length_squared()) 153 | if len(intersections) > 0: 154 | return intersections[0] 155 | return None 156 | -------------------------------------------------------------------------------- /source/core/layercontent.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohlöffel 7 | # Vinzenz Schulz 8 | # Jean-Paul Schouwstra 9 | # Robert Lichtenberger 10 | # 11 | # This file is part of DXF2GCODE. 12 | # 13 | # DXF2GCODE is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU General Public License as published by 15 | # the Free Software Foundation, either version 3 of the License, or 16 | # (at your option) any later version. 17 | # 18 | # DXF2GCODE is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU General Public License 24 | # along with DXF2GCODE. If not, see . 25 | # 26 | ############################################################################ 27 | 28 | from __future__ import absolute_import 29 | from __future__ import division 30 | 31 | import re 32 | 33 | import globals.globals as g 34 | 35 | 36 | class LayerContent(object): 37 | def __init__(self, nr, name, shapes): 38 | self.nr = nr 39 | self.name = name 40 | self.shapes = Shapes(shapes) 41 | self.exp_order = [] # used for shape order optimization, ... Only contains shapes 42 | 43 | # Use default tool 1 (always exists in config) 44 | self.tool_nr = 1 45 | self.tool_diameter = g.config.vars.Tool_Parameters['1']['diameter'] 46 | self.speed = g.config.vars.Tool_Parameters['1']['speed'] 47 | self.start_radius = g.config.vars.Tool_Parameters['1']['start_radius'] 48 | 49 | # preset defaults 50 | self.axis3_retract = g.config.vars.Depth_Coordinates['axis3_retract'] 51 | self.axis3_safe_margin = g.config.vars.Depth_Coordinates['axis3_safe_margin'] 52 | 53 | def __str__(self): 54 | """ 55 | Standard method to print the object 56 | @return: A string 57 | """ 58 | return "\nLayerContent" +\ 59 | "\nnr: %i" % self.nr +\ 60 | "\nname: %s" % self.name +\ 61 | "\nshapes: %s" % self.shapes 62 | 63 | def should_ignore(self): 64 | return self.name.startswith('IGNORE' + g.config.vars.Layer_Options['id_float_separator']) 65 | 66 | def isBreakLayer(self): 67 | return self.name.startswith('BREAKS' + g.config.vars.Layer_Options['id_float_separator']) 68 | 69 | def isMillLayer(self): 70 | return self.name.startswith('MILL' + g.config.vars.Layer_Options['id_float_separator']) 71 | 72 | def isDrillLayer(self): 73 | return self.name.startswith('DRILL' + g.config.vars.Layer_Options['id_float_separator']) 74 | 75 | def isParameterizableLayer(self): 76 | return self.isMillLayer() or self.isDrillLayer() or self.isBreakLayer() 77 | 78 | def automaticCutterCompensationEnabled(self): 79 | return not self.should_ignore() and not self.isDrillLayer() 80 | 81 | def getToolRadius(self): 82 | return self.tool_diameter / 2 83 | 84 | def overrideDefaults(self): 85 | # search for layer commands to override defaults 86 | if self.isParameterizableLayer(): 87 | layer_commands = self.name.replace(",", ".") 88 | lopts_re = re.compile("([a-zA-Z]+ *"+g.config.vars.Layer_Options['id_float_separator']+" *[\-\.0-9]+)") 89 | # print lopts_re.findall(layer_commands) 90 | for lc in lopts_re.findall(layer_commands): 91 | name, value = lc.split(g.config.vars.Layer_Options['id_float_separator']) 92 | name = name.strip() 93 | # print '\"%s\" \"%s\"' %(name, value) 94 | if name in g.config.vars.Layer_Options['tool_nr_identifiers']: 95 | self.tool_nr = float(value) 96 | elif name in g.config.vars.Layer_Options['tool_diameter_identifiers']: 97 | self.tool_diameter = float(value) 98 | elif name in g.config.vars.Layer_Options['spindle_speed_identifiers']: 99 | self.speed = float(value) 100 | elif name in g.config.vars.Layer_Options['start_radius_identifiers']: 101 | self.start_radius = float(value) 102 | elif name in g.config.vars.Layer_Options['retract_identifiers']: 103 | self.axis3_retract = float(value) 104 | elif name in g.config.vars.Layer_Options['safe_margin_identifiers']: 105 | self.axis3_safe_margin = float(value) 106 | elif name in g.config.vars.Layer_Options['start_mill_depth_identifiers']: 107 | for shape in self.shapes: 108 | shape.axis3_start_mill_depth = float(value) 109 | elif name in g.config.vars.Layer_Options['slice_depth_identifiers']: 110 | for shape in self.shapes: 111 | shape.axis3_slice_depth = float(value) 112 | elif name in g.config.vars.Layer_Options['mill_depth_identifiers']: 113 | for shape in self.shapes: 114 | shape.axis3_mill_depth = float(value) 115 | elif name in g.config.vars.Layer_Options['f_g1_plane_identifiers']: 116 | for shape in self.shapes: 117 | shape.f_g1_plane = float(value) 118 | elif name in g.config.vars.Layer_Options['f_g1_depth_identifiers']: 119 | for shape in self.shapes: 120 | shape.f_g1_depth = float(value) 121 | if self.should_ignore(): 122 | # Disable shape by default, if it lives on an ignored layer 123 | for shape in self.shapes: 124 | shape.setDisable(True) 125 | 126 | 127 | class Layers(list): 128 | def __init__(self, *args): 129 | list.__init__(self, *args) 130 | 131 | # def __iter__(self): 132 | def non_break_layer_iter(self): 133 | for layer in list.__iter__(self): 134 | if not layer.isBreakLayer(): 135 | yield layer 136 | else: 137 | raise StopIteration() 138 | 139 | def break_layer_iter(self): 140 | for layer in list.__iter__(self): 141 | if layer.isBreakLayer(): 142 | yield layer 143 | else: 144 | raise StopIteration() 145 | 146 | 147 | class Shapes(list): 148 | def __init__(self, *args): 149 | list.__init__(self, *args) 150 | 151 | # def __iter__(self): 152 | def selected_iter(self): 153 | for shape in list.__iter__(self): 154 | if shape.selected: 155 | yield shape 156 | else: 157 | raise StopIteration() 158 | 159 | def not_selected_iter(self): 160 | for shape in list.__iter__(self): 161 | if not shape.selected: 162 | yield shape 163 | else: 164 | raise StopIteration() 165 | 166 | def not_disabled_iter(self): 167 | for shape in list.__iter__(self): 168 | if not shape.disabled: 169 | yield shape 170 | else: 171 | raise StopIteration() 172 | -------------------------------------------------------------------------------- /source/core/point3d.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2015 6 | # Jean-Paul Schouwstra 7 | # 8 | # This file is part of DXF2GCODE. 9 | # 10 | # DXF2GCODE is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # DXF2GCODE is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with DXF2GCODE. If not, see . 22 | # 23 | ############################################################################ 24 | 25 | from __future__ import absolute_import 26 | from __future__ import division 27 | 28 | from math import sqrt 29 | 30 | class Point3D(object): 31 | __slots__ = ["x", "y", "z"] 32 | 33 | def __init__(self, x=0.0, y=0.0, z=0.0): 34 | self.x = x 35 | self.y = y 36 | self.z = z 37 | 38 | def __str__(self): 39 | return 'X -> %6.3f Y -> %6.3f Z -> %6.3f' % (self.x, self.y, self.z) 40 | 41 | def save_v1(self): 42 | return 'X -> %6.3f Y -> %6.3f Z -> %6.3f' % (self.x, self.y, self.z) 43 | 44 | def __eq__(self, other): 45 | return (-1e-12 < self.x - other.x < 1e-12) and\ 46 | (-1e-12 < self.y - other.y < 1e-12) and\ 47 | (-1e-12 < self.z - other.z < 1e-12) 48 | 49 | def __ne__(self, other): 50 | return not self == other 51 | 52 | def __neg__(self): 53 | return -1.0 * self 54 | 55 | def __add__(self, other): 56 | return Point3D(self.x + other.x, self.y + other.y, self.z + other.z) 57 | 58 | def __radd__(self, other): 59 | return Point3D(self.x + other, self.y + other, self.z + other) 60 | 61 | def __sub__(self, other): 62 | return self + -other 63 | 64 | def __mul__(self, other): 65 | # Calculate Scalar (dot) Product 66 | return self.x * other.x + self.y * other.y + self.z * other.z 67 | 68 | def __rmul__(self, other): 69 | return Point3D(self.x * other, self.y * other, self.z * other) 70 | 71 | def __truediv__(self, other): 72 | return Point3D(self.x / other, self.y / other, self.z / other) 73 | 74 | def cross_product(self, other): 75 | return Point3D(self.y * other.z - self.z * other.y, 76 | self.z * other.x - self.x * other.z, 77 | self.x * other.y - self.y * other.x) 78 | 79 | def unit_vector(self): 80 | return self / self.length() 81 | 82 | def length_squared(self): 83 | return self.x**2 + self.y**2 + self.z**2 84 | 85 | def length(self): 86 | return sqrt(self.length_squared()) 87 | -------------------------------------------------------------------------------- /source/dxf2gcode_images.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/custom.png 4 | images/blocks.png 5 | images/collapse-all.png 6 | images/delete.png 7 | images/dxf2gcode_logo.png 8 | images/DXF2GCODE-001.ico 9 | images/expand-all.png 10 | images/go-down.png 11 | images/go-up.png 12 | images/layer.png 13 | images/shape.png 14 | images/list-add.png 15 | images/list-remove.png 16 | 17 | 18 | -------------------------------------------------------------------------------- /source/dxfimport/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /source/dxfimport/classes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohl�ffel 7 | # Vinzenz Schulz 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | 27 | class PointsClass(object): 28 | # Initialisieren der Klasse 29 | # Initialise the class 30 | def __init__(self, point_nr=0, geo_nr=0, Layer_Nr=None, be=[], en=[], be_cp=[], en_cp=[]): 31 | self.point_nr = point_nr 32 | self.geo_nr = geo_nr 33 | self.Layer_Nr = Layer_Nr 34 | self.be = be 35 | self.en = en 36 | self.be_cp = be_cp 37 | self.en_cp = en_cp 38 | 39 | # Wie die Klasse ausgegeben wird. 40 | def __str__(self): 41 | # how to print the object 42 | return "\npoint_nr ->" + str(self.point_nr) + "\ngeo_nr ->" + str(self.geo_nr) +\ 43 | "\nLayer_Nr ->" + str(self.Layer_Nr) +\ 44 | "\nbe ->" + str(self.be) + "\nen ->" + str(self.en) +\ 45 | "\nbe_cp ->" + str(self.be_cp) + "\nen_cp ->" + str(self.en_cp) 46 | 47 | class ContourClass: 48 | # Initialisieren der Klasse 49 | # Initialise the class 50 | def __init__(self, cont_nr=0, closed=0, order=[], length=0): 51 | self.cont_nr = cont_nr 52 | self.closed = closed 53 | self.order = order 54 | self.length = length 55 | 56 | def reverse(self): 57 | """ 58 | reverse() - Reverse the contour 59 | """ 60 | self.order.reverse() 61 | for i in range(len(self.order)): 62 | if self.order[i][1] == 0: 63 | self.order[i][1] = 1 64 | else: 65 | self.order[i][1] = 0 66 | return 67 | 68 | def is_contour_closed(self): 69 | """ 70 | is_contour_closed() 71 | Return 1 if the contour is closed 72 | """ 73 | 74 | # Check as this is new... 75 | for j in range(len(self.order) - 1): 76 | if self.order[-1][0] == self.order[j][0]: 77 | if j == 0: 78 | self.closed = 1 79 | return self.closed 80 | else: 81 | self.closed = 2 82 | return self.closed 83 | return self.closed 84 | 85 | def remove_other_closed_contour(self): 86 | """ 87 | remove_other_closed_contour() 88 | """ 89 | for i in range(len(self.order)): 90 | for j in range(i + 1, len(self.order)): 91 | # print '\ni: '+str(i)+'j: '+str(j) 92 | if self.order[i][0] == self.order[j][0]: 93 | self.order = self.order[0:i] 94 | break 95 | return 96 | 97 | def calc_length(self, geos=None): 98 | """ 99 | Calculate the contour length 100 | """ 101 | # If the best is closed and first geo == last then remove 102 | if self.closed == 1 and len(self.order) > 1: 103 | if self.order[0] == self.order[-1]: 104 | del(self.order[-1]) 105 | 106 | self.length = 0 107 | for i in range(len(self.order)): 108 | self.length += geos[self.order[i][0]].length 109 | return 110 | 111 | # New starting point, set to the beginning 112 | def set_new_startpoint(self, st_p): 113 | self.order = self.order[st_p:len(self.order)] + self.order[0:st_p] 114 | 115 | # Wie die Klasse ausgegeben wird. 116 | def __str__(self): 117 | # how to print the object 118 | return '\ncont_nr ->' + str(self.cont_nr) + '\nclosed ->' + str(self.closed) \ 119 | + '\norder ->' + str(self.order) + '\nlength ->' + str(self.length) 120 | -------------------------------------------------------------------------------- /source/dxfimport/geoent_arc.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohlöffel 7 | # Vinzenz Schulz 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | from __future__ import absolute_import 27 | 28 | from math import sin, cos, radians, pi 29 | import logging 30 | 31 | from core.point import Point 32 | from dxfimport.classes import PointsClass 33 | from core.arcgeo import ArcGeo 34 | 35 | from globals.six import text_type 36 | import globals.constants as c 37 | if c.PYQT5notPYQT4: 38 | from PyQt5 import QtCore 39 | else: 40 | from PyQt4 import QtCore 41 | 42 | logger = logging.getLogger("DXFImport.GeoentArc") 43 | 44 | 45 | class GeoentArc(object): 46 | def __init__(self, Nr=0, caller=None): 47 | self.Typ = 'Arc' 48 | self.Nr = Nr 49 | self.Layer_Nr = 0 50 | self.length = 0 51 | self.geo = [] 52 | 53 | # Lesen der Geometrie 54 | # Read the geometry 55 | self.Read(caller) 56 | 57 | def __str__(self): 58 | # how to print the object 59 | return "\nTyp: Arc" + \ 60 | "\nNr: %i" % self.Nr + \ 61 | "\nLayer Nr:%i" % self.Layer_Nr + \ 62 | str(self.geo[-1]) 63 | 64 | def tr(self, string_to_translate): 65 | """ 66 | Translate a string using the QCoreApplication translation framework 67 | @param string_to_translate: a unicode string 68 | @return: the translated unicode string if it was possible to translate 69 | """ 70 | return text_type(QtCore.QCoreApplication.translate('GeoentArc', 71 | string_to_translate)) 72 | 73 | def App_Cont_or_Calc_IntPts(self, cont, points, i, tol, warning): 74 | """ 75 | App_Cont_or_Calc_IntPts() 76 | """ 77 | if abs(self.length) > tol: 78 | points.append(PointsClass(point_nr=len(points), 79 | geo_nr=i, 80 | Layer_Nr=self.Layer_Nr, 81 | be=self.geo[-1].Ps, 82 | en=self.geo[-1].Pe, 83 | be_cp=[], en_cp=[])) 84 | else: 85 | warning = 1 86 | return warning 87 | 88 | def Read(self, caller): 89 | """ 90 | Read() 91 | """ 92 | # Assign short name 93 | lp = caller.line_pairs 94 | e = lp.index_code(0, caller.start + 1) 95 | 96 | # Assign layer 97 | s = lp.index_code(8, caller.start + 1) 98 | self.Layer_Nr = caller.Get_Layer_Nr(lp.line_pair[s].value) 99 | 100 | # X Value 101 | s = lp.index_code(10, s + 1) 102 | x0 = float(lp.line_pair[s].value) 103 | 104 | # Y Value 105 | s = lp.index_code(20, s + 1) 106 | y0 = float(lp.line_pair[s].value) 107 | O = Point(x0, y0) 108 | 109 | # Radius 110 | s = lp.index_code(40, s + 1) 111 | r = float(lp.line_pair[s].value) 112 | 113 | # Start angle 114 | s = lp.index_code(50, s + 1) 115 | s_ang = radians(float(lp.line_pair[s].value)) 116 | 117 | # End angle 118 | s = lp.index_code(51, s + 1) 119 | e_ang = radians(float(lp.line_pair[s].value)) 120 | 121 | # Searching for an extrusion direction 122 | s_nxt_xt = lp.index_code(230, s + 1, e) 123 | # If there is a extrusion direction given flip around x-Axis 124 | if s_nxt_xt is not None: 125 | extrusion_dir = float(lp.line_pair[s_nxt_xt].value) 126 | logger.debug(self.tr('Found extrusion direction: %s') % extrusion_dir) 127 | if extrusion_dir == -1: 128 | x0 = -x0 129 | s_ang = s_ang + pi 130 | e_ang = e_ang + pi 131 | 132 | # Calculate the start and end points of the arcs 133 | Ps = Point(cos(s_ang) * r, sin(s_ang) * r) + O 134 | Pe = Point(cos(e_ang) * r, sin(e_ang) * r) + O 135 | 136 | # Anh�ngen der ArcGeo Klasse f�r die Geometrie 137 | # Annexes to ArcGeo class for geometry 138 | self.geo.append(ArcGeo(Ps=Ps, Pe=Pe, O=O, r=r, 139 | s_ang=s_ang, e_ang=e_ang, direction=1)) 140 | 141 | # L�nge entspricht der L�nge des Kreises 142 | # Length is the length (circumference?) of the circle 143 | self.length = self.geo[-1].length 144 | 145 | # logger.debug(self.geo[-1]) 146 | 147 | # Neuen Startwerd f�r die n�chste Geometrie zur�ckgeben 148 | # New starting value for the next geometry 149 | caller.start = s 150 | 151 | def get_start_end_points(self, direction): 152 | """ 153 | get_start_end_points() 154 | """ 155 | punkt, angle = self.geo[-1].get_start_end_points(direction) 156 | return punkt, angle 157 | -------------------------------------------------------------------------------- /source/dxfimport/geoent_circle.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohlöffel 7 | # Vinzenz Schulz 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | from __future__ import absolute_import 27 | from __future__ import division 28 | 29 | from math import sin, cos, pi 30 | import logging 31 | 32 | from core.point import Point 33 | from core.arcgeo import ArcGeo 34 | from dxfimport.classes import ContourClass 35 | 36 | from globals.six import text_type 37 | import globals.constants as c 38 | if c.PYQT5notPYQT4: 39 | from PyQt5 import QtCore 40 | else: 41 | from PyQt4 import QtCore 42 | 43 | logger = logging.getLogger("DXFImport.GeoentCircle") 44 | 45 | 46 | class GeoentCircle(object): 47 | def __init__(self, Nr=0, caller=None): 48 | self.Typ = 'Circle' 49 | self.Nr = Nr 50 | self.Layer_Nr = 0 51 | self.length = 0.0 52 | self.geo = [] 53 | 54 | # Lesen der Geometrie 55 | # Read the geometry 56 | self.Read(caller) 57 | 58 | def __str__(self): 59 | # how to print the object 60 | return "\nTyp: Circle " +\ 61 | "\nNr: %i" % self.Nr +\ 62 | "\nLayer Nr:%i" % self.Layer_Nr +\ 63 | str(self.geo[-1]) 64 | 65 | def tr(self, string_to_translate): 66 | """ 67 | Translate a string using the QCoreApplication translation framework 68 | @param string_to_translate: a unicode string 69 | @return: the translated unicode string if it was possible to translate 70 | """ 71 | return text_type(QtCore.QCoreApplication.translate('GeoentCircle', 72 | string_to_translate)) 73 | 74 | def App_Cont_or_Calc_IntPts(self, cont, points, i, tol, warning): 75 | cont.append(ContourClass(len(cont), 1, [[i, 0]], self.length)) 76 | return warning 77 | 78 | def Read(self, caller): 79 | """ 80 | Read() 81 | """ 82 | 83 | # Assign short name 84 | lp = caller.line_pairs 85 | e = lp.index_code(0, caller.start + 1) 86 | 87 | # Assign layer 88 | s = lp.index_code(8, caller.start + 1) 89 | self.Layer_Nr = caller.Get_Layer_Nr(lp.line_pair[s].value) 90 | 91 | # X Value 92 | s = lp.index_code(10, s + 1) 93 | x0 = float(lp.line_pair[s].value) 94 | 95 | # Y Value 96 | s = lp.index_code(20, s + 1) 97 | y0 = float(lp.line_pair[s].value) 98 | 99 | # Radius 100 | s = lp.index_code(40, s + 1) 101 | r = float(lp.line_pair[s].value) 102 | 103 | # Searching for an extrusion direction 104 | s_nxt_xt = lp.index_code(230, s + 1, e) 105 | # If there is a extrusion direction given flip around x-Axis 106 | if s_nxt_xt is not None: 107 | extrusion_dir = float(lp.line_pair[s_nxt_xt].value) 108 | logger.debug(self.tr('Found extrusion direction: %s') % extrusion_dir) 109 | if extrusion_dir == -1: 110 | x0 = -x0 111 | 112 | O = Point(x0, y0) 113 | 114 | # Calculate the start and end values of the circle without clipping 115 | s_ang = -3 * pi / 4 116 | m_ang = s_ang - pi 117 | e_ang = -3 * pi / 4 118 | 119 | # Calculate the start and end values of the arcs 120 | Ps = Point(cos(s_ang) * r, sin(s_ang) * r) + O 121 | Pm = Point(cos(m_ang) * r, sin(m_ang) * r) + O 122 | Pe = Point(cos(e_ang) * r, sin(e_ang) * r) + O 123 | 124 | # Annexes to ArcGeo class for geometry 125 | self.geo.append(ArcGeo(Ps=Ps, Pe=Pm, O=O, r=r, s_ang=s_ang, e_ang=m_ang, direction=-1)) 126 | self.geo.append(ArcGeo(Ps=Pm, Pe=Pe, O=O, r=r, s_ang=m_ang, e_ang=e_ang, direction=-1)) 127 | 128 | # Length corresponds to the length (circumference?) of the circle 129 | self.length = self.geo[-1].length+self.geo[-2].length 130 | 131 | # New starting value for the next geometry 132 | caller.start = s 133 | 134 | def get_start_end_points(self, direction=0): 135 | """ 136 | get_start_end_points() 137 | """ 138 | if not direction: 139 | punkt, angle = self.geo[0].get_start_end_points(direction) 140 | else: 141 | punkt, angle = self.geo[-1].get_start_end_points(direction) 142 | return punkt, angle 143 | -------------------------------------------------------------------------------- /source/dxfimport/geoent_insert.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohlöffel 7 | # Vinzenz Schulz 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | from __future__ import absolute_import 27 | 28 | from math import degrees, radians 29 | 30 | from core.point import Point 31 | from dxfimport.classes import ContourClass 32 | 33 | class GeoentInsert(object): 34 | def __init__(self, Nr=0, caller=None): 35 | self.Typ = 'Insert' 36 | self.Nr = Nr 37 | 38 | # Initialisieren der Werte 39 | # Initialise the values 40 | self.Layer_Nr = 0 41 | self.BlockName = '' 42 | self.Point = [] 43 | self.Scale = [1.0, 1.0, 1.0] 44 | self.rot = 0.0 45 | self.length = 0.0 46 | 47 | # Lesen der Geometrie 48 | # Red the geometry 49 | self.Read(caller) 50 | 51 | def __str__(self): 52 | # how to print the object 53 | return "\nTyp: Insert" +\ 54 | "\nNr: %i" % self.Nr +\ 55 | "\nLayer Nr: %i" % self.Layer_Nr +\ 56 | "\nBlockName: %s" % self.BlockName +\ 57 | "\nPoint: %s" % self.Point +\ 58 | "\nrot: %0.2f" % degrees(self.rot) +\ 59 | "\nScale: %s" % self.Scale 60 | 61 | def App_Cont_or_Calc_IntPts(self, cont, points, i, tol, warning): 62 | """ 63 | App_Cont_or_Calc_IntPts() 64 | """ 65 | cont.append(ContourClass(len(cont), 0, [[i, 0]], 0)) 66 | return warning 67 | 68 | def Read(self, caller): 69 | """ 70 | Read() 71 | """ 72 | # Assign short name 73 | lp = caller.line_pairs 74 | e = lp.index_code(0, caller.start + 1) 75 | 76 | # Block Name 77 | ind = lp.index_code(2, caller.start + 1, e) 78 | # print lp.line_pair[ind].value ######################################## 79 | self.BlockName = lp.line_pair[ind].value 80 | 81 | # Assign layer 82 | s = lp.index_code(8, caller.start + 1, e) 83 | self.Layer_Nr = caller.Get_Layer_Nr(lp.line_pair[s].value) 84 | 85 | # X Value 86 | s = lp.index_code(10, s + 1, e) 87 | x0 = float(lp.line_pair[s].value) 88 | 89 | # Y Value 90 | s = lp.index_code(20, s + 1, e) 91 | y0 = float(lp.line_pair[s].value) 92 | self.Point = Point(x0, y0) 93 | 94 | # XScale 95 | s_temp = lp.index_code(41, s + 1, e) 96 | if s_temp is not None: 97 | self.Scale[0] = float(lp.line_pair[s_temp].value) 98 | 99 | # YScale 100 | s_temp = lp.index_code(42, s + 1, e) 101 | if s_temp is not None: 102 | self.Scale[1] = float(lp.line_pair[s_temp].value) 103 | 104 | # ZScale 105 | s_temp = lp.index_code(43, s + 1, e) 106 | if s_temp is not None: 107 | self.Scale[2] = float(lp.line_pair[s_temp].value) 108 | 109 | # Rotation 110 | s_temp = lp.index_code(50, s + 1, e) 111 | if s_temp is not None: 112 | self.rot = radians(float(lp.line_pair[s_temp].value)) 113 | 114 | # New starting value for the next geometry 115 | caller.start = e 116 | 117 | -------------------------------------------------------------------------------- /source/dxfimport/geoent_line.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohlöffel 7 | # Vinzenz Schulz 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | from __future__ import absolute_import 27 | 28 | import logging 29 | 30 | from core.point import Point 31 | from core.linegeo import LineGeo 32 | from dxfimport.classes import PointsClass 33 | 34 | from globals.six import text_type 35 | import globals.constants as c 36 | if c.PYQT5notPYQT4: 37 | from PyQt5 import QtCore 38 | else: 39 | from PyQt4 import QtCore 40 | 41 | logger = logging.getLogger("DXFImport.GeoentLine") 42 | 43 | 44 | class GeoentLine(object): 45 | def __init__(self, Nr=0, caller=None): 46 | self.Typ = 'Line' 47 | self.Nr = Nr 48 | self.Layer_Nr = 0 49 | self.geo = [] 50 | self.length = 0 51 | 52 | # Lesen der Geometrie 53 | # Read the geometry 54 | self.Read(caller) 55 | 56 | def __str__(self): 57 | # how to print the object 58 | return "\nTyp: Line" +\ 59 | "\nNr: %i" % self.Nr +\ 60 | "\nLayer Nr: %i" % self.Layer_Nr +\ 61 | str(self.geo[-1]) 62 | 63 | def tr(self, string_to_translate): 64 | """ 65 | Translate a string using the QCoreApplication translation framework 66 | @param: string_to_translate: a unicode string 67 | @return: the translated unicode string if it was possible to translate 68 | """ 69 | return text_type(QtCore.QCoreApplication.translate("GeoentLine", 70 | string_to_translate)) 71 | 72 | def App_Cont_or_Calc_IntPts(self, cont, points, i, tol, warning): 73 | """ 74 | App_Cont_or_Calc_IntPts() 75 | """ 76 | if abs(self.length) > tol: 77 | points.append(PointsClass(point_nr=len(points), geo_nr=i, 78 | Layer_Nr=self.Layer_Nr, 79 | be=self.geo[-1].Ps, 80 | en=self.geo[-1].Pe, be_cp=[], en_cp=[])) 81 | else: 82 | # showwarning("Short Arc Elemente", ("Length of Line geometry too short!"\ 83 | # "\nLength must be greater than tolerance."\ 84 | # "\nSkipping Line Geometry")) 85 | warning = 1 86 | return warning 87 | 88 | def Read(self, caller): 89 | """ 90 | This function does read the geometry. 91 | @param caller: The instance which is calling the function 92 | """ 93 | # Assign short name 94 | lp = caller.line_pairs 95 | e = lp.index_code(0, caller.start + 1) 96 | 97 | # Assign layer 98 | s = lp.index_code(8, caller.start + 1) 99 | self.Layer_Nr = caller.Get_Layer_Nr(lp.line_pair[s].value) 100 | 101 | # X Value 102 | sl = lp.index_code(10, s + 1) 103 | x0 = float(lp.line_pair[sl].value) 104 | 105 | # Y Value 106 | s = lp.index_code(20, sl + 1) 107 | y0 = float(lp.line_pair[s].value) 108 | 109 | # X Value 2 110 | s = lp.index_code(11, sl + 1) 111 | x1 = float(lp.line_pair[s].value) 112 | 113 | # Y Value 2 114 | s = lp.index_code(21, s + 1) 115 | y1 = float(lp.line_pair[s].value) 116 | 117 | # Searching for an extrusion direction 118 | s_nxt_xt = lp.index_code(230, s + 1, e) 119 | # If there is a extrusion direction given flip around x-Axis 120 | if s_nxt_xt is not None: 121 | extrusion_dir = float(lp.line_pair[s_nxt_xt].value) 122 | logger.debug(self.tr('Found extrusion direction: %s') % extrusion_dir) 123 | if extrusion_dir == -1: 124 | x0 = -x0 125 | x1 = -x1 126 | 127 | Ps = Point(x0, y0) 128 | Pe = Point(x1, y1) 129 | 130 | # Anhängen der LineGeo Klasse für die Geometrie 131 | # Annexes to LineGeo class for geometry ??? 132 | self.geo.append(LineGeo(Ps=Ps, Pe=Pe)) 133 | 134 | # Länge entspricht der Länge des Kreises 135 | # Length corresponding to the length (circumference?) of the circle 136 | self.length = self.geo[-1].length 137 | 138 | # Neuen Startwert für die nächste Geometrie zurückgeben 139 | # New starting value for the next geometry 140 | caller.start = s 141 | 142 | def get_start_end_points(self, direction): 143 | """ 144 | get_start_end_points() 145 | """ 146 | punkt, angle = self.geo[-1].get_start_end_points(direction) 147 | return punkt, angle 148 | -------------------------------------------------------------------------------- /source/dxfimport/geoent_point.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2014-2015 6 | # Robert Lichtenberger 7 | # 8 | # This file is part of DXF2GCODE. 9 | # 10 | # DXF2GCODE is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # DXF2GCODE is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with DXF2GCODE. If not, see . 22 | # 23 | ############################################################################ 24 | 25 | from __future__ import absolute_import 26 | 27 | from core.holegeo import HoleGeo 28 | from core.point import Point 29 | from dxfimport.classes import ContourClass 30 | 31 | 32 | class GeoentPoint: 33 | def __init__(self, Nr=0, caller=None): 34 | self.Typ = 'Point' 35 | self.Nr = Nr 36 | self.Layer_Nr = 0 37 | self.geo = [] 38 | self.length = 0 39 | 40 | # Lesen der Geometrie 41 | # Read the geometry 42 | self.Read(caller) 43 | 44 | def __str__(self): 45 | # how to print the object 46 | return "\nTyp: Point" +\ 47 | "\nNr: %i" % self.Nr +\ 48 | "\nLayer Nr: %i" % self.Layer_Nr +\ 49 | str(self.geo[-1]) 50 | 51 | def App_Cont_or_Calc_IntPts(self, cont, points, i, tol, warning): 52 | """ 53 | App_Cont_or_Calc_IntPts() 54 | """ 55 | cont.append(ContourClass(len(cont), 0, [[i, 0]], 0)) 56 | return warning 57 | 58 | def Read(self, caller): 59 | """ 60 | Read() 61 | """ 62 | # Assign short name 63 | lp = caller.line_pairs 64 | e = lp.index_code(0, caller.start + 1) 65 | 66 | # Assign layer 67 | s = lp.index_code(8, caller.start + 1) 68 | self.Layer_Nr = caller.Get_Layer_Nr(lp.line_pair[s].value) 69 | 70 | # X Value 71 | s = lp.index_code(10, s + 1) 72 | x0 = float(lp.line_pair[s].value) 73 | 74 | # Y Value 75 | s = lp.index_code(20, s + 1) 76 | y0 = float(lp.line_pair[s].value) 77 | 78 | Ps = Point(x0, y0) 79 | 80 | self.geo.append(HoleGeo(Ps)) 81 | # self.geo.append(LineGeo(Ps=Point(0,0), Pe=P)) 82 | 83 | # Neuen Startwert für die nächste Geometrie zurückgeben 84 | # New starting value for the next geometry 85 | caller.start = s 86 | 87 | -------------------------------------------------------------------------------- /source/globals/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /source/globals/configobj/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.1 2 | Name: configobj 3 | Version: 5.0.6 4 | Summary: Config file reading, writing and validation. 5 | Home-page: https://github.com/DiffSK/configobj 6 | Author: Rob Dennis, Eli Courtwright (Michael Foord & Nicola Larosa original maintainers) 7 | Author-email: rdennis+configobj@gmail.com, eli@courtwright.org, fuzzyman@voidspace.co.uk, nico@tekNico.net 8 | License: UNKNOWN 9 | Description: **ConfigObj** is a simple but powerful config file reader and writer: an *ini 10 | file round tripper*. Its main feature is that it is very easy to use, with a 11 | straightforward programmer's interface and a simple syntax for config files. 12 | It has lots of other features though : 13 | 14 | * Nested sections (subsections), to any level 15 | * List values 16 | * Multiple line values 17 | * Full Unicode support 18 | * String interpolation (substitution) 19 | * Integrated with a powerful validation system 20 | 21 | - including automatic type checking/conversion 22 | - and allowing default values 23 | - repeated sections 24 | 25 | * All comments in the file are preserved 26 | * The order of keys/sections is preserved 27 | * Powerful ``unrepr`` mode for storing/retrieving Python data-types 28 | 29 | | Release 5.0.6 improves error messages in certain edge cases 30 | | Release 5.0.5 corrects a unicode-bug that still existed in writing files 31 | | Release 5.0.4 corrects a unicode-bug that still existed in reading files after 32 | | fixing lists of string in 5.0.3 33 | | Release 5.0.3 corrects errors related to the incorrectly handling unicode 34 | | encoding and writing out files 35 | | Release 5.0.2 adds a specific error message when trying to install on 36 | | Python versions older than 2.5 37 | | Release 5.0.1 fixes a regression with unicode conversion not happening 38 | | in certain cases PY2 39 | | Release 5.0.0 updates the supported Python versions to 2.6, 2.7, 3.2, 3.3 40 | | and is otherwise unchanged 41 | | Release 4.7.2 fixes several bugs in 4.7.1 42 | | Release 4.7.1 fixes a bug with the deprecated options keyword in 43 | | 4.7.0. 44 | | Release 4.7.0 improves performance adds features for validation and 45 | | fixes some bugs. 46 | Keywords: config,ini,dictionary,application,admin,sysadmin,configuration,validation 47 | Platform: UNKNOWN 48 | Classifier: Development Status :: 6 - Mature 49 | Classifier: Intended Audience :: Developers 50 | Classifier: License :: OSI Approved :: BSD License 51 | Classifier: Programming Language :: Python 52 | Classifier: Programming Language :: Python :: 2 53 | Classifier: Programming Language :: Python :: 2.6 54 | Classifier: Programming Language :: Python :: 2.7 55 | Classifier: Programming Language :: Python :: 3 56 | Classifier: Programming Language :: Python :: 3.2 57 | Classifier: Programming Language :: Python :: 3.3 58 | Classifier: Operating System :: OS Independent 59 | Classifier: Topic :: Software Development :: Libraries 60 | Classifier: Topic :: Software Development :: Libraries :: Python Modules 61 | -------------------------------------------------------------------------------- /source/globals/configobj/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /source/globals/configobj/_version.py: -------------------------------------------------------------------------------- 1 | __version__ = '5.0.6' -------------------------------------------------------------------------------- /source/globals/configobj/setup.py: -------------------------------------------------------------------------------- 1 | # setup.py 2 | # Install script for ConfigObj 3 | # Copyright (C) 2005-2014: 4 | # (name) : (email) 5 | # Michael Foord: fuzzyman AT voidspace DOT org DOT uk 6 | # Mark Andrews: mark AT la-la DOT com 7 | # Nicola Larosa: nico AT tekNico DOT net 8 | # Rob Dennis: rdennis AT gmail DOT com 9 | # Eli Courtwright: eli AT courtwright DOT org 10 | 11 | # This software is licensed under the terms of the BSD license. 12 | # http://opensource.org/licenses/BSD-3-Clause 13 | import os 14 | import sys 15 | from distutils.core import setup 16 | # a simple import wouldn't work if we moved towards a package with __init__ 17 | from _version import __version__ 18 | 19 | if sys.version_info < (2, 6): 20 | print('for python versions < 2.6 use configobj ' 21 | 'version 4.7.2') 22 | sys.exit(1) 23 | 24 | __here__ = os.path.abspath(os.path.dirname(__file__)) 25 | 26 | VERSION = __version__ 27 | NAME = 'configobj' 28 | MODULES = 'configobj', 'validate', '_version' 29 | 30 | DESCRIPTION = 'Config file reading, writing and validation.' 31 | 32 | URL = 'https://github.com/DiffSK/configobj' 33 | 34 | LONG_DESCRIPTION = """**ConfigObj** is a simple but powerful config file reader and writer: an *ini 35 | file round tripper*. Its main feature is that it is very easy to use, with a 36 | straightforward programmer's interface and a simple syntax for config files. 37 | It has lots of other features though : 38 | 39 | * Nested sections (subsections), to any level 40 | * List values 41 | * Multiple line values 42 | * Full Unicode support 43 | * String interpolation (substitution) 44 | * Integrated with a powerful validation system 45 | 46 | - including automatic type checking/conversion 47 | - and allowing default values 48 | - repeated sections 49 | 50 | * All comments in the file are preserved 51 | * The order of keys/sections is preserved 52 | * Powerful ``unrepr`` mode for storing/retrieving Python data-types 53 | 54 | | Release 5.0.6 improves error messages in certain edge cases 55 | | Release 5.0.5 corrects a unicode-bug that still existed in writing files 56 | | Release 5.0.4 corrects a unicode-bug that still existed in reading files after 57 | | fixing lists of string in 5.0.3 58 | | Release 5.0.3 corrects errors related to the incorrectly handling unicode 59 | | encoding and writing out files 60 | | Release 5.0.2 adds a specific error message when trying to install on 61 | | Python versions older than 2.5 62 | | Release 5.0.1 fixes a regression with unicode conversion not happening 63 | | in certain cases PY2 64 | | Release 5.0.0 updates the supported Python versions to 2.6, 2.7, 3.2, 3.3 65 | | and is otherwise unchanged 66 | | Release 4.7.2 fixes several bugs in 4.7.1 67 | | Release 4.7.1 fixes a bug with the deprecated options keyword in 68 | | 4.7.0. 69 | | Release 4.7.0 improves performance adds features for validation and 70 | | fixes some bugs.""" 71 | 72 | CLASSIFIERS = [ 73 | 'Development Status :: 6 - Mature', 74 | 'Intended Audience :: Developers', 75 | 'License :: OSI Approved :: BSD License', 76 | 'Programming Language :: Python', 77 | 'Programming Language :: Python :: 2', 78 | 'Programming Language :: Python :: 2.6', 79 | 'Programming Language :: Python :: 2.7', 80 | 'Programming Language :: Python :: 3', 81 | 'Programming Language :: Python :: 3.2', 82 | 'Programming Language :: Python :: 3.3', 83 | 'Operating System :: OS Independent', 84 | 'Topic :: Software Development :: Libraries', 85 | 'Topic :: Software Development :: Libraries :: Python Modules', 86 | ] 87 | 88 | AUTHOR = 'Rob Dennis, Eli Courtwright (Michael Foord & Nicola Larosa original maintainers)' 89 | 90 | AUTHOR_EMAIL = 'rdennis+configobj@gmail.com, eli@courtwright.org, fuzzyman@voidspace.co.uk, nico@tekNico.net' 91 | 92 | KEYWORDS = "config, ini, dictionary, application, admin, sysadmin, configuration, validation".split(', ') 93 | 94 | 95 | setup(name=NAME, 96 | version=VERSION, 97 | install_requires=['six'], 98 | description=DESCRIPTION, 99 | long_description=LONG_DESCRIPTION, 100 | author=AUTHOR, 101 | author_email=AUTHOR_EMAIL, 102 | url=URL, 103 | py_modules=MODULES, 104 | classifiers=CLASSIFIERS, 105 | keywords=KEYWORDS 106 | ) 107 | -------------------------------------------------------------------------------- /source/globals/constants.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2010-2015 6 | # Christian Kohlöffel 7 | # Jean-Paul Schouwstra 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | """ 27 | All global constants are initialized in this module. 28 | They are used in the other modules. 29 | 30 | see http://code.activestate.com/recipes/65207/ for module const 31 | 32 | @purpose: initialization of the global constants used within the other modules. 33 | """ 34 | 35 | import logging 36 | 37 | ''' 38 | By default we (should) want to run the PyQt5 version 39 | ''' 40 | PYQT5notPYQT4 = True 41 | try: 42 | import PyQt5 43 | except ImportError: 44 | PYQT5notPYQT4 = False 45 | 46 | # Global Variables 47 | APPNAME = "DXF2GCODE" 48 | VERSION = "PyQt%i Beta" % (5 if PYQT5notPYQT4 else 4) 49 | 50 | DATE = "$Date$" 51 | REVISION = "$Revision$" 52 | AUTHOR = u"$Author$" 53 | 54 | CONFIG_EXTENSION = '.cfg' 55 | PY_EXTENSION = '.py' 56 | PROJECT_EXTENSION = '.d2g' 57 | 58 | # Rename unreadable config/varspace files to .bad 59 | BAD_CONFIG_EXTENSION = '.bad' 60 | DEFAULT_CONFIG_DIR = 'config' 61 | DEFAULT_POSTPRO_DIR = 'postpro_config' 62 | 63 | # log related 64 | DEFAULT_LOGFILE = 'dxf2gcode.log' 65 | STARTUP_LOGLEVEL = logging.DEBUG 66 | # PRT = logging.INFO 67 | -------------------------------------------------------------------------------- /source/globals/d2gexceptions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2009-2015 6 | # Michael Haberler 7 | # 8 | # This file is part of DXF2GCODE. 9 | # 10 | # DXF2GCODE is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # DXF2GCODE is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with DXF2GCODE. If not, see . 22 | # 23 | ############################################################################ 24 | 25 | """ 26 | user defined exceptions 27 | """ 28 | 29 | 30 | class BadConfigFileError(SyntaxError): 31 | """ 32 | syntax error in config file 33 | """ 34 | def __init__(self, value): 35 | print("bin hier") 36 | self.value = value 37 | 38 | def __str__(self): 39 | return repr(self.value) 40 | 41 | 42 | class VersionMismatchError(Exception): 43 | """ 44 | version mismatch in config file 45 | """ 46 | def __init__(self, fileversion, CONFIG_VERSION): 47 | self.fileversion = fileversion 48 | self.CONFIG_VERSION = CONFIG_VERSION 49 | 50 | def __str__(self): 51 | return repr('config file versions do not match - internal: %s,' 52 | ' config file: %s - delete existing file to resolve issue' 53 | % (self.CONFIG_VERSION, self.fileversion)) 54 | 55 | 56 | class OptionError(SyntaxError): 57 | """ 58 | conflicting command line option 59 | """ 60 | 61 | 62 | class PluginError(SyntaxError): 63 | """ 64 | something went wrong during plugin loading or initialization 65 | """ 66 | -------------------------------------------------------------------------------- /source/globals/globals.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2009-2015 6 | # Michael Haberler 7 | # 8 | # This file is part of DXF2GCODE. 9 | # 10 | # DXF2GCODE is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # DXF2GCODE is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with DXF2GCODE. If not, see . 22 | # 23 | ############################################################################ 24 | 25 | """ 26 | Container for global variables accessible to all classes 27 | """ 28 | 29 | from __future__ import absolute_import 30 | 31 | import os 32 | import sys 33 | import gettext 34 | import locale 35 | 36 | import globals.constants as constants 37 | 38 | 39 | # logger instance, see http://docs.python.org/library/logging.html 40 | # once set, use as logger.error("foo") 41 | logger = None 42 | 43 | # Config instance 44 | config = None 45 | 46 | # Folder of the main instance 47 | folder = None 48 | 49 | window = None 50 | 51 | 52 | #------------------------------------- 53 | 54 | # determine Platform 55 | platform = "" 56 | if os.name == "posix" and sys.platform == "darwin": 57 | platform = "mac" 58 | 59 | 60 | # Language support 61 | # 62 | langs = [] # list of supported languages 63 | 64 | # figure default language 65 | lc, encoding = locale.getdefaultlocale() 66 | 67 | if lc: 68 | langs = [lc] # if there's one, use as default 69 | 70 | language = os.environ.get('LANGUAGE', None) 71 | if language: 72 | """language comes back something like en_CA:en_US:en_GB:en 73 | on linuxy systems, on Win32 it's nothing, so we need to 74 | split it up into a list""" 75 | langs += language.split(":") 76 | 77 | """Now add on to the back of the list the translations that we 78 | know that we have, our defaults""" 79 | langs += [] 80 | 81 | """Now langs is a list of all of the languages that we are going 82 | to try to use. First we check the default, then what the system 83 | told us, and finally the 'known' list""" 84 | 85 | gettext.bindtextdomain(constants.APPNAME, 86 | os.path.realpath(os.path.dirname(sys.argv[0]))) 87 | gettext.textdomain(constants.APPNAME) 88 | # Get the language to use 89 | trans = gettext.translation(constants.APPNAME, localedir='languages', 90 | languages=langs, fallback=True) 91 | trans.install() 92 | -------------------------------------------------------------------------------- /source/globals/logger.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2009-2015 6 | # Michael Haberler 7 | # 8 | # This file is part of DXF2GCODE. 9 | # 10 | # DXF2GCODE is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # DXF2GCODE is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with DXF2GCODE. If not, see . 22 | # 23 | ############################################################################ 24 | 25 | from __future__ import absolute_import 26 | 27 | import sys 28 | import logging 29 | 30 | from globals.six import string_types 31 | import globals.globals as g 32 | 33 | 34 | logger = logging.getLogger(__name__) 35 | 36 | 37 | class LoggerClass(object): 38 | """ 39 | handle 3 log streams: 40 | console 41 | file 42 | message window 43 | """ 44 | def __init__(self, root_logger): 45 | """ 46 | Initialisation of the Logger Class. Only the root logger is initialized 47 | and the console handler is set. All other handlers needs to be set later 48 | since the config / window is not present during the start. 49 | """ 50 | 51 | self.root_logger = root_logger 52 | 53 | """ 54 | The level of the root_logger needs to be the highest in order to get 55 | all messages into the handlers. The handles may have higher logging level 56 | """ 57 | root_logger.setLevel(logging.DEBUG) 58 | 59 | self.console_handler = logging.StreamHandler(sys.stderr) 60 | self.console_handler.setLevel(logging.ERROR) 61 | 62 | formatter = logging.Formatter("%(levelname)-10s %(name)-15s %(funcName)-10s %(lineno)-4d: - %(message)s") 63 | self.console_handler.setFormatter(formatter) 64 | root_logger.addHandler(self.console_handler) 65 | 66 | def set_console_handler_loglevel(self): 67 | """ 68 | This function is used to reset the Loglevel after the config file hase 69 | been loaded. 70 | """ 71 | self.console_handler.setLevel(self._cvtlevel(g.config.vars.Logging['console_loglevel'])) 72 | 73 | def add_window_logger(self, stream=sys.stderr): 74 | """ 75 | Add the logger, which may be used to log to the window. This stream will 76 | be shown in the messagebox in the canvas window. 77 | @param stream: The stream which shall be used for writing. Here the 78 | window will be used. This Class needs a function "def write(self, charstr) 79 | {DEBUG, INFO, WARNING, ERROR, CRITICAL} 80 | """ 81 | self.window_handler = logging.StreamHandler(stream) 82 | self.window_handler.setLevel(self._cvtlevel(g.config.vars.Logging['window_loglevel'])) 83 | 84 | if g.config.vars.Logging['window_loglevel'] == 'INFO': 85 | self.window_handler.setFormatter(logging.Formatter("%(message)s")) 86 | else: 87 | formatter=logging.Formatter("%(levelname)s - %(message)s") 88 | self.window_handler.setFormatter(formatter) 89 | 90 | self.root_logger.addHandler(self.window_handler) 91 | 92 | def add_file_logger(self): 93 | """ 94 | Add the logger, which may be used to log to a dedicated file. This logger 95 | will be enabled all the time. 96 | """ 97 | self.file_handler = logging.FileHandler(g.config.vars.Logging['logfile'], 'w') #create 98 | self.file_handler.setLevel(self._cvtlevel(g.config.vars.Logging['file_loglevel'])) 99 | self.file_handler.setFormatter(logging.Formatter("%(levelname)-10s %(name)-15s %(funcName)-10s %(lineno)-4d: - %(message)s")) 100 | self.root_logger.addHandler(self.file_handler) 101 | 102 | def _cvtlevel(self, level): 103 | """ 104 | This function converts the given logging levels as they are: 105 | {DEBUG, INFO, WARNING, ERROR, CRITICAL} to a conform format which is 106 | required by the function e.g. logging.DEBUG 107 | @param level: The String with the Level 108 | @return: Returns the converted string acc. to logging needs. 109 | """ 110 | if isinstance(level, string_types): 111 | return logging.getLevelName(level) 112 | else: 113 | return level 114 | 115 | 116 | class FilterModule(logging.Filter): 117 | def filter(self, record): 118 | """A dedicated filter may be added here for debug use 119 | @param record: The log message is posted here in order to do some checks 120 | @return: If the value is true it will be shown in the log 121 | """ 122 | return True 123 | -------------------------------------------------------------------------------- /source/gui/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /source/gui/aboutdialog.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2010-2014 6 | # Christian Kohl�ffel 7 | # Jean-Paul Schouwstra 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | import globals.constants as c 27 | if c.PYQT5notPYQT4: 28 | from PyQt5.QtWidgets import QDialog, QVBoxLayout, QGridLayout, QTextBrowser 29 | from PyQt5.QtGui import QIcon, QPixmap, QTextCursor 30 | from PyQt5 import QtCore 31 | else: 32 | from PyQt4.QtGui import QDialog, QVBoxLayout, QGridLayout, QIcon, QPixmap, QTextBrowser, QTextCursor 33 | from PyQt4 import QtCore 34 | 35 | import logging 36 | 37 | logger = logging.getLogger("Gui.AboutDialog") 38 | 39 | 40 | class AboutDialog(QDialog): 41 | def __init__(self, title="Test", message="Test Text"): 42 | super(AboutDialog, self).__init__() 43 | 44 | self.title = title 45 | self.message = message 46 | 47 | self.initUI() 48 | 49 | def initUI(self): 50 | """ 51 | initUI() 52 | """ 53 | 54 | vbox = QVBoxLayout(self) 55 | grid1 = QGridLayout() 56 | grid1.setSpacing(10) 57 | 58 | self.text = QTextBrowser() 59 | self.text.setReadOnly(True) 60 | self.text.setOpenExternalLinks(True) 61 | self.text.append(self.message) 62 | self.text.moveCursor(QTextCursor.Start) 63 | self.text.ensureCursorVisible() 64 | 65 | vbox.addWidget(self.text) 66 | 67 | self.setLayout(vbox) 68 | self.setMinimumSize(550, 450) 69 | self.resize(550, 600) 70 | self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint) 71 | self.setWindowTitle(self.title) 72 | iconWT = QIcon() 73 | iconWT.addPixmap(QPixmap(":images/DXF2GCODE-001.ico"), 74 | QIcon.Normal, QIcon.Off) 75 | self.setWindowIcon(QIcon(iconWT)) 76 | 77 | self.exec_() 78 | -------------------------------------------------------------------------------- /source/gui/arrow.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohlöffel 7 | # Vinzenz Schulz 8 | # Jean-Paul Schouwstra 9 | # 10 | # This file is part of DXF2GCODE. 11 | # 12 | # DXF2GCODE is free software: you can redistribute it and/or modify 13 | # it under the terms of the GNU General Public License as published by 14 | # the Free Software Foundation, either version 3 of the License, or 15 | # (at your option) any later version. 16 | # 17 | # DXF2GCODE is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | # GNU General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU General Public License 23 | # along with DXF2GCODE. If not, see . 24 | # 25 | ############################################################################ 26 | 27 | from __future__ import absolute_import 28 | from __future__ import division 29 | 30 | from math import sin, cos, acos, pi 31 | import logging 32 | 33 | from core.point import Point 34 | 35 | import globals.constants as c 36 | if c.PYQT5notPYQT4: 37 | from PyQt5.QtWidgets import QGraphicsLineItem, QGraphicsItem 38 | from PyQt5.QtGui import QPen, QPolygonF 39 | from PyQt5 import QtCore 40 | else: 41 | from PyQt4.QtGui import QGraphicsLineItem, QGraphicsItem, QPen, QPolygonF 42 | from PyQt4 import QtCore 43 | 44 | logger = logging.getLogger("Gui.Arrow") 45 | 46 | 47 | class Arrow(QGraphicsLineItem): 48 | def __init__(self, startp=Point(), endp=None, 49 | length=60.0, angle=50.0, 50 | color=QtCore.Qt.red, pencolor=QtCore.Qt.green, 51 | startarrow=True): 52 | """ 53 | Initialisation of the class. 54 | """ 55 | self.sc = None 56 | super(Arrow, self).__init__() 57 | 58 | self.startp = QtCore.QPointF(startp.x, -startp.y) 59 | self.endp = endp 60 | 61 | self.length = length 62 | self.angle = angle 63 | self.startarrow = startarrow 64 | self.allwaysshow = False 65 | 66 | self.arrowHead = QPolygonF() 67 | self.setFlag(QGraphicsItem.ItemIsSelectable, False) 68 | self.myColor = color 69 | self.pen = QPen(pencolor, 1, QtCore.Qt.SolidLine) 70 | self.pen.setCosmetic(True) 71 | self.arrowSize = 8.0 72 | 73 | def contains_point(self, point): 74 | """ 75 | Arrows cannot be selected. Return maximal distance 76 | """ 77 | return float(0x7fffffff) 78 | 79 | def setSelected(self, flag=True, blockSignals=True): 80 | """ 81 | Override inherited function to turn off selection of Arrows. 82 | @param flag: The flag to enable or disable Selection 83 | """ 84 | if self.allwaysshow: 85 | pass 86 | elif flag is True: 87 | self.show() 88 | else: 89 | self.hide() 90 | 91 | def setallwaysshow(self, flag=False): 92 | """ 93 | If the directions shall be allwaysshown the parameter 94 | will be set and all paths will be shown. 95 | @param flag: The flag to enable or disable Selection 96 | """ 97 | self.allwaysshow = flag 98 | if flag is True: 99 | self.show() 100 | elif flag is True and self.isSelected(): 101 | self.show() 102 | else: 103 | self.hide() 104 | 105 | def paint(self, painter, option, widget=None): 106 | """ 107 | Method for painting the arrow. 108 | """ 109 | 110 | demat = painter.deviceTransform() 111 | self.sc = demat.m11() 112 | 113 | if self.endp is None: 114 | dx = cos(self.angle) * self.length / self.sc 115 | dy = sin(self.angle) * self.length / self.sc 116 | 117 | endp = QtCore.QPointF(self.startp.x() - dx, self.startp.y() + dy) 118 | else: 119 | endp = QtCore.QPointF(self.endp.x, -self.endp.y) 120 | 121 | arrowSize = self.arrowSize / self.sc 122 | 123 | painter.setPen(self.pen) 124 | painter.setBrush(self.myColor) 125 | 126 | self.setLine(QtCore.QLineF(endp, self.startp)) 127 | line = self.line() 128 | 129 | if line.length() != 0: 130 | angle = acos(line.dx() / line.length()) 131 | 132 | if line.dy() >= 0: 133 | angle = (pi * 2.0) - angle 134 | 135 | if self.startarrow: 136 | arrowP1 = line.p2() - QtCore.QPointF(sin(angle + pi / 3.0) * arrowSize, 137 | cos(angle + pi / 3.0) * arrowSize) 138 | arrowP2 = line.p2() - QtCore.QPointF(sin(angle + pi - pi / 3.0) * arrowSize, 139 | cos(angle + pi - pi / 3.0) * arrowSize) 140 | self.arrowHead.clear() 141 | for Point in [line.p2(), arrowP1, arrowP2]: 142 | self.arrowHead.append(Point) 143 | 144 | else: 145 | arrowP1 = line.p1() + QtCore.QPointF(sin(angle + pi / 3.0) * arrowSize, 146 | cos(angle + pi / 3.0) * arrowSize) 147 | arrowP2 = line.p1() + QtCore.QPointF(sin(angle + pi - pi / 3.0) * arrowSize, 148 | cos(angle + pi - pi / 3.0) * arrowSize) 149 | self.arrowHead.clear() 150 | for Point in [line.p1(), arrowP1, arrowP2]: 151 | self.arrowHead.append(Point) 152 | 153 | painter.drawLine(line) 154 | painter.drawPolygon(self.arrowHead) 155 | 156 | def boundingRect(self): 157 | """ 158 | Override inherited function to enlarge selection of Arrow to include all 159 | @param flag: The flag to enable or disable Selection 160 | """ 161 | if not self.sc: # since this function is called before paint; and scale is unknown 162 | return QtCore.QRectF(self.startp.x(), self.startp.y(), 1e-9, 1e-9) 163 | 164 | arrowSize = self.arrowSize / self.sc 165 | extra = arrowSize # self.pen.width() + 166 | 167 | if self.endp is None: 168 | dx = cos(self.angle) * self.length / self.sc 169 | dy = sin(self.angle) * self.length / self.sc 170 | 171 | endp = QtCore.QPointF(self.startp.x() - dx, self.startp.y() + dy) 172 | else: 173 | endp = QtCore.QPointF(self.endp.x, -self.endp.y) 174 | 175 | brect = QtCore.QRectF(self.startp, 176 | QtCore.QSizeF(endp.x()-self.startp.x(), 177 | endp.y()-self.startp.y())).normalized().adjusted(-extra, -extra, extra, extra) 178 | return brect 179 | -------------------------------------------------------------------------------- /source/gui/messagebox.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2011-2014 6 | # Christian Kohlöffel 7 | # 8 | # This file is part of DXF2GCODE. 9 | # 10 | # DXF2GCODE is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # DXF2GCODE is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with DXF2GCODE. If not, see . 22 | # 23 | ############################################################################ 24 | 25 | """ 26 | Special purpose canvas including all required plotting function etc. 27 | """ 28 | 29 | from globals.six import text_type 30 | import globals.constants as c 31 | if c.PYQT5notPYQT4: 32 | from PyQt5.QtWidgets import QTextBrowser 33 | from PyQt5 import QtCore 34 | else: 35 | from PyQt4.QtGui import QTextBrowser 36 | from PyQt4 import QtCore 37 | 38 | class MessageBox(QTextBrowser): 39 | """ 40 | The MessageBox Class performs the write functions in the Message Window. 41 | The previous defined MessageBox class is used as output (Within ui). 42 | @sideeffect: None 43 | """ 44 | 45 | def __init__(self, origobj): 46 | """ 47 | Initialization of the MessageBox class. 48 | @param origobj: This is the reference to to parent class initialized 49 | previously. 50 | """ 51 | super(MessageBox, self).__init__() 52 | self.setOpenExternalLinks(True) 53 | 54 | self.append(self.tr("You are using DXF2GCODE")) 55 | self.append(self.tr("Version %s (%s)") % (c.VERSION, c.DATE)) 56 | self.append(self.tr("For more information and updates visit:")) 57 | self.append("http://sourceforge.net/projects/dxf2gcode/") 58 | 59 | def tr(self, string_to_translate): 60 | """ 61 | Translate a string using the QCoreApplication translation framework 62 | @param: string_to_translate: a unicode string 63 | @return: the translated unicode string if it was possible to translate 64 | """ 65 | return text_type(QtCore.QCoreApplication.translate('MessageBox', 66 | string_to_translate)) 67 | 68 | def write(self, string): 69 | """ 70 | The function is called by the window logger to write 71 | the log message to the Messagebox 72 | @param charstr: The log message which will be written. 73 | """ 74 | stripped_string = string.strip() 75 | if stripped_string: 76 | self.append(stripped_string) 77 | self.verticalScrollBar().setValue(1e9) 78 | -------------------------------------------------------------------------------- /source/gui/popupdialog.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2010-2014 6 | # Christian Kohlöffel 7 | # Jean-Paul Schouwstra 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | from __future__ import absolute_import 27 | 28 | import logging 29 | 30 | from globals.six import text_type 31 | import globals.constants as c 32 | if c.PYQT5notPYQT4: 33 | from PyQt5.QtWidgets import QDialog, QVBoxLayout, QFrame, QGridLayout, QLabel, QLineEdit, QPushButton 34 | from PyQt5.QtGui import QIcon, QPixmap 35 | from PyQt5 import QtCore 36 | else: 37 | from PyQt4.QtGui import QDialog, QVBoxLayout, QFrame, QGridLayout, QLabel, QLineEdit, QPushButton, QIcon, QPixmap 38 | from PyQt4 import QtCore 39 | 40 | logger = logging.getLogger("Gui.PopUpDialog") 41 | 42 | 43 | class PopUpDialog(QDialog): 44 | 45 | def __init__(self, title="Test", label='Value1', value=1.0, haveAuto=False): 46 | super(PopUpDialog, self).__init__() 47 | 48 | logger.debug(title) 49 | logger.debug(label) 50 | logger.debug(value) 51 | 52 | self.title = title 53 | self.label = label 54 | self.value = value 55 | 56 | self.result = None 57 | 58 | if not(len(label) == len(value)): 59 | raise Exception("Number of labels different to number of values") 60 | 61 | self.initUI(haveAuto) 62 | 63 | def tr(self, string_to_translate): 64 | """ 65 | Translate a string using the QCoreApplication translation framework 66 | @param: string_to_translate: a unicode string 67 | @return: the translated unicode string if it was possible to translate 68 | """ 69 | return text_type(QtCore.QCoreApplication.translate('PopUpDialog', 70 | string_to_translate)) 71 | 72 | def initUI(self, haveAuto): 73 | 74 | vbox = QVBoxLayout(self) 75 | 76 | top = QFrame(self) 77 | top.setFrameShape(QFrame.StyledPanel) 78 | 79 | bottom = QFrame(self) 80 | bottom.setFrameShape(QFrame.StyledPanel) 81 | 82 | grid1 = QGridLayout() 83 | grid1.setSpacing(10) 84 | self.lineLabel = [] 85 | self.lineEdit = [] 86 | 87 | for i in range(len(self.label)): 88 | self.lineLabel.append(QLabel(self.label[i])) 89 | self.lineEdit.append(QLineEdit('%s' % self.value[i])) 90 | 91 | grid1.addWidget(self.lineLabel[i], i, 0) 92 | grid1.addWidget(self.lineEdit[i], i, 1) 93 | 94 | top.setLayout(grid1) 95 | 96 | grid2 = QGridLayout() 97 | grid2.setSpacing(5) 98 | 99 | autoButton = QPushButton(self.tr("Auto")) 100 | okButton = QPushButton(self.tr("OK")) 101 | cancelButton = QPushButton(self.tr("Cancel")) 102 | 103 | autoButton.clicked.connect(self.cbAuto) 104 | okButton.clicked.connect(self.cbOK) 105 | cancelButton.clicked.connect(self.cbCancel) 106 | 107 | if haveAuto: 108 | grid2.addWidget(autoButton, 0, 0) 109 | grid2.addWidget(okButton, 0, 1) 110 | grid2.addWidget(cancelButton, 0, 2) 111 | 112 | bottom.setLayout(grid2) 113 | 114 | vbox.addWidget(top) 115 | vbox.addWidget(bottom) 116 | 117 | self.setLayout(vbox) 118 | 119 | self.resize(50, 50) 120 | self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint) 121 | self.setWindowTitle(self.title) 122 | iconWT = QIcon() 123 | iconWT.addPixmap(QPixmap(":images/DXF2GCODE-001.ico"), QIcon.Normal, QIcon.Off) 124 | self.setWindowIcon(QIcon(iconWT)) 125 | 126 | self.exec_() 127 | 128 | def cbAuto(self): 129 | """ 130 | Determine WP zero automatically by finding the left/bottom-most shape 131 | """ 132 | self.result = 'Auto' 133 | self.close() 134 | 135 | def cbOK(self): 136 | self.result = [] 137 | for lineEdit in self.lineEdit: 138 | self.result.append(lineEdit.text()) 139 | self.close() 140 | 141 | def cbCancel(self): 142 | logger.debug('Cancel') 143 | self.close() 144 | 145 | -------------------------------------------------------------------------------- /source/gui/routetext.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2014 6 | # Christian Kohl�ffel 7 | # Vinzenz Schulz 8 | # 9 | # This file is part of DXF2GCODE. 10 | # 11 | # DXF2GCODE is free software: you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation, either version 3 of the License, or 14 | # (at your option) any later version. 15 | # 16 | # DXF2GCODE is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with DXF2GCODE. If not, see . 23 | # 24 | ############################################################################ 25 | 26 | import logging 27 | 28 | from core.point import Point 29 | 30 | import globals.constants as c 31 | if c.PYQT5notPYQT4: 32 | from PyQt5.QtWidgets import QGraphicsItem 33 | from PyQt5.QtGui import QPainterPath, QPen, QColor, QFont 34 | from PyQt5 import QtCore 35 | else: 36 | from PyQt4.QtGui import QPainterPath, QGraphicsItem, QPen, QColor, QFont 37 | from PyQt4 import QtCore 38 | 39 | logger = logging.getLogger("Gui.RouteText") 40 | 41 | class RouteText(QGraphicsItem): 42 | def __init__(self, text='S', startp=Point(x=0.0, y=0.0),): 43 | """ 44 | Initialisation of the class. 45 | """ 46 | QGraphicsItem.__init__(self) 47 | 48 | self.setFlag(QGraphicsItem.ItemIsSelectable, False) 49 | 50 | self.text = text 51 | self.sc = 1.0 52 | self.startp = QtCore.QPointF(startp.x, -startp.y) 53 | 54 | pencolor = QColor(0, 200, 255) 55 | self.brush = QColor(0, 100, 255) 56 | 57 | self.pen = QPen(pencolor, 1, QtCore.Qt.SolidLine) 58 | self.pen.setCosmetic(True) 59 | 60 | self.path = QPainterPath() 61 | self.path.addText(QtCore.QPointF(0, 0), 62 | QFont("Arial", 10/self.sc), 63 | self.text) 64 | 65 | def contains_point(self, point): 66 | """ 67 | Text cannot be selected. Return maximal distance 68 | """ 69 | return float(0x7fffffff) 70 | 71 | def setSelected(self, *args): 72 | """ 73 | Override inherited function - with possibility to be called with multiple arguments 74 | """ 75 | 76 | def paint(self, painter, option, widget=None): 77 | """ 78 | Method for painting the arrow. 79 | """ 80 | demat = painter.deviceTransform() 81 | self.sc = demat.m11() 82 | 83 | # painter.setClipRect(self.boundingRect()) 84 | painter.setPen(self.pen) 85 | painter.setBrush(self.brush) 86 | painter.scale(1/self.sc, 1/self.sc) 87 | painter.translate(self.startp.x() * self.sc, 88 | self.startp.y() * self.sc) 89 | 90 | painter.drawPath(self.path) 91 | 92 | def shape(self): 93 | """ 94 | Reimplemented function to select outline only. 95 | @return: Returns the Outline only 96 | """ 97 | logger.debug("Hier sollte ich nicht sein") 98 | return super(RouteText, self).shape() 99 | 100 | def boundingRect(self): 101 | """ 102 | Required method for painting. Inherited by Painterpath 103 | @return: Gives the Bounding Box 104 | """ 105 | rect = self.path.boundingRect().getRect() 106 | 107 | newrect = QtCore.QRectF(self.startp.x()+rect[0]/self.sc, 108 | self.startp.y()+rect[1]/self.sc, 109 | rect[2]/self.sc, 110 | rect[3]/self.sc) 111 | return newrect 112 | -------------------------------------------------------------------------------- /source/gui/wpzero.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | ############################################################################ 4 | # 5 | # Copyright (C) 2008-2015 6 | # Christian Kohlöffel 7 | # Vinzenz Schulz 8 | # Jean-Paul Schouwstra 9 | # 10 | # This file is part of DXF2GCODE. 11 | # 12 | # DXF2GCODE is free software: you can redistribute it and/or modify 13 | # it under the terms of the GNU General Public License as published by 14 | # the Free Software Foundation, either version 3 of the License, or 15 | # (at your option) any later version. 16 | # 17 | # DXF2GCODE is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | # GNU General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU General Public License 23 | # along with DXF2GCODE. If not, see . 24 | # 25 | ############################################################################ 26 | 27 | from __future__ import absolute_import 28 | from __future__ import division 29 | 30 | import globals.constants as c 31 | if c.PYQT5notPYQT4: 32 | from PyQt5.QtWidgets import QGraphicsItem 33 | from PyQt5.QtGui import QPen 34 | from PyQt5 import QtCore 35 | else: 36 | from PyQt4.QtGui import QGraphicsItem, QPen 37 | from PyQt4 import QtCore 38 | 39 | 40 | class WpZero(QGraphicsItem): 41 | """ 42 | class WpZero 43 | """ 44 | def __init__(self, center, color=QtCore.Qt.gray): 45 | self.sc = None 46 | super(WpZero, self).__init__() 47 | 48 | self.center = center 49 | self.allwaysshow = False 50 | self.color = color 51 | self.pen = QPen(QtCore.Qt.darkGray, 1, QtCore.Qt.SolidLine) 52 | self.pen.setCosmetic(True) 53 | 54 | self.diameter = 23.0 55 | 56 | def contains_point(self, point): 57 | """ 58 | WpZero cannot be selected. Return maximal distance 59 | """ 60 | return float(0x7fffffff) 61 | 62 | def setSelected(self, *args): 63 | """ 64 | Override inherited function - with possibility to be called with multiple arguments 65 | """ 66 | pass 67 | 68 | def paint(self, painter, option, widget=None): 69 | """ 70 | paint() 71 | """ 72 | painter.setPen(self.pen) 73 | demat = painter.deviceTransform() 74 | self.sc = demat.m11() 75 | 76 | diameter1 = self.diameter / self.sc 77 | diameter2 = (self.diameter - 4) / self.sc 78 | 79 | rectangle1 = QtCore.QRectF(-diameter1 / 2, -diameter1 / 2, diameter1, diameter1) 80 | rectangle2 = QtCore.QRectF(-diameter2 / 2, -diameter2 / 2, diameter2, diameter2) 81 | startAngle1 = 90 * 16 82 | spanAngle = 90 * 16 83 | startAngle2 = 270 * 16 84 | 85 | painter.drawEllipse(rectangle1) 86 | painter.drawEllipse(rectangle2) 87 | painter.drawPie(rectangle2, startAngle1, spanAngle) 88 | 89 | painter.setBrush(self.color) 90 | painter.drawPie(rectangle2, startAngle2, spanAngle) 91 | 92 | def boundingRect(self): 93 | """ 94 | Override inherited function to enlarge selection of Arrow to include all 95 | @param flag: The flag to enable or disable Selection 96 | """ 97 | if not self.sc: # since this function is called before paint; and scale is unknown 98 | return QtCore.QRectF(0, 0, 1e-9, 1e-9) 99 | 100 | diameter = self.diameter / self.sc 101 | return QtCore.QRectF(-diameter / 2, -diameter / 2, diameter, diameter) 102 | -------------------------------------------------------------------------------- /source/i18n/dxf2gcode_de_DE.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/i18n/dxf2gcode_de_DE.qm -------------------------------------------------------------------------------- /source/i18n/dxf2gcode_fr.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/i18n/dxf2gcode_fr.qm -------------------------------------------------------------------------------- /source/i18n/dxf2gcode_ru.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/i18n/dxf2gcode_ru.qm -------------------------------------------------------------------------------- /source/images/DXF2GCODE-001.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/DXF2GCODE-001.ico -------------------------------------------------------------------------------- /source/images/blocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/blocks.png -------------------------------------------------------------------------------- /source/images/collapse-all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/collapse-all.png -------------------------------------------------------------------------------- /source/images/custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/custom.png -------------------------------------------------------------------------------- /source/images/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/delete.png -------------------------------------------------------------------------------- /source/images/dxf2gcode_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/dxf2gcode_logo.png -------------------------------------------------------------------------------- /source/images/expand-all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/expand-all.png -------------------------------------------------------------------------------- /source/images/go-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/go-down.png -------------------------------------------------------------------------------- /source/images/go-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/go-up.png -------------------------------------------------------------------------------- /source/images/layer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/layer.png -------------------------------------------------------------------------------- /source/images/list-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/list-add.png -------------------------------------------------------------------------------- /source/images/list-remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/list-remove.png -------------------------------------------------------------------------------- /source/images/shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnc-club/dxf2gcode/dff70cbd1cc6548041d7c79c561afc8bdc1e3e4f/source/images/shape.png -------------------------------------------------------------------------------- /source/make_exe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | import subprocess 7 | 8 | PYTHONPATH = os.path.split(sys.executable)[0] 9 | pyinpfad = os.path.join(PYTHONPATH, "Scripts\\pyinstaller-script.py") 10 | 11 | pyt = os.path.join(PYTHONPATH, "python.exe") 12 | filepfad = os.path.realpath(os.path.dirname(sys.argv[0])) 13 | exemakepfad = filepfad 14 | file_ = "dxf2gcode" 15 | icon = "%s\\images\\DXF2GCODE-001.ico" % filepfad 16 | 17 | options = "--noconsole --icon=%s" % icon 18 | print(options) 19 | 20 | cmd = "%s %s %s %s\\%s.py" % (pyt, pyinpfad, options, filepfad, file_) 21 | print(cmd) 22 | print(subprocess.call(cmd)) 23 | 24 | print("\n!!!!!!!Do not forget the language folder!!!!!!") 25 | print("\nREADY") 26 | -------------------------------------------------------------------------------- /source/make_py_uic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | Generates the python file based on the defined uifile 5 | """ 6 | 7 | import os 8 | import sys 9 | import subprocess 10 | import tempfile 11 | 12 | from globals.six import PY2 13 | import globals.constants as c 14 | 15 | if len(sys.argv) > 1: 16 | try: 17 | pyQtVer = sys.argv[1] 18 | print("Using PyQt version read from command line = %d", int(pyQtVer)) 19 | except: 20 | sys.exit("Argument 1 is the PyQt version and must be an integer number (currently 4 and 5 are supported)") 21 | else: 22 | if c.PYQT5notPYQT4: 23 | pyQtVer = '5' 24 | else: 25 | pyQtVer = '4' 26 | 27 | if "linux" in sys.platform.lower() or "unix" in sys.platform.lower(): 28 | #On Linux, the executable are normaly on the PATH (just install packages like lib64-qt4-devel and python-qt4-devel) 29 | UICPATH = "pyuic%s" % pyQtVer 30 | RCCPATH = "pyrcc%s" % pyQtVer 31 | print("Using Linux platform tools \"%s\" and \"%s\"\n" % (UICPATH, RCCPATH)) 32 | else: 33 | PYTHONPATH = os.path.split(sys.executable)[0] 34 | UICPATH = os.path.join(PYTHONPATH, "Lib/site-packages/PyQt%s/pyuic%s.bat" % (pyQtVer, pyQtVer)) 35 | RCCPATH = os.path.join(PYTHONPATH, "Lib/site-packages/PyQt%s/pyrcc%s.exe" % (pyQtVer, pyQtVer)) 36 | print("Using Windows platform tools \"%s\" and \"%s\"\n" % (UICPATH, RCCPATH)) 37 | 38 | FILEPATH = os.path.realpath(os.path.dirname(sys.argv[0])) 39 | 40 | UIFILE = "dxf2gcode.ui" 41 | PYFILEver = "dxf2gcode_ui%s.py" % pyQtVer 42 | 43 | RCFILE = "dxf2gcode_images.qrc" 44 | RCFILEver = "dxf2gcode_images%s.qrc" % pyQtVer 45 | 46 | RCPYFILEver = "dxf2gcode_images%s_rc.py" % pyQtVer 47 | 48 | ui_data = "" 49 | with open(UIFILE, "r") as myfile: 50 | ui_data = myfile.read().replace(RCFILE, RCFILEver) 51 | 52 | fd, tmp_ui_filename = tempfile.mkstemp() 53 | try: 54 | if PY2: 55 | os.write(fd, ui_data) 56 | else: # Python3 57 | os.write(fd, bytes(ui_data, 'UTF-8')) 58 | os.close(fd) 59 | 60 | OPTIONS = "-o" 61 | 62 | cmd1 = "%s %s %s %s" % (UICPATH, tmp_ui_filename, OPTIONS, PYFILEver) 63 | cmd2 = "%s %s %s %s" % (RCCPATH, OPTIONS, RCPYFILEver, RCFILE) 64 | 65 | print(cmd1) 66 | print(subprocess.call(cmd1, shell=True)) #shell=True argument needed on Linux 67 | 68 | print(cmd2) 69 | print(subprocess.call(cmd2, shell=True)) #shell=True argument needed on Linux 70 | 71 | finally: 72 | os.remove(tmp_ui_filename) 73 | 74 | print("\n!!!!!!!Do not commit the updated ...rc.py files to the repository if the .qrc files did not change,\n" 75 | " i.e. if you did not make any changes with relation to the images\n" 76 | " - the updated .pys are not important especially with PyQt5; it makes too many unnecessary changes!!!!!!") 77 | print("\nREADY") 78 | -------------------------------------------------------------------------------- /source/make_tr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Generates the tr file based on the defined PyQt Project File 6 | """ 7 | 8 | import os, sys 9 | import subprocess 10 | 11 | if "linux" in sys.platform.lower() or "unix" in sys.platform.lower(): 12 | #On Linux, the executable are normaly on the PATH (just install lib64-qt4-devel and python-qt4-devel) 13 | PLYPATH = "pylupdate4" 14 | LREPATH = "lrelease" 15 | print("Using Linux platform tools \"%s\" and \"%s\"\n" % (PLYPATH, LREPATH)) 16 | else: 17 | PYTHONPATH = os.path.split(sys.executable)[0] 18 | PLYPATH = os.path.join(PYTHONPATH, "Lib/site-packages/PyQt4/pylupdate4.exe") 19 | LREPATH = os.path.join(PYTHONPATH, "Lib/site-packages/PyQt4/lrelease.exe") 20 | print("Using Windows platform tools \"%s\" and \"%s\"\n" % (PLYPATH, LREPATH)) 21 | 22 | FILEPATH = os.path.realpath(os.path.dirname(sys.argv[0])) 23 | 24 | FILES = ("../core/arcgeo.py", 25 | "../core/project.py", 26 | "../core/shape.py", 27 | "../dxfimport/geoent_arc.py", 28 | "../dxfimport/geoent_circle.py", 29 | "../dxfimport/geoent_line.py", 30 | "../dxfimport/importer.py", 31 | "../globals/config.py", 32 | "../gui/canvas.py", 33 | "../gui/canvas2d.py", 34 | "../gui/canvas3d.py", 35 | "../gui/configwindow.py", 36 | "../gui/messagebox.py", 37 | "../gui/popupdialog.py", 38 | "../gui/treehandling.py", 39 | "../postpro/postprocessor.py", 40 | "../postpro/postprocessorconfig.py", 41 | "../postpro/tspoptimisation.py", 42 | "../dxf2gcode.py", 43 | "../dxf2gcode.ui" 44 | ) 45 | 46 | 47 | TSFILES = ("dxf2gcode_de_DE.ts", 48 | "dxf2gcode_fr.ts", 49 | "dxf2gcode_ru.ts") 50 | 51 | FILESSTR = "" 52 | for FILE in FILES: 53 | FILESSTR += ("%s/i18n/%s " % (FILEPATH, FILE)) 54 | 55 | TSFILESTR = "" 56 | for TSFILE in TSFILES: 57 | TSFILESTR += ("%s/i18n/%s " % (FILEPATH, TSFILE)) 58 | 59 | OPTIONS = "-ts" 60 | 61 | cmd1 = ("%s %s %s %s\n" % (PLYPATH, FILESSTR, OPTIONS, TSFILESTR)) 62 | print(cmd1) 63 | print(subprocess.call(cmd1, shell=True)) 64 | 65 | cmd2 = ("%s %s\n" % (LREPATH, TSFILESTR)) 66 | print(cmd2) 67 | print(subprocess.call(cmd2, shell=True)) 68 | 69 | print("\nREADY") 70 | 71 | -------------------------------------------------------------------------------- /source/postpro/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /source/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # run: python setup.py build 3 | 4 | import sys, os 5 | import shutil 6 | from cx_Freeze import setup, Executable 7 | 8 | 9 | version = "4.10.2015" 10 | 11 | base = 'Console' 12 | if sys.platform == 'win32': 13 | base = 'Win32GUI' # Tells the build script to hide the console. 14 | 15 | # script based on 16 | # https://github.com/Fireforge/PySide-OpenGL-cx_Freeze-Example 17 | # http://stackoverflow.com/questions/15486292/cx-freeze-doesnt-find-all-dependencies 18 | def include_OpenGL(): 19 | PYTHONPATH = os.path.split(sys.executable)[0] 20 | path_base = os.path.join(PYTHONPATH, "Lib\\site-packages\\OpenGL") 21 | skip_count = len(path_base) 22 | zip_includes = [(path_base, "OpenGL")] 23 | for root, sub_folders, files in os.walk(path_base): 24 | for file_in_root in files: 25 | zip_includes.append( 26 | ("{}".format(os.path.join(root, file_in_root)), 27 | "{}".format(os.path.join("OpenGL", root[skip_count + 1:], file_in_root)) 28 | ) 29 | ) 30 | return zip_includes 31 | 32 | # Remove the existing folders 33 | shutil.rmtree("build", ignore_errors=True) 34 | shutil.rmtree("dist", ignore_errors=True) 35 | 36 | options = { 37 | 'build_exe': { 38 | # 'packages': '' , 39 | # 'includes': '', 40 | # 'excludes': '', 41 | 'zip_includes': include_OpenGL(), 42 | 'silent': True 43 | } 44 | } 45 | 46 | executables = [ 47 | Executable(script='dxf2gcode.py', 48 | base=base, 49 | icon="images\\DXF2GCODE-001.ico", 50 | appendScriptToExe=True, 51 | appendScriptToLibrary=False, 52 | targetName="dxf2gcode.exe" 53 | ) 54 | ] 55 | 56 | setup(name='DXF2GCODE', 57 | version=version, 58 | description='Converting 2D drawings to CNC machine compatible G-Code.', 59 | options=options, 60 | executables=executables 61 | ) 62 | --------------------------------------------------------------------------------