Giter Site home page Giter Site logo

kliment / printrun Goto Github PK

View Code? Open in Web Editor NEW
2.3K 176.0 993.0 81.38 MB

Pronterface, Pronsole, and Printcore - Pure Python 3d printing host software

License: GNU General Public License v3.0

Python 96.98% C 0.12% Batchfile 1.11% G-code 0.64% Cython 1.15%

printrun's Introduction

PRINTRUN

License GitHub - Downloads GitHub contributors PyPI - Version PyPI - Downloads

Printrun consists of a suite of hosts for 3D printers and other CNC machines (printcore, pronsole and pronterface) and a small collection of helpful scripts.

  • printcore.py is a library that makes writing RepRap hosts easy
  • pronsole.py is an interactive command-line host with tab-completion goodness
  • pronterface.py is a graphical host with the same functionality as pronsole

The contents of this document are organized in the following sections:

GETTING PRINTRUN

Installation of Printrun can be done in several ways, either installing a pre-compiled binary, via distribution-specific packages from official repositories or from PyPI. If you want the newest, shiniest features, you can run Printrun from source.

Distributed Binaries and Packages

Windows and macOS pre-compiled binaries

Everything bundled into one single package for easy installation. Downloads available at: https://github.com/kliment/Printrun/releases/latest

Note for OSX users: if OSX tells you "pronterface.app" cannot be opened because the developer cannot be verified., you don't need to re-download it. Instead, you need to allow OSX to run the unsigned app. To do this, right- or ctrl click the application in Finder and select Open. Then click Open in the popup window that appears. You only need to do this once.

Linux packages from official repositories

Ubuntu / Mint / Raspberry Pi OS / Debian

Install the full suite: sudo apt install printrun

Or only the apps you need: sudo apt install pronsole or pronterface or plater

Chrome OS

You can use Printrun via crouton. Assuming you want Ubuntu Trusty, you used probably sudo sh -e ~/Downloads/crouton -r trusty -t xfce to install Ubuntu. Fetch and install printrun with the line given above for Ubuntu/Debian.

By default you have no access to the serial port under Chrome OS crouton, so you cannot connect to your 3D printer. Add yourself to the serial group within the linux environment to fix this

sudo usermod -G serial -a <username>

where <username> should be your username. Log out and in to make this group change active and allow communication with your printer.

Fedora

Install the full suite: sudo dnf install printrun

Or only the apps you need: sudo dnf install pronsole or pronterface or plater

Adding --enablerepo updates-testing option to dnf might sometimes give you newer packages (but also not very tested).

Arch Linux

Packages are available in AUR. Just run

yaourt printrun

Printrun package from PyPI

If you have a working Python environment, regardless of your OS, you can install the latest release distributed through the PyPI repository using pip and, optionally (but highly recommended), a virtual environment.

Activate your virtual environment, and run (Linux / macOS):

python -m pip install Printrun

or (Windows):

py -m pip install Printrun

Running From Source

By running Printrun from source you get access to the latest features and in-development changes. Warning note: these might not be fully working or stable.

Linux / macOS

1. Install Python

Almost all Linux distributions come with Python already pre-installed. If not, install Python normally from your package manager. On macOS download and install the latest Python from python.org.

2. Download the latest Printrun source code

Obtain the latest source code by running the following in a terminal window:

$ git clone https://github.com/kliment/Printrun.git  # clone the repository
$ cd Printrun  # change to Printrun directory

3. Use a Python virtual environment

Easiest way to run Printrun from source is to create and use a Python virtual environment. This step is optional but highly recommended to avoid conflicts with other Python libraries already installed (or that will be installed in the future) in your system. Within the Printrun's root directory, create and activate a virtual environment by running:

$ python -m venv venv       # create a virtual environment
$ source venv/bin/activate  # activate the virtual environment

Note for Ubuntu/Debian: You might need to install python3-venv first.

Note for Ubuntu/Debian: If you get python: command not found use python3 -m venv venv instead.

4. Install Printrun

Once activated your virtual environment, install Printrun' source code with:

(venv) $ python -m pip install .

Note for Linux users: wxPython4 doesn't have Linux wheels available from the Python Package Index yet. Before running the command above, find a proper wheel for your distro at extras.wxpython.org and substitute the link in the below example. You might skip this wheel installation, but that results in compiling wxPython4 from source, which can be time and resource consuming and might fail.

(venv) $ python -m pip install https://extras.wxpython.org/wxPython4/extras/linux/gtk3/fedora-27/wxPython-4.0.1-cp36-cp36m-linux_x86_64.whl  # replace the link with yours

5. Run Printrun

With your virtual environment still active, invoke the app you need like:

(venv) $ pronterface.py  # or `pronsole.py` or `plater.py`

Windows

First download and install GIT for Windows, Python 3.10 and a C-compiler environment. For the next steps we need a CMD window or a PowerShell window. You can use Windows Terminal for this as well. Create and navigate to a directory of your choice where you want to download the source files of this repository and follow the next steps:

CMD

> git clone https://github.com/kliment/Printrun.git
> cd Printrun
> release_windows.bat

PowerShell:

> git clone https://github.com/kliment/Printrun.git
> cd Printrun
> ./release_windows.bat

The script above will clone this repository. The script release_windows.bat will install a virtual environment named v3, download all needed python libraries and compile the binaries for Pronterface.exe and Pronsole.exe. You will find the files in the new created directory dist. You will find further and more detailed information in the script release_windows.bat. Run Pronterface or Pronsole from the binary files or from source calling pronterface.py for the GUI version and pronsole.py for the commandline version.

Running Pronsole works best by running it in WindowsTerminal. You can create a desktop shortcut link to the file pronsole.exe. Then edit the target for your shortcut as shown in belows example: %LocalAppData%\Microsoft\WindowsApps\wt.exe --title Pronsole %USERPROFILE%\Downloads\pronterface-test\pronsole.exe You need to adjust the path to your location of pronsole.exe.

Run 'release_windows.bat' when ever you make changes or updates. With each new run it will compile the binaries and update all involved libraries in the virtual environment if needed. Delete the virtual environment if you have problems with it.

USING PRINTRUN

USING PRONTERFACE

When you're done setting up Printrun, you can start pronterface.py in the directory you unpacked it. Select the port name you are using from the first drop-down, select your baud rate, and hit connect. Load an STL (see the note on skeinforge below) or GCODE file, and you can upload it to SD or print it directly. The "monitor printer" function, when enabled, checks the printer state (temperatures, SD print progress) every 3 seconds. The command box recognizes all pronsole commands, but has no tabcompletion.

If you want to load stl files, you need to install a slicing program such as Slic3r or Skeinforge and add its path to the settings.

Slic3r integration

To invoke Slic3r directly from Pronterface your slicing command (Settings > Options > External Commands > Slice Command) should look something like slic3r $s -o $o. If Slic3r is properly installed "slic3r" will suffice, otherwise, replace it with the full path to Slic3r's executable.

If the Slic3r integration option (Settings > Options > User interface > Enable Slic3r integration) is checked a new menu will appear after application restart which will allow you to choose among your previously saved Slic3r Print/Filament/Printer settings.

USING PRONSOLE

To use pronsole, you need:

  • Python 3 (ideally 3.10),
  • pyserial (or python3-serial on ubuntu/debian) and
  • pyreadline (not needed on Linux)

Start pronsole and you will be greeted with a command prompt. Type help to view the available commands. All commands have internal help, which you can access by typing "help commandname", for example "help connect"

If you want to load stl files, you need to put a version of skeinforge (doesn't matter which one) in a folder called "skeinforge". The "skeinforge" folder must be in the same folder as pronsole.py

USING PRINTCORE

To use printcore you need Python 3 (ideally 3.10) and pyserial (or python3-serial on ubuntu/debian) See pronsole for an example of a full-featured host, the bottom of printcore.py for a simple command-line sender, or the following code example:

#to send a file of gcode to the printer
from printrun.printcore import printcore
from printrun import gcoder
import time
p=printcore('/dev/ttyUSB0', 115200) # or p.printcore('COM3',115200) on Windows
gcode=[i.strip() for i in open('filename.gcode')] # or pass in your own array of gcode lines instead of reading from a file
gcode = gcoder.LightGCode(gcode)

# startprint silently exits if not connected yet
while not p.online:
  time.sleep(0.1)

p.startprint(gcode) # this will start a print

#If you need to interact with the printer:
p.send_now("M105") # this will send M105 immediately, ahead of the rest of the print
p.pause() # use these to pause/resume the current print
p.resume()
p.disconnect() # this is how you disconnect from the printer once you are done. This will also stop running prints.

PLATERS

Printrun provides two platers: a STL plater (plater.py) and a G-Code plater (gcodeplater.py).

3D VIEWER CONTROLS

When the 3D viewer is enabled, the controls are the following:

  • Mousewheel: zoom (Control reduces the zoom change steps)
  • Shift+mousewheel: explore layers (in print gcode view ; Control key makes layer change by increments of 10 instead of 1) or rotate object (in platers)
  • Left-click dragging: rotate view
  • Right-click dragging: pan view
  • Shift + left-click dragging: move object (in platers)
  • Page up/down keys: zoom (Control reduces the zoom change steps)
  • Up/down keys: explore layers
  • R key: reset view
  • F key: fit view to display entire print
  • C key: toggle "display current layer only" mode (in print gcode view)

RPC SERVER

pronterface and pronsole start a RPC server, which runs by default on localhost port 7978, which provides print progress information. Here is a sample Python script querying the print status:

import xmlrpc.client

rpc = xmlrpc.client.ServerProxy('http://localhost:7978')
print(rpc.status())

CONFIGURATION

Build dimensions

Build dimensions can be specified using the build_dimensions option (which can be graphically edited in Pronterface settings). This option is formed of 9 parameters: 3 for the build volume dimensions, 3 for the build volume coordinate system offset minimum, 3 for the endstop positions.

The default value is 200x200x100+0+0+0+0+0+0, which corresponds to a 200x200mm (width x height) bed with 100mm travel in Z (there are the first three numbers) and no offset. The absolute coordinates system origin (0,0,0) is at the bottom left corner on the bed surface, and the top right corner on the bed surface is (200,200,0).

A common practice is to have the origin of the coordinate system (0,0,0) at the center of the bed surface. This is achieved by using the next three parameters, for instance with 200x200x100-100-100+0+0+0+0. In this case, the bottom left corner of the bed will be at (-100,-100,0) and the top right one at (100,100,0).

These two sets of settings should be sufficient for most people. However, for some specific complicated setups and GCodes and some features, we might also need the endstops positions for perfect display. These positions (which are usually 0,0,0, so if you don't know you probably have a standard setup) are specified in absolute coordinates, so if you have your bed starting at (-100,-100,0) and your endstops are 10mm away from the bed left and right and the Z endstop 5mm above the bed, you'll want to set the endstops positions to (-110,-110,5) for this option.

USING MACROS AND CUSTOM BUTTONS

Macros in pronsole and pronterface

To send simple G-code (or pronsole command) sequence is as simple as entering them one by one in macro definition. If you want to use parameters for your macros, substitute them with {0} {1} {2} ... etc.

All macros are saved automatically immediately after being entered.

Example 1, simple one-line alias:

PC> macro where M114

Instead of having to remember the code to query position, you can query the position:

PC> where
X:25.00Y:11.43Z:5.11E:0.00

Example 2 - macros to switch between different slicer programs, using "set" command to change options:

PC> macro use_slicer
Enter macro using indented lines, end with empty line
..> set sliceoptscommand Slic3r/slic3r.exe --load slic3r.ini
..> set slicecommand Slic3r/slic3r.exe $s --load slic3r.ini --output $o
Macro 'use_slicer' defined
PC> macro use_sfact
..> set sliceoptscommand python skeinforge/skeinforge_application/skeinforge.py
..> set slicecommand python skeinforge/skeinforge_application/skeinforge_utilities/skeinforge_craft.py $s
Macro 'use_sfact' defined

Example 3, simple parametric macro:

PC> macro move_down_by
Enter macro using indented lines, end with empty line
..> G91
..> G1 Z-{0}
..> G90
..>

Invoke the macro to move the printhead down by 5 millimeters:

PC> move_down_by 5

For more powerful macro programming, it is possible to use python code escaping using ! symbol in front of macro commands. Note that this python code invocation also works in interactive prompt:

PC> !print("Hello, printer!")
Hello printer!

PC> macro debug_on !self.p.loud = 1
Macro 'debug_on' defined
PC> debug_on
PC> M114
SENT:  M114
X:0.00Y:0.00Z:0.00E:0.00 Count X:0.00Y:0.00Z:0.00
RECV:  X:0.00Y:0.00Z:0.00E:0.00 Count X:0.00Y:0.00Z:0.00
RECV:  ok

You can use macro command itself to create simple self-modify or toggle functionality:

Example: swapping two macros to implement toggle:

PC> macro toggle_debug_on
Enter macro using indented lines, end with empty line
..> !self.p.loud = 1
..> !print("Diagnostic information ON")
..> macro toggle_debug toggle_debug_off
..>
Macro 'toggle_debug_on' defined
PC> macro toggle_debug_off
Enter macro using indented lines, end with empty line
..> !self.p.loud = 0
..> !print("Diagnostic information OFF")
..> macro toggle_debug toggle_debug_on
..>
Macro 'toggle_debug_off' defined
PC> macro toggle_debug toggle_debug_on
Macro 'toggle_debug' defined

Now, each time we invoke "toggle_debug" macro, it toggles debug information on and off:

PC> toggle_debug
Diagnostic information ON

PC> toggle_debug
Diagnostic information OFF

When python code (using ! symbol) is used in macros, it is even possible to use blocks/conditionals/loops. It is okay to mix python code with pronsole commands, just keep the python indentation. For example, following macro toggles the diagnostic information similarily to the previous example:

!if self.p.loud:
  !self.p.loud = 0
  !print("Diagnostic information OFF")
!else:
  !self.p.loud = 1
  !print("Diagnostic information ON")

Macro parameters are available in '!'-escaped python code as locally defined list variable: arg[0] arg1 ... arg[N]

All python code is executed in the context of the pronsole (or PronterWindow) object, so it is possible to use all internal variables and methods, which provide great deal of functionality. However the internal variables and methods are not very well documented and may be subject of change, as the program is developed. Therefore it is best to use pronsole commands, which easily contain majority of the functionality that might be needed.

Some useful python-mode-only variables:

!self.settings - contains all settings, e.g.
  port (!self.settings.port), baudrate, xy_feedrate, e_feedrate, slicecommand, final_command, build_dimensions
  You can set them also via pronsole command "set", but you can query the values only via python code.
!self.p - printcore object (see USING PRINTCORE section for using printcore object)
!self.cur_button - if macro was invoked via custom button, the number of the custom button, e.g. for usage in "button" command
!self.gwindow - wx graphical interface object for pronterface (highly risky to use because the GUI implementation details may change a lot between versions)

Some useful methods:

!self.onecmd - invokes raw command, e.g.
    !self.onecmd("move x 10")
    !self.onecmd("!print self.p.loud")
    !self.onecmd("button "+self.cur_button+" fanOFF /C cyan M107")
!self.project - invoke Projector

USING HOST COMMANDS

Pronsole and the console interface in Pronterface accept a number of commands which you can either use directly or inside your G-Code. To run a host command from inside a G-Code, simply prefix it with ;@.

List of available commands:

  • pause: pauses the print until the user resumes it
  • run_script scriptname [arg1 ...]: runs a custom script or program on the host computer. This can for instance be used to produce a sound to warn the user (e.g. run_script beep -r 2 on machines were the beep util is available), or to send an email or text message at the end of a print. The $s token can be used in the arguments to get the current gcode file name
  • run_gcode_script scripname [arg1 ...]: same as run_script, except that all lines displayed by the script will be interpreted in turn (so that G-Code lines will be immediately sent to the printer)
  • shell pythoncommand: run a python command (can also be achieved by doing !pythoncommand)
  • set option value: sets the value of an option, e.g. set mainviz 3D
  • connect
  • block_until_online: wait for the printer to be online. For instance you can do python pronsole.py -e "connect" -e "block_until_online" -e "upload object.gcode" to start pronsole, connect for the printer, wait for it to be online to start uploading the object.gcode file.
  • disconnect
  • load gcodefile
  • upload gcodefile target.g: upload gcodefile to target.g on the SD card
  • slice stlfile: slice stlfile and load the produced G-Code
  • print: print the currently loaded file
  • sdprint target.g: start a SD print
  • ls: list files on SD card
  • eta: display remaining print time
  • gettemp: get current printer temperatures
  • settemp: set hotend target temperature
  • bedtemp: set bed target temperature
  • monitor: monitor printer progress during a print
  • tool K: switch to tool K
  • move xK: move along x axis (works with other axes too)
  • extrude length [speed]
  • reverse length [speed]
  • home [axis]
  • off: turns off fans, motors, extruder, heatbed, power supply
  • exit

TESTING

A small (work in progress) test suite is developed within folder tests using unittest which can be run with (requires Python 3.11+):

python -m unittest discover tests

Small utilities for testing/debugging communications or g-code reading/writing are also provided within folder testtools.

CONTRIBUTING

Thinking of contributing to Printrun? Awesome! Thank you! ❤️

Printrun is an open source project and we love to receive contributions from anyone. There are many ways to contribute:

  • Improving the documentation. This README is our main source of documentation and it surely lacks some love here and there or requires being brought up to date.

  • Submitting bug reports and feature requests.

    • We use GitHub's issue tracker to keep track of them.
    • Please remember to state your OS and Printrun version on new issues.
  • Improving the test code base. Current code coverage is extremely low. See testing section for more information.

  • Fixing existing issues and/or implementing requested features. There is a fair amount of known issues and a great deal of requested features waiting to be implemented. We (the maintainers) don't have the time and resources to look at them all so every code contribution will be very welcome.

    • We use GitHub's pull requests to review and incorporate new code.
    • Issues labeled Regression would be the most urgent fixes needed, followed by issues/requests labeled 2.x and lastly those with 3.x.
    • Ideally every new contribution should comply with PEP 8 style guide as much as possible and should be thoroughly documented to ease reviewing and future understanding of the code.
    • Please note that breaking changes might need to wait to be incorporated until the next major release is due.

CONTRIBUTORS

An enormous number of people helped make Printrun. See the list here.

LICENSE

Copyright (C) 2011-2024 Kliment Yanev, Guillaume Seguin, and the other contributors listed in CONTRIBUTORS.md

Printrun is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Printrun is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Printrun.  If not, see <http://www.gnu.org/licenses/>.

All scripts should contain this license note, if not, feel free to ask us. Please note that files where it is difficult to state this license note (such as images) are distributed under the same terms.

printrun's People

Contributors

a2k-hanlon avatar alranel avatar avag-sayan avatar axtheb avatar cakeller98 avatar chicagoduane avatar colah avatar d1plo1d avatar dependabot[bot] avatar divingduck avatar edef1c avatar freddii avatar fsantini avatar garyhodgson avatar hroncok avatar igoryeremin avatar ixce avatar jezmy avatar k-eex avatar kazw avatar kliment avatar maaajaaa avatar metzench avatar neofelis2x avatar rockstorm101 avatar sbliven avatar skateboss avatar tjhowse avatar traumflug avatar volconst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

printrun's Issues

Mac Pronterface cutting heating to nozzle?

I am using pronterface (precompiled) for mac with 0.6 slicer and I notice sometimes when I print that the heating will just be cut to the nozzle and it isn't until 5 or 10 minutes later that I notice this when the print fails. Is there a particular reason why it is doing this?

Thanks for such a great program!

Z+, Z- max buttons in new UI?

The new ui has buttons for Z+- .1, 1 , and 10, clicking the button above and below the 10 seems to send the z axis ALL the way in either direction. This is a potentially dangerous thing, especially with its proximity so close to the 10+- buttons.

Temperature indicators while running gcode

The temperature indicators in current experimental updates so you can see target temperature when manually setting the temperature, but does not when temperature is set in the gcode.

Python 2.5.2 problems

I downloaded 2011jul26 - fba262b

It works ok on Debian 601 with Python 2.6.6
It fails on Debian 506 with Python 2.5.2

Traceback (most recent call last):
File "./pronterface.py", line 23, in
import pronsole
File ".../kliment-Printrun-fba262b/pronsole.py", line 263
except ValueError as ve:
^
SyntaxError: invalid syntax

NOTE: "^" is under "as"

SFACT Profiles and Alterations location...

When I first ran SFACT directly, the Profiles and Alterations were in the "Skeinforge_Application" folder. Then when I ran it from within Pronterface, I ended up with all the adjusted settings lost... thought it was wierd, but turns out the profiles, and alterations end up inside "sfact_profiles" just under the main printrun folder.

is this expected behavior? - IOW, is it known that SFACT puts the profile folder within the folder you launch it from, rather than in your home folder? - so then should we be copying this folder to wherever we intend to run it from? and then what? we have to remember to disseminate all the modifications to all the various locations?

anyway - just wondered if it was something that pronterface was doing wierd, or sfact.

Loading a Slic3r generated GCode file causes error

When every I load a gocde file that has been generated by Slic3r(0.5.5b / 0.5.6) I get the following exception and nothing is displayed in the preview window.

I can send the code to the printer and it prints OK.

Exception in thread Thread-23:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 522, in __bootstrap_inner
self.run()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 477, in run
self.__target(_self.__args, *_self.__kwargs)
File "./r", line 1307, in loadviz
print _("Estimated duration (pessimistic): "), pronsole.estimate_duration(self.f)
File "/Users/geoffd/projects/mechanical/printrun/pronsole.py", line 129, in estimate_duration
f = get_coordinate_value("F", parts[1:])
File "/Users/geoffd/projects/mechanical/printrun/pronsole.py", line 88, in get_coordinate_value
return float(i[1:])
ValueError: invalid literal for float(): 900 ;

Time estimate seems off by factor of 60x

Latest Print::
Pessimistic estimate: 143 Hours, 13 Minutes
Actual time: 134 minutes, 6 seconds

is the estimate off by labels only? or is it just me?

another print - here's the output

Estimated duration (pessimistic): 192h41m
Print took 149 minutes 37 seconds.

again - seems like hours are minutes and minutes are seconds?

Possibility to set origin of preview window

I like that I can see the progress of the print in the preview window, however since I use pronterface with a makerbot I am used that (0,0) is located in the middle of the build platform. If I use multiply and set it to (0,0) I will always have prints which are located in the center of the build platform.

In pronterface (0,0) seems to be located at the lower left hand corner of the preview window. It would be nice if users could choose to have it in the middle.

Estimated duration and number of layers are way off

I sliced an object using slic3r which is 35mm high, at a layer height of 0.2mm. It should have 175layers, but Pronterface says 1955 layers and a vastly exaggerated print time estimate.

I am guessing this is something to do with the fact that I use the "Lift Z on retract" setting in slic3r, and pronterface is just counting every Z movement as a layer? If that is the case, I think the best way to solve this would be to ignore layers that only contain travels, when counting layers.

My print is still in progress as I write this issue but it looks like the current estimate has dropped from 17 hours down to 2h30m

From the console window:
...
the print goes from 0.2 mm to 35.2 mm in Z
and is 35.0 mm high

Estimated duration (pessimistic): 1955 layers, 17:13:32

[experimental branch] Unable to open file twice

On the experimental branch ( & Mac OS X):
I can load file and have it processed (either skeinforge or slic3r).
When I want to load the next file, no file menu dialog appears, instead I get a stacktrace:
Traceback (most recent call last):
File "pronterface.py", line 1280, in loadfile
self.skeinp.terminate()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1392, in terminate
self.send_signal(signal.SIGTERM)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1387, in send_signal
os.kill(self.pid, sig)
OSError: [Errno 3] No such process

Error on UTF8 output of slicer

problems with localized debugging output (UTF8) of slicer

Fehler beim Ausführen der Slicing Software:
Traceback (most recent call last):
File "/S/data/o/3D/Steuerung/printrun/Printrun/pronterface.py", line 1308, in skein_func
sys.stdout.write(o)
File "/S/data/o/3D/Steuerung/printrun/Printrun/pronterface.py", line 65, in write
self.stdout.write(data.encode("utf-8"))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 14665, in
lambda event: event.callable(_event.args, *_event.kw) )
File "/usr/lib/python2.7/site-packages/wx-2.8-gtk2-unicode/wx/_controls.py", line 1850, in AppendText
return controls.TextCtrl_AppendText(_args, *_kwargs)
File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xc3 in position 0: unexpected end of data

Pressing Connect Twice - Quickly

Pressing the connect button twice in quick succession will connect, then start sending/receiving twice as many messages from/to the reprap. The issue will persist until printrun is closed.

Maybe graying out the connect button immediately after it's pressed and only enabling the button again after it fails to connect will prevent this?

SD Print not working properly

It's a long time I live with this bug.

When I click SD print and then select a file, an exception is raised, and nothing happens. Except that when I manually select the file with M23, the print immediately start without issuing M24.

This is the exception:
Traceback (most recent call last):
File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 14614, in
lambda event: event.callable(_event.args, *_event.kw) )
File "pronterface.py", line 924, in filesloaded
self.p.send_now("M23 "+target.lower())
File "/home/caru/Printrun/printcore.py", line 182, in send_now
self._send(command)
File "/home/caru/Printrun/printcore.py", line 251, in _send
self.printer.write(command+"\n")
File "/usr/lib/python2.6/dist-packages/serial/serialposix.py", line 330, in write
raise TypeError('expected str, got %s' % type(data))
TypeError: expected str, got <type 'unicode'>

Message from firmware to host

Hi!
From what I understand, it would be awesome if the firmware could send a message to the host, that is just displayed, e.g. "dude, you are doomed".

In printcore.py line 90 you have

if(line.startswith('DEBUG_')):
continue
However an additional safe ignore of lines starting with "echo:" would be nice.
if(line.startswith('DEBUG_') ||line.startswith('echo:')):

The "echo:" is done at least in the
https://github.com/makerbot/ReplicatorG/blob/master/src/replicatorg/drivers/reprap/RepRap5DDriver.java line 702
and it would be cool to have a host-software independent mechanism for displaying firmware infos..

We needed it because if some machine settings are read from the eeprom (acceleration, speed, whatever), we wanted to output it to the host software, so the user sees that a lot of stuff is read from eeprom.

Maybe there is a better way even.

Event object missing message

I am running Pronterface under MacOs Snow Leopard.

I can successfully connect, load a gcode file and print, but if at anytime I use Sfact from within Pronterface I often see the following message. The only way to recover is to quit Pronterface, re-plug the USB cable, and restart Pronterface. Any idea what might be causing this?

event object missing
Traceback (most recent call last):
  File "./r", line 806, in procbutton
    self.onecmd(e.GetEventObject().properties[1])
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/cmd.py", line 218, in onecmd
    return self.default(line)
  File "/Users/geoffd/projects/mechanical/printrun/pronsole.py", line 761, in default
    self.p.send_now(l)
  File "/Users/geoffd/projects/mechanical/printrun/printcore.py", line 186, in send_now
self._send(command)
  File "/Users/geoffd/projects/mechanical/printrun/printcore.py", line 255, in _send
self.printer.write(str(command+"\n"))
  File "/Library/Python/2.6/site-packages/serial/serialposix.py", line 485, in write
raise SerialException('write failed: %s' % (v,))
serial.serialutil.SerialException: write failed: [Errno 6] Device not configured
Disconnected.

Pronterface crashes when loading Gcode

I am running Ubuntu 64-bit, latest commit of pronterface. Python 2.7. It seems that, I can load my first gcode file fine, when I first start the program. Then if I press load file and try to load either another gcode file or the same file, the program either quits immediately or it locks up and I have to force a shut down.

So, every time I want to load a gcode file, I have to restart the application.

pronterface in french on macosx has grayed out controls

Hi,
on macosx 10.5 and 10.6, with python 2.6.1, when locale is set to fr_FR.UTF-8, pronterface shows up in french but won't enable the grayed-out controls after connecting to the machine. When launched with LANG=C, everything works as expected.
Thanks,
Charles

Random freezes while printing from Serial port

I cannot finish almost any of my prints as they stop after a few minutes (or seconds). The error message I get at the console is:

Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/usr/lib/python2.6/threading.py", line 484, in run
self.__target(_self.__args, *_self.__kwargs)
File "/home/misan/Documentos/prusa/Printrun/printcore.py", line 79, in _listen
line=self.printer.readline()
File "/usr/lib/python2.6/dist-packages/serial/serialutil.py", line 60, in readline
c = self.read(1)
File "/usr/lib/python2.6/dist-packages/serial/serialposix.py", line 320, in read
buf = os.read(self.fd, size-len(read))
OSError: [Errno 11] Recurso no disponible temporalmente

I'm running 10.4 64bit Ubuntu with python-serial 2.3.1. Problem happens with or without power in the RAMPS board (I guess it is not an EMI problem). Firmware is Sprinter.

As I understand it, it seems the serial port device vanishes temporarily so serialposix cannot complete a read. dmesg however, does not show a USB disconnect/connect cycle and USB device responds happily. I guess it might be an OS or pyserial problem, but I'm reporting it here just in case.

Setting infill solidity to zero produces error in quick settings

Original value is 0.35, setting this value to 0 in quick settings is not possible.

Error:

Saving ... Infill Solidity (ratio): = 0
Traceback (most recent call last):
File "C:\dev\PrintrunFork\SkeinforgeQuickEditDialog.py", line 134, in OnSave
settings.saveRepository(repo)
File "C:\dev\PrintrunFork\skeinforge\fabmetheus_utilities\settings.py", line 4
66, in saveRepository
setting.setToDisplay()
File "C:\dev\PrintrunFork\skeinforge\fabmetheus_utilities\settings.py", line 1
718, in setToDisplay
self.value = ( self.latentStringVar.getString() == self.radiobutton['value']
)
File "C:\dev\PrintrunFork\skeinforge\fabmetheus_utilities\settings.py", line 1
382, in getString
return self.getVar().get()
File "C:\dev\PrintrunFork\skeinforge\fabmetheus_utilities\settings.py", line 1
377, in getVar
self.stringVar = Tkinter.StringVar()
File "C:\Python27\lib\lib-tk\Tkinter.py", line 251, in init
Variable.init(self, master, value, name)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 182, in init
self._tk = master.tk
AttributeError: 'NoneType' object has no attribute 'tk'

estimate_duration bails with ZeroDivisionError when moves have no feedrate

If the first two or more moves in a gcode file have no feed rate specified then this happens:

Estimated duration (pessimistic): .... estimating ....
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 505, in run
self.__target(_self.__args, *_self.__kwargs)
File "./pronterface.py", line 1358, in loadviz
print _("Estimated duration (pessimistic): "), pronsole.estimate_duration(self.f)
File "/home/sparr/src/printrun/git/Printrun/pronsole.py", line 141, in estimate_duration
moveduration = 2 * distance / ( lastf + f )
ZeroDivisionError: float division by zero

Gets stuck when some code has to be resent.

First I noticed this it happened when I tried to see how the behaviour was when homing individual axis mid print.. After that it just kept trying to resend and it moved maybe 1 move every 1 or 2 seconds. Today it happened twice. The last time in the middle of a regular print without intervention...

UI on Mac OS X

So now that we've replaced the X/Y/Z buttons with a better UI, I'm looking at some other things that could use improvement. Since I'm on a Mac, I'd like to highlight some of the things that look odd or could be improved. I'm not sure if these things apply to all platforms:

http://dl.dropbox.com/u/118766/Ultimaker/pronterface-on-mac2.png

What do you think of:

a) reducing the height of the console on the right so that it matches the height of the gviz panel in the middle? We could then use the blank space at the bottom for other things, like a live graph of temperatures.

b) creating our own button control that does background colors on all platforms?

c) centering the gcode in gviz?

crash on connect with e5b0a4ff

Connecting...
ok T:57.90 B:75.00
Printer is now online.
**
Gdk:ERROR:gdkregion-generic.c:1110:miUnionNonO: assertion failed: (y1 < y2)
Aborted

doesn't happen every time but the error looks like it might be useful?

[experimental branch] slicing with slic3r fails to load gcode file

When I slice the STL file with slic3r pronterface will not open the generated gcode file.
My command to invoke slic3r:
/Applications/Slic3r.app/Contents/MacOS/slic3r $s

The gcode file is generated and can be loaded afterwards into pronterface.
Here are the file names:
domekit2v-hexa.gcode domekit2v-hexa.stl

How to change/delete custom buttons?

Hi Kliment, great program, thank you so much! However...

A couple of months ago, I clicked the button on the toolbar that lets you add buttons with specific gcode, rather than adding them by editing the 'custombtn.txt' file, thinking that they would automatically be added to that file. However, they were not, and I can't edit them. Also,when I update Printrun, the same buttons remain, which I can't edit. Each time I update I create a new folder, and delete the old version once I have tested the new version. Is there a file hidden somewhere that I need to delete?

Also, if I edit 'custombtn.txt', the changes are not shown in the GUI when Printrun is next loaded. It just shows the custom buttons that were there before.

I'm running Printrun on OS X 10.6.8.

Readme is incorrect, WX only runs on Lion in 32-bit mode

The Readme says that you don't need to worry about 32 vs 64-bit mode on OS X Lion. This is incorrect. If the user runs it in 64-bit mode, WX gives an error (and this is with the Carbon version):

python ./pronterface.py
WX is not installed. This program requires WX to run.
Traceback (most recent call last):
File "./pronterface.py", line 13, in
import wx
File "/usr/local/lib/wxPython-2.9.2.4/lib/python2.7/site-packages/wx-2.9.2-osx_carbon/wx/init.py", line 45, in
from wx._core import *
File "/usr/local/lib/wxPython-2.9.2.4/lib/python2.7/site-packages/wx-2.9.2-osx_carbon/wx/_core.py", line 4, in
import core
ImportError: /usr/local/lib/wxPython-2.9.2.4/lib/python2.7/site-packages/wx-2.9.2-osx_carbon/wx/core.so: no appropriate 64-bit architecture (see "man python" for running in 32-bit mode)


If the following is used and pronterface is run again, the UI comes up:

export VERSIONER_PYTHON_PREFER_32_BIT=yes

skeinforge not closing/closeable after rendering gcode

Using Printrun [HEAD] skeinforge is not closing properly, after I loaded a stl and it rendered the gcode. I'm also unable to close the skeinforge windows, it simply won't react on clicks. pronterface is stil usable. Closing pronteface sometimes closes skeinforge as well.

GCode Vis - Shows everything at a particular height...

it seems that the GCode visualizer shows everything that's at a particular height which yields rather strange results especially for intro gcode that starts with any kind of Z-jump.

my gcode starts 5mm above Zero, then extrudes and then wipes the excess to prime the nozzle that's been sitting.

I kept seeing what looked like an anomalous layer from the middle of the gcode at the very beginning of the gcode vis.

it might be better, since there's no 3D visualization tool for gcode in pronterface, if the gcode vis created a list of heights, and sorted them from low-high, then displayed the layers in that order.

as it is it appears it's stepping through the gcode to determine the height.

imagine the issue with hops before retraction, or similar moves.

Display Print Time at End of Print

This is a new feature request, is it possible to have the total print time displayed when a print is finished? It's not really an important feature, it'd just be a nice feature.

Thanks Kliment, keep up the great work!!

README results in 'unknown syntax'

sudo python ./pronsole.py
Welcome to the printer console! Type "help" for a list of available commands.
PC>p=printcore('/dev/ttyUSB0',115200)
*** Unknown syntax: p=printcore('/dev/ttyUSB0',115200)

[Enhancement] Integrate with slic3r

It would be awesome if models could be sliced by slic3r from within printrun. No need for quicksettings, just pass the selected stl file to slice and have printrun load and display the selected STL file.

gcode generated with Slic3r doesn't show up in the preview window

When i am using the latest 07Dec2011 precompiled version of Pronterface, gcode generated in Slic3r doesn't seem to finish loading (it still prints fine thought).

I don't have slic3r integrated with Pronterface, i am just using them separately... when i open a gcode file that has been created with Slic3r it tries to load it, shows all the estimations on the right, but fails to display the last line which shows the Total Duration. The preview of the gcode also doesn't show up and i can't flip through the layers to inspect my object.

I downloaded the previous version of pronterface (precompiled) and it loads and displays my slic3r generated gcode just fine.

Probably remove test.py

I just noticed that my test.py file snuck in on the merge request. It's not really needed--I was just testing the new UI elements.

Suggestion for declutering the status line

Currently the status line is getting very full, and especially if the file name is long, it can overrun the size of the window.

As a suggestion how about moving the currently loaded file name to the title of the window and then removing it from the status line which would free lots of space and allow all the other fields to be visible,

Lockup at end of print (slic3r with custom end.gcode)

With the following gcode at the end of the print, pronterface stops just before the end.gcode with a "Missing CRC" error.

G1 X0 Y0 F3000.0 ; home X and Y - leave Z alone.
M84 ; Shut the motors off - no point in cooking them.
M104 S0 ; Shut off the extruder heater, so we don't cook the plastic.

Further testing shows that it's the comments that are messing pronterface up. Perhaps the ' mark in "don't"?

Pronterface not centering with large parts

Hi there,
I am using os x version of pronterface and it works great for many objects, but there are some that it refuses to center properly so that I can't print them. A good example is this one:
http://www.thingiverse.com/thing:10254
I print it and it tries to put it at the bottom 1/3 of the print bed so that it engages the endstop as it tries to print the lower half of the part. I have this problem with sprinter & marlin as well as sfact & slic3r. I get this issue even when I try and recenter the 0 point so that Y=50 or Y=150.

Does anyone know why this may be happening? Thanks for your help!

EDIT: So apparently it isn't all large prints. This octopus one seemed to print centered, but the pin printed off center. Weird!
http://www.thingiverse.com/thing:13019

Extrusion during pause should, somehow, correct E position...

(oops this was originally posted as issue in sprinter, my mistake, it should have been here)

During a recent print, I paused because I could see there was a plastic problem, so I homed in X and Y.... of course, the nozzle sitting there oozed etc, so I primed the extruder....

After I resumed, the extruder RETRACTED the amount of extrusion I had extruded to prime.
In other words, when I manually extruded 150mm and then resumed, the next E command was now 150mm backward from where the board thought it was, so it retracts 150mm to get there... (IT IS BAD to retract too much filament, gets soft filament into the pinch-wheel... BAD BAD BAD :) )

On Pause it would be nice if Pronterface PUSHed the XYZE position of the last G-Code sent.
Then when un-pausing POPed that position back by, moving to that stored Z position, then that X/Y, then G92'd that E position!

Ideally... maybe even start with Z + some offset, then drop down to the correct Z after the rest...
G1 Z+2.0,
G1 X Y,
G92 E
G1 Z


What do you think?? if this sounds like a good idea - I might give it a shot. If there's a better way to do it, let me know (maybe I'm doing something stupid)

Pronterface is missing library

The new version somehow introduced new dependencies, with pronterface.py or for convenience test.py I get:
python test.py
Traceback (most recent call last):
File "/Users/markusklink/Documents/Printrun/bufferedcanvas.py", line 117, in onPaint
self.draw(dc, w, h)
File "/Users/markusklink/Documents/Printrun/zbuttons.py", line 77, in draw
gc = wx.GraphicsContext.Create(dc)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/wx-2.8-gtk2-unicode/wx/_gdi.py", line 5501, in Create
val = gdi.GraphicsContext_Create(_args)
NotImplementedError: wx.GraphicsContext is not available on this platform.
Traceback (most recent call last):
File "/Users/markusklink/Documents/Printrun/bufferedcanvas.py", line 117, in onPaint
self.draw(dc, w, h)
File "/Users/markusklink/Documents/Printrun/xybuttons.py", line 192, in draw
gc = wx.GraphicsContext.Create(dc)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/wx-2.8-gtk2-unicode/wx/_gdi.py", line 5501, in Create
val = gdi.GraphicsContext_Create(_args)
NotImplementedError: wx.GraphicsContext is not available on this platform.
Traceback (most recent call last):
File "/Users/markusklink/Documents/Printrun/bufferedcanvas.py", line 117, in onPaint
self.draw(dc, w, h)
File "/Users/markusklink/Documents/Printrun/zbuttons.py", line 77, in draw
gc = wx.GraphicsContext.Create(dc)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/wx-2.8-gtk2-unicode/wx/_gdi.py", line 5501, in Create
val = gdi.GraphicsContext_Create(_args)
NotImplementedError: wx.GraphicsContext is not available on this platform.
Traceback (most recent call last):
File "/Users/markusklink/Documents/Printrun/bufferedcanvas.py", line 117, in onPaint
self.draw(dc, w, h)
File "/Users/markusklink/Documents/Printrun/xybuttons.py", line 192, in draw
gc = wx.GraphicsContext.Create(dc)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/wx-2.8-gtk2-unicode/wx/_gdi.py", line 5501, in Create
val = gdi.GraphicsContext_Create(_args)
NotImplementedError: wx.GraphicsContext is not available on this platform.

Using macports on Mac OS X Lion I do not know what kind of library I need to fix this.

SFACT integration- cannot open settings after skein

to reproduce:
open sfact settings, close
pronterface->open, choose an STL (don't need to print or transfer to SD, just skein)
open sfact settings again

may affect skeinforge integration too

result:

this should never happen, getDisplayedDialogFromConstructor in settings could not open
<skeinforge.skeinforge_application.skeinforge.SkeinforgeRepository instance at 0xab05f44c>
Traceback (most recent call last):
File "/home/triffid/Projects/Printrun/skeinforge/fabmetheus_utilities/settings.py", line 147, in getDisplayedDialogFromConstructor
return RepositoryDialog( repository, Tkinter.Tk() )
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1685, in init
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
TclError: out of stack space (infinite loop?)
Warning, displayedDialogFromConstructor in settings is none, so the window will not be displayed.

No images in OS X

I am using OS X Lion, python 2.7.2 in 32 bit mode and previous versions of pronterface work great for me. I am having issues seeing the graphics on this version which means that I can't control the X,Y,Z motion. Is there a good way to fix this?

Thanks for making such a nice piece of software!

manipulates GCode

Layers of serial builds by repsnapper are thrown together and not kept in their original sequence.

.... Probably they are printed in the correct sequence, but not shown in the layer view

Feature request: mention remaining layers in status line

Seeing the percentage of the build that is completed is great, but sometimes I also wish I knew what layer # the print was on, out of how many total layers. (My assumption is that the percentage isn't solely derived from the current layer, but instead on the amount of remaining gcode). On pieces with large bases but small upper layers, percentage complete is often quite different from the number of remaining layers.

Mentioning something like

58% done (layer 23 of 45)

would be a much welcomed feature.

Trouble when loading some gcode files

When loading GCode files, the load terminates unexpectedly. I've noticed this particularly on gcode from Slic3r but I have not confirmed whether or not it happens with SF generated GCode. If I comment out pronterface.py line 1306 giving estimated duration, the file loads and prints fine.

Here's the error. GCode file available on request.
layer z: 13.5 will take: 00:05:50
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Program Files (x86)\Python27\lib\threading.py", line 552, in __bootst
rap_inner
self.run()
File "C:\Program Files (x86)\Python27\lib\threading.py", line 505, in run
self.__target(_self.__args, *_self.__kwargs)
File "D:\apps\reprap\Printrun-2011-12-09\pronterface.py", line 1307, in loadviz
print _("Estimated duration (pessimistic): "), pronsole.estimate_duration(self.f)
File "D:\apps\reprap\Printrun-2011-12-09\pronsole.py", line 129, in estimate_duration
f = get_coordinate_value("F", parts[1:])
File "D:\apps\reprap\Printrun-2011-12-09\pronsole.py", line 88, in get_coordinate_value
return float(i[1:])
ValueError: invalid literal for float(): 900 ;Retract

Feature req: alternate keys to scroll layer window

Selfish but hopefully easy request; my terrible old laptop that runs my printer has a terrible touchpad, no mouse, and it's next to impossible to scroll in the popup pronterface layers window. Can you possibly add arrow key up/down (or whatever keys you want) to scroll through layers?

Thanks either way :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.