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']
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 |
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 |
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( '' ) ] == '':
101 | del parents[ - 1 ]
102 | return
103 | self.className = line[ 1 : line.replace( '>', ' ' ).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 = '%s>' % 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 |
--------------------------------------------------------------------------------