├── .gitignore ├── README.markdown ├── __init__.py ├── documentation ├── contents.html ├── skeinforge.html ├── skeinforge_tools.analyze.html ├── skeinforge_tools.analyze_plugins.analyze_utilities.display_line.html ├── skeinforge_tools.analyze_plugins.analyze_utilities.html ├── skeinforge_tools.analyze_plugins.analyze_utilities.mouse_tool_base.html ├── skeinforge_tools.analyze_plugins.analyze_utilities.tableau.html ├── skeinforge_tools.analyze_plugins.analyze_utilities.view_move.html ├── skeinforge_tools.analyze_plugins.analyze_utilities.view_rotate.html ├── skeinforge_tools.analyze_plugins.analyze_utilities.zoom_in.html ├── skeinforge_tools.analyze_plugins.analyze_utilities.zoom_out.html ├── skeinforge_tools.analyze_plugins.behold.html ├── skeinforge_tools.analyze_plugins.comment.html ├── skeinforge_tools.analyze_plugins.export_canvas_plugins.html ├── skeinforge_tools.analyze_plugins.export_canvas_plugins.postscript.html ├── skeinforge_tools.analyze_plugins.export_canvas_plugins.scalable_vector_graphics.html ├── skeinforge_tools.analyze_plugins.html ├── skeinforge_tools.analyze_plugins.skeinview.html ├── skeinforge_tools.analyze_plugins.statistic.html ├── skeinforge_tools.analyze_plugins.vectorwrite.html ├── skeinforge_tools.craft.html ├── skeinforge_tools.craft_plugins.carve.html ├── skeinforge_tools.craft_plugins.chamber.html ├── skeinforge_tools.craft_plugins.chop.html ├── skeinforge_tools.craft_plugins.cleave.html ├── skeinforge_tools.craft_plugins.clip.html ├── skeinforge_tools.craft_plugins.coil.html ├── skeinforge_tools.craft_plugins.comb.html ├── skeinforge_tools.craft_plugins.cool.html ├── skeinforge_tools.craft_plugins.dimension.html ├── skeinforge_tools.craft_plugins.drill.html ├── skeinforge_tools.craft_plugins.export.html ├── skeinforge_tools.craft_plugins.export_plugins.binary_16_byte.html ├── skeinforge_tools.craft_plugins.export_plugins.gcode_step.html ├── skeinforge_tools.craft_plugins.export_plugins.html ├── skeinforge_tools.craft_plugins.export_plugins.static_plugins.gcode_small.html ├── skeinforge_tools.craft_plugins.export_plugins.static_plugins.html ├── skeinforge_tools.craft_plugins.feed.html ├── skeinforge_tools.craft_plugins.fill.html ├── skeinforge_tools.craft_plugins.fillet.html ├── skeinforge_tools.craft_plugins.flow.html ├── skeinforge_tools.craft_plugins.home.html ├── skeinforge_tools.craft_plugins.hop.html ├── skeinforge_tools.craft_plugins.html ├── skeinforge_tools.craft_plugins.inset.html ├── skeinforge_tools.craft_plugins.jitter.html ├── skeinforge_tools.craft_plugins.lash.html ├── skeinforge_tools.craft_plugins.lift.html ├── skeinforge_tools.craft_plugins.mill.html ├── skeinforge_tools.craft_plugins.multiply.html ├── skeinforge_tools.craft_plugins.oozebane.html ├── skeinforge_tools.craft_plugins.outset.html ├── skeinforge_tools.craft_plugins.preface.html ├── skeinforge_tools.craft_plugins.raft.html ├── skeinforge_tools.craft_plugins.speed.html ├── skeinforge_tools.craft_plugins.splodge.html ├── skeinforge_tools.craft_plugins.stretch.html ├── skeinforge_tools.craft_plugins.tower.html ├── skeinforge_tools.craft_plugins.unpause.html ├── skeinforge_tools.craft_plugins.whittle.html ├── skeinforge_tools.craft_plugins.widen.html ├── skeinforge_tools.craft_plugins.wipe.html ├── skeinforge_tools.help.html ├── skeinforge_tools.html ├── skeinforge_tools.import_plugins.gts.html ├── skeinforge_tools.import_plugins.html ├── skeinforge_tools.import_plugins.obj.html ├── skeinforge_tools.import_plugins.py.html ├── skeinforge_tools.import_plugins.slc.html ├── skeinforge_tools.import_plugins.stl.html ├── skeinforge_tools.import_plugins.svg.html ├── skeinforge_tools.import_plugins.xml.html ├── skeinforge_tools.meta.html ├── skeinforge_tools.meta_plugins.description.html ├── skeinforge_tools.meta_plugins.html ├── skeinforge_tools.meta_plugins.polyfile.html ├── skeinforge_tools.profile.html ├── skeinforge_tools.profile_plugins.cutting.html ├── skeinforge_tools.profile_plugins.extrusion.html ├── skeinforge_tools.profile_plugins.html ├── skeinforge_tools.profile_plugins.milling.html ├── skeinforge_tools.profile_plugins.winding.html ├── skeinforge_tools.skeinforge_utilities.consecution.html ├── skeinforge_tools.skeinforge_utilities.euclidean.html ├── skeinforge_tools.skeinforge_utilities.gcodec.html ├── skeinforge_tools.skeinforge_utilities.html ├── skeinforge_tools.skeinforge_utilities.intercircle.html ├── skeinforge_tools.skeinforge_utilities.interpret.html ├── skeinforge_tools.skeinforge_utilities.settings.html ├── skeinforge_tools.skeinforge_utilities.svg_codec.html ├── skeinforge_tools.skeinforge_utilities.triangle_mesh.html ├── skeinforge_tools.skeinforge_utilities.vector3.html ├── skeinforge_tools.skeinforge_utilities.wikifier.html └── skeinforge_tools.skeinforge_utilities.xml_simple_parser.html ├── images ├── display_line.ppm ├── dive.ppm ├── soar.ppm ├── stop.ppm ├── view_move.ppm ├── view_rotate.ppm ├── zoom_in.ppm └── zoom_out.ppm ├── miscellaneous ├── Art of Illusion Scripts │ ├── Drill.bsh │ ├── Export GNU Triangulated Surface.bsh │ ├── Export Topology.bsh │ ├── Gearweaver.bsh │ ├── Import GNU Triangulated Surface.bsh │ ├── Import Topology.bsh │ ├── Platonic Solid.bsh │ └── Truncated Teardrop Shaper.bsh ├── OccSlicer_0.3 │ ├── INSTALL.TXT │ ├── OccSliceLib.py │ └── svg_template.tmpl ├── fabricate │ ├── RepRapArduinoSerialSender.py │ ├── __init__.py │ ├── demo.py │ ├── example.py │ ├── extrude.py │ ├── frank_davies │ │ ├── bring_to_temp.py │ │ └── t.sh │ ├── reprap.py │ ├── send.html │ ├── send.py │ └── snap.py └── nophead │ ├── enrique.py │ ├── gRead.py │ ├── layers.py │ ├── preview.py │ └── vector3.py ├── models ├── Screw Holder Bottom.stl ├── Screw Holder.gts ├── box.obj ├── circular_wave.py ├── electromagnet_demispool.stl └── sphere.xml ├── runskeinforge.sh ├── show_skeinforge.sh ├── skeinforge.py └── skeinforge_tools ├── __init__.py ├── alterations ├── example_cool_end.gcode ├── example_cool_start.gcode ├── example_end.gcode ├── example_homing.gcode ├── example_replace.csv ├── example_start.gcode ├── example_support_end.gcode └── example_support_start.gcode ├── analyze.py ├── analyze_plugins ├── __init__.py ├── analyze_utilities │ ├── __init__.py │ ├── display_line.py │ ├── mouse_tool_base.py │ ├── tableau.py │ ├── view_move.py │ ├── view_rotate.py │ ├── zoom_in.py │ └── zoom_out.py ├── behold.py ├── comment.py ├── export_canvas_plugins │ ├── __init__.py │ ├── postscript.py │ └── scalable_vector_graphics.py ├── skeinview.py ├── statistic.py └── vectorwrite.py ├── craft.py ├── craft_plugins ├── __init__.py ├── carve.py ├── chamber.py ├── chop.py ├── cleave.py ├── clip.py ├── coil.py ├── comb.py ├── cool.py ├── dimension.py ├── drill.py ├── export.py ├── export_plugins │ ├── __init__.py │ ├── binary_16_byte.py │ ├── gcode_step.py │ └── static_plugins │ │ ├── __init__.py │ │ └── gcode_small.py ├── feed.py ├── fill.py ├── fillet.py ├── flow.py ├── home.py ├── hop.py ├── inset.py ├── jitter.py ├── lash.py ├── lift.py ├── mill.py ├── multiply.py ├── oozebane.py ├── outset.py ├── preface.py ├── raft.py ├── speed.py ├── splodge.py ├── stretch.py ├── tower.py ├── unpause.py ├── whittle.py ├── widen.py └── wipe.py ├── help.py ├── import_plugins ├── __init__.py ├── gts.py ├── obj.py ├── py.py ├── slc.py ├── stl.py ├── svg.py └── xml.py ├── meta.py ├── meta_plugins ├── __init__.py ├── description.py └── polyfile.py ├── profile.py ├── profile_plugins ├── __init__.py ├── cutting.py ├── extrusion.py ├── milling.py └── winding.py ├── profiles ├── cutting │ ├── End_Mill │ │ ├── chop.csv │ │ └── lift.csv │ └── Laser │ │ ├── chop.csv │ │ └── lift.csv ├── extrusion │ ├── ABS │ │ └── raft.csv │ ├── HDPE │ │ └── raft.csv │ ├── PCL │ │ └── raft.csv │ ├── PLA │ │ └── raft.csv │ └── rapman_ABS │ │ ├── carve.csv │ │ ├── clip.csv │ │ ├── comb.csv │ │ ├── cool.csv │ │ ├── craft.csv │ │ ├── fill.csv │ │ ├── hop.csv │ │ ├── inset.csv │ │ ├── multiply.csv │ │ ├── oozebane.csv │ │ ├── preface.csv │ │ ├── raft.csv │ │ ├── speed.csv │ │ ├── stretch.csv │ │ └── tower.csv └── milling │ ├── End_Mill │ ├── chop.csv │ └── lift.csv │ └── Laser │ ├── chop.csv │ └── lift.csv └── skeinforge_utilities ├── __init__.py ├── consecution.py ├── euclidean.py ├── gcodec.py ├── intercircle.py ├── interpret.py ├── settings.py ├── svg_canvas.template ├── svg_codec.py ├── svg_layer.template ├── triangle_mesh.py ├── vector3.py ├── version.txt ├── wikifier.py └── xml_simple_parser.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmander/skeinforge/fd69d8e856780c826386dc973ceabcc03623f3e8/__init__.py -------------------------------------------------------------------------------- /documentation/skeinforge_tools.analyze_plugins.analyze_utilities.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.analyze_plugins.analyze_utilities 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.analyze_plugins.analyze_utilities
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/analyze_plugins/analyze_utilities/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
display_line
21 | mouse_tool_base
22 |
tableau
23 | view_move
24 |
view_rotate
25 | zoom_in
26 |
zoom_out
27 |

28 | 29 | 30 | 32 | 33 | 34 |
 
31 | Data
       level = 3
35 | numberOfLevelsDeepInPackageHierarchy = 3
36 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
37 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.analyze_plugins.export_canvas_plugins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.analyze_plugins.export_canvas_plugins 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.analyze_plugins.export_canvas_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/analyze_plugins/export_canvas_plugins/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
postscript
21 |
scalable_vector_graphics
22 |

23 | 24 | 25 | 27 | 28 | 29 |
 
26 | Data
       level = 3
30 | numberOfLevelsDeepInPackageHierarchy = 3
31 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
32 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.analyze_plugins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.analyze_plugins 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.analyze_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/analyze_plugins/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
analyze_utilities (package)
21 | behold
22 |
comment
23 | export_canvas_plugins (package)
24 |
skeinview
25 | statistic
26 |
vectorwrite
27 |

28 | 29 | 30 | 32 | 33 | 34 |
 
31 | Data
       level = 2
35 | numberOfLevelsDeepInPackageHierarchy = 2
36 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
37 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.craft_plugins.export_plugins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.craft_plugins.export_plugins 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.craft_plugins.export_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/export_plugins/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
binary_16_byte
21 |
gcode_step
22 |
static_plugins (package)
23 |

24 | 25 | 26 | 28 | 29 | 30 |
 
27 | Data
       level = 3
31 | numberOfLevelsDeepInPackageHierarchy = 3
32 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
33 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.craft_plugins.export_plugins.static_plugins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.craft_plugins.export_plugins.static_plugins 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.craft_plugins.export_plugins.static_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/export_plugins/static_plugins/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
gcode_small
21 |

22 | 23 | 24 | 26 | 27 | 28 |
 
25 | Data
       level = 4
29 | numberOfLevelsDeepInPackageHierarchy = 4
30 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
31 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.craft_plugins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.craft_plugins 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.craft_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
carve
21 | chamber
22 | chop
23 | cleave
24 | clip
25 | coil
26 | comb
27 | cool
28 | dimension
29 |
drill
30 | export
31 | export_plugins (package)
32 | feed
33 | fill
34 | fillet
35 | flow
36 | home
37 | hop
38 |
inset
39 | jitter
40 | lash
41 | lift
42 | mill
43 | multiply
44 | oozebane
45 | outset
46 | preface
47 |
raft
48 | speed
49 | splodge
50 | stretch
51 | tower
52 | unpause
53 | whittle
54 | widen
55 | wipe
56 |

57 | 58 | 59 | 61 | 62 | 63 |
 
60 | Data
       level = 2
64 | numberOfLevelsDeepInPackageHierarchy = 2
65 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
66 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
analyze
21 | analyze_plugins (package)
22 | craft
23 |
craft_plugins (package)
24 | help
25 | import_plugins (package)
26 |
meta
27 | meta_plugins (package)
28 | profile
29 |
profile_plugins (package)
30 | skeinforge_utilities (package)
31 |

32 | 33 | 34 | 36 | 37 | 38 |
 
35 | Data
       level = 1
39 | numberOfLevelsDeepInPackageHierarchy = 1
40 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
41 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.import_plugins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.import_plugins 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.import_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/import_plugins/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
gts
21 | obj
22 |
py
23 | slc
24 |
stl
25 | svg
26 |
xml
27 |

28 | 29 | 30 | 32 | 33 | 34 |
 
31 | Data
       level = 2
35 | numberOfLevelsDeepInPackageHierarchy = 2
36 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
37 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.meta.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module skeinforge_tools.meta 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.meta ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/meta.py
12 |

13 | Previous / Next / Contents 14 |

15 |


16 | Meta is a script to access the plugins which handle meta information.
17 |
18 |
19 |

20 | Previous / Next / Contents 21 |

22 |
23 |

24 |

25 | 26 | 27 | 29 | 30 | 31 |
 
28 | Modules
       
__init__
32 |
skeinforge_tools.skeinforge_utilities.gcodec
33 |
skeinforge_tools.skeinforge_utilities.settings
34 |

35 | 36 | 37 | 39 | 40 | 41 |
 
38 | Classes
       
42 |
MetaRepository 43 |
44 |

45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 |
 
48 | class MetaRepository
   A class to handle the meta settings.
 
 Methods defined here:
54 |
__init__(self)
Set the default settings, execute title & settings fileName.
55 | 56 |

57 | 58 | 59 | 61 | 62 | 63 |
 
60 | Functions
       
addToMenu(master, menu, repository, window)
Add a tool plugin menu.
64 |
getNewRepository()
Get the repository constructor.
65 |
getPluginFileNames()
Get meta plugin file names.
66 |
getPluginsDirectoryPath()
Get the plugins directory path.
67 |
main()
Display the meta dialog.
68 |

69 | 70 | 71 | 73 | 74 | 75 |
 
72 | Data
       __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
76 | __date__ = '$Date: 2008/21/04 $'
77 | __license__ = 'GPL 3.0'
78 | absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

79 | 80 | 81 | 83 | 84 | 85 |
 
82 | Author
       Enrique Perez (perez_enrique@yahoo.com)
86 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.meta_plugins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.meta_plugins 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.meta_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/meta_plugins/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
description
21 |
polyfile
22 |

23 | 24 | 25 | 27 | 28 | 29 |
 
26 | Data
       level = 2
30 | numberOfLevelsDeepInPackageHierarchy = 2
31 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
32 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.profile_plugins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.profile_plugins 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.profile_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/profile_plugins/__init__.py
12 |

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
cutting
21 |
extrusion
22 |
milling
23 |
winding
24 |

25 | 26 | 27 | 29 | 30 | 31 |
 
28 | Data
       level = 2
32 | numberOfLevelsDeepInPackageHierarchy = 2
33 | packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap'
34 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.skeinforge_utilities.consecution.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module skeinforge_tools.skeinforge_utilities.consecution 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.skeinforge_utilities.consecution ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/skeinforge_utilities/consecution.py
12 |

Consecution is a collection of utilities to chain together the craft plugins.

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Modules
       
__init__
21 | skeinforge_tools.analyze
22 |
skeinforge_tools.skeinforge_utilities.gcodec
23 | os
24 |
skeinforge_tools.profile
25 | skeinforge_tools.skeinforge_utilities.settings
26 |
sys
27 | time
28 |

29 | 30 | 31 | 33 | 34 | 35 |
 
32 | Functions
       
getChainText(fileName, procedure)
Get a crafted shape file.
36 |
getChainTextFromProcedures(fileName, procedures, text)
Get a crafted shape file from a list of procedures.
37 |
getCraftModule(fileName)
Get craft module.
38 |
getLastModule()
Get the last tool.
39 |
getProcedures(procedure, text)
Get the procedures up to and including the given procedure.
40 |
getReadCraftSequence()
Get profile sequence.
41 |
getSequenceIndexFromProcedure(procedure)
Get the profile sequence index of the procedure.  Return None if the procedure is not in the sequence
42 |
getSequenceIndexPlusOneFromText(fileText)
Get the profile sequence index of the file plus one.  Return zero if the procedure is not in the file
43 |
writeChainTextWithNounMessage(fileName, procedure)
Get and write a crafted shape file.
44 |

45 | 46 | 47 | 49 | 50 | 51 |
 
48 | Data
       __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
52 | __date__ = '$Date: 2008/21/04 $'
53 | __license__ = 'GPL 3.0'
54 | absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

55 | 56 | 57 | 59 | 60 | 61 |
 
58 | Author
       Enrique Perez (perez_enrique@yahoo.com)
62 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.skeinforge_utilities.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package skeinforge_tools.skeinforge_utilities 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.skeinforge_utilities
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/skeinforge_utilities/__init__.py
12 |

13 |

14 | 15 | 16 | 18 | 19 | 20 |
 
17 | Package Contents
       
consecution
21 | euclidean
22 | gcodec
23 |
intercircle
24 | interpret
25 | settings
26 |
svg_codec
27 | triangle_mesh
28 | vector3
29 |
wikifier
30 | xml_simple_parser
31 |

32 | 33 | 34 | 36 | 37 | 38 |
 
35 | Data
       __all__ = ['euclidean', 'gcodec', 'intercircle', 'preferences', 'trianglemesh', 'vec3']
39 | -------------------------------------------------------------------------------- /documentation/skeinforge_tools.skeinforge_utilities.interpret.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module skeinforge_tools.skeinforge_utilities.interpret 4 | 5 | 6 | 7 | 8 |
 
9 |  
skeinforge_tools.skeinforge_utilities.interpret ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/skeinforge_utilities/interpret.py
12 |

Interpret is a collection of utilities to list the import plugins.
13 |
14 | An import plugin is a script in the import_plugins folder which has the function getTriangleMesh.
15 |
16 | The following examples shows functions of interpret. The examples are run in a terminal in the folder which contains interpret.py.
17 |
18 |
19 | > python
20 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31)
21 | [GCC 4.2.1 (SUSE Linux)] on linux2
22 | Type "help", "copyright", "credits" or "license" for more information.
23 | >>> import interpret
24 | >>> interpret.getGNUTranslatorGcodeFileTypeTuples()
25 | [('GTS files', '*.gts'), ('Gcode text files', '*.gcode'), ('STL files', '*.stl'), ('SVG files', '*.svg')]
26 |
27 | >>> interpret.getImportPluginFileNames()
28 | ['gts', 'stl', 'svg']

29 |

30 | 31 | 32 | 34 | 35 | 36 |
 
33 | Modules
       
__init__
37 |
skeinforge_tools.skeinforge_utilities.gcodec
38 |
os
39 |

40 | 41 | 42 | 44 | 45 | 46 |
 
43 | Functions
       
getFirstTranslatorFileNameUnmodified(fileName)
Get the first file name from the translators in the import plugins folder, if the file name is not already set.
47 |
getGNUTranslatorFilesUnmodified()
Get the file types from the translators in the import plugins folder.
48 |
getGNUTranslatorGcodeFileTypeTuples()
Get the file type tuples from the translators in the import plugins folder plus gcode.
49 |
getImportPluginFileNames()
Get analyze plugin fileNames.
50 |
getTranslatorFileTypeTuples()
Get the file types from the translators in the import plugins folder.
51 |

52 | 53 | 54 | 56 | 57 | 58 |
 
55 | Data
       __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
59 | __date__ = '$Date: 2008/21/04 $'
60 | __license__ = 'GPL 3.0'
61 | absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

62 | 63 | 64 | 66 | 67 | 68 |
 
65 | Author
       Enrique Perez (perez_enrique@yahoo.com)
69 | -------------------------------------------------------------------------------- /images/display_line.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmander/skeinforge/fd69d8e856780c826386dc973ceabcc03623f3e8/images/display_line.ppm -------------------------------------------------------------------------------- /images/dive.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmander/skeinforge/fd69d8e856780c826386dc973ceabcc03623f3e8/images/dive.ppm -------------------------------------------------------------------------------- /images/soar.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmander/skeinforge/fd69d8e856780c826386dc973ceabcc03623f3e8/images/soar.ppm -------------------------------------------------------------------------------- /images/stop.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmander/skeinforge/fd69d8e856780c826386dc973ceabcc03623f3e8/images/stop.ppm -------------------------------------------------------------------------------- /images/view_move.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmander/skeinforge/fd69d8e856780c826386dc973ceabcc03623f3e8/images/view_move.ppm -------------------------------------------------------------------------------- /images/view_rotate.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmander/skeinforge/fd69d8e856780c826386dc973ceabcc03623f3e8/images/view_rotate.ppm -------------------------------------------------------------------------------- /images/zoom_in.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmander/skeinforge/fd69d8e856780c826386dc973ceabcc03623f3e8/images/zoom_in.ppm -------------------------------------------------------------------------------- /images/zoom_out.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmander/skeinforge/fd69d8e856780c826386dc973ceabcc03623f3e8/images/zoom_out.ppm -------------------------------------------------------------------------------- /miscellaneous/Art of Illusion Scripts/Truncated Teardrop Shaper.bsh: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 12 | */ 13 | 14 | do 15 | { 16 | scene = window.getScene(); 17 | 18 | directionType = new RadioButtonGroup(); 19 | up = new BRadioButton("Up", false, directionType); 20 | down = new BRadioButton("Down", false, directionType); 21 | left = new BRadioButton("Left", false, directionType); 22 | right = new BRadioButton("Right", false, directionType); 23 | 24 | directional = new GridContainer(2, 2); 25 | directional.setDefaultLayout(new LayoutInfo(LayoutInfo.WEST, LayoutInfo.NONE, new Insets(2, 2, 2, 2), null)); 26 | directional.add(up, 0, 0); 27 | directional.add(down, 0, 1); 28 | directional.add(left, 1, 0); 29 | directional.add(right, 1, 1); 30 | 31 | vertexValueField = new ValueField(45, ValueField.NONNEGATIVE); 32 | radiusValueField = new ValueField(1.0, ValueField.NONNEGATIVE); 33 | maxErrorValueField = new ValueField(0.05, ValueField.NONNEGATIVE); 34 | directionValueField = new ValueField(0.0, ValueField.NONNEGATIVE); 35 | truncationValueField = new ValueField(0.0, ValueField.NONNEGATIVE); 36 | 37 | dlg = new ComponentsDialog(window, "TearDrop Tool" , 38 | new Widget [] { directional, directionValueField, vertexValueField, truncationValueField, radiusValueField, maxErrorValueField }, 39 | new String [] { "Orientation about z-axis: ", "or specific rotation about z-axis (degrees): ", "Vertex angle (degrees): ", "Truncation: ", "Radius: ", "Max error: " } ); 40 | 41 | if (!dlg.clickedOk()) return; 42 | 43 | theta = vertexValueField.getValue() / 180 * Math.PI; 44 | radius = radiusValueField.getValue(); 45 | maxError = maxErrorValueField.getValue(); 46 | directionAngle = directionValueField.getValue() / 180 * Math.PI; 47 | 48 | errorAngle = Math.acos((radius - maxError) / radius); // inverse cosine 49 | 50 | // numberSides = Math.ceil(((2 * Math.PI) - 2 * (Math.PI / 2 - theta)) / errorAngle); // rounded up 51 | numberSides = Math.ceil(((2 * Math.PI) - 2 * (Math.PI / 2 - theta)) / errorAngle) + 1; // rounded up 52 | 53 | if (numberSides <= 10) 54 | new MessageDialog(window, "Please decrease the value of the maximum error"); 55 | } 56 | while (numberSides < 10); 57 | 58 | 59 | // Setting the orientation of the teardrop shape depending on the outcome of Radio Buttons 60 | if (up.getState()) 61 | directionAngle = Math.PI / 2; 62 | 63 | if (down.getState()) 64 | directionAngle = (3 * Math.PI) / 2; 65 | 66 | if (left.getState()) 67 | directionAngle = Math.PI; 68 | 69 | if (right.getState()) 70 | directionAngle = 0; 71 | 72 | 73 | Vec3[] v = new Vec3[numberSides]; 74 | float[] smoothness = new float[numberSides]; 75 | 76 | //double phi = ((2.0 * Math.PI) - (2.0 * ((Math.PI / 2) - theta))) / (numberSides - 2); 77 | double phi = ((2.0 * Math.PI) - (2.0 * ((Math.PI / 2) - theta))) / (numberSides - 3); 78 | 79 | double angle = ((Math.PI / 2.0) - theta); 80 | 81 | //for (int i = 0 ; i < (numberSides - 1) ; i++) 82 | for (int i = 0 ; i < (numberSides - 2) ; i++) 83 | { 84 | x1 = Math.cos(angle + phi * i); 85 | y1 = Math.sin(angle + phi * i); 86 | x2 = x1 * Math.cos(directionAngle) - y1 * Math.sin(directionAngle); // rotational vectors - x 87 | y2 = y1 * Math.cos(directionAngle) + x1 * Math.sin(directionAngle); // rotational vectors - y 88 | v[i] = new Vec3(x2, y2, 0); 89 | v[i].scale(radius); 90 | smoothness[i] = 0; 91 | } 92 | 93 | // final vertex point at the sharp tip 94 | //x3 = Math.cos(directionAngle) * (radius / Math.sin(theta)); 95 | //y3 = Math.sin(directionAngle) * (radius / Math.sin(theta)); 96 | //v[numberSides - 2.0] = new Vec3(x3, y3, 0); 97 | truncationToVertex = truncationValueField.getValue() * (2 - Math.sqrt(2)); 98 | xTip = Math.cos(directionAngle) * (radius / Math.sin(theta)); 99 | yTip = Math.sin(directionAngle) * (radius / Math.sin(theta)); 100 | vTip = new Vec3(xTip, yTip, 0); 101 | vLast = v[numberSides - 3.0]; 102 | vFromTipToLast = vLast.minus( vTip ); 103 | vFromTipToLast.scale( truncationToVertex ); 104 | v[numberSides - 2.0] = vTip.plus( vFromTipToLast ); 105 | vStart = v[0]; 106 | vFromTipToStart = vStart.minus( vTip ); 107 | vFromTipToStart.scale( truncationToVertex ); 108 | x4 = xTip + 0.2; 109 | y4 = yTip + 0.3; 110 | v[numberSides - 1.0] = vTip.plus( vFromTipToStart ); 111 | 112 | name = "Truncated Teardrop (" + numberSides + " sides)"; 113 | 114 | tolerance = 0.02; //surface accuracy 115 | 116 | curve = new Curve(v, smoothness, Mesh.APPROXIMATING, true); 117 | window.addObject(curve, new CoordinateSystem(), name, null); 118 | 119 | // Finished -------------------------------------------------------------------------------- /miscellaneous/OccSlicer_0.3/INSTALL.TXT: -------------------------------------------------------------------------------- 1 | OccSliceLIb 2 | 3 | A library for using OCC to slice solids for 3d printing. 4 | Author: Dave Cowden, dave.cowden@gmail.com 5 | 6 | Features: 7 | Slice STEP and STL files by creating layers of faces 8 | Tolerate and fix bad STL files 9 | Provide viewer for slices and the target object 10 | Export an SVG slice file 11 | Installation: 12 | 13 | 0)Get the latest version with everything at: 14 | GET: http://home.bluedirt.org/OccSlicer/OccSlicer_0.3.zip 15 | or continue to use this abridged version. 16 | 17 | 1)Install Python, version 2.5 or 2.6, 18 | GET: http://www.python.org/download/ 19 | TEST: at a command prompt/console, type "python"-- you should get something like this: 20 | 21 | Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32 22 | Type "help", "copyright", "credits" or "license" for more information 23 | >>> 24 | 25 | 2)Install OpenCascade+pythonOCC. Follow instructions here: 26 | This script requires release wo-0.2 or more recent 27 | 28 | GET: http://www.pythonocc.org/wiki/index.php/InstallWindows 29 | TEST: at a python command prompt, type from OCC import *, 30 | you should get no error, like this: 31 | 32 | Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] o 33 | win32 34 | Type "help", "copyright", "credits" or "license" for more information. 35 | >>> from OCC import * 36 | >>> 37 | 38 | 3)Install the Cheetah Template library for python, version 2.2 from here: 39 | GET: http://sourceforge.net/project/showfiles.php?group_id=28961 40 | TEST: at a python prompt try to import Cheetah, like this: 41 | 42 | Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] o 43 | win32 44 | Type "help", "copyright", "credits" or "license" for more information. 45 | >>> from Cheetah import * 46 | >>> 47 | 48 | 4)Copy OccSliceLib(this script) into a directory of your choice. 49 | TEST: Run the script without any arguments to confirm installation is ok, and to print help: 50 | 51 | >python OccSliceLib.py 52 | > 53 | >OccSliceLib usage: 54 | ..... 55 | -------------------------------------------------------------------------------- /miscellaneous/fabricate/RepRapArduinoSerialSender.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | Extrude requires pySerial installed for this module to work. If you are using Fedora it is available on yum 5 | (run "sudo yum install pyserial"). To actually control the reprap requires write access to the serial device, 6 | running as root is one way to get that access. 7 | 8 | Created by Brendan Erwin on 2008-05-21. 9 | Copyright (c) 2008 Brendan Erwin. All rights reserved. 10 | 11 | This program is free software; you can redistribute it and/or 12 | modify it under the terms of the GNU General Public License 13 | as published by the Free Software Foundation; either version 2 14 | of the License, or (at your option) any later version. 15 | 16 | This program 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 this program; if not, write to the Free Software 23 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 24 | 25 | """ 26 | 27 | try: 28 | import serial # Import the pySerial modules. 29 | except: 30 | print( 'You do not have pySerial installed, which is needed to control the serial port.' ) 31 | print( 'Information on pySerial is at:\nhttp://pyserial.wiki.sourceforge.net/pySerial' ) 32 | 33 | import os 34 | import sys 35 | import time 36 | 37 | 38 | class RepRapArduinoSerialSender: 39 | """ 40 | A utility class for communication with the Arduino from python. 41 | Intended for g-code only. Raises ValueException if the arduino 42 | returns an unexpected response. Usually caused by sending invalid 43 | g-code. 44 | """ 45 | 46 | _verbose = False 47 | block = "empty" 48 | 49 | def __init__(self, port, verbose=False): 50 | """ 51 | Opens the serial port and prepares for writing. 52 | port MUST be set, and values are operating system dependant. 53 | """ 54 | self._verbose = verbose 55 | 56 | if self._verbose: 57 | print >> sys.stdout, "Opening serial port: " + port 58 | 59 | #Timeout value 10" max travel, 1RPM, 20 threads/in = 200 seconds 60 | self.ser = serial.Serial(port, 19200, timeout=200) 61 | 62 | if self._verbose: 63 | print >> sys.stdout, "Serial Open?: " + str(self.ser.isOpen()) 64 | print >> sys.stdout, "Baud Rate: " + str(self.ser.baudrate) 65 | 66 | def reset(self): 67 | """ 68 | Resets the arduino by droping DTR for 1 second 69 | This will then wait for a response ("ready") and return. 70 | """ 71 | #Reboot the arduino, and wait for it's response 72 | if self._verbose: 73 | print "reseting arduino..." 74 | 75 | self.ser.setDTR(0) 76 | # There is presumably some latency required. 77 | time.sleep(1) 78 | self.ser.setDTR(1) 79 | self.read("start") 80 | 81 | def write(self, block): 82 | """ 83 | Writes one block of g-code out to arduino and waits for an "ok". 84 | This version will wait for an "ok" before returning and prints any intermediate output received. 85 | No error will be raised if non-ok response is received. Loop in read() is infinite if "ok" 86 | does not come back! 87 | This routine also removes all whitespace before sending it to the arduino, 88 | which is handy for gcode, but will screw up if you try to do binary communications. 89 | """ 90 | if self._verbose: 91 | print block 92 | 93 | # The arduino GCode interperter firmware doesn't like whitespace 94 | # and if there's anything other than space and tab, we have other problems. 95 | block=block.strip() 96 | block=block.replace(' ','') 97 | block=block.replace("\t",'') 98 | #Skip blank blocks. 99 | if len(block) == 0: 100 | return 101 | 102 | self.ser.write(block) 103 | self.read("ok") 104 | 105 | def read(self, expect=None): 106 | """ 107 | This routine should never be called directly. It's used by write() and reset() 108 | to read a one-line response from the Arduino. 109 | This version will wait for an "ok" before returning and prints any intermediate output received. 110 | No error will be raised if non-ok response is received. Loop is infinite if "ok" 111 | does not come back! 112 | """ 113 | #The g-code firmware returns exactly ONE line per block of gcode sent. 114 | #Unless it is M104, M105 or other code that returns info!! 115 | #It WILL return "ok" once the command has finished sending and completed. 116 | while True: 117 | response = self.ser.readline().strip() 118 | if expect is None: 119 | return 120 | 121 | if expect in response: 122 | if self._verbose: 123 | print response 124 | return 125 | else: 126 | #Just print the response since it is useful data or an error message 127 | print response 128 | 129 | 130 | def close(): 131 | """ 132 | Closes the serial port, terminating communications with the arduino. 133 | """ 134 | if self._verbose: 135 | print >> sys.stdout, "Closing serial port." 136 | self.ser.close() 137 | 138 | if self._verbose: 139 | print >> sys.stdout, "Serial Open?: " + str(self.ser.isOpen()) 140 | -------------------------------------------------------------------------------- /miscellaneous/fabricate/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | 3 | import os 4 | import sys 5 | 6 | numberOfLevelsDeepInPackageHierarchy = 2 7 | packageFilePath = os.path.abspath( __file__ ) 8 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 9 | packageFilePath = os.path.dirname( packageFilePath ) 10 | if packageFilePath not in sys.path: 11 | sys.path.insert( 0, packageFilePath ) 12 | -------------------------------------------------------------------------------- /miscellaneous/fabricate/demo.py: -------------------------------------------------------------------------------- 1 | try: 2 | import serial 3 | except: 4 | print( 'You do not have pySerial installed, which is needed to control the serial port.' ) 5 | print( 'Information on pySerial is at:\nhttp://pyserial.wiki.sourceforge.net/pySerial' ) 6 | import reprap, time # Import the reprap and pySerial modules. 7 | 8 | reprap.serial = serial.Serial(0, 19200, timeout = reprap.snap.messageTimeout) # Initialise serial port, here the first port (0) is used. 9 | reprap.cartesian.x.active = True # These devices are present in network, will automatically scan in the future. 10 | reprap.cartesian.y.active = True 11 | reprap.cartesian.z.active = True 12 | reprap.extruder.active = True 13 | # The module is now ready to recieve commands # 14 | moveSpeed = 220 15 | reprap.cartesian.homeReset( moveSpeed, True ) # Send all axies to home position. Wait until arrival. 16 | reprap.cartesian.seek( (1000, 1000, 0), moveSpeed, True ) # Seek to (1000, 1000, 0). Wait until arrival. 17 | time.sleep(2) # Pause. 18 | reprap.cartesian.seek( (500, 1000, 0), moveSpeed, True ) # Seek to (500, 1000, 0). Wait until arrival. 19 | time.sleep(2) 20 | reprap.cartesian.seek( (1000, 500, 0), moveSpeed, True ) # Seek to (1000, 500, 0). Wait until arrival. 21 | time.sleep(2) 22 | reprap.cartesian.seek( (100, 100, 0), moveSpeed, True ) # Seek to (100, 100, 0). Wait until arrival. 23 | reprap.cartesian.homeReset( moveSpeed, True ) # Send all axies to home position. Wait until arrival. 24 | reprap.cartesian.free() # Shut off power to all motors. 25 | -------------------------------------------------------------------------------- /miscellaneous/fabricate/example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | try: 3 | import serial 4 | except: 5 | print( 'You do not have pySerial installed, which is needed to control the serial port.' ) 6 | print( 'Information on pySerial is at:\nhttp://pyserial.wiki.sourceforge.net/pySerial' ) 7 | 8 | import reprap, time, sys 9 | 10 | #reprap.snap.printOutgoingPackets = True 11 | #reprap.snap.printIncomingPackets = True 12 | #reprap.snap.printFailedPackets = True 13 | #reprap.printDebug = True 14 | 15 | #work surface approx x 2523, y 2743 16 | 17 | #reprap.serial = serial.Serial(0, 19200, timeout = reprap.snap.messageTimeout) 18 | reprap.serial = serial.Serial(0, 19200, timeout = 60) 19 | 20 | reprap.cartesian.x.active = True # these devices are present in network 21 | reprap.cartesian.y.active = True 22 | reprap.cartesian.z.active = True 23 | reprap.extruder.active = True 24 | 25 | reprap.cartesian.x.setNotify() 26 | reprap.cartesian.y.setNotify() 27 | reprap.cartesian.z.setNotify() 28 | reprap.cartesian.x.limit = 2523 29 | #reprap.cartesian.y.limit = 2743 30 | reprap.cartesian.y.limit = 2000 31 | 32 | def printPos(): 33 | x, y, z = reprap.cartesian.getPos() 34 | print "Location [" + str(x) + ", " + str(y) + ", " + str(z) + "]" 35 | 36 | 37 | print "================================================================" 38 | 39 | 40 | ########### control of cartesian frame as a whole ######### 41 | 42 | #stop all steppers 43 | if sys.argv[1] == "stop": 44 | reprap.cartesian.stop() 45 | 46 | #goto 0,0 47 | if sys.argv[1] == "reset": 48 | reprap.cartesian.homeReset( 200, True ) 49 | #time.sleep(2) 50 | printPos() 51 | 52 | #print current positon 53 | if sys.argv[1] == "pos": 54 | printPos() 55 | 56 | #goto a specific location 57 | if sys.argv[1] == "goto": 58 | reprap.cartesian.seek( ( int(sys.argv[2]), int(sys.argv[3]), 0 ), 200, False) 59 | printPos() 60 | 61 | #goto a specific location (use sync) 62 | if sys.argv[1] == "gotos": 63 | reprap.cartesian.syncSeek( ( int(sys.argv[2]), int(sys.argv[3]), 0 ), 200, False) 64 | printPos() 65 | 66 | if sys.argv[1] == "power": 67 | reprap.cartesian.setPower( int( sys.argv[2] ) ) # This is a value from 0 to 63 (6 bits) 68 | 69 | 70 | #test routine 71 | if sys.argv[1] == "go": #stepper test 72 | reprap.cartesian.seek( (1000, 1000, 0), 200, True ) 73 | time.sleep(2) 74 | reprap.cartesian.seek( (500, 1000, 0), 200, True ) 75 | time.sleep(2) 76 | reprap.cartesian.seek( (500, 500, 0), 200, True ) 77 | time.sleep(2) 78 | reprap.cartesian.seek( (10, 10, 0), 200, True ) 79 | 80 | #free motors (switch off all coils) 81 | if sys.argv[1] == "free": 82 | reprap.axies.free(reprap.axisX) 83 | reprap.axies.free(reprap.axisY) 84 | 85 | ############## control of individual steppers ############# 86 | 87 | #spin stepper 88 | if sys.argv[1] == "run": # run axis 89 | if sys.argv[2] == "x": 90 | reprap.cartesian.x.forward( int(sys.argv[3]) ) 91 | elif sys.argv[2] == "y": 92 | reprap.cartesian.y.forward( int(sys.argv[3]) ) 93 | 94 | #spin stepper in reverse 95 | if sys.argv[1] == "runb": #runb axis 96 | if sys.argv[2] == "x": 97 | reprap.axies.backward( reprap.axisX, int(sys.argv[3]) ) 98 | elif sys.argv[2] == "y": 99 | reprap.axies.backward( reprap.axisY, int(sys.argv[3]) ) 100 | 101 | if sys.argv[1] == "step": 102 | if sys.argv[2] == "x": 103 | reprap.cartesian.x.forward1() 104 | elif sys.argv[2] == "y": 105 | reprap.cartesian.y.forward1() 106 | 107 | ################# control of extruder ##################### 108 | 109 | #test extrder motor 110 | elif sys.argv[1] == "motor": 111 | nn = 0 112 | while 1: 113 | if nn > 0: 114 | nn = 0 115 | else: 116 | nn = 150 117 | reprap.extruder.setMotor(reprap.CMD_REVERSE, nn) 118 | time.sleep(1) 119 | 120 | elif sys.argv[1] == "getinfo": 121 | mtype = reprap.extruder.getModuleType() 122 | version = reprap.extruder.getVersion() 123 | print "module", mtype, "version", version 124 | 125 | elif sys.argv[1] == "heat": 126 | reprap.extruder.setHeat(255, 255, 255, 255) 127 | 128 | #setHeat(self, lowHeat, highHeat, tempTarget, tempMax 129 | 130 | elif sys.argv[1] == "temp": 131 | print "Temp is ", reprap.extruder.getTemp() 132 | 133 | elif sys.argv[1] == "setref": 134 | reprap.extruder.setVoltateReference( int(sys.argv[2]) ) 135 | 136 | 137 | 138 | 139 | ############### scan network for devices ################### 140 | 141 | #scan snap network 142 | elif sys.argv[1] == "scan": 143 | reprap.scanNetwork() 144 | 145 | -------------------------------------------------------------------------------- /miscellaneous/fabricate/frank_davies/bring_to_temp.py: -------------------------------------------------------------------------------- 1 | # bring reprap to temperature 2 | # Frank Davies 3 | import serial 4 | import time 5 | import sys 6 | 7 | def out_rep(out_string): 8 | ser.write(out_string) 9 | print out_string 10 | #print "waiting for OK" 11 | start_time=time.clock() 12 | while (ser.inWaiting()==0) and (time.clock()temp.gcode # make temporary file with extra at the beginning 6 | ascii-xfr -sv temp.gcode >/dev/ttyUSB0 # transfer the file 7 | #cp $1 /dev/ttyUSB0 # alternate transfer method commented out. 8 | echo DONE 9 | -------------------------------------------------------------------------------- /miscellaneous/fabricate/send.html: -------------------------------------------------------------------------------- 1 |

2 | send.py is "glue" for sending a skeinforge-generated gcode file to your arduino-based reprap. 3 |

4 |

5 | It is a command-line only utility, starting it from your GUI of choice will not be useful. 6 |

7 |

8 | 9 | Syntax is simple: 10 |

11 | send.py [options] <gcode or file> [<gcode or file>...]
12 | 
13 |

14 |

15 | 16 | To send your extruder.gcode file to your reprap, type: 17 |

18 | send.py extruder.gcode
19 | 
20 |

21 |

22 | This will print the extruder.gcode shape, and print comments to the console. 23 | Typically, comments are such things as 24 | (>layerStart< 0.402 ) 25 | which can be very useful to track the progress of your build, so these are "on" by default. 26 |

27 |

28 | There are a simple options that may be useful for special circumstances. 29 | These are --quiet, --noreset, --port, and --verbose. 30 | These can also be writted -q, -n, -p, and -v for short. 31 | If you are writing a script (for instance, the M100 scripts for use with EMC) then I'd recommend that you use the long options, so future maintainers don't have to look things up. 32 |

33 |

34 | Quiet will suppress all but the most basic messages. It won't supress everything, however. Error messages will still be printed. But it will supress almost everything. 35 | Since options are processed in order on the command line, so if you want to supress messages about processing options, you'll have to make Quiet the first option. 36 |

37 |

38 | Normally, the arduino is reset by dropping the DTR line for 1 second. 39 | Since the Arduino takes several seconds to reboot, you will want to disable this behavior when including send.py in scripts. 40 |

41 |

42 | The verbose option will cause not just comments, but every command sent to and every response recieved from the arduino to be printed out. Useful for debugging, but it prints a great deal of text in ordinary usage. 43 |

44 |

45 | The port option uses reasonable defaults for most operating systems - /dev/ttyUSB0 for posix systems, and COM3 for windows systems. 46 | If you have some other port you'll have to set in manually as "send.py -p COM5 extruder.gcode" or 47 | "send.py --port /dev/ttyUSB5 extruder.gcode" or something. 48 |

49 |

50 | Future improvements: 51 |

52 |

53 |

54 | I would like to add support for more g-code contructs on the python side of things. 55 | Stuff like variables, subroutines, etc. 56 | Stuff that the g-code firmware is unlikely to ever implement because of size restrictions. 57 | The current version works, and skeinforge doesn't use these features. 58 | It might be nice for a future "print several objects at once, automatically filling the bed area" interface. 59 | And if I get my extruder built, I might even take the time to do that! 60 |

61 | RepRapArduinoSerialSender.py 62 |

63 |

64 | 65 | This, like send.py, was cribbed from Brenden Erwin's code for using EMC. It's been modified somewhat for more general use. 66 | There are only five methods: 67 |

68 |
69 | __init__
70 | reset
71 | write
72 | read
73 | close
74 | 
75 |

76 | Of these, you should not directly use read(). It's used internally by write and reset to verify that the operation was completed successfully. 77 |

78 | 79 | -------------------------------------------------------------------------------- /miscellaneous/fabricate/send.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.5 2 | # encoding: utf-8 3 | """ 4 | Created by Brendan Erwin on 2008-05-21. 5 | Modified by John Gilmore 2008-08-23 6 | Copyright (c) 2008 Brendan Erwin. All rights reserved. 7 | Copyright (c) 2008 John Gilmore. 8 | 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . 21 | """ 22 | 23 | import os 24 | import sys 25 | import getopt 26 | import RepRapArduinoSerialSender 27 | 28 | help_message = ''' 29 | Usage: send [options] [...] 30 | --verbose : Verbose - print ALL communication, not just comments. 31 | -v : prints responses from the arduino, and every command sent. 32 | 33 | --quiet : Quiet - don't print anything, whereas 34 | -q : normally comments are printed. 35 | 36 | --noreset : skip the reset. 37 | -n : causes the arduino to not be deliberately reset. 38 | 39 | --port : Set the port to write to 40 | -p : default is "/dev/ttyUSB0" for posix, "COM3" for windows. 41 | 42 | You may call this with either a single statement of g-code 43 | to be sent to the arduino, or with the name of a g-code file. 44 | ------------------------------------------------------------------ 45 | Copyright (C) 2008 Brendan Erwin 46 | Copyright (C) 2008 John Gilmore 47 | 48 | This program is free software: you can redistribute it and/or modify 49 | it under the terms of the GNU General Public License as published by 50 | the Free Software Foundation, either version 3 of the License, or 51 | (at your option) any later version. 52 | 53 | This program is distributed in the hope that it will be useful, 54 | but WITHOUT ANY WARRANTY; without even the implied warranty of 55 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 56 | GNU General Public License for more details. 57 | 58 | You should have received a copy of the GNU General Public License 59 | along with this program. If not, see . 60 | ''' 61 | #This was originally release by Brendan under GPLv2 or later 62 | 63 | 64 | 65 | class Usage(Exception): 66 | def __init__(self, msg): 67 | self.msg = msg 68 | 69 | def main(argv=None): 70 | 71 | # Set resonable defaults for port, verbosity, and reset. 72 | verbose = 1 73 | reset = True 74 | if os.name == "posix": 75 | port = "/dev/ttyUSB0" 76 | elif os.name == "nt": 77 | port = "COM3" 78 | else: 79 | port = "/dev/ttyUSB0" 80 | 81 | if argv is None: 82 | argv = sys.argv 83 | 84 | try: 85 | try: 86 | opts, argv = getopt.getopt(argv[1:], "vqnhp:", ["verbose","quiet","noreset","help","port="]) 87 | except getopt.error, msg: 88 | raise Usage(msg) 89 | 90 | # option processing 91 | for option, value in opts: 92 | if option in ( "-v" , "--verbose" ): 93 | verbose = 2 94 | print "You have requested that verbosity be set to True" 95 | print "All communication with the arduino will be printed" 96 | elif option in ( "-q" , "--quiet" ): 97 | verbose = 0 98 | #don't print "quiet mode on" 99 | elif option in ( "-n" , "--noreset" ): 100 | reset = False 101 | if verbose: 102 | print "Arduino will not be reset before sending gcode" 103 | elif option in ( "-p" , "--port" ): 104 | port = value 105 | elif option in ("-h", "--help" ): 106 | raise Usage(help_message) 107 | 108 | if verbose: 109 | print "Arduino port set to "+port 110 | 111 | except Usage, err: 112 | #print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg) 113 | print >> sys.stderr, str(err.msg) 114 | print >> sys.stderr, "For help use --help" 115 | return 2 116 | 117 | 118 | sender = RepRapArduinoSerialSender.RepRapArduinoSerialSender(port,verbose>1) 119 | if reset: 120 | sender.reset() 121 | 122 | for filename in argv: 123 | processfile(filename,sender,verbose) 124 | 125 | def processfile(filename,sender,verbose): 126 | try: 127 | datafile = open(filename) 128 | except IOError: 129 | #Ignore verbosity settings here, as if it's a typo we'll want to know. 130 | line=filename 131 | if line.lstrip().startswith(("G","X","Y","Z","M")): 132 | if verbose: 133 | print "Unable to open file \"" + line + "\", assuming it's one line of direct G-code..." 134 | sender.write(line) 135 | return 0 136 | else: 137 | print "Unable to open file \"" + line + "\"" 138 | sys.exit(-1) 139 | 140 | try: 141 | for line in datafile: 142 | line=line.rstrip() 143 | # Ignore lines with comments (not technically correct, should ignore only the comment, 144 | # but all gcode files that I've actually seen so far don't have code on comment lines. 145 | if line.lstrip().startswith( ('(', '"' , '\\') ): 146 | if verbose: 147 | print line 148 | continue 149 | 150 | # This is the place to insert G-Code interpretation. 151 | # Subroutines, Variables, all sorts of fun stuff. 152 | # probably by calling a "gcode interpreter" class intead 153 | # of simply "sender". 154 | 155 | sender.write(line) 156 | finally: 157 | datafile.close() 158 | 159 | return 0 160 | 161 | if __name__ == "__main__": 162 | sys.exit(main()) 163 | -------------------------------------------------------------------------------- /miscellaneous/nophead/enrique.py: -------------------------------------------------------------------------------- 1 | import Image, ImageDraw, ImageChops 2 | from GifImagePlugin import getheader, getdata 3 | from vector3 import Vector3 4 | 5 | # Get the entire text of a file. 6 | # @param fileName name of the file 7 | # @return entire text of a file. 8 | def getFileText( fileName ): 9 | file = open( fileName, 'r' ) 10 | fileText = file.read() 11 | file.close() 12 | return fileText 13 | 14 | # Get the all the lines of text of a text. 15 | # @param text text 16 | # @return the lines of text of a text 17 | def getTextLines( text ): 18 | return text.replace( '\r', '\n' ).split( '\n' ) 19 | 20 | # Get the double value of the word after the first letter. 21 | # @param word string with value starting after the first letter 22 | # @return double value of the word after the first letter 23 | def getDoubleAfterFirstLetter( word ): 24 | return float( word[ 1 : ] ) 25 | 26 | # Get the double value of the word after the first occurence of the letter in the split line. 27 | def getDoubleForLetter( letter, splitLine ): 28 | return getDoubleAfterFirstLetter( splitLine[ indexOfStartingWithSecond( letter, splitLine ) ] ) 29 | 30 | # Get index of the first occurence of the given letter in the split line, starting with the second word. Return - 1 if letter is not found 31 | def indexOfStartingWithSecond( letter, splitLine ): 32 | for wordIndex in xrange( 1, len( splitLine ) ): 33 | word = splitLine[ wordIndex ] 34 | firstLetter = word[ 0 ] 35 | if firstLetter == letter: 36 | return wordIndex 37 | return - 1 38 | 39 | # straightforward delta encoding taken from gifmaker.py 40 | def makedelta(fp, sequence): 41 | """Convert list of image frames to a GIF animation file""" 42 | previous = None 43 | for im in sequence: 44 | if not previous: 45 | # global header 46 | for s in getheader(im) + getdata(im): 47 | fp.write(s) 48 | else: 49 | # delta frame 50 | delta = ImageChops.subtract_modulo(im, previous) 51 | bbox = delta.getbbox() 52 | if not bbox: 53 | bbox = (0,0, 1,1) 54 | # compress difference 55 | for s in getdata(im.crop(bbox), offset = bbox[:2]): 56 | fp.write(s) 57 | previous = im.copy() 58 | fp.write(";") 59 | 60 | 61 | 62 | class g2gif: 63 | def __init__(self,fileName, outfile): 64 | self.last_pos = Vector3() 65 | self.last_pos.z = 999 66 | self.do_move = 1 67 | fileText = getFileText( fileName ) 68 | textLines = getTextLines( fileText ) 69 | self.images = [] 70 | self.image = None 71 | for line in textLines: 72 | self.parseLine( line ) 73 | self.images.append(self.image) 74 | # write GIF animation 75 | fp = open(outfile, "wb") 76 | makedelta(fp, self.images) 77 | fp.close() 78 | 79 | 80 | def parseLine(self, line): 81 | splitLine = line.split( ' ' ) 82 | if len( splitLine ) < 1: 83 | return 0 84 | firstWord = splitLine[ 0 ] 85 | if firstWord == 'G1': 86 | self.linearMove( splitLine ) 87 | if firstWord == 'M101': 88 | self.do_move = 1 89 | 90 | # Set the feedRate to the gcode split line. 91 | def setFeedRate( self, splitLine ): 92 | indexOfF = indexOfStartingWithSecond( "F", splitLine ) 93 | if indexOfF > 0: 94 | self.feedRateMinute = getDoubleAfterFirstLetter( splitLine[ indexOfF ] ) 95 | 96 | # Set a point to the gcode split line. 97 | def setPointComponent( self, point, splitLine ): 98 | point.x = getDoubleForLetter( "X", splitLine ) 99 | point.y = getDoubleForLetter( "Y", splitLine ) 100 | indexOfZ = indexOfStartingWithSecond( "Z", splitLine ) 101 | if indexOfZ > 0: 102 | point.z = getDoubleAfterFirstLetter( splitLine[ indexOfZ ] ) 103 | 104 | def scale( self, x, y ): 105 | return x * 5 + 150, - y * 5 + 100 106 | 107 | def linearMove( self, splitLine ): 108 | location = Vector3() 109 | self.setFeedRate( splitLine ) 110 | self.setPointComponent( location, splitLine ) 111 | if location.z != self.last_pos.z: 112 | if self.image: 113 | for i in xrange(10): 114 | self.images.append(self.image) 115 | self.image = Image.new('P', (300, 200), 255) 116 | palette = [] 117 | for red in xrange(8): 118 | for green in xrange(8): 119 | for blue in xrange(4): 120 | palette.extend((red * 255 / 7, green * 255 / 7, blue * 255 / 3)) 121 | self.image.putpalette(palette) 122 | self.segment = 0 123 | else: 124 | if self.do_move: 125 | draw = ImageDraw.Draw(self.image) 126 | draw.line( ( self.scale( self.last_pos.x, self.last_pos.y ), self.scale( location.x, location.y ) ), fill = 192 ) 127 | self.segment = self.segment + 1 128 | else: 129 | draw = ImageDraw.Draw(self.image) 130 | draw.line( ( self.scale( self.last_pos.x, self.last_pos.y ), self.scale(location.x, location.y ) ), fill = self.segment ) 131 | self.last_pos = location 132 | self.do_move = 0 133 | -------------------------------------------------------------------------------- /miscellaneous/nophead/gRead.py: -------------------------------------------------------------------------------- 1 | from vector3 import Vector3 2 | 3 | # Get the entire text of a file. 4 | # @param fileName name of the file 5 | # @return entire text of a file. 6 | def getFileText( fileName ): 7 | file = open( fileName, 'r' ) 8 | fileText = file.read() 9 | file.close() 10 | return fileText 11 | 12 | # Get the all the lines of text of a text. 13 | # @param text text 14 | # @return the lines of text of a text 15 | def getTextLines( text ): 16 | return text.replace( '\r', '\n' ).split( '\n' ) 17 | 18 | # Get the double value of the word after the first letter. 19 | # @param word string with value starting after the first letter 20 | # @return double value of the word after the first letter 21 | def getDoubleAfterFirstLetter( word ): 22 | return float( word[ 1 : ] ) 23 | 24 | # Get index of the first occurence of the given letter in the split line, starting with the second word. Return - 1 if letter is not found 25 | def indexOfStartingWithSecond( letter, splitLine ): 26 | for wordIndex in xrange( 1, len( splitLine ) ): 27 | word = splitLine[ wordIndex ] 28 | firstLetter = word[ 0 ] 29 | if firstLetter == letter: 30 | return wordIndex 31 | return - 1 32 | 33 | 34 | class gRead: 35 | def __init__(self,fileName, layers,gcodeText = ''): 36 | if gcodeText == '': 37 | gcodeText = getFileText( fileName ) 38 | textLines = getTextLines( gcodeText ) 39 | self.last_pos = Vector3() 40 | self.layers = layers 41 | self.layer = None 42 | self.thread = None 43 | self.skeinforge = 0 44 | self.max_z = -9999999999 45 | for line in textLines: 46 | self.parseLine( line ) 47 | self.newLayer() 48 | 49 | def parseLine(self, line): 50 | if line.startswith( "(" ): 51 | if line.startswith( "(" ): 52 | self.newLayer() 53 | return 54 | splitLine = line.split() 55 | if len( splitLine ) < 1: 56 | return 0 57 | firstWord = splitLine[ 0 ] 58 | if firstWord == 'G1': 59 | self.linearMove( splitLine ) 60 | if firstWord == 'M110': #filament height only sent by skeinforge at the moment 61 | self.skeinforge = 1 62 | self.newThread() 63 | if firstWord == 'M103': #extruder off 64 | if self.skeinforge: 65 | self.newThread() #end of thread if skeinforge 66 | if firstWord == 'G92': #offset coordinate system 67 | self.newThread() #for RepRap 68 | 69 | # Set a point to the gcode split line. 70 | def setPointComponent( self, point, splitLine ): 71 | indexOfX = indexOfStartingWithSecond( "X", splitLine ) 72 | if indexOfX > 0: 73 | point.x = getDoubleAfterFirstLetter( splitLine[ indexOfX ] ) 74 | indexOfY = indexOfStartingWithSecond( "Y", splitLine ) 75 | if indexOfY > 0: 76 | point.y = getDoubleAfterFirstLetter( splitLine[ indexOfY ] ) 77 | indexOfZ = indexOfStartingWithSecond( "Z", splitLine ) 78 | if indexOfZ > 0: 79 | point.z = getDoubleAfterFirstLetter( splitLine[ indexOfZ ] ) 80 | 81 | def newLayer(self): 82 | self.newThread() 83 | if self.layer: 84 | self.layers.append(self.layer) 85 | self.layer = [] 86 | 87 | def newThread(self): 88 | if self.thread: 89 | self.layer.append(self.thread) 90 | self.thread = [] 91 | 92 | def linearMove( self, splitLine ): 93 | if self.thread != None: 94 | pos = self.last_pos.copy() 95 | self.setPointComponent( pos, splitLine ) 96 | if pos.z > self.max_z: 97 | # self.newLayer() 98 | self.max_z = pos.z 99 | if pos.z < self.last_pos.z: 100 | self.newThread() 101 | if self.skeinforge or pos.z < self.max_z: 102 | self.thread.append(pos) 103 | self.last_pos = pos 104 | -------------------------------------------------------------------------------- /miscellaneous/nophead/layers.py: -------------------------------------------------------------------------------- 1 | from vector3 import Vector3 2 | import Image, ImageDraw 3 | 4 | def bounding_cube(layers): 5 | min_x = 999999 6 | min_y = 999999 7 | min_z = 999999 8 | max_x = -999999 9 | max_y = -999999 10 | max_z = -999999 11 | for layer in layers: 12 | for thread in layer: 13 | for point in thread: 14 | if point.x > max_x: 15 | max_x = point.x 16 | if point.y > max_y: 17 | max_y = point.y 18 | if point.z > max_z: 19 | max_z = point.z 20 | if point.x < min_x: 21 | min_x = point.x 22 | if point.y < min_y: 23 | min_y = point.y 24 | if point.z < min_z: 25 | min_z = point.z 26 | return Vector3(min_x, min_y, min_z), Vector3(max_x, max_y, max_z) 27 | 28 | def make_images(layers): 29 | palette = [] 30 | for i in xrange(256): 31 | #resistor colour codes 32 | if i == 1: 33 | palette.extend((134, 100, 57)) # brown 34 | elif i == 2: 35 | palette.extend((255, 0, 0)) # red 36 | elif i == 3: 37 | palette.extend((218, 90, 35)) # orange 38 | elif i == 4: 39 | palette.extend((255, 255, 0)) # yellow 40 | elif i == 5: 41 | palette.extend(( 0, 255, 0)) # green 42 | elif i == 6: 43 | palette.extend(( 0, 0, 255)) # blue 44 | elif i == 7: 45 | palette.extend((255, 0, 255)) # purple 46 | else: 47 | palette.extend((i, i, i)) # shades of grey 48 | cube = bounding_cube(layers) 49 | scale = 10 50 | x0 = int(cube[0].x) - 1 51 | y0 = int(cube[0].y) - 1 52 | width = int(round(cube[1].x - x0) + 1) * scale 53 | height = int(round(cube[1].y - y0) + 1) * scale 54 | last_pos = None 55 | images = [] 56 | for layer in layers: 57 | image = Image.new('P', (width, height), 255) 58 | image.putpalette(palette) 59 | draw = ImageDraw.Draw(image) 60 | segment = 0 61 | for thread in layer: 62 | if last_pos != None: 63 | draw.line(((( last_pos.x - x0) * scale, height - ( last_pos.y - y0) * scale), 64 | ((thread[0].x - x0) * scale, height - (thread[0].y - y0) * scale)), fill = 128) 65 | last_pos = thread[ 0 ].copy() 66 | for point in thread[1:]: 67 | draw.line((((last_pos.x - x0) * scale, height - (last_pos.y - y0) * scale), 68 | ( (point.x - x0) * scale, height - (point.y - y0) * scale)), fill = segment % 8) 69 | last_pos = point.copy() 70 | segment = segment + 1 71 | images.append(image) 72 | return images 73 | -------------------------------------------------------------------------------- /miscellaneous/nophead/preview.py: -------------------------------------------------------------------------------- 1 | import sys 2 | try: 3 | import Tkinter 4 | except: 5 | print( 'You do not have Tkinter, which is needed for the graphical interface.' ) 6 | print( 'Information on how to download Tkinter is at:\nwww.tcl.tk/software/tcltk/' ) 7 | try: 8 | from layers import * 9 | from gRead import * 10 | import ImageTk 11 | except: 12 | print( 'You do not have the Python Imaging Library, which is needed by preview and gifview to view the gcode.' ) 13 | print( 'The Python Imaging Library can be downloaded from:\nwww.pythonware.com/products/pil/' ) 14 | 15 | class Preview: 16 | def __init__(self, layers): 17 | self.images = make_images(layers) 18 | self.index = 0 19 | size = self.images[0].size 20 | self.root = Tkinter.Tk() 21 | self.root.title("Gifscene from HydraRaptor") 22 | frame = Tkinter.Frame(self.root) 23 | frame.pack() 24 | self.canvas = Tkinter.Canvas(frame, width = size[0], height = size[1]) 25 | self.canvas.pack() 26 | self.canvas.config(scrollregion=self.canvas.bbox(Tkinter.ALL)) 27 | self.exit_button = Tkinter.Button(frame, text = "Exit", fg = "red", command = frame.quit) 28 | self.exit_button.pack(side=Tkinter.RIGHT) 29 | self.down_button = Tkinter.Button(frame, text = "Down", command = self.down) 30 | self.down_button.pack(side=Tkinter.LEFT) 31 | self.up_button = Tkinter.Button(frame, text = "Up", command = self.up) 32 | self.up_button.pack(side=Tkinter.LEFT) 33 | self.update() 34 | self.root.mainloop() 35 | 36 | def update(self): 37 | # FIXME: Somehow this fails if this is launched using the Preferences, 38 | # but works from the command-line. 39 | self.image = ImageTk.PhotoImage(self.images[self.index]) 40 | self.canvas.create_image(0,0, anchor= Tkinter.NW, image = self.image) 41 | if self.index < len(self.images) - 1: 42 | self.up_button.config(state = Tkinter.NORMAL) 43 | else: 44 | self.up_button.config(state = Tkinter.DISABLED) 45 | if self.index > 0: 46 | self.down_button.config(state = Tkinter.NORMAL) 47 | else: 48 | self.down_button.config(state = Tkinter.DISABLED) 49 | 50 | def up(self): 51 | self.index += 1 52 | self.update() 53 | 54 | def down(self): 55 | self.index -= 1 56 | self.update() 57 | 58 | 59 | def viewGif( fileName, gcodeText = '' ): 60 | layers = [] 61 | try: 62 | gRead(fileName, layers, gcodeText) 63 | Preview(layers) 64 | except Exception, why: 65 | print( 'Preview failed: ' + str( why ) ) 66 | 67 | 68 | if __name__ == "__main__": 69 | viewGif( ' '.join( sys.argv[ 1 : ] ) ) 70 | -------------------------------------------------------------------------------- /models/box.obj: -------------------------------------------------------------------------------- 1 | # ----------------- 2 | # Start of obj file 3 | g Box01 4 | mtllib box.mat 5 | usemtl box 6 | v -62.0579 -41.4791 0.0 7 | v 58.8424 -41.4791 0.0 8 | v -62.0579 22.1865 0.0 9 | v 58.8424 22.1865 0.0 10 | v -62.0579 -41.4791 39.8714 11 | v 58.8424 -41.4791 39.8714 12 | v -62.0579 22.1865 39.8714 13 | v 58.8424 22.1865 39.8714 14 | 15 | vt 0.843206 0.405444 0.000499517 16 | vt 0.482802 0.71377 0.9995 17 | vt 0.478066 0.404023 0.000499636 18 | vt 0.482802 0.716612 0.9995 19 | vt 0.841627 0.688332 0.000499517 20 | vt 0.482013 0.981029 0.9995 21 | vt 0.480434 0.688332 0.000499636 22 | vt 0.485959 0.978188 0.9995 23 | vt 0.450102 0.00618343 0.000499547 24 | vt 0.45247 0.509304 0.000499547 25 | vt 0.000499517 0.512146 0.000499547 26 | vt 0.000499517 0.512146 0.000499547 27 | vt -0.0010791 0.00618302 0.000499547 28 | vt 0.450102 0.00618343 0.000499547 29 | vt 0.000499517 0.512009 0.9995 30 | vt 0.450891 0.510588 0.9995 31 | vt 0.45247 0.995237 0.9995 32 | vt 0.45247 0.996658 0.9995 33 | vt 0.000499636 0.9995 0.9995 34 | vt 0.000499517 0.51343 0.9995 35 | vt 0.478855 0.405444 0.000500023 36 | vt 0.841627 0.408286 0.000499576 37 | vt 0.83847 0.688332 0.000499576 38 | vt 0.83847 0.688332 0.000499576 39 | vt 0.477276 0.694016 0.000500023 40 | vt 0.478855 0.405444 0.000500023 41 | vt 0.482802 0.71377 0.9995 42 | vt 0.845574 0.71377 0.999501 43 | vt 0.844784 0.976767 0.999501 44 | vt 0.844784 0.976767 0.999501 45 | vt 0.482802 0.716612 0.9995 46 | vt 0.842417 0.710929 0.9995 47 | vt 0.843995 0.975346 0.9995 48 | vt 0.843995 0.975346 0.9995 49 | vt 0.478066 0.404023 0.000499636 50 | vt 0.841627 0.688332 0.000499517 51 | 52 | vn 0.0 0.0 -1.0 53 | vn 0.0 0.0 -1.0 54 | vn 0.0 0.0 1.0 55 | vn 0.0 0.0 1.0 56 | vn 0.0 -1.0 0.0 57 | vn 0.0 -1.0 0.0 58 | vn 1.0 0.0 0.0 59 | vn 1.0 0.0 0.0 60 | vn 0.0 1.0 0.0 61 | vn 0.0 1.0 0.0 62 | vn -1.0 0.0 0.0 63 | vn -1.0 0.0 0.0 64 | 65 | f 1/9/1 3/10/1 4/11/1 66 | f 4/12/2 2/13/2 1/14/2 67 | f 5/15/3 6/16/3 8/17/3 68 | f 8/18/4 7/19/4 5/20/4 69 | f 1/21/5 2/22/5 6/23/5 70 | f 6/24/6 5/25/6 1/26/6 71 | f 2/27/7 4/28/7 8/29/7 72 | f 8/30/8 6/6/8 2/2/8 73 | f 4/31/9 3/32/9 7/33/9 74 | f 7/34/10 8/8/10 4/4/10 75 | f 3/35/11 1/1/11 5/36/11 76 | f 5/5/12 7/7/12 3/3/12 77 | 78 | # end of obj file 79 | # --------------- 80 | -------------------------------------------------------------------------------- /models/circular_wave.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | The py.py script is an import translator plugin to get a carving from a python script. 4 | 5 | An explanation of the SLC format can be found at: 6 | http://rapid.lpt.fi/archives/rp-ml-1999/0713.html 7 | 8 | An import plugin is a script in the import_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. 9 | 10 | The getCarving function takes the file name of a python script and returns the carving. 11 | 12 | This example gets a carving for the python script circular_wave.py. This example is run in a terminal in the folder which contains circular_wave.py and py.py. 13 | 14 | 15 | > python 16 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 17 | [GCC 4.2.1 (SUSE Linux)] on linux2 18 | Type "help", "copyright", "credits" or "license" for more information. 19 | >>> import py 20 | >>> py.getCarving() 21 | 0.20000000298, 999999999.0, -999999999.0, [8.72782748851e-17, None 22 | .. 23 | many more lines of the carving 24 | .. 25 | 26 | 27 | """ 28 | 29 | 30 | from __future__ import absolute_import 31 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 32 | import __init__ 33 | 34 | import math 35 | 36 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 37 | __credits__ = 'Nophead \nArt of Illusion ' 38 | __date__ = "$Date: 2008/21/04 $" 39 | __license__ = "GPL 3.0" 40 | 41 | 42 | def getLoopLayers( layerThickness ): 43 | "Get the loop layers." 44 | return CircularWave( layerThickness ).getLoopLayers() 45 | 46 | 47 | class LoopLayer: 48 | "Loops with a z." 49 | def __init__( self, z ): 50 | self.loops = [] 51 | self.z = z 52 | 53 | def __repr__( self ): 54 | "Get the string representation of this loop layer." 55 | return '%s, %s' % ( self.z, self.loops ) 56 | 57 | 58 | class CircularWave: 59 | "A twisted circular wave." 60 | def __init__( self, layerThickness ): 61 | "Initialize." 62 | self.layerThickness = layerThickness 63 | self.loopLayers = [] 64 | self.setRootParameters() 65 | self.setDerivedParameters() 66 | for layerIndex in xrange( self.numberOfLayers ): 67 | self.addLoopLayer( layerIndex ) 68 | 69 | def __repr__( self ): 70 | "Get the string representation of this carving." 71 | return '%s, %s, %s, %s' % ( self.layerThickness, self.minimumZ, self.maximumZ, self.rotatedBoundaryLayers ) 72 | 73 | def addLoopLayer( self, layerIndex ): 74 | "Add a loop layer." 75 | z = self.halfLayerThickness + layerIndex * self.layerThickness 76 | loopLayer = LoopLayer( z ) 77 | loop = [] 78 | for pointIndex in xrange( self.numberOfPoints ): 79 | twist = self.twist * z / self.height 80 | self.addPoint( loop, pointIndex, twist ) 81 | loopLayer.loops.append( loop ) 82 | self.loopLayers.append( loopLayer ) 83 | 84 | def addPoint( self, loop, pointIndex, twist ): 85 | "Add a point." 86 | rotation = - self.rotationIncrement * pointIndex 87 | waveRotation = rotation * float( self.numberOfWaves ) 88 | radius = self.midRadius + math.sin( waveRotation ) * self.halfRingWidth 89 | twistedRotation = rotation + twist 90 | point = complex( math.cos( twistedRotation ), - math.sin( twistedRotation ) ) * radius 91 | loop.append( point ) 92 | 93 | def getLoopLayers( self ): 94 | "Get the loop layers." 95 | return self.loopLayers 96 | 97 | def setDerivedParameters( self ): 98 | "Set the derived parameters." 99 | self.halfLayerThickness = 0.5 * self.layerThickness 100 | self.innerRadius = self.innerRadiusRatio * self.radius 101 | self.midRadius = 0.5 * ( self.innerRadius + self.radius ) 102 | self.halfRingWidth = self.radius - self.midRadius 103 | self.numberOfLayers = max( 1, int( round( self.height / self.layerThickness ) ) ) 104 | self.rotationIncrement = 2.0 * math.pi / float( self.numberOfPoints ) 105 | 106 | def setRootParameters( self ): 107 | "Set the root parameters." 108 | self.height = 10.0 109 | self.innerRadiusRatio = 0.5 110 | self.numberOfPoints = 40 111 | self.numberOfWaves = 3 112 | self.radius = 10.0 113 | self.twist = math.radians( 30.0 ) 114 | 115 | 116 | def main(): 117 | "Display the inset dialog." 118 | if len( sys.argv ) > 1: 119 | getCarving( ' '.join( sys.argv[ 1 : ] ) ) 120 | 121 | if __name__ == "__main__": 122 | main() 123 | -------------------------------------------------------------------------------- /runskeinforge.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Utility script for keeping track of which preference settings a file was processed 5 | # with, by copying the current preferences to a date-tagged directory together 6 | # with the output files. 7 | # 8 | # Usage: runskeinforge.sh 9 | # 10 | 11 | dir=`dirname $1` 12 | file=`basename $1` 13 | 14 | for s in .gts .GTS .stl .STL; do 15 | if [ ! `basename $file $s` = $file ]; then suffix=$s; fi 16 | done 17 | 18 | if [ -n $suffix ]; then 19 | filename=`basename $file $suffix` 20 | newdir=$filename-`date +%m%d%H%M` 21 | mkdir -p $newdir/skeinforge-prefs 22 | cp $1 $newdir 23 | cp ~/.skeinforge/*.csv $newdir/skeinforge-prefs 24 | python skeinforge.py $newdir/$filename$suffix 25 | echo $PWD/$newdir/${filename}_export.gcode 26 | fi 27 | -------------------------------------------------------------------------------- /show_skeinforge.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # Script to show the skeinforge dialog. 4 | # 5 | # Usage: set the executable property to true if it isn't already. Then double click the file. 6 | # 7 | import skeinforge 8 | skeinforge.main() 9 | -------------------------------------------------------------------------------- /skeinforge.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from __future__ import absolute_import 4 | 5 | from skeinforge_tools import craft 6 | from skeinforge_tools import profile 7 | from skeinforge_tools.meta_plugins import polyfile 8 | from skeinforge_tools.skeinforge_utilities import euclidean 9 | from skeinforge_tools.skeinforge_utilities import gcodec 10 | from skeinforge_tools.skeinforge_utilities import settings 11 | from skeinforge_tools.skeinforge_utilities import interpret 12 | import os 13 | import sys 14 | 15 | 16 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 17 | __credits__ = """ 18 | Adrian Bowyer 19 | Brendan Erwin 20 | Greenarrow 21 | Ian England 22 | John Gilmore 23 | Jonwise 24 | Kyle Corbitt 25 | Michael Duffin 26 | Marius Kintel 27 | Nophead 28 | PJR 29 | Reece.Arnott 30 | Wade 31 | Xsainnz 32 | Zach Hoeken 33 | 34 | Organizations: 35 | Art of Illusion """ 36 | __date__ = "$Date: 2008/21/11 $" 37 | __license__ = "GPL 3.0" 38 | 39 | 40 | def addToProfileMenu( profileSelection, profileType, repository ): 41 | "Add a profile menu." 42 | pluginFileNames = profile.getPluginFileNames() 43 | craftTypeName = profile.getCraftTypeName() 44 | pluginModule = profile.getCraftTypePluginModule() 45 | profilePluginSettings = settings.getReadRepository( pluginModule.getNewRepository() ) 46 | for pluginFileName in pluginFileNames: 47 | profile.ProfileTypeMenuRadio().getFromMenuButtonDisplay( profileType, pluginFileName, repository, craftTypeName == pluginFileName ) 48 | for profileName in profilePluginSettings.profileList.value: 49 | profile.ProfileSelectionMenuRadio().getFromMenuButtonDisplay( profileSelection, profileName, repository, profileName == profilePluginSettings.profileListbox.value ) 50 | 51 | def getPluginsDirectoryPath(): 52 | "Get the plugins directory path." 53 | return gcodec.getAbsoluteFolderPath( __file__, 'skeinforge_tools' ) 54 | 55 | def getPluginFileNames(): 56 | "Get analyze plugin fileNames." 57 | return gcodec.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() ) 58 | 59 | def getNewRepository(): 60 | "Get the repository constructor." 61 | return SkeinforgeRepository() 62 | 63 | def writeOutput( fileName = '' ): 64 | "Craft a gcode file." 65 | craft.writeOutput( fileName ) 66 | 67 | 68 | class SkeinforgeRepository: 69 | "A class to handle the skeinforge settings." 70 | def __init__( self ): 71 | "Set the default settings, execute title & settings fileName." 72 | settings.addListsToRepository( 'skeinforge.html', '', self ) 73 | self.fileNameInput = settings.FileNameInput().getFromFileName( interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Skeinforge', self, '' ) 74 | versionText = gcodec.getFileText( gcodec.getVersionFileName() ) 75 | self.createdOnLabel = settings.LabelDisplay().getFromName( 'Created On: ' + versionText, self ) 76 | self.profileType = settings.MenuButtonDisplay().getFromName( 'Profile Type: ', self ) 77 | self.profileSelection = settings.MenuButtonDisplay().getFromName( 'Profile Selection: ', self ) 78 | addToProfileMenu( self.profileSelection, self.profileType, self ) 79 | settings.LabelDisplay().getFromName( '', self ) 80 | self.skeinforgeLabel = settings.LabelDisplay().getFromName( 'Open Settings: ', self ) 81 | importantFileNames = [ 'craft', 'profile' ] 82 | settings.getDisplayToolButtonsRepository( gcodec.getAbsoluteFolderPath( __file__, 'skeinforge_tools' ), importantFileNames, getPluginFileNames(), self ) 83 | self.executeTitle = 'Skeinforge' 84 | 85 | def execute( self ): 86 | "Skeinforge button has been clicked." 87 | fileNames = polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled ) 88 | for fileName in fileNames: 89 | writeOutput( fileName ) 90 | 91 | def save( self ): 92 | "Profile has been saved and profile menu should be updated." 93 | self.profileType.removeMenus() 94 | self.profileSelection.removeMenus() 95 | addToProfileMenu( self.profileSelection, self.profileType, self ) 96 | self.profileType.addRadiosToDialog( self.repositoryDialog ) 97 | self.profileSelection.addRadiosToDialog( self.repositoryDialog ) 98 | 99 | 100 | def main(): 101 | "Display the skeinforge dialog." 102 | if len( sys.argv ) > 1: 103 | writeOutput( ' '.join( sys.argv[ 1 : ] ) ) 104 | else: 105 | settings.startMainLoopFromConstructor( getNewRepository() ) 106 | 107 | if __name__ == "__main__": 108 | main() 109 | -------------------------------------------------------------------------------- /skeinforge_tools/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 1 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/alterations/example_cool_end.gcode: -------------------------------------------------------------------------------- 1 | (this is a sample cool end file, it must be renamed cool_end.gcode for skeinforge to recognize it) 2 | M107 3 | -------------------------------------------------------------------------------- /skeinforge_tools/alterations/example_cool_start.gcode: -------------------------------------------------------------------------------- 1 | (this is a sample cool start file, it must be renamed cool_start.gcode for skeinforge to recognize it) 2 | M106 3 | -------------------------------------------------------------------------------- /skeinforge_tools/alterations/example_end.gcode: -------------------------------------------------------------------------------- 1 | (this is a sample gcode end file, it must be renamed end.gcode for skeinforge to recognize it) 2 | M2 3 | -------------------------------------------------------------------------------- /skeinforge_tools/alterations/example_homing.gcode: -------------------------------------------------------------------------------- 1 | (this is a sample gcode homing file, it must be renamed homing.gcode for skeinforge to recognize it) 2 | G1 X-250.0 3 | G92 X0 ;set x 0 4 | G1 Y-250.0 5 | G92 Y0 ;set y 0 6 | -------------------------------------------------------------------------------- /skeinforge_tools/alterations/example_replace.csv: -------------------------------------------------------------------------------- 1 | G1,G0 2 | M101,M121 3 | M103,M123 4 | -------------------------------------------------------------------------------- /skeinforge_tools/alterations/example_start.gcode: -------------------------------------------------------------------------------- 1 | (This is a sample gcode start file, it must be renamed start.gcode for skeinforge to recognize it. Also, to remove confusion this comment line should be deleted.) 2 | G28 3 | -------------------------------------------------------------------------------- /skeinforge_tools/alterations/example_support_end.gcode: -------------------------------------------------------------------------------- 1 | (this is a sample support end file, it must be renamed support_end.gcode for skeinforge to recognize it) 2 | 3 | -------------------------------------------------------------------------------- /skeinforge_tools/alterations/example_support_start.gcode: -------------------------------------------------------------------------------- 1 | (this is a sample support start file, it must be renamed support_start.gcode for skeinforge to recognize it) 2 | 3 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Analyze is a script to access the plugins which analyze a gcode file. 4 | 5 | The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight. 6 | 7 | ==Gcodes== 8 | An explanation of the gcodes is at: 9 | http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter 10 | 11 | and at: 12 | http://reprap.org/bin/view/Main/MCodeReference 13 | 14 | A gode example is at: 15 | http://forums.reprap.org/file.php?12,file=565 16 | 17 | """ 18 | 19 | from __future__ import absolute_import 20 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 21 | import __init__ 22 | 23 | from skeinforge_tools.skeinforge_utilities import gcodec 24 | from skeinforge_tools.skeinforge_utilities import settings 25 | from skeinforge_tools.meta_plugins import polyfile 26 | import os 27 | import sys 28 | 29 | 30 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 31 | __date__ = "$Date: 2008/21/04 $" 32 | __license__ = "GPL 3.0" 33 | 34 | 35 | def addToMenu( master, menu, repository, window ): 36 | "Add a tool plugin menu." 37 | settings.addPluginsParentToMenu( getPluginsDirectoryPath(), menu, __file__, getPluginFileNames() ) 38 | 39 | def getPluginFileNames(): 40 | "Get analyze plugin fileNames." 41 | return gcodec.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() ) 42 | 43 | def getPluginsDirectoryPath(): 44 | "Get the plugins directory path." 45 | return gcodec.getAbsoluteFolderPath( __file__, 'analyze_plugins' ) 46 | 47 | def getNewRepository(): 48 | "Get the repository constructor." 49 | return AnalyzeRepository() 50 | 51 | def writeOutput( fileName, gcodeText = '' ): 52 | "Analyze a gcode file." 53 | gcodeText = gcodec.getTextIfEmpty( fileName, gcodeText ) 54 | pluginFileNames = getPluginFileNames() 55 | for pluginFileName in pluginFileNames: 56 | analyzePluginsDirectoryPath = getPluginsDirectoryPath() 57 | pluginModule = gcodec.getModuleWithDirectoryPath( analyzePluginsDirectoryPath, pluginFileName ) 58 | if pluginModule != None: 59 | pluginModule.writeOutput( fileName, gcodeText ) 60 | 61 | 62 | class AnalyzeRepository: 63 | "A class to handle the analyze settings." 64 | def __init__( self ): 65 | "Set the default settings, execute title & settings fileName." 66 | settings.addListsToRepository( 'skeinforge_tools.analyze.html', '', self ) 67 | self.fileNameInput = settings.FileNameInput().getFromFileName( [ ( 'Gcode text files', '*.gcode' ) ], 'Open File for Analyze', self, '' ) 68 | importantFileNames = [ 'skeinview', 'behold', 'statistic' ] 69 | settings.getRadioPluginsAddPluginFrame( getPluginsDirectoryPath(), importantFileNames, getPluginFileNames(), self ) 70 | self.executeTitle = 'Analyze' 71 | 72 | def execute( self ): 73 | "Analyze button has been clicked." 74 | fileNames = polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, [], self.fileNameInput.wasCancelled ) 75 | for fileName in fileNames: 76 | writeOutput( fileName ) 77 | 78 | 79 | def main(): 80 | "Display the analyze dialog." 81 | if len( sys.argv ) > 1: 82 | writeOutput( ' '.join( sys.argv[ 1 : ] ) ) 83 | else: 84 | settings.startMainLoopFromConstructor( getNewRepository() ) 85 | 86 | if __name__ == "__main__": 87 | main() 88 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze_plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 2 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze_plugins/analyze_utilities/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 3 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze_plugins/analyze_utilities/display_line.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Display line is a mouse tool to select and display information about the line. 4 | 5 | When a line is clicked, the line will be selected and information about the line will be displayed. If a gcode line is clicked, the information will be file line count of the line clicked, counting from one, and the line itself. 6 | 7 | When the display line tool is chosen and the canvas has the focus, display line will listen to the arrow keys. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. When the right arrow key is pressed, display line will increase the line index of the layer by one, and change the selection accordingly. If the line index of the layer goes over the index of the last line, the layer index will be increased by one and the new line index will be zero. When the left arrow key is pressed, the index will be decreased. If the line index goes below the index of the first line, the layer index will be decreased by one and the new line index will be at the last line. The up arrow key increases the layer index by one and the down arow key decreases the line index. 8 | 9 | """ 10 | 11 | from __future__ import absolute_import 12 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 13 | import __init__ 14 | 15 | from skeinforge_tools.analyze_plugins.analyze_utilities.mouse_tool_base import MouseToolBase 16 | from skeinforge_tools.skeinforge_utilities import gcodec 17 | from skeinforge_tools.skeinforge_utilities import settings 18 | 19 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 20 | __date__ = "$Date: 2008/21/04 $" 21 | __license__ = "GPL 3.0" 22 | 23 | 24 | def getNewMouseTool(): 25 | "Get a new mouse tool." 26 | return DisplayLine() 27 | 28 | 29 | class DisplayLine( MouseToolBase ): 30 | "Display the line when it is clicked." 31 | def button1( self, event, shift = False ): 32 | "Print line text and connection line." 33 | self.destroyEverythingGetFocus() 34 | x = self.canvas.canvasx( event.x ) 35 | y = self.canvas.canvasy( event.y ) 36 | tags = self.getTagsGivenXY( x, y ) 37 | if tags == '': 38 | return 39 | if gcodec.getHasPrefix( tags, 'colored_line_index:' ): 40 | splitLine = tags.split() 41 | coloredLineIndex = int( splitLine[ 1 ] ) 42 | self.repository.line.value = coloredLineIndex 43 | tags = self.getSelectedColoredLine().displayString 44 | self.drawLineText( complex( float( x ), float( y ) ), tags ) 45 | 46 | def drawLineText( self, location, tags ): 47 | "Draw the line text." 48 | self.window.getDrawnLineText( location, 'mouse_item', tags ) 49 | 50 | def drawSelectedColoredLineText( self ): 51 | "Draw the selected line and text." 52 | selectedColoredLine = self.getSelectedColoredLine() 53 | if len( self.canvas.find_withtag( 'mouse_item' ) ) < 1 or selectedColoredLine == None: 54 | return 55 | tags = selectedColoredLine.displayString 56 | lineCoordinates = self.canvas.coords( self.canvas.find_withtag( 'mouse_item' )[ - 1 ] ) 57 | begin = complex( lineCoordinates[ 0 ], lineCoordinates[ 1 ] ) 58 | end = complex( lineCoordinates[ 2 ], lineCoordinates[ 3 ] ) 59 | segment = end - begin 60 | segmentLength = abs( segment ) 61 | if segmentLength <= 0.0: 62 | return 63 | towardEnd = 0.75 * segment 64 | segmentClockwise = 20.0 * complex( segment.imag, - segment.real ) / segmentLength 65 | location = begin + towardEnd + segmentClockwise 66 | self.drawLineText( location, tags ) 67 | 68 | def getSelectedColoredLine( self ): 69 | "Draw the selected line, add it to the items and return the colored line." 70 | self.window.cancelTimerResetButtons() 71 | coloredLines = self.window.getColoredLines() 72 | self.repository.line.value = max( 0, self.repository.line.value ) 73 | if len( coloredLines ) < 1: 74 | return None 75 | self.repository.line.value = min( len( coloredLines ) - 1, self.repository.line.value ) 76 | coloredLine = coloredLines[ self.repository.line.value ] 77 | lineCoordinates = self.canvas.coords( self.window.getDrawnSelectedColoredLine( coloredLine ) ) 78 | end = complex( lineCoordinates[ 2 ], lineCoordinates[ 3 ] ) 79 | radiusComplex = complex( 16.0, 16.0 ) 80 | upperLeft = end - radiusComplex 81 | lowerRight = end + radiusComplex 82 | self.canvas.create_oval ( int( upperLeft.real ), int( upperLeft.imag ), int( lowerRight.real ), int( lowerRight.imag ), tags = 'mouse_item' ) 83 | settings.setEntryText( self.window.lineEntry, self.repository.line.value ) 84 | self.window.setLineButtonsState() 85 | return coloredLine 86 | 87 | def isSelectionTool( self ): 88 | "Return if this mouse tool is a selection tool." 89 | return True 90 | 91 | def keyPressDown( self, event ): 92 | "The down arrow was pressed." 93 | self.destroyEverything() 94 | self.window.setLayerIndex( self.repository.layer.value - 1 ) 95 | 96 | def keyPressLeft( self, event ): 97 | "The left arrow was pressed." 98 | self.destroyEverything() 99 | self.repository.line.value -= 1 100 | if self.window.isLineBelowZeroSetLayer(): 101 | return 102 | self.drawSelectedColoredLineText() 103 | 104 | def keyPressRight( self, event ): 105 | "The right arrow was pressed." 106 | self.destroyEverything() 107 | self.repository.line.value += 1 108 | if self.window.isLineBeyondListSetLayer(): 109 | return 110 | self.drawSelectedColoredLineText() 111 | 112 | def keyPressUp( self, event ): 113 | "The up arrow was pressed." 114 | self.destroyEverything() 115 | self.window.setLayerIndex( self.repository.layer.value + 1 ) 116 | 117 | def update( self ): 118 | "Update the mouse tool." 119 | self.destroyEverything() 120 | self.drawSelectedColoredLineText() 121 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze_plugins/analyze_utilities/mouse_tool_base.py: -------------------------------------------------------------------------------- 1 | """ 2 | Display line is a mouse tool to display the line index of the line clicked, counting from one, and the line itself. 3 | 4 | """ 5 | 6 | from __future__ import absolute_import 7 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 8 | import __init__ 9 | 10 | 11 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 12 | __date__ = "$Date: 2008/21/04 $" 13 | __license__ = "GPL 3.0" 14 | 15 | 16 | class MouseToolBase: 17 | "The mouse tool base class, which does nothing." 18 | def button1( self, event ): 19 | "The left button was clicked, function." 20 | pass 21 | 22 | def buttonRelease1( self, event ): 23 | "The left button was released, function." 24 | pass 25 | 26 | def destroyEverything( self ): 27 | "Destroy items." 28 | self.canvas.delete( 'mouse_item' ) 29 | 30 | def destroyEverythingGetFocus( self ): 31 | "Destroy items and get the focus for the canvas." 32 | self.destroyEverything() 33 | self.canvas.focus_set() 34 | 35 | def getReset( self, window ): 36 | "Reset the mouse tool to default." 37 | self.setWindowItems( window ) 38 | self.destroyEverything() 39 | return self 40 | 41 | def getTagsGivenXY( self, x, y ): 42 | "Get the tag for the x and y." 43 | tags = self.canvas.itemcget( self.canvas.find_closest( x, y ), 'tags' ) 44 | currentEnd = ' current' 45 | if tags.find( currentEnd ) != - 1: 46 | return tags[ : - len( currentEnd ) ] 47 | return tags 48 | 49 | def isSelectionTool( self ): 50 | "Return if this mouse tool is a selection tool." 51 | return False 52 | 53 | def keyPressDown( self, event ): 54 | "The down arrow was pressed." 55 | pass 56 | 57 | def keyPressLeft( self, event ): 58 | "The left arrow was pressed." 59 | pass 60 | 61 | def keyPressReturn( self, event ): 62 | "The return key was pressed." 63 | pass 64 | 65 | def keyPressRight( self, event ): 66 | "The right arrow was pressed." 67 | pass 68 | 69 | def keyPressUp( self, event ): 70 | "The up arrow was pressed." 71 | pass 72 | 73 | def motion( self, event, shift = False ): 74 | "The mouse moved, function." 75 | pass 76 | 77 | def setWindowItems( self, window ): 78 | "Set the canvas and items." 79 | self.canvas = window.canvas 80 | self.repository = window.repository 81 | self.window = window 82 | 83 | def update( self ): 84 | "Update the mouse tool." 85 | pass 86 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze_plugins/analyze_utilities/view_move.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Viewpoint move is a mouse tool to move the viewpoint in the xy plane. 4 | 5 | When the mouse is clicked and dragged on the canvas, viewpoint move will drag the scroll pane accordingly. If the shift key is also pressed, the scroll pane will be moved only in the x or y direction, whichever is largest. 6 | 7 | When the viewpoint move tool is chosen and the canvas has the focus, viewpoint move will listen to the arrow keys. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. When the right arrow key is pressed, viewpoint move will move the scroll pane to the right by a pixel. When the left arrow key is pressed, the scroll pane will be moved a pixel to the left. The up arrow key moves the scroll pane a pixel up and the down arow key moves the scroll pane a pixel down. 8 | 9 | """ 10 | 11 | from __future__ import absolute_import 12 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 13 | import __init__ 14 | 15 | from skeinforge_tools.analyze_plugins.analyze_utilities.mouse_tool_base import MouseToolBase 16 | from skeinforge_tools.skeinforge_utilities import settings 17 | 18 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 19 | __date__ = "$Date: 2008/21/04 $" 20 | __license__ = "GPL 3.0" 21 | 22 | 23 | def getNewMouseTool(): 24 | "Get a new mouse tool." 25 | return ViewpointMove() 26 | 27 | 28 | class ViewpointMove( MouseToolBase ): 29 | "Display the line when it is clicked." 30 | def button1( self, event, shift = False ): 31 | "Print line text and connection line." 32 | self.destroyEverythingGetFocus() 33 | self.buttonOnePressedScreenCoordinate = complex( event.x, event.y ) 34 | self.scrollPaneFraction = self.window.getScrollPaneFraction() 35 | 36 | def buttonRelease1( self, event, shift = False ): 37 | "The left button was released, function." 38 | self.destroyEverything() 39 | 40 | def destroyEverything( self ): 41 | "Destroy items." 42 | self.buttonOnePressedScreenCoordinate = None 43 | 44 | def keyPressDown( self, event ): 45 | "The down arrow was pressed." 46 | self.setScrollPaneMove( complex( 0.0, 1.0 ) ) 47 | 48 | def keyPressLeft( self, event ): 49 | "The left arrow was pressed." 50 | self.setScrollPaneMove( complex( - 1.0, 0.0 ) ) 51 | 52 | def keyPressRight( self, event ): 53 | "The right arrow was pressed." 54 | self.setScrollPaneMove( complex( 1.0, 0.0 ) ) 55 | 56 | def keyPressUp( self, event ): 57 | "The up arrow was pressed." 58 | self.setScrollPaneMove( complex( 0.0, - 1.0 ) ) 59 | 60 | def motion( self, event, shift = False ): 61 | "The mouse moved, function." 62 | if self.buttonOnePressedScreenCoordinate == None: 63 | return 64 | motionCoordinate = complex( event.x, event.y ) 65 | relativeMotion = motionCoordinate - self.buttonOnePressedScreenCoordinate 66 | if shift: 67 | if abs( relativeMotion.real ) > abs( relativeMotion.imag ): 68 | relativeMotion = complex( relativeMotion.real, 0.0 ) 69 | else: 70 | relativeMotion = complex( 0.0, relativeMotion.imag ) 71 | self.relativeMove( relativeMotion ) 72 | 73 | def relativeMove( self, relativeMotion ): 74 | "Move the view given the relative motion." 75 | relativeScreenMotion = complex( relativeMotion.real / float( self.window.screenSize.real ), relativeMotion.imag / float( self.window.screenSize.imag ) ) 76 | moveTo = self.scrollPaneFraction - relativeScreenMotion 77 | self.window.relayXview( settings.Tkinter.MOVETO, moveTo.real ) 78 | self.window.relayYview( settings.Tkinter.MOVETO, moveTo.imag ) 79 | 80 | def setScrollPaneMove( self, relativeMotion ): 81 | "The up arrow was pressed." 82 | self.scrollPaneFraction = self.window.getScrollPaneFraction() 83 | self.relativeMove( relativeMotion ) 84 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze_plugins/analyze_utilities/zoom_in.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Zoom in is a mouse tool to zoom in the display at the point where the mouse was clicked, increasing the scale by a factor of two. 4 | 5 | """ 6 | 7 | from __future__ import absolute_import 8 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 9 | import __init__ 10 | 11 | from skeinforge_tools.analyze_plugins.analyze_utilities.mouse_tool_base import MouseToolBase 12 | from skeinforge_tools.skeinforge_utilities import settings 13 | 14 | 15 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 16 | __date__ = "$Date: 2008/21/04 $" 17 | __license__ = "GPL 3.0" 18 | 19 | 20 | def getNewMouseTool(): 21 | "Get a new mouse tool." 22 | return ZoomIn() 23 | 24 | 25 | class ZoomIn( MouseToolBase ): 26 | "The zoom in mouse tool." 27 | def button1( self, event, shift = False ): 28 | "Print line text and connection line." 29 | scaleSetting = self.window.repository.scale 30 | scaleSetting.value *= self.getMultiplier() 31 | delta = complex( float( event.x ) / float( self.window.screenSize.real ), float( event.y ) / float( self.window.screenSize.imag ) ) - self.window.canvasScreenCenter 32 | delta *= 1.0 - 1.0 / self.getMultiplier() 33 | scrollPaneCenter = self.window.getScrollPaneCenter() + delta 34 | self.window.updateNewDestroyOld( scrollPaneCenter ) 35 | 36 | def click( self, event = None ): 37 | "Set the window mouse tool to this." 38 | self.window.destroyMouseToolRaiseMouseButtons() 39 | self.window.mouseTool = self 40 | self.mouseButton[ 'relief' ] = settings.Tkinter.SUNKEN 41 | 42 | def getReset( self, window ): 43 | "Reset the mouse tool to default." 44 | self.setWindowItems( window ) 45 | self.mouseButton = None 46 | return self 47 | 48 | def getMultiplier( self ): 49 | "Get the scale multiplier." 50 | return 2.0 51 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze_plugins/analyze_utilities/zoom_out.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Zoom out is a mouse tool to zoom out the display at the point where the mouse was clicked, decreasing the scale by a factor of two. 4 | 5 | """ 6 | 7 | from __future__ import absolute_import 8 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 9 | import __init__ 10 | 11 | from skeinforge_tools.analyze_plugins.analyze_utilities import zoom_in 12 | from skeinforge_tools.skeinforge_utilities import settings 13 | 14 | 15 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 16 | __date__ = "$Date: 2008/21/04 $" 17 | __license__ = "GPL 3.0" 18 | 19 | 20 | def getNewMouseTool(): 21 | "Get a new mouse tool." 22 | return ZoomOut() 23 | 24 | 25 | class ZoomOut( zoom_in.ZoomIn ): 26 | "The zoom out mouse tool." 27 | def getMultiplier( self ): 28 | "Get the scale multiplier." 29 | return 0.5 30 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze_plugins/export_canvas_plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 3 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/analyze_plugins/export_canvas_plugins/postscript.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Postscript is an export canvas plugin to export the canvas to a postscript file. 4 | 5 | When the export menu item in the file menu in an analyze viewer tool, like skeinview or behold is clicked, the postscript dialog will be displayed. When the 'Export to Postscript' button on that dialog is clicked, the canvas will be exported as a postscript file. If the 'Postscript Program' is set to a program name, the postscript file will be sent to that program to be opened. The default is gimp, the Gnu Image Manipulation Program (Gimp), which is open source, can open postscript and save in a variety of formats. It is available at: 6 | http://www.gimp.org/ 7 | 8 | If furthermore the 'File Extension' is set to a file extension, the postscript file will be sent to the program, along with the file extension for the converted output. The default is blank because some systems do not have an image conversion program; if you have or will install an image conversion program, a common 'File Extension' is png. A good open source conversion program is Image Magick, which is available at: 9 | http://www.imagemagick.org/script/index.php 10 | 11 | An export canvas plugin is a script in the export_canvas_plugins folder which has the function getNewRepository, and which has a repository class with the functions setCanvasFileNameSuffix to set variables and execute to save the file. It is meant to be run from an analyze viewer tool, like skeinview or behold. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. 12 | 13 | """ 14 | 15 | 16 | from __future__ import absolute_import 17 | import __init__ 18 | from skeinforge_tools.skeinforge_utilities import gcodec 19 | from skeinforge_tools.skeinforge_utilities import settings 20 | import cStringIO 21 | import os 22 | import sys 23 | 24 | 25 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 26 | __date__ = "$Date: 2008/21/04 $" 27 | __license__ = "GPL 3.0" 28 | 29 | 30 | def getNewRepository(): 31 | "Get the repository constructor." 32 | return PostscriptRepository() 33 | 34 | 35 | class PostscriptRepository: 36 | "A class to handle the export settings." 37 | def __init__( self ): 38 | "Set the default settings, execute title & settings fileName." 39 | settings.addListsToRepository( 'skeinforge_tools.analyze_plugins.export_canvas_plugins.postscript.html', '', self ) 40 | self.fileExtension = settings.StringSetting().getFromValue( 'File Extension:', self, '' ) 41 | self.postscriptProgram = settings.StringSetting().getFromValue( 'Postscript Program:', self, 'gimp' ) 42 | 43 | def execute( self ): 44 | "Convert to postscript button has been clicked." 45 | "Export the canvas as a postscript file." 46 | postscriptFileName = gcodec.getFilePathWithUnderscoredBasename( self.fileName, self.suffix ) 47 | boundingBox = self.canvas.bbox( settings.Tkinter.ALL ) # tuple (w, n, e, s) 48 | boxW = boundingBox[ 0 ] 49 | boxN = boundingBox[ 1 ] 50 | boxWidth = boundingBox[ 2 ] - boxW 51 | boxHeight = boundingBox[ 3 ] - boxN 52 | print( 'Exported postscript file saved as ' + postscriptFileName ) 53 | self.canvas.postscript( file = postscriptFileName, height = boxHeight, width = boxWidth, pageheight = boxHeight, pagewidth = boxWidth, x = boxW, y = boxN ) 54 | fileExtension = self.fileExtension.value 55 | postscriptProgram = self.postscriptProgram.value 56 | if postscriptProgram == '': 57 | return 58 | postscriptFilePath = '"' + os.path.normpath( postscriptFileName ) + '"' # " to send in file name with spaces 59 | shellCommand = postscriptProgram + ' ' + postscriptFilePath 60 | print( '' ) 61 | if fileExtension == '': 62 | print( 'Sending the shell command:' ) 63 | print( shellCommand ) 64 | commandResult = os.system( shellCommand ) 65 | if commandResult != 0: 66 | print( 'It may be that the system could not find the %s program.' % postscriptProgram ) 67 | print( 'If so, try installing the %s program or look for another one, like the Gnu Image Manipulation Program (Gimp) which can be found at:' % postscriptProgram ) 68 | print( 'http://www.gimp.org/' ) 69 | return 70 | convertedFileName = gcodec.getFilePathWithUnderscoredBasename( postscriptFilePath, '.' + fileExtension + '"' ) 71 | shellCommand += ' ' + convertedFileName 72 | print( 'Sending the shell command:' ) 73 | print( shellCommand ) 74 | commandResult = os.system( shellCommand ) 75 | if commandResult != 0: 76 | print( 'The %s program could not convert the postscript to the %s file format.' % ( postscriptProgram, fileExtension ) ) 77 | print( 'Try installing the %s program or look for another one, like Image Magick which can be found at:' % postscriptProgram ) 78 | print( 'http://www.imagemagick.org/script/index.php' ) 79 | 80 | def setCanvasFileNameSuffix( self, canvas, fileName, suffix ): 81 | "Set the canvas and initialize the execute title." 82 | self.canvas = canvas 83 | self.executeTitle = 'Export to Postscript' 84 | self.fileName = fileName 85 | self.suffix = suffix + '.ps' 86 | 87 | 88 | def main(): 89 | "Display the file or directory dialog." 90 | settings.startMainLoopFromConstructor( getNewRepository() ) 91 | 92 | if __name__ == "__main__": 93 | main() 94 | -------------------------------------------------------------------------------- /skeinforge_tools/craft_plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 2 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/craft_plugins/export_plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 3 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/craft_plugins/export_plugins/static_plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 4 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/craft_plugins/export_plugins/static_plugins/gcode_small.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Gcode_small is an export plugin to remove the comments and the redundant z and feed rate parameters from a gcode file. 4 | 5 | An export plugin is a script in the export_plugins folder which has the functions getOutput, isReplaceable and if it's output is not replaceable, writeOutput. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. 6 | 7 | The getOutput function of this script takes a gcode text and returns that text without comments and redundant z and feed rate parameters. The writeOutput function of this script takes a gcode text and writes that text without comments and redundant z and feed rate parameters to a file. 8 | 9 | Many of the functions in this script are copied from gcodec in skeinforge_utilities. They are copied rather than imported so developers making new plugins do not have to learn about gcodec, the code here is all they need to learn. 10 | 11 | """ 12 | 13 | from __future__ import absolute_import 14 | import cStringIO 15 | import os 16 | 17 | 18 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 19 | __date__ = "$Date: 2008/21/04 $" 20 | __license__ = "GPL 3.0" 21 | 22 | def getOutput( gcodeText ): 23 | """Get the exported version of a gcode file. This function, and writeOutput are the only necessary functions in a skeinforge export plugin. 24 | If this plugin writes an output than should not be printed, an empty string should be returned.""" 25 | return GcodeSmallSkein().getCraftedGcode( gcodeText ) 26 | 27 | def getSplitLineBeforeBracketSemicolon( line ): 28 | "Get the split line before a bracket or semicolon." 29 | bracketSemicolonIndex = min( line.find( ';' ), line.find( '(' ) ) 30 | if bracketSemicolonIndex < 0: 31 | return line.split() 32 | return line[ : bracketSemicolonIndex ].split() 33 | 34 | def getStringFromCharacterSplitLine( character, splitLine ): 35 | "Get the string after the first occurence of the character in the split line." 36 | indexOfCharacter = indexOfStartingWithSecond( character, splitLine ) 37 | if indexOfCharacter < 0: 38 | return None 39 | return splitLine[ indexOfCharacter ][ 1 : ] 40 | 41 | def getSummarizedFileName( fileName ): 42 | "Get the fileName basename if the file is in the current working directory, otherwise return the original full name." 43 | if os.getcwd() == os.path.dirname( fileName ): 44 | return os.path.basename( fileName ) 45 | return fileName 46 | 47 | def getTextLines( text ): 48 | "Get the all the lines of text of a text." 49 | return text.replace( '\r', '\n' ).split( '\n' ) 50 | 51 | def indexOfStartingWithSecond( letter, splitLine ): 52 | "Get index of the first occurence of the given letter in the split line, starting with the second word. Return - 1 if letter is not found" 53 | for wordIndex in xrange( 1, len( splitLine ) ): 54 | word = splitLine[ wordIndex ] 55 | firstLetter = word[ 0 ] 56 | if firstLetter == letter: 57 | return wordIndex 58 | return - 1 59 | 60 | def isReplaceable(): 61 | "Return whether or not the output from this plugin is replaceable. This should be true if the output is text and false if it is binary." 62 | return True 63 | 64 | 65 | class GcodeSmallSkein: 66 | "A class to remove redundant z and feed rate parameters from a skein of extrusions." 67 | def __init__( self ): 68 | self.lastFeedRateString = None 69 | self.lastZString = None 70 | self.output = cStringIO.StringIO() 71 | 72 | def getCraftedGcode( self, gcodeText ): 73 | "Parse gcode text and store the gcode." 74 | lines = getTextLines( gcodeText ) 75 | for line in lines: 76 | self.parseLine( line ) 77 | return self.output.getvalue() 78 | 79 | def parseLine( self, line ): 80 | "Parse a gcode line." 81 | splitLine = getSplitLineBeforeBracketSemicolon( line ) 82 | if len( splitLine ) < 1: 83 | return 84 | firstWord = splitLine[ 0 ] 85 | if len( firstWord ) < 1: 86 | return 87 | if firstWord[ 0 ] == '(': 88 | return 89 | if firstWord != 'G1': 90 | self.output.write( line + "\n" ) 91 | return 92 | eString = getStringFromCharacterSplitLine( 'E', splitLine ) 93 | xString = getStringFromCharacterSplitLine( 'X', splitLine ) 94 | yString = getStringFromCharacterSplitLine( 'Y', splitLine ) 95 | zString = getStringFromCharacterSplitLine( 'Z', splitLine ) 96 | feedRateString = getStringFromCharacterSplitLine( 'F', splitLine ) 97 | self.output.write( 'G1' ) 98 | if xString != None: 99 | self.output.write( ' X' + xString ) 100 | if yString != None: 101 | self.output.write( ' Y' + yString ) 102 | if zString != None and zString != self.lastZString: 103 | self.output.write( ' Z' + zString ) 104 | if feedRateString != None and feedRateString != self.lastFeedRateString: 105 | self.output.write( ' F' + feedRateString ) 106 | if eString != None: 107 | self.output.write( ' E' + eString ) 108 | self.lastFeedRateString = feedRateString 109 | self.lastZString = zString 110 | self.output.write( '\n' ) 111 | -------------------------------------------------------------------------------- /skeinforge_tools/import_plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 2 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/import_plugins/gts.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | The gts.py script is an import translator plugin to get a carving from an gts file. 4 | 5 | An import plugin is a script in the import_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. 6 | 7 | The getCarving function takes the file name of an gts file and returns the carving. 8 | 9 | The GNU Triangulated Surface (.gts) format is described at: 10 | http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE 11 | 12 | This example gets a carving for the gts file Screw Holder Bottom.gts. This example is run in a terminal in the folder which contains Screw Holder Bottom.gts and gts.py. 13 | 14 | 15 | > python 16 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 17 | [GCC 4.2.1 (SUSE Linux)] on linux2 18 | Type "help", "copyright", "credits" or "license" for more information. 19 | >>> import gts 20 | >>> gts.getCarving() 21 | [11.6000003815, 10.6837882996, 7.80209827423 22 | .. 23 | many more lines of the carving 24 | .. 25 | 26 | """ 27 | 28 | 29 | from __future__ import absolute_import 30 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 31 | import __init__ 32 | 33 | from skeinforge_tools.skeinforge_utilities.vector3 import Vector3 34 | from skeinforge_tools.skeinforge_utilities import gcodec 35 | from skeinforge_tools.skeinforge_utilities import triangle_mesh 36 | 37 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 38 | __credits__ = 'Nophead \nArt of Illusion ' 39 | __date__ = "$Date: 2008/21/04 $" 40 | __license__ = "GPL 3.0" 41 | 42 | 43 | def getFromGNUTriangulatedSurfaceText( gnuTriangulatedSurfaceText, triangleMesh ): 44 | "Initialize from a GNU Triangulated Surface Text." 45 | if gnuTriangulatedSurfaceText == '': 46 | return None 47 | lines = gcodec.getTextLines( gnuTriangulatedSurfaceText ) 48 | linesWithoutComments = [] 49 | for line in lines: 50 | if len( line ) > 0: 51 | firstCharacter = line[ 0 ] 52 | if firstCharacter != '#' and firstCharacter != '!': 53 | linesWithoutComments.append( line ) 54 | splitLine = linesWithoutComments[ 0 ].split() 55 | numberOfVertices = int( splitLine[ 0 ] ) 56 | numberOfEdges = int( splitLine[ 1 ] ) 57 | numberOfFaces = int( splitLine[ 2 ] ) 58 | faceTriples = [] 59 | for vertexIndex in xrange( numberOfVertices ): 60 | line = linesWithoutComments[ vertexIndex + 1 ] 61 | splitLine = line.split() 62 | vertex = Vector3( float( splitLine[ 0 ] ), float( splitLine[ 1 ] ), float( splitLine[ 2 ] ) ) 63 | triangleMesh.vertices.append( vertex ) 64 | edgeStart = numberOfVertices + 1 65 | for edgeIndex in xrange( numberOfEdges ): 66 | line = linesWithoutComments[ edgeIndex + edgeStart ] 67 | splitLine = line.split() 68 | vertexIndexes = [] 69 | for word in splitLine[ : 2 ]: 70 | vertexIndexes.append( int( word ) - 1 ) 71 | edge = triangle_mesh.Edge().getFromVertexIndexes( edgeIndex, vertexIndexes ) 72 | triangleMesh.edges.append( edge ) 73 | faceStart = edgeStart + numberOfEdges 74 | for faceIndex in xrange( numberOfFaces ): 75 | line = linesWithoutComments[ faceIndex + faceStart ] 76 | splitLine = line.split() 77 | edgeIndexes = [] 78 | for word in splitLine[ : 3 ]: 79 | edgeIndexes.append( int( word ) - 1 ) 80 | face = triangle_mesh.Face().getFromEdgeIndexes( edgeIndexes, triangleMesh.edges, faceIndex ) 81 | triangleMesh.faces.append( face ) 82 | return triangleMesh 83 | 84 | def getCarving( fileName = '' ): 85 | "Get the triangle mesh for the gts file." 86 | if fileName == '': 87 | unmodified = gcodec.getFilesWithFileTypeWithoutWords( 'gts' ) 88 | if len( unmodified ) == 0: 89 | print( "There is no gts file in this folder." ) 90 | return None 91 | fileName = unmodified[ 0 ] 92 | return getFromGNUTriangulatedSurfaceText( gcodec.getFileText( fileName ), triangle_mesh.TriangleMesh() ) 93 | -------------------------------------------------------------------------------- /skeinforge_tools/import_plugins/obj.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | The obj.py script is an import translator plugin to get a carving from an obj file. 4 | 5 | An import plugin is a script in the import_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. 6 | 7 | The getCarving function takes the file name of an obj file and returns the carving. 8 | 9 | From wikipedia, OBJ (or .OBJ) is a geometry definition file format first developed by Wavefront Technologies for its Advanced Visualizer animation package: 10 | http://en.wikipedia.org/wiki/Obj 11 | 12 | The Object File specification is at: 13 | http://local.wasp.uwa.edu.au/~pbourke/dataformats/obj/ 14 | 15 | An excellent link page about obj files is at: 16 | http://people.sc.fsu.edu/~burkardt/data/obj/obj.html 17 | 18 | This example gets a carving for the obj file box.obj. This example is run in a terminal in the folder which contains box.obj and obj.py. 19 | 20 | 21 | > python 22 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 23 | [GCC 4.2.1 (SUSE Linux)] on linux2 24 | Type "help", "copyright", "credits" or "license" for more information. 25 | >>> import obj 26 | >>> obj.getCarving() 27 | [-62.0579, -41.4791, 0.0, 58.8424, -41.4791, 0.0, -62.0579, 22.1865, 0.0, 58.8424, 22.1865, 0.0, 28 | -62.0579, -41.4791, 39.8714, 58.8424, -41.4791, 39.8714, -62.0579, 22.1865, 39.8714, 58.8424, 22.1865, 39.8714] 29 | [0 [0, 10] [0, 2], 1 [0, 1] [0, 3], 2 [0, 8] [2, 3], 3 [1, 6] [1, 3], 4 [1, 4] [0, 1], 5 [2, 5] [4, 5], 6 [2, 3] [4, 7], 7 [2, 7] [5, 7], 30 | 8 [3, 9] [6, 7], 9 [3, 11] [4, 6], 10 [4, 5] [0, 5], 11 [4, 7] [1, 5], 12 [5, 10] [0, 4], 13 [6, 7] [1, 7], 14 [6, 9] [3, 7], 31 | 15 [8, 9] [3, 6], 16 [8, 11] [2, 6], 17 [10, 11] [2, 4]] 32 | [0 [0, 1, 2] [0, 2, 3], 1 [3, 1, 4] [3, 1, 0], 2 [5, 6, 7] [4, 5, 7], 3 [8, 6, 9] [7, 6, 4], 4 [4, 10, 11] [0, 1, 5], 5 [5, 10, 12] [5, 4, 0], 33 | 6 [3, 13, 14] [1, 3, 7], 7 [7, 13, 11] [7, 5, 1], 8 [2, 15, 16] [3, 2, 6], 9 [8, 15, 14] [6, 7, 3], 10 [0, 17, 12] [2, 0, 4], 34 | 11 [9, 17, 16] [4, 6, 2]][11.6000003815, 10.6837882996, 7.80209827423 35 | 36 | """ 37 | 38 | 39 | from __future__ import absolute_import 40 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 41 | import __init__ 42 | 43 | from skeinforge_tools.skeinforge_utilities.vector3 import Vector3 44 | from skeinforge_tools.skeinforge_utilities import gcodec 45 | from skeinforge_tools.skeinforge_utilities import triangle_mesh 46 | from struct import unpack 47 | 48 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 49 | __credits__ = 'Nophead \nArt of Illusion ' 50 | __date__ = "$Date: 2008/21/04 $" 51 | __license__ = "GPL 3.0" 52 | 53 | 54 | def addFacesGivenText( objText, triangleMesh ): 55 | "Add faces given obj text." 56 | lines = gcodec.getTextLines( objText ) 57 | for line in lines: 58 | splitLine = line.split() 59 | firstWord = gcodec.getFirstWord( splitLine ) 60 | if firstWord == 'v': 61 | triangleMesh.vertices.append( getVertexGivenLine( line ) ) 62 | elif firstWord == 'f': 63 | triangleMesh.faces.append( getFaceGivenLine( line, triangleMesh ) ) 64 | 65 | def getFaceGivenLine( line, triangleMesh ): 66 | "Add face given line index and lines." 67 | face = triangle_mesh.Face() 68 | face.index = len( triangleMesh.faces ) 69 | splitLine = line.split() 70 | for vertexStringIndex in xrange( 1, 4 ): 71 | vertexString = splitLine[ vertexStringIndex ] 72 | vertexStringWithSpaces = vertexString.replace( '/', ' ' ) 73 | vertexStringSplit = vertexStringWithSpaces.split() 74 | vertexIndex = int( vertexStringSplit[ 0 ] ) - 1 75 | face.vertexIndexes.append( vertexIndex ) 76 | return face 77 | 78 | def getCarving( fileName = '' ): 79 | "Get the triangle mesh for the obj file." 80 | if fileName == '': 81 | unmodified = gcodec.getFilesWithFileTypeWithoutWords( 'obj' ) 82 | if len( unmodified ) == 0: 83 | print( "There is no obj file in this folder." ) 84 | return None 85 | fileName = unmodified[ 0 ] 86 | objText = gcodec.getFileText( fileName, 'rb' ) 87 | if objText == '': 88 | return None 89 | triangleMesh = triangle_mesh.TriangleMesh() 90 | addFacesGivenText( objText, triangleMesh ) 91 | triangleMesh.setEdgesForAllFaces() 92 | return triangleMesh 93 | 94 | def getVertexGivenLine( line ): 95 | "Get vertex given obj vertex line." 96 | splitLine = line.split() 97 | return Vector3( float( splitLine[ 1 ] ), float( splitLine[ 2 ] ), float( splitLine[ 3 ] ) ) 98 | -------------------------------------------------------------------------------- /skeinforge_tools/import_plugins/py.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | The py.py script is an import translator plugin to get a carving from a python script. 4 | 5 | An explanation of the SLC format can be found at: 6 | http://rapid.lpt.fi/archives/rp-ml-1999/0713.html 7 | 8 | An import plugin is a script in the import_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. 9 | 10 | The getCarving function takes the file name of a python script and returns the carving. 11 | 12 | This example gets a carving for the python script circular_wave.py. This example is run in a terminal in the folder which contains circular_wave.py and py.py. 13 | 14 | 15 | > python 16 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 17 | [GCC 4.2.1 (SUSE Linux)] on linux2 18 | Type "help", "copyright", "credits" or "license" for more information. 19 | >>> import py 20 | >>> py.getCarving() 21 | 0.20000000298, 999999999.0, -999999999.0, [8.72782748851e-17, None 22 | .. 23 | many more lines of the carving 24 | .. 25 | 26 | 27 | """ 28 | 29 | 30 | from __future__ import absolute_import 31 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 32 | import __init__ 33 | 34 | from skeinforge_tools.skeinforge_utilities.vector3 import Vector3 35 | from skeinforge_tools.skeinforge_utilities import euclidean 36 | from skeinforge_tools.skeinforge_utilities import gcodec 37 | import os 38 | import sys 39 | 40 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 41 | __credits__ = 'Nophead \nArt of Illusion ' 42 | __date__ = "$Date: 2008/21/04 $" 43 | __license__ = "GPL 3.0" 44 | 45 | 46 | def getCarving( fileName = '' ): 47 | "Get the triangle mesh for the slc file." 48 | return PythonCarving( fileName ) 49 | 50 | 51 | class PythonCarving: 52 | "A python carving." 53 | def __init__( self, fileName ): 54 | "Add empty lists." 55 | self.maximumZ = - 999999999.0 56 | self.minimumZ = 999999999.0 57 | self.layerThickness = None 58 | self.rotatedBoundaryLayers = [] 59 | self.untilDotName = gcodec.getUntilDot( fileName ) 60 | 61 | def __repr__( self ): 62 | "Get the string representation of this carving." 63 | return '%s, %s, %s, %s' % ( self.layerThickness, self.minimumZ, self.maximumZ, self.rotatedBoundaryLayers ) 64 | 65 | def getCarveCornerMaximum( self ): 66 | "Get the corner maximum of the vertices." 67 | return self.cornerMaximum 68 | 69 | def getCarveCornerMinimum( self ): 70 | "Get the corner minimum of the vertices." 71 | return self.cornerMinimum 72 | 73 | def getCarveLayerThickness( self ): 74 | "Get the layer thickness." 75 | return self.layerThickness 76 | 77 | def getCarveRotatedBoundaryLayers( self ): 78 | "Get the rotated boundary layers." 79 | self.importModule() 80 | self.cornerMaximum = Vector3( - 999999999.0, - 999999999.0, self.maximumZ ) 81 | self.cornerMinimum = Vector3( 999999999.0, 999999999.0, self.minimumZ ) 82 | for rotatedBoundaryLayer in self.rotatedBoundaryLayers: 83 | for loop in rotatedBoundaryLayer.loops: 84 | for point in loop: 85 | pointVector3 = Vector3( point.real, point.imag, rotatedBoundaryLayer.z ) 86 | self.cornerMaximum = euclidean.getPointMaximum( self.cornerMaximum, pointVector3 ) 87 | self.cornerMinimum = euclidean.getPointMinimum( self.cornerMinimum, pointVector3 ) 88 | halfLayerThickness = 0.5 * self.layerThickness 89 | self.cornerMaximum.z += halfLayerThickness 90 | self.cornerMinimum.z -= halfLayerThickness 91 | return self.rotatedBoundaryLayers 92 | 93 | def importModule( self ): 94 | "Import the python script and store the layers." 95 | path = os.path.abspath( self.untilDotName ) 96 | pluginModule = gcodec.getModuleWithPath( path ) 97 | loopLayers = pluginModule.getLoopLayers( self.layerThickness ) 98 | for loopLayer in loopLayers: 99 | rotatedBoundaryLayer = euclidean.RotatedLoopLayer( loopLayer.z ) 100 | rotatedBoundaryLayer.loops = loopLayer.loops 101 | self.rotatedBoundaryLayers.append( rotatedBoundaryLayer ) 102 | 103 | def setCarveBridgeLayerThickness( self, bridgeLayerThickness ): 104 | "Set the bridge layer thickness. If the infill is not in the direction of the bridge, the bridge layer thickness should be given as None or not set at all." 105 | pass 106 | 107 | def setCarveLayerThickness( self, layerThickness ): 108 | "Set the layer thickness." 109 | self.layerThickness = layerThickness 110 | 111 | def setCarveImportRadius( self, importRadius ): 112 | "Set the import radius." 113 | pass 114 | 115 | def setCarveIsCorrectMesh( self, isCorrectMesh ): 116 | "Set the is correct mesh flag." 117 | pass 118 | 119 | 120 | def main(): 121 | "Display the inset dialog." 122 | if len( sys.argv ) > 1: 123 | getCarving( ' '.join( sys.argv[ 1 : ] ) ) 124 | 125 | if __name__ == "__main__": 126 | main() 127 | -------------------------------------------------------------------------------- /skeinforge_tools/import_plugins/stl.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | The stl.py script is an import translator plugin to get a carving from an stl file. 4 | 5 | An import plugin is a script in the import_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. 6 | 7 | The getCarving function takes the file name of an stl file and returns the carving. 8 | 9 | STL is an inferior triangle surface format, described at: 10 | http://en.wikipedia.org/wiki/STL_(file_format) 11 | 12 | A good triangle surface format is the GNU Triangulated Surface format which is described at: 13 | http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE 14 | 15 | This example gets a carving for the stl file Screw Holder Bottom.stl. This example is run in a terminal in the folder which contains Screw Holder Bottom.stl and stl.py. 16 | 17 | 18 | > python 19 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 20 | [GCC 4.2.1 (SUSE Linux)] on linux2 21 | Type "help", "copyright", "credits" or "license" for more information. 22 | >>> import stl 23 | >>> stl.getCarving() 24 | [11.6000003815, 10.6837882996, 7.80209827423 25 | .. 26 | many more lines of the carving 27 | .. 28 | 29 | """ 30 | 31 | 32 | from __future__ import absolute_import 33 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 34 | import __init__ 35 | 36 | from skeinforge_tools.skeinforge_utilities.vector3 import Vector3 37 | from skeinforge_tools.skeinforge_utilities import gcodec 38 | from skeinforge_tools.skeinforge_utilities import triangle_mesh 39 | from struct import unpack 40 | 41 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 42 | __credits__ = 'Nophead \nArt of Illusion ' 43 | __date__ = "$Date: 2008/21/04 $" 44 | __license__ = "GPL 3.0" 45 | 46 | 47 | def addFacesGivenBinary( stlData, triangleMesh, vertexIndexTable ): 48 | "Add faces given stl binary." 49 | numberOfVertices = ( len( stlData ) - 84 ) / 50 50 | vertices = [] 51 | for vertexIndex in xrange( numberOfVertices ): 52 | byteIndex = 84 + vertexIndex * 50 53 | vertices.append( getVertexGivenBinary( byteIndex + 12, stlData ) ) 54 | vertices.append( getVertexGivenBinary( byteIndex + 24, stlData ) ) 55 | vertices.append( getVertexGivenBinary( byteIndex + 36, stlData ) ) 56 | addFacesGivenVertices( triangleMesh, vertexIndexTable, vertices ) 57 | 58 | def addFacesGivenText( stlText, triangleMesh, vertexIndexTable ): 59 | "Add faces given stl text." 60 | lines = gcodec.getTextLines( stlText ) 61 | vertices = [] 62 | for line in lines: 63 | if line.find( 'vertex' ) != - 1: 64 | vertices.append( getVertexGivenLine( line ) ) 65 | addFacesGivenVertices( triangleMesh, vertexIndexTable, vertices ) 66 | 67 | def addFacesGivenVertices( triangleMesh, vertexIndexTable, vertices ): 68 | "Add faces given stl text." 69 | for vertexIndex in xrange( 0, len( vertices ), 3 ): 70 | triangleMesh.faces.append( getFaceGivenLines( triangleMesh, vertexIndex, vertexIndexTable, vertices ) ) 71 | 72 | def getCarving( fileName = '' ): 73 | "Get the triangle mesh for the stl file." 74 | if fileName == '': 75 | unmodified = gcodec.getFilesWithFileTypeWithoutWords( 'stl' ) 76 | if len( unmodified ) == 0: 77 | print( "There is no stl file in this folder." ) 78 | return None 79 | fileName = unmodified[ 0 ] 80 | stlData = gcodec.getFileText( fileName, 'rb' ) 81 | if stlData == '': 82 | return None 83 | triangleMesh = triangle_mesh.TriangleMesh() 84 | vertexIndexTable = {} 85 | numberOfVertexStrings = stlData.count( 'vertex' ) 86 | requiredVertexStringsForText = max( 2, len( stlData ) / 8000 ) 87 | if numberOfVertexStrings > requiredVertexStringsForText: 88 | addFacesGivenText( stlData, triangleMesh, vertexIndexTable ) 89 | else: 90 | # A binary stl should never start with the word "solid". Because this error is common the file is been parsed as binary regardless. 91 | addFacesGivenBinary( stlData, triangleMesh, vertexIndexTable ) 92 | triangleMesh.setEdgesForAllFaces() 93 | return triangleMesh 94 | 95 | def getFaceGivenLines( triangleMesh, vertexStartIndex, vertexIndexTable, vertices ): 96 | "Add face given line index and lines." 97 | face = triangle_mesh.Face() 98 | face.index = len( triangleMesh.faces ) 99 | for vertexIndex in xrange( vertexStartIndex, vertexStartIndex + 3 ): 100 | vertex = vertices[ vertexIndex ] 101 | vertexUniqueIndex = len( vertexIndexTable ) 102 | if str( vertex ) in vertexIndexTable: 103 | vertexUniqueIndex = vertexIndexTable[ str( vertex ) ] 104 | else: 105 | vertexIndexTable[ str( vertex ) ] = vertexUniqueIndex 106 | triangleMesh.vertices.append( vertex ) 107 | face.vertexIndexes.append( vertexUniqueIndex ) 108 | return face 109 | 110 | def getFloat( floatString ): 111 | "Get the float, replacing commas if necessary because an inferior program is using a comma instead of a point for the decimal point." 112 | try: 113 | return float( floatString ) 114 | except: 115 | return float( floatString.replace( ',', '.' ) ) 116 | 117 | def getFloatGivenBinary( byteIndex, stlData ): 118 | "Get vertex given stl vertex line." 119 | return unpack( 'f', stlData[ byteIndex : byteIndex + 4 ] )[ 0 ] 120 | 121 | def getVertexGivenBinary( byteIndex, stlData ): 122 | "Get vertex given stl vertex line." 123 | return Vector3( getFloatGivenBinary( byteIndex, stlData ), getFloatGivenBinary( byteIndex + 4, stlData ), getFloatGivenBinary( byteIndex + 8, stlData ) ) 124 | 125 | def getVertexGivenLine( line ): 126 | "Get vertex given stl vertex line." 127 | splitLine = line.split() 128 | return Vector3( getFloat( splitLine[ 1 ] ), getFloat( splitLine[ 2 ] ), getFloat( splitLine[ 3 ] ) ) 129 | -------------------------------------------------------------------------------- /skeinforge_tools/meta.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Meta is a script to access the plugins which handle meta information. 4 | 5 | """ 6 | 7 | from __future__ import absolute_import 8 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 9 | import __init__ 10 | 11 | from skeinforge_tools.skeinforge_utilities import gcodec 12 | from skeinforge_tools.skeinforge_utilities import settings 13 | 14 | 15 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 16 | __date__ = "$Date: 2008/21/04 $" 17 | __license__ = "GPL 3.0" 18 | 19 | 20 | def addToMenu( master, menu, repository, window ): 21 | "Add a tool plugin menu." 22 | settings.addPluginsParentToMenu( getPluginsDirectoryPath(), menu, __file__, getPluginFileNames() ) 23 | 24 | def getPluginFileNames(): 25 | "Get meta plugin file names." 26 | return gcodec.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() ) 27 | 28 | def getPluginsDirectoryPath(): 29 | "Get the plugins directory path." 30 | return gcodec.getAbsoluteFolderPath( __file__, 'meta_plugins' ) 31 | 32 | def getNewRepository(): 33 | "Get the repository constructor." 34 | return MetaRepository() 35 | 36 | 37 | class MetaRepository: 38 | "A class to handle the meta settings." 39 | def __init__( self ): 40 | "Set the default settings, execute title & settings fileName." 41 | settings.addListsToRepository( 'skeinforge_tools.meta.html', '', self ) 42 | importantFileNames = [ 'polyfile' ] 43 | settings.getRadioPluginsAddPluginFrame( getPluginsDirectoryPath(), importantFileNames, getPluginFileNames(), self ) 44 | 45 | 46 | def main(): 47 | "Display the meta dialog." 48 | settings.startMainLoopFromConstructor( getNewRepository() ) 49 | 50 | if __name__ == "__main__": 51 | main() 52 | -------------------------------------------------------------------------------- /skeinforge_tools/meta_plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 2 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/meta_plugins/description.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Description is a script to store a description of the profile. 4 | 5 | ==Settings== 6 | ===Description Text=== 7 | Default is empty. 8 | 9 | The suggested format is a description, followed by a link to a profile post or web page. 10 | 11 | ==Examples== 12 | Examples of using description follow below. 13 | 14 | 15 | > python description.py 16 | This brings up the description dialog. 17 | 18 | > python 19 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 20 | [GCC 4.2.1 (SUSE Linux)] on linux2 21 | Type "help", "copyright", "credits" or "license" for more information. 22 | >>> import description 23 | >>> description.main() 24 | This brings up the description setting dialog. 25 | 26 | """ 27 | 28 | from __future__ import absolute_import 29 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 30 | import __init__ 31 | 32 | from skeinforge_tools.skeinforge_utilities import settings 33 | 34 | 35 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 36 | __date__ = "$Date: 2008/21/04 $" 37 | __license__ = "GPL 3.0" 38 | 39 | 40 | def getNewRepository(): 41 | "Get the repository constructor." 42 | return DescriptionRepository() 43 | 44 | 45 | class DescriptionRepository: 46 | "A class to handle the description settings." 47 | def __init__( self ): 48 | "Set the default settings, execute title & settings fileName." 49 | settings.addListsToRepository( 'skeinforge_tools.meta_plugins.description.html', '', self ) 50 | description = 'Write your description of the profile here.\n\nSuggested format is a description, followed by a link to the profile post or web page.' 51 | self.descriptionText = settings.TextSetting().getFromValue( 'Description Text:', self, description ) 52 | 53 | 54 | def main(): 55 | "Display the file or directory dialog." 56 | settings.startMainLoopFromConstructor( getNewRepository() ) 57 | 58 | if __name__ == "__main__": 59 | main() 60 | -------------------------------------------------------------------------------- /skeinforge_tools/meta_plugins/polyfile.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Polyfile is a script to choose whether the skeinforge toolchain will operate on one file or all the files in a directory. 4 | 5 | ==Settings== 6 | ===Polyfile Choice=== 7 | Default is 'Execute File', 8 | 9 | ====Execute File==== 10 | When selected, the toolchain will operate on only the chosen file. 11 | 12 | ====Execute All Unmodified Files in a Directory'==== 13 | When selected, the toolchain will operate on all the unmodifed files in the directory that the chosen file is in. 14 | 15 | ==Examples== 16 | Examples of using polyfile follow below. 17 | 18 | 19 | > python polyfile.py 20 | This brings up the polyfile dialog. 21 | 22 | 23 | > python 24 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 25 | [GCC 4.2.1 (SUSE Linux)] on linux2 26 | Type "help", "copyright", "credits" or "license" for more information. 27 | >>> import polyfile 28 | >>> polyfile.main() 29 | This brings up the polyfile dialog. 30 | 31 | 32 | >>> polyfile.isDirectorySetting() 33 | This returns true if 'Execute All Unmodified Files in a Directory' is chosen and returns false if 'Execute File' is chosen. 34 | 35 | """ 36 | 37 | from __future__ import absolute_import 38 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 39 | import __init__ 40 | 41 | from skeinforge_tools.skeinforge_utilities import gcodec 42 | from skeinforge_tools.skeinforge_utilities import settings 43 | 44 | 45 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 46 | __date__ = "$Date: 2008/21/04 $" 47 | __license__ = "GPL 3.0" 48 | 49 | 50 | def getFileOrGcodeDirectory( fileName, wasCancelled, words = [] ): 51 | "Get the gcode files in the directory the file is in if directory setting is true. Otherwise, return the file in a list." 52 | if isEmptyOrCancelled( fileName, wasCancelled ): 53 | return [] 54 | if isDirectorySetting(): 55 | return gcodec.getFilesWithFileTypeWithoutWords( 'gcode', words, fileName ) 56 | return [ fileName ] 57 | 58 | def getFileOrDirectoryTypes( fileName, fileTypes, wasCancelled ): 59 | "Get the gcode files in the directory the file is in if directory setting is true. Otherwise, return the file in a list." 60 | if isEmptyOrCancelled( fileName, wasCancelled ): 61 | return [] 62 | if isDirectorySetting(): 63 | return gcodec.getFilesWithFileTypesWithoutWords( fileTypes, [], fileName ) 64 | return [ fileName ] 65 | 66 | def getFileOrDirectoryTypesUnmodifiedGcode( fileName, fileTypes, wasCancelled ): 67 | "Get the gcode files in the directory the file is in if directory setting is true. Otherwise, return the file in a list." 68 | if isEmptyOrCancelled( fileName, wasCancelled ): 69 | return [] 70 | if isDirectorySetting(): 71 | return gcodec.getFilesWithFileTypesWithoutWords( fileTypes, [], fileName ) + gcodec.getUnmodifiedGCodeFiles( fileName ) 72 | return [ fileName ] 73 | 74 | def getNewRepository(): 75 | "Get the repository constructor." 76 | return PolyfileRepository() 77 | 78 | def isDirectorySetting(): 79 | "Determine if the directory setting is true." 80 | return settings.getReadRepository( PolyfileRepository() ).directorySetting.value 81 | 82 | def isEmptyOrCancelled( fileName, wasCancelled ): 83 | "Determine if the fileName is empty or the dialog was cancelled." 84 | return str( fileName ) == '' or str( fileName ) == '()' or wasCancelled 85 | 86 | 87 | class PolyfileRepository: 88 | "A class to handle the polyfile settings." 89 | def __init__( self ): 90 | "Set the default settings, execute title & settings fileName." 91 | settings.addListsToRepository( 'skeinforge_tools.meta_plugins.polyfile.html', '', self ) 92 | self.directoryOrFileChoiceLabel = settings.LabelDisplay().getFromName( 'Directory or File Choice: ', self ) 93 | directoryLatentStringVar = settings.LatentStringVar() 94 | self.directorySetting = settings.Radio().getFromRadio( directoryLatentStringVar, 'Execute All Unmodified Files in a Directory', self, False ) 95 | self.fileSetting = settings.Radio().getFromRadio( directoryLatentStringVar, 'Execute File', self, True ) 96 | 97 | 98 | def main(): 99 | "Display the file or directory dialog." 100 | settings.startMainLoopFromConstructor( getNewRepository() ) 101 | 102 | if __name__ == "__main__": 103 | main() 104 | -------------------------------------------------------------------------------- /skeinforge_tools/profile_plugins/__init__.py: -------------------------------------------------------------------------------- 1 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 2 | import os 3 | import sys 4 | numberOfLevelsDeepInPackageHierarchy = 2 5 | packageFilePath = os.path.abspath( __file__ ) 6 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 7 | packageFilePath = os.path.dirname( packageFilePath ) 8 | if packageFilePath not in sys.path: 9 | sys.path.insert( 0, packageFilePath ) 10 | -------------------------------------------------------------------------------- /skeinforge_tools/profile_plugins/cutting.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Cutting is a script to set the cutting profile for the skeinforge chain. 4 | 5 | The displayed craft sequence is the sequence in which the tools craft the model and export the output. 6 | 7 | On the cutting dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm. The 'Delete Profile' button deletes the selected profile. 8 | 9 | The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles. 10 | 11 | To change the cutting profile, in a shell in the profile_plugins folder type: 12 | > python cutting.py 13 | 14 | An example of using cutting from the python interpreter follows below. 15 | 16 | 17 | > python 18 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 19 | [GCC 4.2.1 (SUSE Linux)] on linux2 20 | Type "help", "copyright", "credits" or "license" for more information. 21 | >>> import cutting 22 | >>> cutting.main() 23 | This brings up the cutting setting dialog. 24 | 25 | """ 26 | 27 | 28 | from __future__ import absolute_import 29 | import __init__ 30 | from skeinforge_tools.skeinforge_utilities import settings 31 | import sys 32 | 33 | 34 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 35 | __date__ = "$Date: 2008/21/04 $" 36 | __license__ = "GPL 3.0" 37 | 38 | 39 | def getCraftSequence(): 40 | "Get the cutting craft sequence." 41 | return 'chop,preface,outset,multiply,whittle,drill,lift,flow,feed,home,lash,fillet,dimension,unpause,export'.split( ',' ) 42 | 43 | def getNewRepository(): 44 | "Get the repository constructor." 45 | return CuttingRepository() 46 | 47 | 48 | class CuttingRepository: 49 | "A class to handle the cutting settings." 50 | def __init__( self ): 51 | "Set the default settings, execute title & settings fileName." 52 | settings.addListsSetCraftProfileArchive( getCraftSequence(), 'end_mill', self, 'skeinforge_tools.profile_plugins.cutting.html' ) 53 | 54 | 55 | def main(): 56 | "Display the export dialog." 57 | if len( sys.argv ) > 1: 58 | writeOutput( ' '.join( sys.argv[ 1 : ] ) ) 59 | else: 60 | settings.startMainLoopFromConstructor( getNewRepository() ) 61 | 62 | if __name__ == "__main__": 63 | main() 64 | -------------------------------------------------------------------------------- /skeinforge_tools/profile_plugins/extrusion.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Extrusion is a script to set the extrusion profile for the skeinforge chain. 4 | 5 | The displayed craft sequence is the sequence in which the tools craft the model and export the output. 6 | 7 | On the extrusion dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if ABS is selected and the name ABS_black is in the input field, clicking the 'Add Profile' button will duplicate ABS and save it as ABS_black. The 'Delete Profile' button deletes the selected profile. 8 | 9 | The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles. 10 | 11 | To change the extrusion profile, in a shell in the profile_plugins folder type: 12 | > python extrusion.py 13 | 14 | An example of using extrusion from the python interpreter follows below. 15 | 16 | 17 | > python 18 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 19 | [GCC 4.2.1 (SUSE Linux)] on linux2 20 | Type "help", "copyright", "credits" or "license" for more information. 21 | >>> import extrusion 22 | >>> extrusion.main() 23 | This brings up the extrusion setting dialog. 24 | 25 | """ 26 | 27 | 28 | from __future__ import absolute_import 29 | import __init__ 30 | from skeinforge_tools.skeinforge_utilities import settings 31 | import sys 32 | 33 | 34 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 35 | __date__ = "$Date: 2008/21/04 $" 36 | __license__ = "GPL 3.0" 37 | 38 | 39 | def getCraftSequence(): 40 | "Get the extrusion craft sequence." 41 | return 'carve,preface,widen,inset,fill,multiply,speed,raft,chamber,tower,jitter,comb,clip,cool,stretch,hop,wipe,oozebane,splodge,home,lash,fillet,dimension,unpause,export'.split( ',' ) 42 | 43 | def getNewRepository(): 44 | "Get the repository constructor." 45 | return ExtrusionRepository() 46 | 47 | 48 | class ExtrusionRepository: 49 | "A class to handle the export settings." 50 | def __init__( self ): 51 | "Set the default settings, execute title & settings fileName." 52 | settings.addListsSetCraftProfileArchive( getCraftSequence(), 'ABS', self, 'skeinforge_tools.profile_plugins.extrusion.html' ) 53 | 54 | 55 | def main(): 56 | "Display the export dialog." 57 | if len( sys.argv ) > 1: 58 | writeOutput( ' '.join( sys.argv[ 1 : ] ) ) 59 | else: 60 | settings.startMainLoopFromConstructor( getNewRepository() ) 61 | 62 | if __name__ == "__main__": 63 | main() 64 | -------------------------------------------------------------------------------- /skeinforge_tools/profile_plugins/milling.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Milling is a script to set the milling profile for the skeinforge chain. 4 | 5 | The displayed craft sequence is the sequence in which the tools craft the model and export the output. 6 | 7 | On the milling dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm. The 'Delete Profile' button deletes the selected profile. 8 | 9 | The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles. 10 | 11 | To change the milling profile, in a shell in the profile_plugins folder type: 12 | > python milling.py 13 | 14 | An example of using milling from the python interpreter follows below. 15 | 16 | 17 | > python 18 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 19 | [GCC 4.2.1 (SUSE Linux)] on linux2 20 | Type "help", "copyright", "credits" or "license" for more information. 21 | >>> import milling 22 | >>> milling.main() 23 | This brings up the milling setting dialog. 24 | 25 | """ 26 | 27 | 28 | from __future__ import absolute_import 29 | import __init__ 30 | from skeinforge_tools.skeinforge_utilities import settings 31 | import sys 32 | 33 | 34 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 35 | __date__ = "$Date: 2008/21/04 $" 36 | __license__ = "GPL 3.0" 37 | 38 | 39 | def getCraftSequence(): 40 | "Get the milling craft sequence." 41 | return 'chop,preface,outset,mill,multiply,drill,lift,flow,feed,home,lash,fillet,dimension,unpause,export'.split( ',' ) 42 | 43 | def getNewRepository(): 44 | "Get the repository constructor." 45 | return MillingRepository() 46 | 47 | 48 | class MillingRepository: 49 | "A class to handle the milling settings." 50 | def __init__( self ): 51 | "Set the default settings, execute title & settings fileName." 52 | settings.addListsSetCraftProfileArchive( getCraftSequence(), 'end_mill', self, 'skeinforge_tools.profile_plugins.milling.html' ) 53 | 54 | 55 | def main(): 56 | "Display the export dialog." 57 | if len( sys.argv ) > 1: 58 | writeOutput( ' '.join( sys.argv[ 1 : ] ) ) 59 | else: 60 | settings.startMainLoopFromConstructor( getNewRepository() ) 61 | 62 | if __name__ == "__main__": 63 | main() 64 | -------------------------------------------------------------------------------- /skeinforge_tools/profile_plugins/winding.py: -------------------------------------------------------------------------------- 1 | """ 2 | This page is in the table of contents. 3 | Winding is a script to set the winding profile for the skeinforge chain. 4 | 5 | The displayed craft sequence is the sequence in which the tools craft the model and export the output. 6 | 7 | On the winding dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm. The 'Delete Profile' button deletes the selected profile. 8 | 9 | The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles. 10 | 11 | To change the winding profile, in a shell in the profile_plugins folder type: 12 | > python winding.py 13 | 14 | An example of using winding from the python interpreter follows below. 15 | 16 | 17 | > python 18 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 19 | [GCC 4.2.1 (SUSE Linux)] on linux2 20 | Type "help", "copyright", "credits" or "license" for more information. 21 | >>> import winding 22 | >>> winding.main() 23 | This brings up the winding setting dialog. 24 | 25 | """ 26 | 27 | 28 | from __future__ import absolute_import 29 | import __init__ 30 | from skeinforge_tools.skeinforge_utilities import settings 31 | import sys 32 | 33 | 34 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 35 | __date__ = "$Date: 2008/21/04 $" 36 | __license__ = "GPL 3.0" 37 | 38 | 39 | def getCraftSequence(): 40 | "Get the winding craft sequence." 41 | return 'cleave,preface,coil,flow,feed,home,lash,fillet,dimension,unpause,export'.split( ',' ) 42 | 43 | def getNewRepository(): 44 | "Get the repository constructor." 45 | return WindingRepository() 46 | 47 | 48 | class WindingRepository: 49 | "A class to handle the winding settings." 50 | def __init__( self ): 51 | "Set the default settings, execute title & settings fileName." 52 | settings.addListsSetCraftProfileArchive( getCraftSequence(), 'free_wire', self, 'skeinforge_tools.profile_plugins.winding.html' ) 53 | 54 | 55 | def main(): 56 | "Display the export dialog." 57 | if len( sys.argv ) > 1: 58 | writeOutput( ' '.join( sys.argv[ 1 : ] ) ) 59 | else: 60 | settings.startMainLoopFromConstructor( getNewRepository() ) 61 | 62 | if __name__ == "__main__": 63 | main() 64 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/cutting/End_Mill/chop.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated chop preferences. 2 | Name Value 3 | Add Extra Top Layer if Necessary True 4 | Open File to be Chopped 5 | Import Coarseness (ratio): 1.0 6 | Correct Mesh True 7 | Unproven Mesh False 8 | Layer Thickness (mm): 0.4 9 | Layer Thickness over Precision (ratio): 10.0 10 | Layers From (index): 0 11 | Layers To (index): 999999999 12 | Perimeter Width (mm): 2.0 13 | windowPositionChop Preferences 600+0 14 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/cutting/End_Mill/lift.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated lift preferences. 2 | Name Value 3 | Activate Lift: True 4 | Cutting Lift over Layer Step (ratio): -0.5 5 | Open File to be Lifted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/Screw Holder Bottom.stl 6 | Clearance above Top (mm): 5.0 7 | windowPositionLift Preferences 440+53 8 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/cutting/Laser/chop.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated chop preferences. 2 | Name Value 3 | Add Extra Top Layer if Necessary True 4 | Open File to be Chopped 5 | Import Coarseness (ratio): 1.0 6 | Correct Mesh True 7 | Unproven Mesh False 8 | Layer Thickness (mm): 0.4 9 | Layer Thickness over Precision (ratio): 10.0 10 | Layers From (index): 0 11 | Layers To (index): 999999999 12 | Perimeter Width (mm): 0.2 13 | windowPositionChop Preferences 600+0 14 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/cutting/Laser/lift.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated lift preferences. 2 | Name Value 3 | Activate Lift: True 4 | Cutting Lift over Layer Step (ratio): 0.0 5 | Open File to be Lifted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/Screw Holder Bottom.stl 6 | Clearance above Top (mm): 5.0 7 | windowPositionLift Preferences 440+53 8 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/ABS/raft.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated raft preferences. 2 | Name Value 3 | Activate Raft: True 4 | Add Raft, Elevate Nozzle, Orbit and Set Altitude: True 5 | Base Infill Density (ratio): 0.3 6 | Base Layer Thickness over Layer Thickness: 2.0 7 | Base Layers (integer): 1 8 | Base Nozzle Lift over Half Base Layer Thickness (ratio): 0.75 9 | Bottom Altitude: 0.0 10 | Open File to be Rafted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap_v0.1/Hollow Square Bottom_comb_raft.gcode 11 | Infill Overhang (ratio): 0.1 12 | Interface Infill Density (ratio): 0.5 13 | Interface Layer Thickness over Layer Thickness: 1.0 14 | Interface Layers (integer): 2 15 | Interface Nozzle Lift over Half Interface Layer Thickness (ratio): 0.9 16 | Operating Nozzle Lift over Half Layer Thickness (ratio): 1.0 17 | Raft Outset Radius over Extrusion Width (ratio): 10.0 18 | Support Cross Hatch: True 19 | Support Flowrate over Operating Flowrate (ratio): 1.0 20 | Support Gap over Perimeter Extrusion Width (ratio): 1.0 21 | No Support Material True 22 | Support Material Everywhere False 23 | Support Material on Exterior Only False 24 | Support Minimum Angle (degrees): 60.0 25 | Temperature Change Time Before Raft (seconds): 0.0 26 | Temperature Change Time Before First Layer Outline (seconds): 0.0 27 | Temperature Change Time Before Next Threads (seconds): 0.0 28 | Temperature Change Time Before Support Layers (seconds): 0.0 29 | Temperature Change Time Before Supported Layers (seconds): 0.0 30 | Temperature of Raft (Celcius): 235.0 31 | Temperature of Shape First Layer Outline (Celcius): 235.0 32 | Temperature of Shape First Layer Within (Celcius): 240.0 33 | Temperature of Shape Next Layers (Celcius): 242.0 34 | Temperature of Support Layers (Celcius): 230.0 35 | Temperature of Supported Layers (Celcius): 230.0 36 | windowPositionRaft Preferences 654+177 37 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/HDPE/raft.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated preferences. 2 | Activate Raft: True 3 | Add Raft, Elevate Nozzle, Orbit and Set Altitude: True 4 | Base Infill Density (ratio): 0.5 5 | Base Layer Thickness over Layer Thickness: 2.0 6 | Base Layers (integer): 1 7 | Base Nozzle Lift over Half Base Layer Thickness (ratio): 0.75 8 | Bottom Altitude: 0.0 9 | Open File to be Rafted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/Hollow Square_comb.gcode 10 | Infill Overhang (ratio): 0.1 11 | Interface Infill Density (ratio): 0.5 12 | Interface Layer Thickness over Layer Thickness: 1.0 13 | Interface Layers (integer): 2 14 | Interface Nozzle Lift over Half Interface Layer Thickness (ratio): 1.0 15 | Operating Nozzle Lift over Half Layer Thickness (ratio): 1.0 16 | Raft Outset Radius over Extrusion Width (ratio): 15.0 17 | Support Flowrate over Operating Flowrate (ratio): 1.0 18 | Support Gap over Perimeter Extrusion Width (ratio): 1.0 19 | No Support Material True 20 | Support Material Everywhere False 21 | Support Material on Exterior Only False 22 | Support Minimum Angle (degrees): 60.0 23 | Temperature Change Time Before Raft (seconds): 120.0 24 | Temperature Change Time Before First Layer Outline (seconds): 120.0 25 | Temperature Change Time Before Next Threads (seconds): 120.0 26 | Temperature Change Time Before Support Layers (seconds): 120.0 27 | Temperature Change Time Before Supported Layers (seconds): 120.0 28 | Temperature of Raft (Celcius): 200.0 29 | Temperature of Shape First Layer Outline (Celcius): 220.0 30 | Temperature of Shape First Layer Within (Celcius): 195.0 31 | Temperature of Shape Next Layers (Celcius): 230.0 32 | Temperature of Support Layers (Celcius): 200.0 33 | Temperature of Supported Layers (Celcius): 230.0 34 | windowPositionRaft Preferences 0+0 35 | windowPositionRaft Preferences 0+0 36 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/PCL/raft.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated preferences. 2 | Activate Raft: True 3 | Add Raft, Elevate Nozzle, Orbit and Set Altitude: True 4 | Base Infill Density (ratio): 0.5 5 | Base Layer Thickness over Layer Thickness: 2.0 6 | Base Layers (integer): 0 7 | Base Nozzle Lift over Half Base Layer Thickness (ratio): 0.75 8 | Bottom Altitude: 0.0 9 | Open File to be Rafted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap_v0.1/Hollow Square Bottom_comb.gcode 10 | Infill Overhang (ratio): 0.1 11 | Interface Infill Density (ratio): 0.5 12 | Interface Layer Thickness over Layer Thickness: 1.0 13 | Interface Layers (integer): 0 14 | Interface Nozzle Lift over Half Interface Layer Thickness (ratio): 1.0 15 | Operating Nozzle Lift over Half Layer Thickness (ratio): 1.0 16 | Raft Outset Radius over Extrusion Width (ratio): 15.0 17 | Support Flowrate over Operating Flowrate (ratio): 1.0 18 | Support Gap over Perimeter Extrusion Width (ratio): 1.0 19 | No Support Material True 20 | Support Material Everywhere False 21 | Support Material on Exterior Only False 22 | Support Minimum Angle (degrees): 60.0 23 | Temperature Change Time Before Raft (seconds): 120.0 24 | Temperature Change Time Before First Layer Outline (seconds): 120.0 25 | Temperature Change Time Before Next Threads (seconds): 120.0 26 | Temperature Change Time Before Support Layers (seconds): 120.0 27 | Temperature Change Time Before Supported Layers (seconds): 120.0 28 | Temperature of Raft (Celcius): 0.0 29 | Temperature of Shape First Layer Outline (Celcius): 130.0 30 | Temperature of Shape First Layer Within (Celcius): 130.0 31 | Temperature of Shape Next Layers (Celcius): 120.0 32 | Temperature of Support Layers (Celcius): 200.0 33 | Temperature of Supported Layers (Celcius): 230.0 34 | windowPositionRaft Preferences 0+0 35 | windowPositionRaft Preferences 0+0 36 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/PLA/raft.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated preferences. 2 | Activate Raft: True 3 | Add Raft, Elevate Nozzle, Orbit and Set Altitude: True 4 | Base Infill Density (ratio): 0.5 5 | Base Layer Thickness over Layer Thickness: 2.0 6 | Base Layers (integer): 0 7 | Base Nozzle Lift over Half Base Layer Thickness (ratio): 0.75 8 | Bottom Altitude: 0.0 9 | Open File to be Rafted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap_v0.1/Hollow Square Bottom_comb.gcode 10 | Infill Overhang (ratio): 0.1 11 | Interface Infill Density (ratio): 0.5 12 | Interface Layer Thickness over Layer Thickness: 1.0 13 | Interface Layers (integer): 0 14 | Interface Nozzle Lift over Half Interface Layer Thickness (ratio): 1.0 15 | Operating Nozzle Lift over Half Layer Thickness (ratio): 1.0 16 | Raft Outset Radius over Extrusion Width (ratio): 15.0 17 | Support Flowrate over Operating Flowrate (ratio): 1.0 18 | Support Gap over Perimeter Extrusion Width (ratio): 1.0 19 | No Support Material True 20 | Support Material Everywhere False 21 | Support Material on Exterior Only False 22 | Support Minimum Angle (degrees): 60.0 23 | Temperature Change Time Before Raft (seconds): 120.0 24 | Temperature Change Time Before First Layer Outline (seconds): 120.0 25 | Temperature Change Time Before Next Threads (seconds): 120.0 26 | Temperature Change Time Before Support Layers (seconds): 120.0 27 | Temperature Change Time Before Supported Layers (seconds): 120.0 28 | Temperature of Raft (Celcius): 0.0 29 | Temperature of Shape First Layer Outline (Celcius): 180.0 30 | Temperature of Shape First Layer Within (Celcius): 180.0 31 | Temperature of Shape Next Layers (Celcius): 160.0 32 | Temperature of Support Layers (Celcius): 200.0 33 | Temperature of Supported Layers (Celcius): 230.0 34 | windowPositionRaft Preferences 0+0 35 | windowPositionRaft Preferences 0+0 36 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/carve.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated carve preferences. 2 | Name Value 3 | Open File to be Carved 4 | Import Coarseness (ratio): 1.0 5 | Correct Mesh True 6 | Unproven Mesh False 7 | Infill Bridge Thickness over Layer Thickness (ratio): 1.0 8 | Infill in Direction of Bridges True 9 | Layer Thickness (mm): 0.4 10 | Layer Thickness over Precision (ratio): 10.0 11 | Layers From (index): 0 12 | Layers To (index): 999999999 13 | Perimeter Width over Thickness (ratio): 1.8 14 | windowPositionCarve Preferences 698+272 15 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/clip.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated clip preferences. 2 | Name Value 3 | Activate Clip True 4 | Clip Over Extrusion Width (ratio): 0.15 5 | Open File to be Clipped 6 | windowPositionClip Preferences 6+71 7 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/comb.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated comb preferences. 2 | Name Value 3 | Activate Comb False 4 | Arrival Inset Follow Distance over Extrusion Width (ratio): 3.0 5 | Jitter Over Extrusion Width (ratio): 2.0 6 | Minimum Perimeter Departure Distance over Extrusion Width (ratio): 30.0 7 | Open File to be Combed 8 | windowPositionComb Preferences 618+140 9 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/cool.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated cool preferences. 2 | Name Value 3 | Activate Cool False 4 | Open File to be Cooled 5 | Minimum Layer Time (seconds): 0.0 6 | Minimum Orbital Radius (millimeters): 0.0 7 | Turn Fan On at Beginning False 8 | Turn Fan Off at Ending False 9 | windowPositionCool Preferences 9+94 10 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/craft.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated craft preferences. 2 | Name Value 3 | carveButton 0 4 | clipButton 0 5 | combButton 0 6 | coolButton 0 7 | exportButton 0 8 | fillButton 0 9 | filletButton 0 10 | homeButton 0 11 | hopButton 0 12 | insetButton 0 13 | multiplyButton 0 14 | oozebaneButton 0 15 | prefaceButton 0 16 | raftButton 0 17 | speedButton 0 18 | stretchButton 0 19 | towerButton 0 20 | unpauseButton 0 21 | wipeButton 0 22 | Open File to be Crafted 23 | windowPositionCraft Preferences 415+388 24 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/fill.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated fill preferences. 2 | Name Value 3 | Diaphragm Period (layers): 999999 4 | Diaphragm Thickness (layers): 0 5 | Extra Shells on Alternating Solid Layer (layers): 1 6 | Extra Shells on Base (layers): 1 7 | Extra Shells on Sparse Layer (layers): 1 8 | Grid Extra Overlap (ratio): 0.12 9 | Grid Junction Separation Band Height (layers): 10 10 | Grid Junction Separation over Octogon Radius At End (ratio): 0.0 11 | Grid Junction Separation over Octogon Radius At Middle (ratio): 0.0 12 | Open File to be Filled 13 | Infill Begin Rotation (degrees): 45.0 14 | Infill Begin Rotation Repeat (layers): 1 15 | Infill Solidity (ratio): 0.2 16 | Infill Odd Layer Extra Rotation (degrees): 90.0 17 | Grid Hexagonal True 18 | Grid Rectangular False 19 | Line False 20 | Interior Infill Density over Exterior Density (ratio): 0.9 21 | Outside Extruded First True 22 | Solid Surface Thickness (layers): 3 23 | windowPositionFill Preferences 685+377 24 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/hop.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated hop preferences. 2 | Name Value 3 | Activate Hop False 4 | Open File to be Hopped 5 | Hop Over Layer Thickness (ratio): 1.0 6 | Minimum Hop Angle (degrees): 30.0 7 | windowPositionHop Preferences 228+71 8 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/inset.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated inset preferences. 2 | Name Value 3 | Add Custom Code for Temperature Reading True 4 | Extrusion Width over Thickness (ratio): 1.5 5 | Open File to be Insetted 6 | Infill Bridge Width over Extrusion Width (ratio): 1.0 7 | Infill Perimeter Overlap (ratio): 0.3 8 | Calculate Overlap from Perimeter and Infill True 9 | Calculate Overlap from Perimeter Only False 10 | Remove Extrusion Overlap True 11 | Turn Extruder Heater Off at Shut Down True 12 | windowPositionInset Preferences 578+395 13 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/multiply.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated multiply preferences. 2 | Name Value 3 | Activate Multiply: False 4 | Center X (millimeters): 0.0 5 | Center Y (millimeters): 0.0 6 | Open File to be Multiplied 7 | Number of Columns (integer): 2 8 | Number of Rows (integer): 1 9 | Separation over Extrusion Width (ratio): 15.0 10 | windowPositionMultiply Preferences 329+353 11 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/oozebane.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated oozebane preferences. 2 | Name Value 3 | Activate Oozebane False 4 | After Startup Distance (millimeters): 1.2 5 | Early Shutdown Distance (millimeters): 1.2 6 | Early Startup Distance Constant (millimeters): 20.0 7 | Early Startup Maximum Distance (millimeters): 1.2 8 | First Early Startup Distance (millimeters): 25.0 9 | Open File to be Oozebaned 10 | Minimum Distance for Early Startup (millimeters): 0.0 11 | Minimum Distance for Early Shutdown (millimeters): 0.0 12 | Slowdown Startup Steps (positive integer): 3 13 | windowPositionOozebane Preferences 6+71 14 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/preface.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated preface preferences. 2 | Name Value 3 | Add M110 GCode for Compatibility with Nophead's Code False 4 | Open File to be Prefaced 5 | Do Not Add Extrusion Distance True 6 | Extrusion Distance Absolute False 7 | Extrusion Distance Relative False 8 | Name of End File: end.gcode 9 | Name of Start File: start.gcode 10 | Set Positioning to Absolute True 11 | Set Units to Millimeters True 12 | Start at Home False 13 | Turn Extruder Off at Shut Down True 14 | Turn Extruder Off at Start Up True 15 | windowPositionPreface Preferences 612+121 16 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/raft.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated raft preferences. 2 | Name Value 3 | Activate Raft: True 4 | Add Raft, Elevate Nozzle, Orbit and Set Altitude: True 5 | Base Infill Density (ratio): 0.3 6 | Base Layer Thickness over Layer Thickness: 2.0 7 | Base Layers (integer): 1 8 | Base Nozzle Lift over Half Base Layer Thickness (ratio): 0.75 9 | Bottom Altitude: 0.0 10 | Open File to be Rafted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap_v0.1/Hollow Square Bottom_comb_raft.gcode 11 | Infill Overhang (ratio): 0.1 12 | Interface Infill Density (ratio): 0.5 13 | Interface Layer Thickness over Layer Thickness: 1.0 14 | Interface Layers (integer): 2 15 | Interface Nozzle Lift over Half Interface Layer Thickness (ratio): 0.9 16 | Operating Nozzle Lift over Half Layer Thickness (ratio): 1.0 17 | Raft Outset Radius over Extrusion Width (ratio): 10.0 18 | Support Cross Hatch: True 19 | Support Flowrate over Operating Flowrate (ratio): 1.0 20 | Support Gap over Perimeter Extrusion Width (ratio): 1.0 21 | No Support Material True 22 | Support Material Everywhere False 23 | Support Material on Exterior Only False 24 | Support Minimum Angle (degrees): 60.0 25 | Temperature Change Time Before Raft (seconds): 0.0 26 | Temperature Change Time Before First Layer Outline (seconds): 0.0 27 | Temperature Change Time Before Next Threads (seconds): 0.0 28 | Temperature Change Time Before Support Layers (seconds): 0.0 29 | Temperature Change Time Before Supported Layers (seconds): 0.0 30 | Temperature of Raft (Celcius): 235.0 31 | Temperature of Shape First Layer Outline (Celcius): 235.0 32 | Temperature of Shape First Layer Within (Celcius): 240.0 33 | Temperature of Shape Next Layers (Celcius): 242.0 34 | Temperature of Support Layers (Celcius): 230.0 35 | Temperature of Supported Layers (Celcius): 230.0 36 | windowPositionRaft Preferences 654+177 37 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/speed.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated speed preferences. 2 | Name Value 3 | Activate Speed: True 4 | Bridge Feedrate Multiplier (ratio): 1.0 5 | Extrusion Diameter over Thickness (ratio): 1.25 6 | Feedrate (mm/s): 16.0 7 | Open File to be Speeded 8 | Do Not Add Flowrate False 9 | Metric False 10 | PWM Setting True 11 | Flowrate PWM Setting (if PWM Setting is Chosen): 400.0 12 | Maximum Z Feedrate (mm/s): 8.0 13 | Orbital Feedrate over Operating Feedrate (ratio): 0.5 14 | Perimeter Feedrate over Operating Feedrate (ratio): 1.0 15 | Perimeter Flowrate over Operating Flowrate (ratio): 1.0 16 | Travel Feedrate (mm/s): 20.0 17 | windowPositionSpeed Preferences 717+378 18 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/stretch.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated stretch preferences. 2 | Name Value 3 | Activate Stretch True 4 | Loop Stretch Over Extrusion Width (ratio): 0.15 5 | Path Stretch Over Extrusion Width (ratio): 0.0 6 | Open File to be Stretched 7 | Stretch From Distance Over Extrusion Width (ratio): 2.0 8 | Perimeter Maximum Stretch Over Extrusion Width (ratio): 0.38 9 | windowPositionStretch Preferences 522+431 10 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/extrusion/rapman_ABS/tower.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated tower preferences. 2 | Name Value 3 | Activate Tower False 4 | Extruder Possible Collision Cone Angle (degrees): 60.0 5 | Open File to be Towered 6 | Maximum Tower Height (layers): 0 7 | Tower Start Layer (integer): 1 8 | windowPositionTower Preferences 520+486 9 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/milling/End_Mill/chop.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated chop preferences. 2 | Name Value 3 | Add Extra Top Layer if Necessary True 4 | Open File to be Chopped 5 | Import Coarseness (ratio): 1.0 6 | Correct Mesh True 7 | Unproven Mesh False 8 | Layer Thickness (mm): 0.4 9 | Layer Thickness over Precision (ratio): 10.0 10 | Layers From (index): 0 11 | Layers To (index): 999999999 12 | Perimeter Width (mm): 2.0 13 | windowPositionChop Preferences 600+0 14 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/milling/End_Mill/lift.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated lift preferences. 2 | Name Value 3 | Activate Lift: True 4 | Cutting Lift over Layer Step (ratio): -0.5 5 | Open File to be Lifted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/Screw Holder Bottom.stl 6 | Clearance above Top (mm): 5.0 7 | windowPositionLift Preferences 440+53 8 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/milling/Laser/chop.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated chop preferences. 2 | Name Value 3 | Add Extra Top Layer if Necessary True 4 | Open File to be Chopped 5 | Import Coarseness (ratio): 1.0 6 | Correct Mesh True 7 | Unproven Mesh False 8 | Layer Thickness (mm): 0.4 9 | Layer Thickness over Precision (ratio): 10.0 10 | Layers From (index): 0 11 | Layers To (index): 999999999 12 | Perimeter Width (mm): 0.2 13 | windowPositionChop Preferences 600+0 14 | -------------------------------------------------------------------------------- /skeinforge_tools/profiles/milling/Laser/lift.csv: -------------------------------------------------------------------------------- 1 | Format is tab separated lift preferences. 2 | Name Value 3 | Activate Lift: True 4 | Cutting Lift over Layer Step (ratio): 0.0 5 | Open File to be Lifted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/Screw Holder Bottom.stl 6 | Clearance above Top (mm): 5.0 7 | windowPositionLift Preferences 440+53 8 | -------------------------------------------------------------------------------- /skeinforge_tools/skeinforge_utilities/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['euclidean', 'gcodec', 'intercircle', 'preferences', 'trianglemesh', 'vec3'] 2 | 3 | #This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. 4 | 5 | import os 6 | import sys 7 | 8 | numberOfLevelsDeepInPackageHierarchy = 2 9 | packageFilePath = os.path.abspath( __file__ ) 10 | for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): 11 | packageFilePath = os.path.dirname( packageFilePath ) 12 | if packageFilePath not in sys.path: 13 | sys.path.insert( 0, packageFilePath ) 14 | -------------------------------------------------------------------------------- /skeinforge_tools/skeinforge_utilities/consecution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Consecution is a collection of utilities to chain together the craft plugins. 3 | 4 | """ 5 | 6 | from __future__ import absolute_import 7 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 8 | import __init__ 9 | 10 | from skeinforge_tools.skeinforge_utilities import gcodec 11 | from skeinforge_tools.skeinforge_utilities import settings 12 | from skeinforge_tools import analyze 13 | from skeinforge_tools import profile 14 | import os 15 | import sys 16 | import time 17 | 18 | 19 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 20 | __date__ = "$Date: 2008/21/04 $" 21 | __license__ = "GPL 3.0" 22 | 23 | 24 | def getCraftModule( fileName ): 25 | "Get craft module." 26 | craftPluginsDirectoryPath = gcodec.getAbsoluteFolderPath( os.path.dirname( __file__ ), 'craft_plugins' ) 27 | return gcodec.getModuleWithDirectoryPath( craftPluginsDirectoryPath, fileName ) 28 | 29 | def getChainText( fileName, procedure ): 30 | "Get a crafted shape file." 31 | text = gcodec.getFileText( fileName ) 32 | procedures = getProcedures( procedure, text ) 33 | return getChainTextFromProcedures( fileName, procedures, text ) 34 | 35 | def getChainTextFromProcedures( fileName, procedures, text ): 36 | "Get a crafted shape file from a list of procedures." 37 | lastProcedureTime = time.time() 38 | for procedure in procedures: 39 | craftModule = getCraftModule( procedure ) 40 | if craftModule != None: 41 | text = craftModule.getCraftedText( fileName, text ) 42 | if gcodec.isProcedureDone( text, procedure ): 43 | print( '%s procedure took %s seconds.' % ( procedure.capitalize(), int( round( time.time() - lastProcedureTime ) ) ) ) 44 | lastProcedureTime = time.time() 45 | return text 46 | 47 | def getLastModule(): 48 | "Get the last tool." 49 | craftSequence = getReadCraftSequence() 50 | if len( craftSequence ) < 1: 51 | return None 52 | return getCraftModule( craftSequence[ - 1 ] ) 53 | 54 | def getProcedures( procedure, text ): 55 | "Get the procedures up to and including the given procedure." 56 | craftSequence = getReadCraftSequence() 57 | sequenceIndexPlusOneFromText = getSequenceIndexPlusOneFromText( text ) 58 | sequenceIndexFromProcedure = getSequenceIndexFromProcedure( procedure ) 59 | return craftSequence[ sequenceIndexPlusOneFromText : sequenceIndexFromProcedure + 1 ] 60 | 61 | def getReadCraftSequence(): 62 | "Get profile sequence." 63 | return profile.getCraftTypePluginModule().getCraftSequence() 64 | 65 | def getSequenceIndexPlusOneFromText( fileText ): 66 | "Get the profile sequence index of the file plus one. Return zero if the procedure is not in the file" 67 | craftSequence = getReadCraftSequence() 68 | for craftSequenceIndex in xrange( len( craftSequence ) - 1, - 1, - 1 ): 69 | procedure = craftSequence[ craftSequenceIndex ] 70 | if gcodec.isProcedureDone( fileText, procedure ): 71 | return craftSequenceIndex + 1 72 | return 0 73 | 74 | def getSequenceIndexFromProcedure( procedure ): 75 | "Get the profile sequence index of the procedure. Return None if the procedure is not in the sequence" 76 | craftSequence = getReadCraftSequence() 77 | if procedure not in craftSequence: 78 | return 0 79 | return craftSequence.index( procedure ) 80 | 81 | def writeChainTextWithNounMessage( fileName, procedure ): 82 | "Get and write a crafted shape file." 83 | print( '' ) 84 | print( 'The %s tool is parsing the file:' % procedure ) 85 | print( os.path.basename( fileName ) ) 86 | print( '' ) 87 | startTime = time.time() 88 | suffixFileName = fileName[ : fileName.rfind( '.' ) ] + '_' + procedure + '.gcode' 89 | craftText = getChainText( fileName, procedure ) 90 | if craftText == '': 91 | return 92 | gcodec.writeFileText( suffixFileName, craftText ) 93 | print( '' ) 94 | print( 'The %s tool has created the file:' % procedure ) 95 | print( suffixFileName ) 96 | print( '' ) 97 | print( 'It took ' + str( int( round( time.time() - startTime ) ) ) + ' seconds to craft the file.' ) 98 | analyze.writeOutput( suffixFileName, craftText ) 99 | -------------------------------------------------------------------------------- /skeinforge_tools/skeinforge_utilities/interpret.py: -------------------------------------------------------------------------------- 1 | """ 2 | Interpret is a collection of utilities to list the import plugins. 3 | 4 | An import plugin is a script in the import_plugins folder which has the function getTriangleMesh. 5 | 6 | The following examples shows functions of interpret. The examples are run in a terminal in the folder which contains interpret.py. 7 | 8 | 9 | > python 10 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 11 | [GCC 4.2.1 (SUSE Linux)] on linux2 12 | Type "help", "copyright", "credits" or "license" for more information. 13 | >>> import interpret 14 | >>> interpret.getGNUTranslatorGcodeFileTypeTuples() 15 | [('GTS files', '*.gts'), ('Gcode text files', '*.gcode'), ('STL files', '*.stl'), ('SVG files', '*.svg')] 16 | 17 | >>> interpret.getImportPluginFileNames() 18 | ['gts', 'stl', 'svg'] 19 | 20 | """ 21 | 22 | from __future__ import absolute_import 23 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 24 | import __init__ 25 | 26 | from skeinforge_tools.skeinforge_utilities import gcodec 27 | import os 28 | 29 | 30 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 31 | __date__ = "$Date: 2008/21/04 $" 32 | __license__ = "GPL 3.0" 33 | 34 | 35 | def getFirstTranslatorFileNameUnmodified( fileName ): 36 | "Get the first file name from the translators in the import plugins folder, if the file name is not already set." 37 | if fileName != '': 38 | return fileName 39 | unmodified = getGNUTranslatorFilesUnmodified() 40 | if len( unmodified ) == 0: 41 | print( "There are no unmodified gcode files in this folder." ) 42 | return '' 43 | return unmodified[ 0 ] 44 | 45 | def getGNUTranslatorGcodeFileTypeTuples(): 46 | "Get the file type tuples from the translators in the import plugins folder plus gcode." 47 | fileTypeTuples = getTranslatorFileTypeTuples() 48 | fileTypeTuples.append( ( 'Gcode text files', '*.gcode' ) ) 49 | fileTypeTuples.sort() 50 | return fileTypeTuples 51 | 52 | def getGNUTranslatorFilesUnmodified(): 53 | "Get the file types from the translators in the import plugins folder." 54 | return gcodec.getFilesWithFileTypesWithoutWords( getImportPluginFileNames() ) + [ gcodec.getUnmodifiedGCodeFiles() ] 55 | 56 | def getImportPluginFileNames(): 57 | "Get analyze plugin fileNames." 58 | return gcodec.getPluginFileNamesFromDirectoryPath( gcodec.getAbsoluteFolderPath( os.path.dirname( __file__ ), 'import_plugins' ) ) 59 | 60 | def getTranslatorFileTypeTuples(): 61 | "Get the file types from the translators in the import plugins folder." 62 | importPluginFileNames = getImportPluginFileNames() 63 | fileTypeTuples = [] 64 | for importPluginFileName in importPluginFileNames: 65 | fileTypeTitle = importPluginFileName.upper() + ' files' 66 | fileType = ( fileTypeTitle, '*.' + importPluginFileName ) 67 | fileTypeTuples.append( fileType ) 68 | fileTypeTuples.sort() 69 | return fileTypeTuples 70 | -------------------------------------------------------------------------------- /skeinforge_tools/skeinforge_utilities/svg_canvas.template: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | replaceLineWithTitle 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /skeinforge_tools/skeinforge_utilities/version.txt: -------------------------------------------------------------------------------- 1 | 2010-02-05 -------------------------------------------------------------------------------- /skeinforge_tools/skeinforge_utilities/xml_simple_parser.py: -------------------------------------------------------------------------------- 1 | """ 2 | The xml_simple_parser.py script is an xml parser that can parse a line separated xml text. 3 | 4 | This xml parser will read a line seperated xml text and produce a tree of the xml with a root element. Each element can have an attribute table, children, a class name, parents, text and a link to the root element. 5 | 6 | This example gets an xml tree for the xml file boolean.xml. This example is run in a terminal in the folder which contains boolean.xml and xml_simple_parser.py. 7 | 8 | 9 | > python 10 | Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) 11 | [GCC 4.2.1 (SUSE Linux)] on linux2 12 | Type "help", "copyright", "credits" or "license" for more information. 13 | >>> file = open( 'boolean.xml', 'r' ) 14 | >>> xmlText = file.read() 15 | >>> file.close() 16 | >>> from xml_simple_parser import XMLSimpleParser 17 | >>> xmlParser = XMLSimpleParser( xmlText ) 18 | >>> print( xmlParser ) 19 | ?xml, {'version': '1.0'} 20 | ArtOfIllusion, {'xmlns:bf': '//babelfiche/codec', 'version': '2.0', 'fileversion': '3'} 21 | Scene, {'bf:id': 'theScene'} 22 | materials, {'bf:elem-type': 'java.lang.Object', 'bf:list': 'collection', 'bf:id': '1', 'bf:type': 'java.util.Vector'} 23 | .. 24 | many more lines of the xml tree 25 | .. 26 | 27 | """ 28 | 29 | 30 | from __future__ import absolute_import 31 | #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. 32 | import __init__ 33 | 34 | from skeinforge_tools.skeinforge_utilities import euclidean 35 | from skeinforge_tools.skeinforge_utilities import gcodec 36 | 37 | __author__ = "Enrique Perez (perez_enrique@yahoo.com)" 38 | __credits__ = 'Nophead \nArt of Illusion ' 39 | __date__ = "$Date: 2008/21/04 $" 40 | __license__ = "GPL 3.0" 41 | 42 | 43 | class XMLElement: 44 | "An xml element." 45 | def __init__( self ): 46 | "Add empty lists." 47 | self.attributeTable = {} 48 | self.children = [] 49 | self.className = '' 50 | self.parents = [] 51 | self.rootElement = None 52 | self.text = '' 53 | 54 | def __repr__( self ): 55 | "Get the string representation of this XML element." 56 | stringRepresentation = '%s%s, %s' % ( ' ' * len( self.parents ), self.className, self.attributeTable ) 57 | if len( self.text ): 58 | stringRepresentation += '\n%s%s' % ( ' ' * len( self.parents ), self.text ) 59 | for child in self.children: 60 | stringRepresentation += '\n%s' % child 61 | return stringRepresentation 62 | 63 | def addAttribute( self, word ): 64 | "Set the attribute table to the split line." 65 | indexOfEqualSign = word.find( '=' ) 66 | key = word[ : indexOfEqualSign ] 67 | afterEqualSign = word[ indexOfEqualSign + 1 : ] 68 | afterEqualSign = afterEqualSign.lstrip() 69 | value = afterEqualSign[ 1 : - 1 ] 70 | self.attributeTable[ key ] = value 71 | 72 | def getChildrenWithClassName( self, className ): 73 | "Get the children which have the given class name." 74 | childrenWithClassName = [] 75 | for child in self.children: 76 | if className == child.className: 77 | childrenWithClassName.append( child ) 78 | return childrenWithClassName 79 | 80 | def getFirstChildWithClassName( self, className ): 81 | "Get the first child which has the given class name." 82 | childrenWithClassName = self.getChildrenWithClassName( className ) 83 | if len( childrenWithClassName ) < 1: 84 | return None 85 | return childrenWithClassName[ 0 ] 86 | 87 | def getSubChildWithID( self, idReference ): 88 | "Get the child which has the idReference." 89 | for child in self.children: 90 | if 'bf:id' in child.attributeTable: 91 | if child.attributeTable[ 'bf:id' ] == idReference: 92 | return child 93 | subChildWithID = child.getSubChildWithID( idReference ) 94 | if subChildWithID != None: 95 | return subChildWithID 96 | return None 97 | 98 | def parseReplacedLine( self, line, parents ): 99 | "Parse replaced line." 100 | if line[ : len( '', ' ' ).find( ' ' ) ] 104 | indexOfEndOfTheBeginTag = - 1 105 | lastWord = line[ - 2 : ] 106 | splitLine = line.replace( '">', '" > ' ).split() 107 | if lastWord == '/>': 108 | indexOfEndOfTheBeginTag = len( splitLine ) - 1 109 | elif '>' in splitLine: 110 | indexOfEndOfTheBeginTag = splitLine.index( '>' ) 111 | for word in splitLine[ 1 : indexOfEndOfTheBeginTag ]: 112 | self.addAttribute( word ) 113 | self.parents = parents 114 | if len( self.parents ) > 0: 115 | parents[ - 1 ].children.append( self ) 116 | if lastWord == '/>': 117 | return 118 | tagEnd = '' % self.className 119 | if line[ - len( tagEnd ) : ] == tagEnd: 120 | untilTagEnd = line[ : - len( tagEnd ) ] 121 | lastGreaterThanIndex = untilTagEnd.rfind( '>' ) 122 | self.text = untilTagEnd[ lastGreaterThanIndex + 1 : ] 123 | return 124 | parents.append( self ) 125 | 126 | 127 | class XMLSimpleParser: 128 | "A simple xml parser." 129 | def __init__( self, xmlText ): 130 | "Add empty lists." 131 | self.isInComment = False 132 | self.parents = [] 133 | self.rootElement = None 134 | self.lines = gcodec.getTextLines( xmlText ) 135 | for line in self.lines: 136 | self.parseLine( line ) 137 | 138 | def __repr__( self ): 139 | "Get the string representation of this parser." 140 | return str( self.rootElement ) 141 | 142 | def parseLine( self, line ): 143 | "Parse a gcode line and add it to the inset skein." 144 | lineStripped = line.lstrip() 145 | if len( lineStripped ) < 1: 146 | return 147 | if lineStripped[ : len( '' ) != - 1: 151 | self.isInComment = False 152 | return 153 | if self.isInComment: 154 | return 155 | xmlElement = XMLElement() 156 | xmlElement.parseReplacedLine( lineStripped, self.parents ) 157 | if self.rootElement == None: 158 | self.rootElement = xmlElement 159 | xmlElement.rootElement = self.rootElement 160 | --------------------------------------------------------------------------------