diff --git a/plugins_src/autouv/wpc_autouv.erl b/plugins_src/autouv/wpc_autouv.erl
index 3e3adf0fa..9acdc611c 100644
--- a/plugins_src/autouv/wpc_autouv.erl
+++ b/plugins_src/autouv/wpc_autouv.erl
@@ -67,12 +67,27 @@ auv_show_menu(help) ->
 auv_show_menu(Action) ->
     Cmd = {show,toggle_background},
     case Action of
-	true ->
-	    Label = auv_show_menu(label),
-	    Help = auv_show_menu(help),
-	    wings_menu:update_menu(view, Cmd, {append, 0, Label},Help);
-	false ->
-	    wings_menu:update_menu(view, Cmd, delete)
+        true ->
+            Label = auv_show_menu(label),
+            Help = auv_show_menu(help),
+            wings_menu:update_menu(view, Cmd, {append, 0, Label},Help);
+        false ->
+            wings_menu:update_menu(view, Cmd, delete)
+    end.
+
+auv_show_tile_menu(label) ->
+    ?__(1,"Tiled texture");
+auv_show_tile_menu(help) ->
+    ?__(2,"Toggle the show mode for the background texture image");
+auv_show_tile_menu(Action) ->
+    Cmd = {show,toggle_tiled_texture},
+    case Action of
+        true ->
+            Label = auv_show_tile_menu(label),
+            Help = auv_show_tile_menu(help),
+            wings_menu:update_menu(view, Cmd, {append, 0, Label},Help);
+        false ->
+            wings_menu:update_menu(view, Cmd, delete)
     end.
 
 auv_export_menu(label) ->
@@ -268,8 +283,9 @@ create_uv_state(Charts, MatName, Fs, We, #st{shapes=Shs0}=GeomSt) ->
 
     Win = wings_wm:this(),
     case ?GET({?MODULE,show_background}) of
-	undefined -> 
-	    ?SET({?MODULE,show_background}, true);
+	undefined ->
+        ?SET({?MODULE,show_background}, true),
+        ?SET({?MODULE,tiled_texture}, false);
 	_ -> ignore
     end,
     wings:register_postdraw_hook(Win, ?MODULE,
@@ -400,7 +416,8 @@ command_menu(body, X, Y) ->
                                     ?__(412,"Normalize Chart Sizes so that each"
                                         "chart get it's corresponding 2d area")}]},
 	     ?__(5,"Scale selected charts")},
-	    {?__(6,"Rotate"), rotate, ?__(7,"Rotate selected charts")},
+	    {?__(6,"Rotate"), {rotate,rotate_free(false)},
+	     {?__(7,"Rotate selected charts"),[],?__(59,"Pick rotation center")},[]},
 	    separator,
 	    {?__(8,"Move to"),
 	     {move_to,
@@ -433,7 +450,8 @@ command_menu(face, X, Y) ->
     Move = move_directions(true),
     Menu = [{?__(47,"Move"),{move,Move},?__(48,"Move selected faces"),[magnet]},
 	    {?__(49,"Scale"),{scale,Scale},?__(50,"Scale selected faces"), [magnet]},
-	    {?__(51,"Rotate"),rotate,?__(52,"Rotate selected faces"), [magnet]},
+	    {?__(51,"Rotate"),{rotate,rotate_free(true)},
+	     {?__(52,"Rotate selected faces"),[],?__(59,"Pick rotation center")}, [magnet]},
 	    separator,
 	    {?__(521,"Project-Unfold"),	{remap, proj_lsqcm},
 	     ?__(522,"Project selected faces from normal and unfold the rest of chart")}
@@ -443,9 +461,10 @@ command_menu(edge, X, Y) ->
     Scale = scale_directions(true),
     Move = move_directions(true),
     Align = 	    
-	[{?__(53,"Free"),free,?__(54,"Rotate selection freely"), [magnet]},
-	 {?__(55,"Chart to X"), align_x, ?__(56,"Rotate chart to align selected edge to X-axis")},
-	 {?__(57,"Chart to Y"), align_y, ?__(58,"Rotate chart to align selected edge to Y-axis")}],
+	   [{?__(53,"Free"),rotate_free(true),
+	     {?__(54,"Rotate selection freely"),[],?__(59,"Pick rotation center")}, [magnet]},
+	    {?__(55,"Chart to X"), align_x, ?__(56,"Rotate chart to align selected edge to X-axis")},
+	    {?__(57,"Chart to Y"), align_y, ?__(58,"Rotate chart to align selected edge to Y-axis")}],
     Menu = [{?__(60,"Move"),{move,Move},?__(61,"Move selected edges"),[magnet]},
 	    {?__(62,"Scale"),{scale,Scale},?__(63,"Scale selected edges"), [magnet]},
 	    {?__(64,"Rotate"),{rotate,Align},?__(65,"Rotate commands")},
@@ -455,7 +474,8 @@ command_menu(edge, X, Y) ->
 	      [{?__(25,"Horizontal"),horizontal,?__(644,"Distribute horizontally")},
 	       {?__(27,"Vertical"),vertical,?__(645,"Distribute vertically")},
            separator,
-           {?__(647,"Proportional"),proportional,?__(648,"Proportionally distributes the vertices on loop to match the proportions on the object")}]},
+           {?__(647,"Proportional"),proportional,
+            ?__(648,"Proportionally distributes the vertices on loop to match the proportions on the object")}]},
 	     ?__(646,"Distribute vertices evenly")},
 	    separator,
 	    {?__(66,"Stitch"), stitch, ?__(67,"Stitch edges/charts")},
@@ -466,7 +486,8 @@ command_menu(vertex, X, Y) ->
     Scale = scale_directions(true),
     Move = move_directions(true),
     Align =
-        [{?__(70,"Free"),free,?__(71,"Rotate selection freely"), [magnet]},
+        [{?__(70,"Free"),rotate_free(true),
+          {?__(71,"Rotate selection freely"),[],?__(59,"Pick rotation center")}, [magnet]},
         {?__(72,"Chart to X"), align_x,
         ?__(73,"Rotate chart to align (imaginary) edge joining selected verts to X-axis")},
         {?__(74,"Chart to Y"), align_y,
@@ -496,8 +517,10 @@ command_menu(_, X, Y) ->
         true -> ExportMenu = [separator, {auv_export_menu(label), export_uv, auv_export_menu(help)}];
         _ -> ExportMenu = []
     end,
-    Checked = [{crossmark, ?GET({?MODULE,show_background})}],
-    Menu = [{auv_show_menu(label),toggle_background,auv_show_menu(help),Checked}] ++
+    CkdBackground = [{crossmark, ?GET({?MODULE,show_background})}],
+    CkdTiled = [{crossmark, ?GET({?MODULE,tiled_texture})}],
+    Menu = [{auv_show_menu(label),toggle_background,auv_show_menu(help),CkdBackground},
+            {auv_show_tile_menu(label),toggle_tiled_texture,auv_show_tile_menu(help),CkdTiled}] ++
            ExportMenu ++ option_menu(),
     wings_menu:popup_menu(X,Y, {auv,option}, Menu).
 
@@ -519,18 +542,57 @@ move_directions(false) ->
      {?__(5,"Vertical"),   y, ?__(6,"Move vertically (Y dir)")}].
 
 scale_directions(true) ->
-    [{?__(1,"Uniform"),    uniform, ?__(2,"Scale in both directions"), [magnet]},
-     {?__(3,"Horizontal"), x, ?__(4,"Scale horizontally (X dir)"), [magnet]},
-     {?__(5,"Vertical"),   y, ?__(6,"Scale vertically (Y dir)"), [magnet]}];
+    ChosePoint = ?__(7,"Choose point to scale from"),
+    [{?__(1,"Uniform"),    uniform_scale([magnet]),
+      {?__(2,"Scale in both directions"),[],ChosePoint}, [magnet]},
+     {?__(3,"Horizontal"), scale(x,[magnet]),
+      {?__(4,"Scale horizontally (X dir)"),[],ChosePoint}, [magnet]},
+     {?__(5,"Vertical"),   scale(y,[magnet]),
+      {?__(6,"Scale vertically (Y dir)"),[],ChosePoint}, [magnet]}];
 scale_directions(false) ->
-    [{?__(1,"Uniform"),    uniform, ?__(2,"Scale in both directions"), []},
-     {?__(3,"Horizontal"), x, ?__(4,"Scale horizontally (X dir)")},
-     {?__(5,"Vertical"),   y, ?__(6,"Scale vertically (Y dir)")}].
+    ChosePoint = ?__(7,"Choose point to scale from"),
+    [{?__(1,"Uniform"),    uniform_scale([]),
+      {?__(2,"Scale in both directions"),[],ChosePoint}},
+     {?__(3,"Horizontal"), scale(x,[]),
+      {?__(4,"Scale horizontally (X dir)"),[],ChosePoint}},
+     {?__(5,"Vertical"),   scale(y,[]),
+      {?__(6,"Scale vertically (Y dir)"),[],ChosePoint}}].
+
+uniform_scale(Flags) ->
+    fun(B, Ns) ->
+        case B of
+            1 -> wings_menu:build_command({'ASK',{[],[center,uniform],Flags}}, Ns);
+            _ -> wings_menu:build_command({'ASK',{[point],[uniform],Flags}}, Ns)
+        end
+    end.
+scale(Axis, Flags) ->
+    fun(B, Ns) ->
+        case B of
+            1 -> wings_menu:build_command({'ASK',{[],[center,Axis],Flags}}, Ns);
+            _ -> wings_menu:build_command({'ASK',{[point],[Axis],Flags}}, Ns)
+        end
+    end.
+
+rotate_free(true) ->
+    rotate([magnet]);
+rotate_free(false) ->
+    rotate([]).
+
+rotate(Flags) ->
+    fun(B, Ns) ->
+        case B of
+            1 -> wings_menu:build_command({free,{'ASK',{[],[center,z],Flags}}}, Ns);
+            _ -> wings_menu:build_command({free,{'ASK',{[point],[z],Flags}}}, Ns)
+        end
+    end.
 
 align_menu() ->
     {?__(93,"Align"),
      {align,
-      [{?__(15,"Bottom"), bottom, ?__(95,"Align to bottom")},
+      [{?__(9,"Center"), center, ?__(99,"Align to Center")},
+       {?__(11,"Center X"), center_x, ?__(100,"Align to horizontal center")},
+       {?__(13,"Center Y"), center_y, ?__(101,"Align to vertical center")},
+       {?__(15,"Bottom"), bottom, ?__(95,"Align to bottom")},
        {?__(17,"Top"), top, ?__(96,"Align to top")},
        {?__(19,"Left"), left, ?__(97,"Align to left")},
        {?__(21,"Right"), right, ?__(98,"Align to right")}
@@ -670,6 +732,7 @@ handle_event_3({action,{{auv,_},create_texture}}, St) ->
     auv_texture:draw_options(St);
 handle_event_3({action,{auv,{draw_options,restart}}}, St) ->
     ?SET({?MODULE,show_background}, true),
+    ?SET({?MODULE,tiled_texture}, false),
     auv_texture:draw_options(St);
 handle_event_3({action,{auv,{draw_options,Opt}}}, #st{bb=Uvs}=St) ->
     #uvstate{st=GeomSt0,matname=MatName0,bg_img=Image} = Uvs,
@@ -761,7 +824,7 @@ handle_event_3({action,Ev}=Act, #st{selmode=AUVSel, bb=#uvstate{st=#st{selmode=G
 	{_, {move,_}} ->
 	    handle_command(move,St);
 	{_, {rotate,_}} ->
-	    handle_command({rotate,free},St);
+	    handle_command(rotate,St);
 	{_, {scale,{Dir,_S}}} ->
 	    handle_command({scale,Dir},St);
 	{_, {scale,_S}} ->
@@ -772,6 +835,8 @@ handle_event_3({action,Ev}=Act, #st{selmode=AUVSel, bb=#uvstate{st=#st{selmode=G
 	    handle_command(circularise,St);
 	{view,{show,toggle_background}} ->
 	    handle_command(toggle_background,St);
+	{view,{show,toggle_tiled_texture}} ->
+	    handle_command(toggle_tiled_texture,St);
 	{view,aim} ->
 	    St1 = fake_selection(St),
 	    wings_view:command(aim, St1),
@@ -815,9 +880,11 @@ handle_event_3(got_focus, _) ->
     Message = wings_msg:join([Msg1,Msg2,Msg3]),
     wings_wm:message(Message, ""),
     auv_show_menu(true),
+    auv_show_tile_menu(true),
     wings_wm:dirty();
 handle_event_3(lost_focus, _) ->
     auv_show_menu(false),
+    auv_show_tile_menu(false),
     keep;
 handle_event_3(_Event, _) ->
     %% io:format("MissEvent ~P~n", [_Event, 20]),
@@ -908,23 +975,35 @@ handle_command_1({scale,normalize}, St0) -> %% Normalize chart sizes
     St = update_selected_uvcoords(St0#st{shapes=Sh}),
     get_event(St);
 handle_command_1({scale, {'ASK', Ask}}, St) ->
-    wings:ask(Ask, St, fun({Dir,M},St0) -> 
-			       do_drag(wings_scale:setup({Dir,center,M}, St0))
+    wings:ask(Ask, St, fun({Dir,M},St0) when is_tuple(M), element(1,M) == magnet ->
+			       do_drag(wings_scale:setup({Dir,center,M}, St0));
+                          ({Dir,Point},St0) ->
+			       do_drag(wings_scale:setup({Dir,Point}, St0));
+                          ({Dir,Point,M},St0) ->
+			       do_drag(wings_scale:setup({Dir,Point,M}, St0))
 		       end);
-handle_command_1({scale,{Dir,M}}, St) when element(1,M) == magnet ->
+handle_command_1({scale,{Dir,M}}, St) when is_tuple(M), element(1,M) == magnet ->
     wings_scale:setup({Dir,center,M}, St); % For repeat drag
+handle_command_1({scale,{Dir,Point}}, St) ->
+    wings_scale:setup({Dir,Point}, St);
+handle_command_1({scale,{Dir,Point,M}}, St) ->
+    wings_scale:setup({Dir,Point,M}, St);
 handle_command_1({scale,Dir}, St) ->
     wings_scale:setup({Dir,center}, St);
 handle_command_1(rotate, St) ->
     wings_rotate:setup({free,center}, St);
-handle_command_1({rotate,free}, St) ->
-    wings_rotate:setup({free,center}, St);
-handle_command_1({rotate, {'ASK', Ask}}, St) ->
-    wings:ask(Ask, St, fun({Dir,M},St0) -> 
-			       do_drag(wings_rotate:setup({Dir,center,M}, St0)) 
+handle_command_1({rotate,{free,{z,Point}}}, St) ->
+    wings_rotate:setup({free,Point}, St);
+handle_command_1({rotate, {free, {'ASK', Ask}}}, St) ->
+    wings:ask(Ask, St, fun({Dir,M},St0) when is_tuple(M), element(1,M) == magnet ->
+			       do_drag(wings_rotate:setup({Dir,center,M}, St0));
+                          ({Dir,Point},St0) ->
+                              do_drag(wings_rotate:setup({Dir,Point}, St0));
+                          ({Dir,Point,M},St0) ->
+                              do_drag(wings_rotate:setup({Dir,Point,M}, St0))
 		       end);
-handle_command_1({rotate, Magnet}, St) when element(1, Magnet) == magnet ->
-    wings_rotate:setup({free,center,Magnet}, St); % For repeat drag
+handle_command_1({rotate, {free,{z,Point,Magnet}}}, St) when element(1, Magnet) == magnet ->
+    wings_rotate:setup({free,Point,Magnet}, St); % For repeat drag
 handle_command_1({rotate,Dir}, St0) 
   when Dir == align_y; Dir == align_x; Dir == align_xy ->
     St1 = align_chart(Dir, St0),
@@ -1019,6 +1098,10 @@ handle_command_1(toggle_background, _) ->
     Old = ?GET({?MODULE,show_background}),
     ?SET({?MODULE,show_background},not Old),
     wings_wm:dirty();
+handle_command_1(toggle_tiled_texture, _) ->
+    Old = ?GET({?MODULE,tiled_texture}),
+    ?SET({?MODULE,tiled_texture},not Old),
+    wings_wm:dirty();
 handle_command_1(export_uv, #st{}=St) ->
     wpc_hlines:command({file, {export_uv, {eps, true}}}, St);
 handle_command_1(Cmd, #st{selmode=Mode}=St0) ->
@@ -1964,9 +2047,13 @@ move_to(Dir,We) ->
     wings_we:transform_vs(T, We).
 
 align(Dir,[{Xa,Ya,_},{Xb,Yb,_}],We) ->
-    [{X1,Y1,_},{X2,Y2,_}] = wings_vertex:bounding_box(We),
+    [V1={X1,Y1,_},V2={X2,Y2,_}] = wings_vertex:bounding_box(We),
+    ChartCenter = {CCX,CCY,CCZ} = e3d_vec:average(V1,V2),
     Translate =
         case Dir of
+            center ->   e3d_vec:sub({(Xa+Xb)/2.0,(Ya+Yb)/2.0,CCZ}, ChartCenter);
+            center_x -> e3d_vec:sub({(Xa+Xb)/2.0,CCY,CCZ}, ChartCenter);
+            center_y -> e3d_vec:sub({CCX,(Ya+Yb)/2.0,CCZ}, ChartCenter);
             bottom ->   {0.0,(Ya-Y1),0.0};
             top ->      {0.0,(Yb-Y2),0.0};   
             left ->     {(Xa-X1),0.0,0.0};
@@ -2145,18 +2232,22 @@ draw_background(#st{bb=#uvstate{bg_img=Image}}) ->
     %% Draw the background texture.
     gl:polygonMode(?GL_FRONT_AND_BACK, ?GL_FILL),
     gl:color3f(1.0, 1.0, 1.0),			%Clear
-    case ?GET({?MODULE,show_background}) of
-	false -> ok;
-	_ ->
+    Q =
+        case ?GET({?MODULE,show_background}) of
+        false ->
+            init_texture_area(false);
+        _ ->
             case wings_image:txid(Image) of
-                none -> ignore; %% Avoid crash if TexImage is deleted
+                none -> %% Avoid crash if TexImage is deleted
+                    init_texture_area(false);
                 Tx ->
+                    gl:texParameteri(?GL_TEXTURE_2D, ?GL_TEXTURE_WRAP_S, ?GL_REPEAT),
+                    gl:texParameteri(?GL_TEXTURE_2D, ?GL_TEXTURE_WRAP_T, ?GL_REPEAT),
                     gl:enable(?GL_TEXTURE_2D),
-                    gl:bindTexture(?GL_TEXTURE_2D, Tx)
+                    gl:bindTexture(?GL_TEXTURE_2D, Tx),
+                    init_texture_area(?GET({?MODULE,tiled_texture}))
             end
-    end,
-    Q = [{0.0, 0.0},{0.0, 0.0, -0.99999}, {1.0, 0.0},{1.0, 0.0, -0.99999},
-         {1.0, 1.0},{1.0, 1.0, -0.99999}, {0.0, 1.0},{0.0, 1.0, -0.99999}],
+        end,
     wings_vbo:draw(fun(_) -> gl:drawArrays(?GL_QUADS, 0, 4) end, Q, [uv, vertex]),
 
     gl:disable(?GL_TEXTURE_2D),
@@ -2167,6 +2258,16 @@ redraw(St) ->
     wings_wm:set_prop(show_info_text, false),
     wings:redraw(St).
 
+init_texture_area(Tiled) ->
+    case Tiled of
+        true ->
+            [{-20.0, -20.0},{-20.0, -20.0, -0.99999}, {20.0, -20.0},{20.0, -20.0, -0.99999},
+             {20.0, 20.0},{20.0, 20.0, -0.99999}, {-20.0, 20.0},{-20.0, 20.0, -0.99999}];
+        false ->
+            [{0.0, 0.0},{0.0, 0.0, -0.99999}, {1.0, 0.0},{1.0, 0.0, -0.99999},
+             {1.0, 1.0},{1.0, 1.0, -0.99999}, {0.0, 1.0},{0.0, 1.0, -0.99999}]
+    end.
+
 init_drawarea() ->
     {W0,H0} = wings_wm:top_size(),
     W = W0 div 2,