Still playing with DJango I have been able to use the web interface to add and modify objects to the database. Once the server is started, I can log in and add, view and make changes to existing objects. In the dJango tutorial they use a Poll object as an example, as in a poll survey poll with questions and possible choices to choose from. In this example, the Poll and Choice objects are defined ahead of time using classes in python. Once that is done, you can manipulate these objects using the dJango API or the web interface. I’ve experimented using both approaches, but typically if an admin is going to make changes they will probably be using the web interface. You can also very easily add features like a search field, options for sorting and filtering results that make the user experience of viewing the web interface a pleasant one. The way you add these features are all done through modifications to a python file, admin.py, which stores all of the information about how your custom web interface should look to the user.
Archive for the ‘Uncategorized’ category
using the admin web interface
July 21st, 2010Printer Video
July 14th, 2010Here is a video we created yesterday for a presentation. It shows the printing of the list node shown in the last post.
Braille Labels
July 14th, 2010Recently, we’ve implemented a crucial feature to our program that will allow for better usability for blind students. Users can now create Braille labels to be embedded into their 3D objects. These labels can be placed anywhere within the image via our editor GUI.
The previous implementation of hemispheres came in very handy during this process. Braille letters consist of a 2 x 3 grid and the selection of spots in the grid that are filled with a hemisphere determines the letter it represents. Therefore, we only needed to figure out which locations would represent a spot on the grid and place a hemisphere at each of the necessary locations for each letter.
In the GUI, a user can select a sprinkle that they would like to represent the top left corner of the label and fill in the text box in the label dialog. Here is an image of a Braille label that we made and printed:
It is especially interesting to note the size of the hemispheres created. We needed to be sure that the hemispheres were big enough so that they could be distinguishable, yet small enough so that they don’t take up too much space. In the future, we plan to make the “font” size of the Braille lettering configurable.
Also, here is a picture of a linked list node that we recently designed in our GUI and printed:
Rainbow Sprinkles
June 28th, 2010In order to allow users to better interact with our program, we have begun development of a GUI. The creation of a simple user-friendly interface is especially important as we expect that many of our users may not be familiar with more technical interfaces, such as a Linux command line.
The GUI implementation began when we needed a way for users to easily create hemispheres, and other 3D shapes, in their objects. Using the Canvas widget from the Tkinter Python module, and its ability to easily create rectangle objects in specific positions, we were able to represent the sprinklized 2D image as a collection of squares, one per sprinkle.
To select an sprinkle, we implemented a mouse listener to pay attention to mouse clicks and keep track of which square the mouse was over. We then used an attribute of the Canvas widget, object tags, to keep track of which squares had been selected. When the user clicks a sprinkle, we are able to find which square (rectangle object) it’s represented by and place a selected tag on it. Once the user is done, we can go back and get all the sprinkles that had been tagged to determine the location and size of the 3D shape. To allow for better visibility of where and how big the object will be, when a square is selected, it changes colors. There is also a deselect feature (enacted by clicking on an already selected sprinkle) which removes the selected tag and changes the color back to black.
In order to allow the user to easily select the image they wish to sprinklize, we have implemented a file picker, available through a “Choose your destiny” menu option.
After getting a basic GUI set up and having a way for users to easily select regions of their image, we thought it would be inice to allow for different textures in the 3D object. These may be especially useful in the future if, for instance, one would like to differentiate between colors in a diagram.
We attempted to do this by creating a “field” of tiny cones inside the selected area. This didn’t turn out as well as we had hoped as the cones were too small for the printer to produce. However, we will most likely come back to this feature in the future and see if we can tweak it for better results.
Four Plans and a Ziggurat
June 28th, 2010After we figured out how to greatly simplify our 3d models, Sara and I turned out attention to creating different levels of elevation. As a concept this is pretty simple; we used different brightnesses in areas of our 2d picture to tell Blender which shapes we wanted to be the highest, second highest, etcetera., all based on assigning thresholds of pixel value to different “z axis” numbers, which in Blender would become the elevation of the sprinkles.
Thrilled with our success for all of half a day or so, we quickly came to the realization that because we were using sprinkles (which are square), even with a wide range of elevation options, making a smooth hemisphere with the Cupcake would be almost impossible. It’d be like trying to create a pyramid or a dome and getting a ziggurat instead.
So we began brainstorming ideas for creating half a sphere over the surface of our model in Blender, using only the Python scripts. This was problematic to say the least because a) most of Blender’s power comes from the manipulatable interface of the model itself, as well as the hotkeys. Both of which are useless when scripting; and b) There is no “create half sphere” handy hotkey period, even if we could use them. In a fit of creative delusion, frustrated hair-pulling and occasional trips to the local icecream shop, we came up with four ideas. (The last one worked, in case you were panicking on our behalf.)
Idea 1 went something like this: “If we create a whole sphere (Blender lets us do this pretty easily) and chop it in half, we’ll have half a sphere!” Not only did we fail to find a reasonable way of removing half a sphere’s vertices, but we also realized that we’d have to fill in the bottom of what would essentially be an overturned bowl shape. That idea was crossed out. I’m sure it’s possible to do, but our fate lay along a different path etcetera etcetera.
Idea 2: “There’s this cool modifier called ‘Subsurf’! It makes things all rounded!” I’m not quite sure why this one was a flop. I think it had something to do with my tendency to form vague ideas around nifty buttons in art programs.
Idea 3: “We could create branching arcs above the x-y plane, and just fill in the shell with vertices.” See “Idea 2”.
Idea 4 (The One That Worked): “Wait! Boolean expressions! Yes!”
The gist of what we ended up doing is that we realized boolean operations on different objects are pretty simple to script. Boolean options in Blender work just as they do in logic. “And”, “or”, and “not”. We used the Difference boolean operation on a cube and a whole sphere, after positioning them so that they overlap about halfway. What this did was create a sort of ghost mesh of a half-sphere, by telling Blender “remove all of object A that intersects with object B”. (“Difference” is the only Boolean operation in Blender where it matters what order you specify the two objects). So we ended up with a hemisphere (like we wanted), because the rest of that sphere shape overlapped with the dummy cube- which we deleted afterwards.
Now that we could create rounded surfaces wherever we wanted; the next step was to let the user specify where they wanted them, using a GUI.
Designing the Interface
June 16th, 2010During one of our recent meetings, we decided that while Sara and Stephanie continue working on constructing the guts of the image manipulation portion of the software, I would begin working on the front end or the interface for the software. Last week I downloaded and started exploring Django, which is a python-driven framework for the writing and deployment of web applications. It features a rich API that can be accessed via python, separate admin and user interfaces so you can manage your projects, and even includes a server that you can use for testing purposes. Despite the fact that a server is included, the docs explicitly discourage the use of this server in a production environment, and they state that it is only meant to test your web applications in a web browser during development. I successfully installed django on the mac and have been working through the tutorial. I have been able to do some basic things using the python interpreter and the django API. The API is pretty extensive and there is a lot to learn, but luckily the docs and the tutorial are well written and give a great starting point. My next task is to explore the admin options, which can be accessed via a web browser once the server is running. Once logged in you can manage applications, users who have access etc. I haven’t explored all the possibilities yet, but it is fun stuff!
Cranky Skeinforge, Internal Faces, and a Much Happier Printer…
June 10th, 2010As we were joyously drawing, 3D-ifying, and printing various shapes, we noticed that during many of the prints, the printer head would partake in a good amount of jittering and seemingly random movements. The patterns it was creating to fill the objects didn’t make sense and we were curious as to why skeingforge, the program responsible for porting a 3D STL file to printer readable Gcode, would be telling the printer to make such patterns.
We looked at some of the layer patterns skeinforge was creating and we found layers like this abound:
As you can see, there are many little squares visible inside the object and then skeinforge tried filling in around them. After getting slightly annoyed at skeinforge, we thought that maybe it wasn’t the program’s fault and considered what was being inputted into skeinforge to make it act in such a way.
Our creation of a 3D object is essentially placing many many cubes in a pattern corresponding to the original shape. Therefore, when there are multiple cubes placed together many faces were created that weren’t really necessary. They were actually obstructive to the process because when the object was sent to skeinforge, it tried to account for all the faces on all the cubes. The poor thing!
So we had to find some way so that only the outside faces, those that were necessary, were created. After much brain racking, white board diagrams, and thinking about each sprinkle’s role within the shape, we came up with a theory on how to fix our internal faces problem.
We decided that each sprinkle would need a top and a bottom face, as these faces will never be dublicated by another sprinkle. Then we had to look at the four sides of each sprinkle and decide where it should be allowed to have faces. We gave each sprinkle surrounding the current sprinkle, s, a number. Like so:
Then, in our Python program we had a four character string for s. If we looked at the sprinkle in the 1 position and saw that it wasn’t to be used in the final object, then we put a 1 as the first character in the string, indicating that, eventually, a face will need to be made facing that position. If the sprinkle at that position is not to be used, then a 0 would be put into the first character, indicating that a face should not be created there.
This method is done for all four positions for all sprinkles that were to be used in the object. Then we sent all the strings with their corresponding sprinkle coordinates into Blender.
Once in Blender we just have to look at the string of neighboring sprinkles to see where to make faces for each sprinkle. We then tested an object. In Blender we can see which faces have been created and it seems, with a few exceptions, that our method has worked.
After exporting the STL and running it through skeinforge, there is a noticable difference in the filling patterns that are created. Here is an example of a layer produced by skeinforge now:
The printer seems much happier while producing the objects as well. This is especially important, as loyalty is a key factor in the quest for world domination.
Stickzilla, or: Triangle Meshes Hate Us
June 10th, 2010After we used Sprinklation to modify pictures into printer-friendly images, our next step was to give these Sprinkles a third dimension. For that we needed Blender, a vastly complex (but free!) 3D modeling program that lets you script in Python. One of the reasons we chose Python for this project in the first place was that so many CAD-type programs utilize it.
To script a 3D object you need to specify the coordinates of its vertices. In the case of a Sprinkle- which is essentially a cube- eight of them. But all we really need for that is the uppermost “origin” coordinate of each Sprinkle, and a Sprinkle’s length. Those three elements are what we exported from our Python program as a text file- and then imported into Blender. Once there we scripted the creation of each Sprinkle we were given, using an arbitrary value for the height of every one. Changing this “z value” is something we’ll come back to later when we start exploring different topographical heights in our images.
This all sounds pretty straight-forward, but right here is about the time we started running into problems- all of which came up as marvelously cryptic error messages when we ran this Blender output through Skeinforge. (Skeinforge is an open-source print-head mapping software that translates 3D models into something the Cupcake can use).
Our first problem had to do with a warped triangle-filled structure that we were getting instead of a clean, solid cube. If you specify four vertices they should make a face, right? I mean, a square face only has four vertices. Turns out if you don’t list the vertices in order (clockwise or counter-clockwise), the entire thing twists itself up and then the computer explodes. (not really).
So for future reference, a “hole in the triangle mesh”, despite the fact that there aren’t supposed to be triangles in your image anywhere ever, means something along the lines of “you fail at playing connect-the-dots.”
Here are some pictures from Blender:
We refer to him fondly as Stickzilla.
The Advent of… the Sprinkle
June 3rd, 2010Sara and I have returned for the summer session of Serious Programming Awesomeness, and we’re diving right into the world of 2d-to-3d transformations. We’ve used Python and Blender together to take greyscale images and turn them into 3d constructs- this is going a long way toward bridging the gap between diagrams and tangible Cupcake-printed output.
We have a long way to go toward a streamlined, elegant program, but the important thing is that we’re making great progress toward our first completely home-grown print job. (Which means the beginning of scanned diagram prints, and that means using our doe-eyed little Cupcake printer to take over the world. Aww, look at its cute opto-endstop wires spewing all over with happiness.)
Anyway, this is where the Sprinkle comes in. Pixels are too small for a printer like the Cupcake to use- I mean, it’s possible, but it’d be sort of like using a fat marker to trace a line and then an even thinner line, and expecting anyone to tell the difference. At this point it’s much more efficient to work with the Cupcake instead of encouraging it to explode in gear-jittering frustration.
The Sprinkle is a construct that we came up with to simplify the breaking-up of pictures. It’s like a pixel, but bigger. In Python, we analyze a picture to determine which lines warrant printing, based on how much of a Sprinkle is “covered”. It’s sort of like laying a transparent sheet of graph paper over a diagram and then checking which boxes are darkened past a certain threshold. If a Sprinkle is chosen to become part of something so much bigger and more noble than itself, then its coordinates are stored and its contents subsequently blackened entirely, and mapped onto a second image. The result is a somewhat blocky version that is a) simplified, and b) useful for the next step- adding a third dimension.
Both the Sprinkle size and the threshhold percentage (what decides whether or not a Sprinkle is going to be used) can be changed, giving us a little refinement in Sprinklation. Here are some pictures. I did not draw that stick figure and take no responsibility for its face.
Fun With COM Objects and Python
June 1st, 2010Today I achieved what some might consider to be a rather simple milestone, but it is quite exciting for me none the less. I was able to access a COM object using python. More specifically, I was able to create an object for my windows screen reader, Window-Eyes, and make it speak something using the python interpreter. Let me explain precisely how I did this, because it is extremely cool! In windows, many programs have an object model of sorts with which you can communicate to provide enhancements to the application in question. Many main stream applications such as Word, Excel, iTunes and Skype have object models so you can alter or provide your own functionality to the program. This adds extreme flexibility to the program, because script writers now have a way to tailor the software to better meet their needs. Most screen readers are no exception to this rule, although there are a wide variety of implementations depending on the screen reader. The Window-Eyes screen reader happens to be a COM server which can be accessed the way you would access any other COM server. From what I understand, COM is somewhat of a standard in Windows. Before we get started with this example, you will need to grab a few things from the internet, assuming they are not installed already. You will need Python of course, but hopefully that’s a given. The next thing you’ll need is the pywin32 extensions for python. This is a library of modules that are useful if you plan to be writing lots of python scripts or applications under Windows. The win32 extensions purportedly works with Python 3.1.2. However, when trying to install it for 3.1.2 I received an error that python 2.6 was required. As I didn’t feel like trying to figure out why I was getting that error, I have temporarily rolled back to version 2.6.5. Once everything is installed, let’s open up the python interpreter by the usual means, or you could simply create a new script using your favorite text editor. Type the following lines.
# begin example script
# shows how to get a COM object and access some of its properties and methods.
import win32com.client
weObj = win32com.client.Dispatch(“WindowEyes.Application”)
# speaks the string that is passed to the speak method.
weObj.Speech.Speak(“Hello world!”)
As you might have guessed, I immediately heard the phrase “hello world!” spoken by the active speech synthesizer used by Window-Eyes. How cool is that?! A useful application of Window-Eyes scripting, or indeed screen reader scripting in general is to enhance the accessibility of applications that do not work right out of the box. I have already done this using other languages, mostly JScript, but the nice thing about COM is it supports a wide variety of programming languages.
One of the reasons I bring this up here aside from the fact that it is really cool and very relevant to our project, is that we are always looking for potential script writers for Window-Eyes so that more programs can become accessible. If you know python, half the battle is over; it’s simply a matter of learning the Window-Eyes object model, which is well documented.
I have only begun playing around with COM objects using python, so I am hoping to get further with this in the weeks to come.














