Code and Science

A blog about programming by a science enthusiast.

Extrusion Painting | 3D Printing

Mark Wheadon has invented a wonderful technique to place patterns in 3D printing he calls Velocity Painting. Normally, when printing a pattern by slicing a model, the printer will use extra layers to print the design. Mark’s technique post processes the GCode generated after slicing a model. It applies an image to the model by adjusting the speed of the print head where the image intersects the model. Check out his explanation, photos and code. My theory is that it works as follows: Technically, the printer should deposit the same amount of material over a given vector, regardless of speed. However, in reality the quick speed change does not give enough time for pressure to increase or decrease in the print head and so it over or under extrudes after the speed change.

Using the same intersection method, I’ve adjusted his technique and created a new process to do Extrusion Painting. Instead of adjusting the speed to paint the picture, my code adjusts the extrusion. By pushing out more or less plastic during the print a design can be added. I believe this method will provide more control over the process. In fact, an ideal process may actually use a combination of two adjusting both the speed and the extrusion.

Here is my first attempt with this method:

It is a single wall cube. I’ve increased the extrusion by 5X in the smiley so the design is 3D. If you had a model with this design baked in, the best a slicer could do would be to add an extra perimeter to draw the pattern. Instead, this maintains a single perimeter but pushes out more plastic for the pattern. This was sliced with a thickness of 0.48mm and printed at a constant 100mm/s.

I’ve tried 8 different GCode viewers but the only one that showed extrusion thickness was matter control.

Next, I will try to underextrude the design which should create a pattern similar to the vases Mark created. Another improvement would be to anti-alias the pattern by ramping up and down the extrusion rather than the sudden change. With a quick change and high pattern extrusions, the extra plastic is dragged along the print. Reducing the extrusion of both the thick and thin parts may eliminate that too (I used 5X!).

Mark’s code was in Perl but I don’t know Perl so I’ve translated the code to Python and modified it to do the Extrusion Painting. The code is available on GitHub.

How to change the username and password of a windows service using WMI in python

Sometimes it is really hard to find information on the internet. After following instructions from countless blogs and microsoft pages, even trying using the raw WMI API I could not change my service username from “localsystem” to a domain username. Calling the Win32_Server.Change method would return Error 22 – “Status Invalid Parameter”, which was not helpful! Even more frustrating was that when manually changing the service to the new username under Administrative Tools -> services it would work fine. The problem, it turned out, was that when the service was running under local system the checkbox to allow the service to interact with the desktop was checked. This is not allowed when running under an account other than local system and had to be turned off as part of the change call. The second criteria is that under windows 2008 (and above I assume) the user must be given rights to log on as service on the local machine. 

Here is the python code to change a windows service to run under a domain username. Make sure the username has log on as service rights first:

import wmi
#Get a list of services
c = wmi.WMI()
services = c.Win32_Service()
#Find services with a matching prefix (you can change this to find the list of services you want by some other criteria
for service in services:
 if service.Caption.startswith('My_Prefix_'):
 newstartname = r'my_domain\my_username'
 newpassword = r'mypassword'
 result = service.Change(StartMode = 'Automatic',
  DesktopInteract = False,
  StartName = newstartname,
  StartPassword = newpassword)
 print 'Result of attempt to change username to %s: %s' % (newstartname, result)
 service.StartService()

How to set up web.py under IIS 7 using CGI (with nice URLs)

I’ve been using python to create maintenance scripts for our servers and wanted to explore creating a simple web interface for running these scripts. It was pretty simple to create a python script to output some HTML and serve the output of the script as a webpage using IIS. However, using print statements to output HTML is pretty messy; I came across web.py, which is a simple web framework that seemed to do exactly what I wanted: allow me to using python for server side scripting but use templates to store the HTML.

I first attempted to install web.py on IIS6. I got to a point where I kept getting the error, “CGI Error The specified CGI application misbehaved by not returning a complete set of HTTP headers.” I then moved on to IIS7, this time I got a similar error but IIS7 returned more information, showing an exception that python was throwing with the call stack. I imagine this would work fine on IIS6 but troubleshooting problems along the way is more difficult. Below I will show  how to set up serve a web page from IIS7 first just using python and then using web.py (both use CGI) and finally we’ll set up IIS to allow us to use pretty URLs with web.py.

How to serve a webpage from IIS7 using python

  1. Install Python
  2. Create a file test.py with the following, c:\myapp\
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    
    # enable debugging
    
    print "Content-Type: text/plain;charset=utf-8"
    print
    print "Hello World!"
    
  3. Go to a command prompt and run test.py. It should output the code for the simple hello world page.
  4. Open IIS, right click on your website and click “Add Application”. Give your application the alias myapp and point the path to c:\myapp\.
  5. Click on your newly created application and double click “Handler Mappings”.  Click “Add Script Map”. Add *.py as the request path and the path to your python executable for executable, i.e. C:\Python27\Python.exe %s %s. Enter a name, like “python”. Click ok and then when it asks you to add and allow an entry to the ISAPI/CGI restriction list click yes. This tells IIS that if it receives any requests for files with the extension .py, it should execute python, pass the file as a parameter and then return the output. The script will be expected to output a valid webpage.
  6. Now you should be able to go to a web browser and navigate to localhost/myapp/test.py and see your hello world webpage.

Congratulations! You’ve created a website using Python! Now let’s create one using web.py.

How to serve a webpage from IIS7 using web.py

  1. Download web.py, extract it and then in a command prompt from that directory run “python setup.py install”.
  2. Create a new file in c:\myapp named test2.py with the following contents:
    
    import web
    
    urls = (
     '/myapp/test2\.py.*', 'index'
    )
    
    class index:
     def GET(self):
     return "Hello, world!"
    
    if __name__ == "__main__":
     app = web.application(urls, globals())
     app.run()
    

    The urls variable uses a regular expression to tell the script what to do depending on the url the browser requests. This says send anything that starts with with the text “my/app/test2.py” to the class “index”. The class index then says, on a GET request return “Hello, world!”

  3. Now go to a command prompt and run python c:\myapp\test2.py. You should see output of http://0.0.0.0:8080/. The script is now running a mini web server on port 8080. If you point your browser to http://localhost:8080/myapp/test2.py you should see hello world. If you navigate to http://localhost:8080/ you will see “not found”, as that URL does not match the URL pattern we specified. Close the command prompt to stop the script.
  4. We’re not done. If you try and use web.py through IIS now by navigating to localhost/myapp/test2.py you’ll get an error that ends with:
    File "C:\Python27\lib\site-packages\web\wsgi.py", line 16, in runfcgi import flup.server.fcgi as flups ImportError: No module named flup.server.fcgi "
    
  5. We need to install flup (flup may want you to first install python-setuptools, if so google it and install latest version). Download flup but don’t install yet. If you do install you’ll get the following error:
    File "build\bdist.win32\egg\flup\server\fcgi_base.py", line 978, in _setupSocket AttributeError: 'module' object has no attribute 'fromfd'
    
  6. This site had the solution, in the extracted flup directory find and edit the file fcgi_base.py. Comment out following lines: (make sure you comment out every line, including both lines of statements that span multiple lines)
    
    #isFCGI = True
    
    #sock = socket.fromfd(FCGI_LISTENSOCK_FILENO, socket.AF_INET,
     # socket.SOCK_STREAM)
     #try:
     #sock.getpeername()
     #except socket.error, e:
     # if e[0] == errno.ENOTSOCK:
     # Not a socket, assume CGI context.
     # isFCGI = False
     # elif e[0] != errno.ENOTCONN:
     # raise
    

    And right on top of the commented out lines add the line: isFCGI = False

  7. Now install flup by navigating to it’s directory in the command prompt and running  “python setup.py install”.
  8. Now you should be able to navigate to localhost/myapp/test2.py and see helloworld!

Congratulations! You can now use web.py under IIS. However, the URL structure is annoying. In order for our script to run we have to request /myapp/test2.py. We can set up patterns in our script to serve different pages for /myapp/test2.py/home and /myapp/test2.py/about but what if we want our site to respond to /myapp/home and /myapp/about? If we navigate to those pages in IIS now IIS will not even use python, let alone call our script test2.py. Currently IIS is sending anything that ends in .py to python, so when we request test2.py, it executes test2.py passing it the URL. The solution I came up with was to tell IIS to send all requests directly to test2.py, regardless of whether the URL specifies test2.py.

Nice URLs with IIS and web.py

For this example I’m just going to tell IIS to send anything that ends in .test directly to my web.py script. This could easily be modified to send all requests.

  1. In IIS, under navigate to myapp, “Handler Mappings”. Click “Add Script Map”. Under request path but *.test, under executable put C:\Python27\python.exe C:\Myapp\test2.py %s (the first part should be the path to your python executable). For name, put test. Click ok and then when it asks you to add and allow an entry to the ISAPI/CGI restriction list click yes. We’ve now told IIS to send any request ending in .test directly to test2.py.
  2. Modify c:\myapp\test2.py so it looks like this:
    import web
    
    urls = (
     '.*\.test', 'test',
     '/myapp/test2\.py.*', 'index'
    )
    
    class index:
     def GET(self):
     return "Hello, world!"
    
    class test:
     def GET(self):
     return "Hello, world! I'm loving my pretty URL!"
    
    if __name__ == "__main__":
     app = web.application(urls, globals())
     app.run()
    
    

    We’ve added two things to this file. The url will still send anything that starts with /myapp/test.py to index but now it will send anything that ends with .test to the class test. We’ve also added the class test, which will output a different string.

  3. Now you can navigate to localhost/app/home.test and you should see “Hello, world! I’m loving my pretty URL!”. You can now create url patterns and classes for /app/home.test and /app/about.test, or more likely tell IIS to send all requests to your page and remove the .test part.

In this example we’ve still outputted the page contents directly from a string in python but on the web.py website you can find very simple and easy to implement examples of using templates, which will allow you separate out the html into it’s own template page.