Archive for January, 2014

Diffusion curves in matlab

Wednesday, January 29th, 2014

I wrote a little demo to compute and render Diffusion Curves using matlab.

The demo lets the user draw a set of curves,

diffusion curves in matlab curves

meshes the curves with a properly slitted and constrained Delaunay triangulation

diffusion curves in matlab curves

and then applies random colors varying along each of the curves to compute diffusion curves using an FEM solver.

diffusion curves in matlab curves

Try it for yourself, unzip the code and issue:

diffusion_curves_demo

Corresponding list of number of occurrences for each vector element

Wednesday, January 29th, 2014

If I have a n-long vector x and I’d like a new n-long vector counts that contains for each element in x the number of times the same value occurs in x (aka the value frequency), then the following matlab code will compute counts.

[u,~,ic] = unique(x);
counts = histc(x,u);
counts = counts(ic);

The last step is essential to distribute the counts in the same order and length of x.

Render to Mac OS X clipboard from GLUT OpenGL app

Saturday, January 25th, 2014

Here’s a proof of concept application that renders the current viewport to the mac os x clipboard. Then you can paste into Preview.app or Photoshop etc. Save the following in render_to_clipboard.m:

#include <GLUT/GLUT.h>
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#include <stdlib.h>
#include <unistd.h>

void reshape(int width,int height)
{
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glViewport(0,0,width,height);
  gluPerspective(40, (double)width/height, 1, 10);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(0,0,3, 0,0,0, 0,1,0);
  glTranslatef(0, 0.0f, -1);
}

bool buffer_to_clipboard(
  const GLubyte * pixels, 
  const int w, 
  const int h, 
  const int components)
{
  const int length = w*h*components;
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
  // http://stackoverflow.com/a/3416891/148668
  size_t bufferLength = w * h * components;
  CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, bufferLength, NULL);
  size_t bitsPerComponent = 8;
  size_t bitsPerPixel = bitsPerComponent * components;
  size_t bytesPerRow = components * w;
  CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
  CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
  CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

  CGImageRef iref = CGImageCreate(
    w, 
    h, 
    bitsPerComponent, 
    bitsPerPixel, 
    bytesPerRow, 
    colorSpaceRef, 
    bitmapInfo, 
    provider,   // data provider
    NULL,       // decode
    YES,        // should interpolate
    renderingIntent);

  NSImage * temp_image = [[NSImage alloc] initWithCGImage:iref size:NSMakeSize(w, h)];

  // Painfully flip image across x-axis
  NSSize newSize = NSMakeSize(w,h);
  NSImage *image = [[NSImage alloc] initWithSize:newSize];
  [image lockFocus];
  NSAffineTransform *flip = [NSAffineTransform transform];
  [flip translateXBy: 0 yBy: h];
  [flip scaleXBy:1 yBy:-1];
  [flip concat];
  NSRect r1 = NSMakeRect(0, 0, w,h);
  [[temp_image bestRepresentationForRect:r1 context:nil hints:nil] drawInRect: r1];
  [image unlockFocus];

  BOOL copied = false;
  if (image != nil)
  {
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard clearContents];
    NSArray *copiedObjects = [NSArray arrayWithObject:image];
    copied = [pasteboard writeObjects:copiedObjects];
    [pasteboard release];
  }
  [image release];
  [pool release];
  return true;
}

bool render_to_clipboard()
{
  GLenum format = GL_RGBA;
  int components = 4;
  int VP[4];
  glGetIntegerv(GL_VIEWPORT,VP);
  // OpenGL by default tries to read data in multiples of 4, if our data is
  // only RGB or BGR and the width is not divible by 4 then we need to alert
  // opengl
  if((VP[2] % 4) != 0 && 
   (format == GL_RGB || 
    format == GL_BGR))
  {
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
  }
  GLubyte *pixels;
  pixels = (unsigned char *) malloc (VP[2]* VP[3]* components);
  glReadPixels( VP[0], VP[1], VP[2], VP[3], format, GL_UNSIGNED_BYTE, pixels);
  return buffer_to_clipboard(pixels, VP[2], VP[3], components);
}

void display()
{
  glClearColor(1,0,0,1);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glutWireTeapot(1.0);
  glutSwapBuffers();
  render_to_clipboard();
}

void exitCB()
{
  exit(0);
}

int main(int argc, char * argv[])
{
  glutInit(&argc,argv);
  glutInitDisplayString( "rgba depth double samples>=8 ");
  glutInitWindowSize(401,301);
  glutCreateWindow("test");
  glutDisplayFunc(display);
  glutReshapeFunc(reshape);
  // Render once and quit
  glutIdleFunc(exitCB);
  glutMainLoop();
  return 0;
}

Then you can compile with

cc -o render_to_clipboard render_to_clipboard.m -framework GLUT -framework OpenGL -lobjc -framework Foundation -framework AppKit

And run with:

./render_to_clipboard

This will flash a GLUT window, render once and quit. You can then paste your frame, which should be:

render teaport to mac os x clipboard

Copy image file to clipboard

Saturday, January 25th, 2014

Here’s a small objective-c program to take an image file and copy it to the clipboard on Mac OS X. Dump this in a file called impbcopy.m:

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <unistd.h>
BOOL copy_to_clipboard(NSString *path)
{
  // http://stackoverflow.com/questions/2681630/how-to-read-png-image-to-nsimage
  NSImage * image;
  if([path isEqualToString:@"-"])
  {
    // http://caiustheory.com/read-standard-input-using-objective-c 
    NSFileHandle *input = [NSFileHandle fileHandleWithStandardInput];
    image = [[NSImage alloc] initWithData:[input readDataToEndOfFile]];
  }else
  { 
    image =  [[NSImage alloc] initWithContentsOfFile:path];
  }
  // http://stackoverflow.com/a/18124824/148668
  BOOL copied = false;
  if (image != nil)
  {
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard clearContents];
    NSArray *copiedObjects = [NSArray arrayWithObject:image];
    copied = [pasteboard writeObjects:copiedObjects];
    [pasteboard release];
  }
  [image release];
  return copied;
}

int main(int argc, char * const argv[])
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  if(argc<2)
  {
    printf("Usage:\n\n"
      "Copy file to clipboard:\n    ./impbcopy path/to/file\n\n"
      "Copy stdin to clipboard:\n    cat /path/to/file | ./impbcopy -");
    return EXIT_FAILURE;
  }
  NSString *path= [NSString stringWithUTF8String:argv[1]];
  BOOL success = copy_to_clipboard(path);
  [pool release];
  return (success?EXIT_SUCCESS:EXIT_FAILURE);
}

Then compile with:

gcc -Wall -g -O3 -ObjC -framework Foundation -framework AppKit -o impbcopy impbcopy.m

And run with something like:

./impbcopy path/to/file.png

or from stdin use:

cat path/to/file.jpg | ./impbcopy -

Update: For completeness, here’s a small program to paste the clipboard image to a file:

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import <unistd.h>

@interface NSImage(saveAsPNGWithName)
- (void) saveAsPNGWithName:(NSString*) fileName;
@end

@implementation NSImage(saveAsPNGWithName)

- (void) saveAsPNGWithName:(NSString*) fileName
{
    // Cache the reduced image
    NSData *imageData = [self TIFFRepresentation];
    NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
    NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];
    imageData = [imageRep representationUsingType:NSPNGFileType properties:imageProps];
    [imageData writeToFile:fileName atomically:NO];        
}

@end

BOOL paste_from_clipboard(NSString *path)
{
  // http://stackoverflow.com/a/18124824/148668
  NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
  NSArray *classArray = [NSArray arrayWithObject:[NSImage class]];
  NSDictionary *options = [NSDictionary dictionary];
  BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options]; 
  if(ok)
  {
    NSArray *objectsToPaste = [pasteboard readObjectsForClasses:classArray options:options];
    NSImage *image = [objectsToPaste objectAtIndex:0];
    // http://stackoverflow.com/a/3213017/148668
    [image release];
  }else
  {
    printf("Error: Clipboard doesn't seem to contain an image.\n");
  }
  return ok;
}

int main(int argc, char * const argv[])
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  if(argc<2)
  {
    printf("Usage:\n\n"
      "Paste clipboard to file:\n    ./impbcopy path/to/file\n\n");
    return EXIT_FAILURE;
  }
  NSString *path= [NSString stringWithUTF8String:argv[1]];
  BOOL success = paste_from_clipboard(path);
  [pool release];
  return (success?EXIT_SUCCESS:EXIT_FAILURE);
}

Compile with:

clang -Wall -g -O3 -ObjC -framework Foundation -framework AppKit -o impbpaste impbpaste.m

and run:

./impbpaste foo.png

Update: could also try the command line program pngpaste which has more features.

Copy text from a latex file without comments newlines or comments

Monday, January 20th, 2014

Here’s a bash one-liner to copy the raw text from a LaTeX file. It strips comments (be careful if you use % in your text), removes newline, thins whitespace and finally pipes to the keyboard.

cat abstract.tex | sed -e "s/%.*$//" | tr '\n' ' ' | sed -e "s/  */ /g" | sed -e "s/^ //g" | pbcopy

If you’re issuing this from vim then you need to escape the % sign:

    cat abstract.tex | sed -e "s/\%.*$//" | tr '\n' ' ' | sed -e "s/  */ /g" | sed -e "s/^ //g" | pbcopy

vim only spell checking in TeX comments

Monday, January 20th, 2014

Editing a LaTeX document with vim, I noticed it was only spell-checking comments. I fixed this by add this to my ./vimrc:

autocmd FileType plaintex,tex,latex syntax spell toplevel

Silhouette or outline of a group of shapes in Illustrator

Sunday, January 19th, 2014
  1. Select all of the objects
  2. Group them
  3. Copy and paste them as a new layer
  4. Object > Path > Outline Stroke
  5. Window > Pathfinder, “Unite”
  6. Object > Path > Offset Path
  7. Delete result of “Unite”

    turtle outline

Illustrator error during Object > Path > Outline Stroke

Sunday, January 19th, 2014

I got the following error trying to apply “Outline stroke” to a somewhat complex group on a small (3.33in) artboard.

error dialog

The Operation cannot complete because of an unknown error. [%s]

Error: 0SEG

Well, thanks for that.

My work around was to first scale the group a bunch (after going to “Object > Transform > Scale…” and checking “Scale Strokes & Effects”) and then apply “Outline Stroke”.

Change matlab current directory to match terminals current directory

Friday, January 17th, 2014

Here’s a little “one-liner” I’ve aliased to change the current directory in MATLAB to the current directory of a bash script in terminal. It uses applescript to send the cd command to matlab.

osascript -e "`echo -e \"tell application \\"MATLAB_R2013b\\"\ndelay 0.1\nactivate\ntell application \\"System Events\\"\n keystroke \\"   cd $(pwd)\\"\nkeystroke return\nend tell\nend tell\"`"

You may need to fiddle with the delays on your machine.

I alias this to cdmatlab by playing this at the bottom of my ~/.profile:

alias cdmatlab='osascript -e "`echo -e \"tell application \\"MATLAB_R2013b\\"\ndelay 0.1\nactivate\ntell application \\"System Events\\"\n keystroke \\"   cd $(pwd)\\"\nkeystroke return\nend tell\nend tell\"`"'

Distribute spacing in Illustrator (hidden menu item)

Thursday, January 16th, 2014

I found some sites online talking about the “distribute spacing” function of illustrator (as opposed to the “Distribute Objects” function). However, I could not find it on my “Align” window. The button was missing. Turns out, it’s hidden under “Show options”.

illustrator distribute options