diff --git a/README.markdown b/README.markdown
index 9523f8ec6..cb385e08d 100644
--- a/README.markdown
+++ b/README.markdown
@@ -193,6 +193,8 @@ The author is Alessandro Ranellucci.
         --skirt-distance    Distance in mm between innermost skirt and object 
                             (default: 6)
         --skirt-height      Height of skirts to draw (expressed in layers, 0+, default: 1)
+        --brim-thickness    Thickness of the brim that will get added to each object to help adhesion
+                            (mm, default: 0)
        
        Transform options:
         --scale             Factor for scaling input object (default: 1)
diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm
index 350cccf78..72732c250 100644
--- a/lib/Slic3r.pm
+++ b/lib/Slic3r.pm
@@ -150,10 +150,11 @@ our $min_print_speed        = 10;
 our $disable_fan_first_layers = 1;
 our $fan_always_on          = 0;
 
-# skirt options
+# skirt/brim options
 our $skirts             = 1;
 our $skirt_distance     = 6;    # mm
 our $skirt_height       = 1;    # layers
+our $brim_thickness     = 0;    # mm
 
 # transform options
 our $scale              = 1;
diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm
index 5cd0e38a8..41cdd72a7 100644
--- a/lib/Slic3r/Config.pm
+++ b/lib/Slic3r/Config.pm
@@ -406,7 +406,7 @@ our $Options = {
         type    => 'bool',
     },
     
-    # skirt options
+    # skirt/brim options
     'skirts' => {
         label   => 'Loops',
         cli     => 'skirts=i',
@@ -415,13 +415,18 @@ our $Options = {
     'skirt_distance' => {
         label   => 'Distance from object (mm)',
         cli     => 'skirt-distance=f',
-        type    => 'i',
+        type    => 'f',
     },
     'skirt_height' => {
         label   => 'Skirt height (layers)',
         cli     => 'skirt-height=i',
         type    => 'i',
     },
+    'brim_thickness' => {
+        label   => 'Brim thickness (mm)',
+        cli     => 'brim-thickness=f',
+        type    => 'f',
+    },
     
     # transform options
     'scale' => {
diff --git a/lib/Slic3r/GUI/SkeinPanel.pm b/lib/Slic3r/GUI/SkeinPanel.pm
index 4975b4b1e..e5a9f5ce0 100644
--- a/lib/Slic3r/GUI/SkeinPanel.pm
+++ b/lib/Slic3r/GUI/SkeinPanel.pm
@@ -44,7 +44,7 @@ sub new {
         },
         print => {
             title => 'Print settings',
-            options => [qw(perimeters solid_layers fill_density fill_angle fill_pattern solid_fill_pattern randomize_start support_material support_material_tool)],
+            options => [qw(perimeters solid_layers fill_density fill_angle fill_pattern solid_fill_pattern randomize_start support_material)],
         },
         retract => {
             title => 'Retraction',
@@ -57,7 +57,7 @@ sub new {
         },
         skirt => {
             title => 'Skirt',
-            options => [qw(skirts skirt_distance skirt_height)],
+            options => [qw(skirts skirt_distance skirt_height brim_thickness)],
         },
         gcode => {
             title => 'G-code',
@@ -78,7 +78,7 @@ sub new {
         },
         other => {
             title => 'Other',
-            options => [ ($Slic3r::have_threads ? qw(threads) : ()), qw(extra_perimeters) ],
+            options => [ ($Slic3r::have_threads ? qw(threads) : ()), qw(extra_perimeters support_material_tool) ],
         },
         notes => {
             title => 'Notes',
diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm
index 5962a2140..6d257ff9f 100644
--- a/lib/Slic3r/Polyline.pm
+++ b/lib/Slic3r/Polyline.pm
@@ -147,12 +147,14 @@ sub rotate {
     my $self = shift;
     my ($angle, $center) = @_;
     @$self = Slic3r::Geometry::rotate_points($angle, $center, @$self);
+    return $self;
 }
 
 sub translate {
     my $self = shift;
     my ($x, $y) = @_;
     @$self = Slic3r::Geometry::move_points([$x, $y], @$self);
+    return $self;
 }
 
 1;
diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm
index 19b33a370..9d4221cca 100644
--- a/lib/Slic3r/Print.pm
+++ b/lib/Slic3r/Print.pm
@@ -20,6 +20,13 @@ has 'skirt' => (
     default => sub { [] },
 );
 
+# ordered collection of extrusion paths to build a brim
+has 'brim' => (
+    is      => 'rw',
+    #isa     => 'ArrayRef[Slic3r::ExtrusionLoop]',
+    default => sub { [] },
+);
+
 sub add_object_from_file {
     my $self = shift;
     my ($input_file) = @_;
@@ -306,6 +313,7 @@ sub export_gcode {
     # make skirt
     $status_cb->(88, "Generating skirt");
     $self->make_skirt;
+    $self->make_brim;
     
     # output everything to a G-code file
     my $output_file = $self->expanded_output_filepath($params{output_file});
@@ -438,9 +446,10 @@ sub make_skirt {
     my $convex_hull = convex_hull(\@points);
     
     # draw outlines from outside to inside
+    my $flow = $Slic3r::first_layer_flow || $Slic3r::flow;
     my @skirt = ();
     for (my $i = $Slic3r::skirts; $i > 0; $i--) {
-        my $distance = scale ($Slic3r::skirt_distance + ($Slic3r::flow->spacing * $i));
+        my $distance = scale ($Slic3r::skirt_distance + ($flow->spacing * $i));
         my $outline = offset([$convex_hull], $distance, $Slic3r::scaling_factor * 100, JT_ROUND);
         push @skirt, Slic3r::ExtrusionLoop->new(
             polygon => Slic3r::Polygon->new(@{$outline->[0]}),
@@ -450,6 +459,28 @@ sub make_skirt {
     unshift @{$self->skirt}, @skirt;
 }
 
+sub make_brim {
+    my $self = shift;
+    return unless $Slic3r::brim_thickness > 0;
+    
+    my @islands = (); # array of polygons
+    foreach my $obj_idx (0 .. $#{$self->objects}) {
+        my @object_islands = map $_->contour, @{ $self->objects->[$obj_idx]->layers->[0]->slices };
+        foreach my $copy (@{$self->copies->[$obj_idx]}) {
+            push @islands, map $_->clone->translate(@$copy), @object_islands;
+        }
+    }
+    
+    my $flow = $Slic3r::first_layer_flow || $Slic3r::flow;
+    my $num_loops = sprintf "%.0f", $Slic3r::brim_thickness / $flow->width;
+    for my $i (reverse 1 .. $num_loops) {
+        push @{$self->brim}, Slic3r::ExtrusionLoop->new(
+            polygon => Slic3r::Polygon->new($_),
+            role    => EXTR_ROLE_SKIRT,
+        ) for @{Math::Clipper::offset(\@islands, $i * scale $flow->spacing)};
+    }
+}
+
 sub write_gcode {
     my $self = shift;
     my ($file) = @_;
@@ -535,12 +566,18 @@ sub write_gcode {
             $extruder->shift_x($shift[X]);
             $extruder->shift_y($shift[Y]);
             $gcode .= $extruder->set_acceleration($Slic3r::perimeter_acceleration);
-            if ($layer_id < $Slic3r::skirt_height) {
+            # skip skirt if we have a large brim
+            if ($layer_id < $Slic3r::skirt_height && ($layer_id != 0 || $Slic3r::skirt_distance + ($Slic3r::skirts * $Slic3r::flow->width) > $Slic3r::brim_thickness)) {
                 $gcode .= $extruder->extrude_loop($_, 'skirt') for @{$self->skirt};
             }
             $skirt_done++;
         }
         
+        # extrude brim
+        if ($layer_id == 0) {
+            $gcode .= $extruder->extrude_loop($_, 'brim') for @{$self->brim};
+        }
+        
         for my $obj_copy (@$object_copies) {
             my ($obj_idx, $copy) = @$obj_copy;
             my $layer = $self->objects->[$obj_idx]->layers->[$layer_id];
diff --git a/slic3r.pl b/slic3r.pl
index f388acb01..2ee61fae4 100755
--- a/slic3r.pl
+++ b/slic3r.pl
@@ -238,6 +238,8 @@ $j
     --skirt-distance    Distance in mm between innermost skirt and object 
                         (default: $Slic3r::skirt_distance)
     --skirt-height      Height of skirts to draw (expressed in layers, 0+, default: $Slic3r::skirt_height)
+    --brim-thickness    Thickness of the brim that will get added to each object to help adhesion
+                        (mm, default: $Slic3r::brim_thickness)
    
    Transform options:
     --scale             Factor for scaling input object (default: $Slic3r::scale)