]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
Merge commit 'a59855266c41b68a8bfd063713c941eff7449181' into garux-merge
authorThomas Debesse <dev@illwieckz.net>
Mon, 11 Feb 2019 22:57:57 +0000 (23:57 +0100)
committerThomas Debesse <dev@illwieckz.net>
Mon, 11 Feb 2019 23:30:29 +0000 (00:30 +0100)
12 files changed:
1  2 
libs/stringio.h
radiant/brushmanip.cpp
radiant/camwindow.cpp
radiant/entity.cpp
radiant/environment.cpp
radiant/environment.h
radiant/grid.cpp
radiant/main.cpp
radiant/mainframe.cpp
radiant/patch.cpp
radiant/patch.h
radiant/patchmanip.cpp

diff --cc libs/stringio.h
Simple merge
Simple merge
index 447d2341424df5be6138c8e93913686baacb2a2f,e849f4ccd3e179775c23674ffcb58fc04577fb49..2ef5a9862a71d5c9396370c7037397a0aa192521
@@@ -965,7 -970,25 +965,25 @@@ void CamWnd_registerCommands( CamWnd& c
                                                        FreeMoveCameraMoveRightKeyDownCaller( camwnd.getCamera() ),
                                                        FreeMoveCameraMoveRightKeyUpCaller( camwnd.getCamera() )
                                                        );
 -      GlobalKeyEvents_insert( "CameraFreeMoveUp", Accelerator( GDK_period ),
+       GlobalKeyEvents_insert( "CameraFreeMoveForward2", Accelerator( GDK_Up ),
+                                                       FreeMoveCameraMoveForwardKeyDownCaller( camwnd.getCamera() ),
+                                                       FreeMoveCameraMoveForwardKeyUpCaller( camwnd.getCamera() )
+                                                       );
+       GlobalKeyEvents_insert( "CameraFreeMoveBack2", Accelerator( GDK_Down ),
+                                                       FreeMoveCameraMoveBackKeyDownCaller( camwnd.getCamera() ),
+                                                       FreeMoveCameraMoveBackKeyUpCaller( camwnd.getCamera() )
+                                                       );
+       GlobalKeyEvents_insert( "CameraFreeMoveLeft2", Accelerator( GDK_Left ),
+                                                       FreeMoveCameraMoveLeftKeyDownCaller( camwnd.getCamera() ),
+                                                       FreeMoveCameraMoveLeftKeyUpCaller( camwnd.getCamera() )
+                                                       );
+       GlobalKeyEvents_insert( "CameraFreeMoveRight2", Accelerator( GDK_Right ),
+                                                       FreeMoveCameraMoveRightKeyDownCaller( camwnd.getCamera() ),
+                                                       FreeMoveCameraMoveRightKeyUpCaller( camwnd.getCamera() )
+                                                       );
 +      GlobalKeyEvents_insert( "CameraFreeMoveUp", Accelerator( 'D' ),
                                                        FreeMoveCameraMoveUpKeyDownCaller( camwnd.getCamera() ),
                                                        FreeMoveCameraMoveUpKeyUpCaller( camwnd.getCamera() )
                                                        );
@@@ -1898,25 -1935,30 +1928,30 @@@ void CamWnd_Construct()
        GlobalShortcuts_insert( "CameraAngleUp", accelerator_null() );
        GlobalShortcuts_insert( "CameraAngleDown", accelerator_null() );
  
 -      GlobalShortcuts_insert( "CameraFreeMoveForward", Accelerator( 'W' ) );
 -      GlobalShortcuts_insert( "CameraFreeMoveBack", Accelerator( 'S' ) );
 -      GlobalShortcuts_insert( "CameraFreeMoveLeft", Accelerator( 'A' ) );
 -      GlobalShortcuts_insert( "CameraFreeMoveRight", Accelerator( 'D' ) );
 +      GlobalShortcuts_insert( "CameraFreeMoveForward", Accelerator( GDK_Up ) );
 +      GlobalShortcuts_insert( "CameraFreeMoveBack", Accelerator( GDK_Down ) );
 +      GlobalShortcuts_insert( "CameraFreeMoveLeft", Accelerator( GDK_Left ) );
 +      GlobalShortcuts_insert( "CameraFreeMoveRight", Accelerator( GDK_Right ) );
  
 -      GlobalToggles_insert( "ShowStats", ShowStatsToggleCaller(), ToggleItem::AddCallbackCaller( g_show_stats ) );
 -
 -      GlobalPreferenceSystem().registerPreference( "ShowStats", BoolImportStringCaller( g_camwindow_globals_private.m_showStats ), BoolExportStringCaller( g_camwindow_globals_private.m_showStats ) );
 -      GlobalPreferenceSystem().registerPreference( "MoveSpeed", IntImportStringCaller( g_camwindow_globals_private.m_nMoveSpeed ), IntExportStringCaller( g_camwindow_globals_private.m_nMoveSpeed ) );
 -      GlobalPreferenceSystem().registerPreference( "CamLinkSpeed", BoolImportStringCaller( g_camwindow_globals_private.m_bCamLinkSpeed ), BoolExportStringCaller( g_camwindow_globals_private.m_bCamLinkSpeed ) );
 -      GlobalPreferenceSystem().registerPreference( "AngleSpeed", IntImportStringCaller( g_camwindow_globals_private.m_nAngleSpeed ), IntExportStringCaller( g_camwindow_globals_private.m_nAngleSpeed ) );
 -      GlobalPreferenceSystem().registerPreference( "CamInverseMouse", BoolImportStringCaller( g_camwindow_globals_private.m_bCamInverseMouse ), BoolExportStringCaller( g_camwindow_globals_private.m_bCamInverseMouse ) );
 -      GlobalPreferenceSystem().registerPreference( "CamDiscrete", makeBoolStringImportCallback( CamWndMoveDiscreteImportCaller() ), BoolExportStringCaller( g_camwindow_globals_private.m_bCamDiscrete ) );
 -      GlobalPreferenceSystem().registerPreference( "CubicClipping", BoolImportStringCaller( g_camwindow_globals_private.m_bCubicClipping ), BoolExportStringCaller( g_camwindow_globals_private.m_bCubicClipping ) );
 -      GlobalPreferenceSystem().registerPreference( "CubicScale", IntImportStringCaller( g_camwindow_globals.m_nCubicScale ), IntExportStringCaller( g_camwindow_globals.m_nCubicScale ) );
 -      GlobalPreferenceSystem().registerPreference( "SI_Colors4", Vector3ImportStringCaller( g_camwindow_globals.color_cameraback ), Vector3ExportStringCaller( g_camwindow_globals.color_cameraback ) );
 -      GlobalPreferenceSystem().registerPreference( "SI_Colors12", Vector3ImportStringCaller( g_camwindow_globals.color_selbrushes3d ), Vector3ExportStringCaller( g_camwindow_globals.color_selbrushes3d ) );
 -      GlobalPreferenceSystem().registerPreference( "CameraRenderMode", makeIntStringImportCallback( RenderModeImportCaller() ), makeIntStringExportCallback( RenderModeExportCaller() ) );
 -      GlobalPreferenceSystem().registerPreference( "StrafeMode", IntImportStringCaller( g_camwindow_globals_private.m_nStrafeMode ), IntExportStringCaller( g_camwindow_globals_private.m_nStrafeMode ) );
+       GlobalShortcuts_insert( "CameraFreeMoveForward2", Accelerator( GDK_Up ) );
+       GlobalShortcuts_insert( "CameraFreeMoveBack2", Accelerator( GDK_Down ) );
+       GlobalShortcuts_insert( "CameraFreeMoveLeft2", Accelerator( GDK_Left ) );
+       GlobalShortcuts_insert( "CameraFreeMoveRight2", Accelerator( GDK_Right ) );
 +      GlobalToggles_insert( "ShowStats", makeCallbackF(ShowStatsToggle), ToggleItem::AddCallbackCaller( g_show_stats ) );
 +
 +      GlobalPreferenceSystem().registerPreference( "ShowStats", make_property_string( g_camwindow_globals_private.m_showStats ) );
 +      GlobalPreferenceSystem().registerPreference( "MoveSpeed", make_property_string( g_camwindow_globals_private.m_nMoveSpeed ) );
 +      GlobalPreferenceSystem().registerPreference( "CamLinkSpeed", make_property_string( g_camwindow_globals_private.m_bCamLinkSpeed ) );
 +      GlobalPreferenceSystem().registerPreference( "AngleSpeed", make_property_string( g_camwindow_globals_private.m_nAngleSpeed ) );
 +      GlobalPreferenceSystem().registerPreference( "CamInverseMouse", make_property_string( g_camwindow_globals_private.m_bCamInverseMouse ) );
 +      GlobalPreferenceSystem().registerPreference( "CamDiscrete", make_property_string<CamWnd_Move_Discrete>());
 +      GlobalPreferenceSystem().registerPreference( "CubicClipping", make_property_string( g_camwindow_globals_private.m_bCubicClipping ) );
 +      GlobalPreferenceSystem().registerPreference( "CubicScale", make_property_string( g_camwindow_globals.m_nCubicScale ) );
 +      GlobalPreferenceSystem().registerPreference( "SI_Colors4", make_property_string( g_camwindow_globals.color_cameraback ) );
 +      GlobalPreferenceSystem().registerPreference( "SI_Colors12", make_property_string( g_camwindow_globals.color_selbrushes3d ) );
 +      GlobalPreferenceSystem().registerPreference( "CameraRenderMode", make_property_string<RenderMode>() );
 +      GlobalPreferenceSystem().registerPreference( "StrafeMode", make_property_string( g_camwindow_globals_private.m_nStrafeMode ) );
  
        CamWnd_constructStatic();
  
index f7579e5e6573ff80300d56510e2c8fbcd18391f4,a5f42177f1beb5bc57cd99fbf1a93330b2287e46..7a72183666cbc42f04bf8c1ed8a4f4bb705c8db4
  #include "qe3.h"
  #include "commands.h"
  
+ #include "brushmanip.h"
+ #include "patchmanip.h"
 +#include "uilib/uilib.h"
 +
  struct entity_globals_t
  {
        Vector3 color_entity;
index 38c93c41006b978dc44b9530af6cb105d77bc7dd,fc23e9b0f593eb612f56f0705cce2b98deab2fc6..cf3d6b99ebeece96ac90ebfa5f2c3ecdb0981664
@@@ -265,7 -257,19 +265,19 @@@ void environment_init( int argc, char c
  
  #include <windows.h>
  
 -void environment_init( int argc, char* argv[] ){
+ char openCmdMap[260];
+ void cmdMap(){
+       openCmdMap[0] = '\0';
+       for ( int i = 1; i < g_argc; ++i )
+       {
+               if ( !stricmp( g_argv[i] + strlen(g_argv[i]) - 4, ".map" ) ){
+                       strcpy( openCmdMap, g_argv[i] );
+               }
+       }
+ }
 +void environment_init( int argc, char const* argv[] ){
        args_init( argc, argv );
  
        {
index b2828f86ef59e4dd32ccf1feaac5514dc3af3399,8d15115eddaf4bb006ff29c60c754792f62cf084..f36ce11b8a02cb968f09a2b11039fea9c77e6570
@@@ -27,6 -27,11 +27,11 @@@ const char* environment_get_home_path()
  const char* environment_get_app_path();
  
  extern int g_argc;
 -extern char** g_argv;
 +extern char const** g_argv;
  
+ #if defined( WIN32 )
+ extern char openCmdMap[260];
+ #endif
  #endif
Simple merge
index e338baeb0358cc6c8975d96c0fac6eb6a10400e2,0a1eb3b1d3a709630a649ef68f75364cd7b4adfc..fec9894d9d13004ba07d508d958475ba52b82223
@@@ -638,10 -634,13 +648,16 @@@ int main( int argc, char* argv[] )
  
        hide_splash();
  
 -      if ( g_bLoadLastMap && !g_strLastMap.empty() ) {
+ #ifdef WIN32
+       if( openCmdMap[0] != '\0' ){
+               Map_LoadFile( openCmdMap );
+       }
+       else
+ #endif // WIN32
 +      if ( mapname != NULL ) {
 +              Map_LoadFile( mapname );
 +      }
 +      else if ( g_bLoadLastMap && !g_strLastMap.empty() ) {
                Map_LoadFile( g_strLastMap.c_str() );
        }
        else
index 6f377579f484b3015ce5876c606a19e35b1e3023,6cce87d0b917942a0e85ce85a5365da9219f528b..23632f4c061af653f54b1594ee4e204ea5a174f2
@@@ -2364,13 -2221,13 +2364,13 @@@ void PatchInspector_registerShortcuts()
  }
  
  void Patch_registerShortcuts(){
      command_connect_accelerator( "InvertCurveTextureX" );
      command_connect_accelerator( "InvertCurveTextureY" );
//    command_connect_accelerator( "InvertCurveTextureX" );
//    command_connect_accelerator( "InvertCurveTextureY" );
 -      command_connect_accelerator( "IncPatchColumn" );
 -      command_connect_accelerator( "IncPatchRow" );
 -      command_connect_accelerator( "DecPatchColumn" );
 -      command_connect_accelerator( "DecPatchRow" );
 +      command_connect_accelerator( "PatchInsertInsertColumn" );
 +      command_connect_accelerator( "PatchInsertInsertRow" );
 +      command_connect_accelerator( "PatchDeleteLastColumn" );
 +      command_connect_accelerator( "PatchDeleteLastRow" );
      command_connect_accelerator( "NaturalizePatch" );
//    command_connect_accelerator( "NaturalizePatch" );
        //command_connect_accelerator("CapCurrentCurve");
  }
  
@@@ -2427,61 -2286,61 +2429,61 @@@ void register_shortcuts()
        SurfaceInspector_registerShortcuts();
        TexdefNudge_registerShortcuts();
        SelectNudge_registerShortcuts();
      SnapToGrid_registerShortcuts();
      SelectByType_registerShortcuts();
//    SnapToGrid_registerShortcuts();
//    SelectByType_registerShortcuts();
  }
  
 -void File_constructToolbar( GtkToolbar* toolbar ){
 -      toolbar_append_button( toolbar, "Open an existing map (CTRL + O)", "file_open.bmp", "OpenMap" );
 -      toolbar_append_button( toolbar, "Save the active map (CTRL + S)", "file_save.bmp", "SaveMap" );
 +void File_constructToolbar( ui::Toolbar toolbar ){
 +      toolbar_append_button( toolbar, "Open an existing map (CTRL + O)", "file_open.png", "OpenMap" );
 +      toolbar_append_button( toolbar, "Save the active map (CTRL + S)", "file_save.png", "SaveMap" );
  }
  
 -void UndoRedo_constructToolbar( GtkToolbar* toolbar ){
 -      toolbar_append_button( toolbar, "Undo (CTRL + Z)", "undo.bmp", "Undo" );
 -      toolbar_append_button( toolbar, "Redo (CTRL + Y)", "redo.bmp", "Redo" );
 +void UndoRedo_constructToolbar( ui::Toolbar toolbar ){
 +      toolbar_append_button( toolbar, "Undo (CTRL + Z)", "undo.png", "Undo" );
 +      toolbar_append_button( toolbar, "Redo (CTRL + Y)", "redo.png", "Redo" );
  }
  
 -void RotateFlip_constructToolbar( GtkToolbar* toolbar ){
 -      toolbar_append_button( toolbar, "x-axis Flip", "brush_flipx.bmp", "MirrorSelectionX" );
 -      toolbar_append_button( toolbar, "x-axis Rotate", "brush_rotatex.bmp", "RotateSelectionX" );
 -      toolbar_append_button( toolbar, "y-axis Flip", "brush_flipy.bmp", "MirrorSelectionY" );
 -      toolbar_append_button( toolbar, "y-axis Rotate", "brush_rotatey.bmp", "RotateSelectionY" );
 -      toolbar_append_button( toolbar, "z-axis Flip", "brush_flipz.bmp", "MirrorSelectionZ" );
 -      toolbar_append_button( toolbar, "z-axis Rotate", "brush_rotatez.bmp", "RotateSelectionZ" );
 +void RotateFlip_constructToolbar( ui::Toolbar toolbar ){
 +      toolbar_append_button( toolbar, "x-axis Flip", "brush_flipx.png", "MirrorSelectionX" );
 +      toolbar_append_button( toolbar, "x-axis Rotate", "brush_rotatex.png", "RotateSelectionX" );
 +      toolbar_append_button( toolbar, "y-axis Flip", "brush_flipy.png", "MirrorSelectionY" );
 +      toolbar_append_button( toolbar, "y-axis Rotate", "brush_rotatey.png", "RotateSelectionY" );
 +      toolbar_append_button( toolbar, "z-axis Flip", "brush_flipz.png", "MirrorSelectionZ" );
 +      toolbar_append_button( toolbar, "z-axis Rotate", "brush_rotatez.png", "RotateSelectionZ" );
  }
  
 -void Select_constructToolbar( GtkToolbar* toolbar ){
 -      toolbar_append_button( toolbar, "Select touching", "selection_selecttouching.bmp", "SelectTouching" );
 -      toolbar_append_button( toolbar, "Select inside", "selection_selectinside.bmp", "SelectInside" );
 +void Select_constructToolbar( ui::Toolbar toolbar ){
 +      toolbar_append_button( toolbar, "Select touching", "selection_selecttouching.png", "SelectTouching" );
 +      toolbar_append_button( toolbar, "Select inside", "selection_selectinside.png", "SelectInside" );
  }
  
 -void CSG_constructToolbar( GtkToolbar* toolbar ){
 -      toolbar_append_button( toolbar, "CSG Subtract (SHIFT + U)", "selection_csgsubtract.bmp", "CSGSubtract" );
 -      toolbar_append_button( toolbar, "CSG Merge (CTRL + U)", "selection_csgmerge.bmp", "CSGMerge" );
 -      toolbar_append_button( toolbar, "Hollow", "selection_makehollow.bmp", "CSGHollow" );
 -      toolbar_append_button( toolbar, "Room", "selection_makeroom.bmp", "CSGroom" );
 +void CSG_constructToolbar( ui::Toolbar toolbar ){
 +      toolbar_append_button( toolbar, "CSG Subtract (SHIFT + U)", "selection_csgsubtract.png", "CSGSubtract" );
 +      toolbar_append_button( toolbar, "CSG Merge (CTRL + U)", "selection_csgmerge.png", "CSGMerge" );
 +      toolbar_append_button( toolbar, "Make Hollow", "selection_makehollow.png", "CSGHollow" );
 +      toolbar_append_button( toolbar, "Make Room", "selection_makeroom.png", "CSGRoom" );
  }
  
 -void ComponentModes_constructToolbar( GtkToolbar* toolbar ){
 -      toolbar_append_toggle_button( toolbar, "Select Vertices (V)", "modify_vertices.bmp", "DragVertices" );
 -      toolbar_append_toggle_button( toolbar, "Select Edges (E)", "modify_edges.bmp", "DragEdges" );
 -      toolbar_append_toggle_button( toolbar, "Select Faces (F)", "modify_faces.bmp", "DragFaces" );
 +void ComponentModes_constructToolbar( ui::Toolbar toolbar ){
 +      toolbar_append_toggle_button( toolbar, "Select Vertices (V)", "modify_vertices.png", "DragVertices" );
 +      toolbar_append_toggle_button( toolbar, "Select Edges (E)", "modify_edges.png", "DragEdges" );
 +      toolbar_append_toggle_button( toolbar, "Select Faces (F)", "modify_faces.png", "DragFaces" );
  }
  
 -void Clipper_constructToolbar( GtkToolbar* toolbar ){
 +void Clipper_constructToolbar( ui::Toolbar toolbar ){
  
 -      toolbar_append_toggle_button( toolbar, "Clipper (X)", "view_clipper.bmp", "ToggleClipper" );
 +      toolbar_append_toggle_button( toolbar, "Clipper (X)", "view_clipper.png", "ToggleClipper" );
  }
  
 -void XYWnd_constructToolbar( GtkToolbar* toolbar ){
 -      toolbar_append_button( toolbar, "Change views", "view_change.bmp", "NextView" );
 +void XYWnd_constructToolbar( ui::Toolbar toolbar ){
 +      toolbar_append_button( toolbar, "Change views", "view_change.png", "NextView" );
  }
  
 -void Manipulators_constructToolbar( GtkToolbar* toolbar ){
 -      toolbar_append_toggle_button( toolbar, "Translate (W)", "select_mousetranslate.bmp", "MouseTranslate" );
 -      toolbar_append_toggle_button( toolbar, "Rotate (R)", "select_mouserotate.bmp", "MouseRotate" );
 -      toolbar_append_toggle_button( toolbar, "Scale", "select_mousescale.bmp", "MouseScale" );
 -      toolbar_append_toggle_button( toolbar, "Resize (Q)", "select_mouseresize.bmp", "MouseDrag" );
 +void Manipulators_constructToolbar( ui::Toolbar toolbar ){
 +      toolbar_append_toggle_button( toolbar, "Translate (W)", "select_mousetranslate.png", "MouseTranslate" );
 +      toolbar_append_toggle_button( toolbar, "Rotate (R)", "select_mouserotate.png", "MouseRotate" );
 +      toolbar_append_toggle_button( toolbar, "Scale", "select_mousescale.png", "MouseScale" );
 +      toolbar_append_toggle_button( toolbar, "Resize (Q)", "select_mouseresize.png", "MouseDrag" );
  
        Clipper_constructToolbar( toolbar );
  }
@@@ -2951,13 -2801,13 +2953,13 @@@ void MainFrame::Create()
                toolbar_append_toggle_button( plugin_toolbar, "Clips (ALT + 7)", "f-clip.bmp", "FilterClips" );
                toolbar_append_toggle_button( plugin_toolbar, "HintsSkips (CTRL + H)", "f-hint.bmp", "FilterHintsSkips" );
                //toolbar_append_toggle_button( plugin_toolbar, "Paths (ALT + 8)", "texture_lock.bmp", "FilterPaths" );
 -              gtk_toolbar_append_space( GTK_TOOLBAR( plugin_toolbar ) );
 +              space();
                toolbar_append_toggle_button( plugin_toolbar, "Entities (ALT + 2)", "f-entities.bmp", "FilterEntities" );
 -              toolbar_append_toggle_button( plugin_toolbar, "Lights (ALT + 0)", "lightinspector.bmp", "FilterLights" );
 +              toolbar_append_toggle_button( plugin_toolbar, "Lights (ALT + 0)", "lightinspector.png", "FilterLights" );
                toolbar_append_toggle_button( plugin_toolbar, "Models (SHIFT + M)", "f-models.bmp", "FilterModels" );
                toolbar_append_toggle_button( plugin_toolbar, "Triggers (CTRL + SHIFT + T)", "f-triggers.bmp", "FilterTriggers" );
              toolbar_append_toggle_button( plugin_toolbar, "Decals (SHIFT + D)", "f-decals.bmp", "FilterDecals" );
//            toolbar_append_toggle_button( plugin_toolbar, "Decals (SHIFT + D)", "f-decals.bmp", "FilterDecals" );
 -              gtk_toolbar_append_space( GTK_TOOLBAR( plugin_toolbar ) );
 +              space();
                toolbar_append_button( plugin_toolbar, "InvertFilters", "f-invert.bmp", "InvertFilters" );
                toolbar_append_button( plugin_toolbar, "ResetFilters", "f-reset.bmp", "ResetFilters" );
        }
@@@ -3375,75 -3224,80 +3377,79 @@@ void Layout_registerPreferencesPage()
  #include "stringio.h"
  
  void MainFrame_Construct(){
 -      GlobalCommands_insert( "OpenManual", FreeCaller<OpenHelpURL>(), Accelerator( GDK_F1 ) );
 -
 -      GlobalCommands_insert( "Sleep", FreeCaller<thunk_OnSleep>(), Accelerator( 'P', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 -      GlobalCommands_insert( "NewMap", FreeCaller<NewMap>() );
 -      GlobalCommands_insert( "OpenMap", FreeCaller<OpenMap>(), Accelerator( 'O', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "ImportMap", FreeCaller<ImportMap>() );
 -      GlobalCommands_insert( "SaveMap", FreeCaller<SaveMap>(), Accelerator( 'S', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "SaveMapAs", FreeCaller<SaveMapAs>() );
 -      GlobalCommands_insert( "SaveSelected", FreeCaller<ExportMap>() );
 -      GlobalCommands_insert( "SaveRegion", FreeCaller<SaveRegion>() );
 -      GlobalCommands_insert( "RefreshReferences", FreeCaller<RefreshReferences>() );
 -      GlobalCommands_insert( "ProjectSettings", FreeCaller<DoProjectSettings>() );
 -      GlobalCommands_insert( "CheckForUpdate", FreeCaller<OpenUpdateURL>() );
 -      GlobalCommands_insert( "Exit", FreeCaller<Exit>() );
 -
 -      GlobalCommands_insert( "Undo", FreeCaller<Undo>(), Accelerator( 'Z', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "Redo", FreeCaller<Redo>(), Accelerator( 'Y', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "Copy", FreeCaller<Copy>(), Accelerator( 'C', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "Paste", FreeCaller<Paste>(), Accelerator( 'V', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "PasteToCamera", FreeCaller<PasteToCamera>(), Accelerator( 'V', (GdkModifierType)GDK_SHIFT_MASK ) );
 -      GlobalCommands_insert( "CloneSelection", FreeCaller<Selection_Clone>(), Accelerator( GDK_space ) );
 -      GlobalCommands_insert( "CloneSelectionAndMakeUnique", FreeCaller<Selection_Clone_MakeUnique>(), Accelerator( GDK_space, (GdkModifierType)GDK_SHIFT_MASK ) );
 -//    GlobalCommands_insert( "DeleteSelection", FreeCaller<deleteSelection>(), Accelerator( GDK_BackSpace ) );
 -      GlobalCommands_insert( "DeleteSelection2", FreeCaller<deleteSelection>(), Accelerator( GDK_BackSpace ) );
 -      GlobalCommands_insert( "DeleteSelection", FreeCaller<deleteSelection>(), Accelerator( 'Z' ) );
 -      GlobalCommands_insert( "ParentSelection", FreeCaller<Scene_parentSelected>() );
 -//    GlobalCommands_insert( "UnSelectSelection", FreeCaller<Selection_Deselect>(), Accelerator( GDK_Escape ) );
 -      GlobalCommands_insert( "UnSelectSelection2", FreeCaller<Selection_Deselect>(), Accelerator( GDK_Escape ) );
 -      GlobalCommands_insert( "UnSelectSelection", FreeCaller<Selection_Deselect>(), Accelerator( 'C' ) );
 -      GlobalCommands_insert( "InvertSelection", FreeCaller<Select_Invert>(), Accelerator( 'I' ) );
 -      GlobalCommands_insert( "SelectInside", FreeCaller<Select_Inside>() );
 -      GlobalCommands_insert( "SelectTouching", FreeCaller<Select_Touching>() );
 -      GlobalCommands_insert( "ExpandSelectionToEntities", FreeCaller<Scene_ExpandSelectionToEntities>(), Accelerator( 'E', (GdkModifierType)GDK_SHIFT_MASK ) );
 -      GlobalCommands_insert( "Preferences", FreeCaller<PreferencesDialog_showDialog>(), Accelerator( 'P' ) );
 -
 -      GlobalCommands_insert( "ToggleConsole", FreeCaller<Console_ToggleShow>(), Accelerator( 'O' ) );
 -      GlobalCommands_insert( "ToggleEntityInspector", FreeCaller<EntityInspector_ToggleShow>(), Accelerator( 'N' ) );
 -      GlobalCommands_insert( "EntityList", FreeCaller<EntityList_toggleShown>(), Accelerator( 'L' ) );
 -
 -      GlobalCommands_insert( "ShowHidden", FreeCaller<Select_ShowAllHidden>(), Accelerator( 'H', (GdkModifierType)GDK_SHIFT_MASK ) );
 -      GlobalCommands_insert( "HideSelected", FreeCaller<HideSelected>(), Accelerator( 'H' ) );
 -
 -      GlobalToggles_insert( "DragVertices", FreeCaller<SelectVertexMode>(), ToggleItem::AddCallbackCaller( g_vertexMode_button ), Accelerator( 'V' ) );
 -      GlobalToggles_insert( "DragEdges", FreeCaller<SelectEdgeMode>(), ToggleItem::AddCallbackCaller( g_edgeMode_button ), Accelerator( 'E' ) );
 -      GlobalToggles_insert( "DragFaces", FreeCaller<SelectFaceMode>(), ToggleItem::AddCallbackCaller( g_faceMode_button ), Accelerator( 'F' ) );
 -
 -      GlobalCommands_insert( "MirrorSelectionX", FreeCaller<Selection_Flipx>() );
 -      GlobalCommands_insert( "RotateSelectionX", FreeCaller<Selection_Rotatex>() );
 -      GlobalCommands_insert( "MirrorSelectionY", FreeCaller<Selection_Flipy>() );
 -      GlobalCommands_insert( "RotateSelectionY", FreeCaller<Selection_Rotatey>() );
 -      GlobalCommands_insert( "MirrorSelectionZ", FreeCaller<Selection_Flipz>() );
 -      GlobalCommands_insert( "RotateSelectionZ", FreeCaller<Selection_Rotatez>() );
 -
 -      GlobalCommands_insert( "ArbitraryRotation", FreeCaller<DoRotateDlg>(), Accelerator( 'R', (GdkModifierType)GDK_SHIFT_MASK ) );
 -      GlobalCommands_insert( "ArbitraryScale", FreeCaller<DoScaleDlg>(), Accelerator( 'S', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 -
 -      GlobalCommands_insert( "BuildMenuCustomize", FreeCaller<DoBuildMenu>() );
 -
 -      GlobalCommands_insert( "FindBrush", FreeCaller<DoFind>() );
 -
 -      GlobalCommands_insert( "MapInfo", FreeCaller<DoMapInfo>(), Accelerator( 'M' ) );
 -
 -
 -      GlobalToggles_insert( "ToggleClipper", FreeCaller<ClipperMode>(), ToggleItem::AddCallbackCaller( g_clipper_button ), Accelerator( 'X' ) );
 -
 -      GlobalToggles_insert( "MouseTranslate", FreeCaller<TranslateMode>(), ToggleItem::AddCallbackCaller( g_translatemode_button ), Accelerator( 'W' ) );
 -      GlobalToggles_insert( "MouseRotate", FreeCaller<RotateMode>(), ToggleItem::AddCallbackCaller( g_rotatemode_button ), Accelerator( 'R' ) );
 -      GlobalToggles_insert( "MouseScale", FreeCaller<ScaleMode>(), ToggleItem::AddCallbackCaller( g_scalemode_button ) );
 -      GlobalToggles_insert( "MouseDrag", FreeCaller<DragMode>(), ToggleItem::AddCallbackCaller( g_dragmode_button ), Accelerator( 'Q' ) );
 -
 -      GlobalCommands_insert( "ColorSchemeOriginal", FreeCaller<ColorScheme_Original>() );
 -      GlobalCommands_insert( "ColorSchemeQER", FreeCaller<ColorScheme_QER>() );
 -      GlobalCommands_insert( "ColorSchemeBlackAndGreen", FreeCaller<ColorScheme_Black>() );
 -      GlobalCommands_insert( "ColorSchemeYdnar", FreeCaller<ColorScheme_Ydnar>() );
 +      GlobalCommands_insert( "OpenManual", makeCallbackF(OpenHelpURL), Accelerator( GDK_KEY_F1 ) );
 +
 +      GlobalCommands_insert( "Sleep", makeCallbackF(thunk_OnSleep), Accelerator( 'P', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "NewMap", makeCallbackF(NewMap) );
 +      GlobalCommands_insert( "OpenMap", makeCallbackF(OpenMap), Accelerator( 'O', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "ImportMap", makeCallbackF(ImportMap) );
 +      GlobalCommands_insert( "SaveMap", makeCallbackF(SaveMap), Accelerator( 'S', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "SaveMapAs", makeCallbackF(SaveMapAs) );
 +      GlobalCommands_insert( "ExportSelected", makeCallbackF(ExportMap) );
 +      GlobalCommands_insert( "SaveRegion", makeCallbackF(SaveRegion) );
 +      GlobalCommands_insert( "RefreshReferences", makeCallbackF(VFS_Refresh) );
 +      GlobalCommands_insert( "ProjectSettings", makeCallbackF(DoProjectSettings) );
 +      GlobalCommands_insert( "Exit", makeCallbackF(Exit) );
 +
 +      GlobalCommands_insert( "Undo", makeCallbackF(Undo), Accelerator( 'Z', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "Redo", makeCallbackF(Redo), Accelerator( 'Y', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "Copy", makeCallbackF(Copy), Accelerator( 'C', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "Paste", makeCallbackF(Paste), Accelerator( 'V', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "PasteToCamera", makeCallbackF(PasteToCamera), Accelerator( 'V', (GdkModifierType)GDK_MOD1_MASK ) );
 +      GlobalCommands_insert( "CloneSelection", makeCallbackF(Selection_Clone), Accelerator( GDK_KEY_space ) );
 +      GlobalCommands_insert( "CloneSelectionAndMakeUnique", makeCallbackF(Selection_Clone_MakeUnique), Accelerator( GDK_KEY_space, (GdkModifierType)GDK_SHIFT_MASK ) );
-       GlobalCommands_insert( "DeleteSelection", makeCallbackF(deleteSelection), Accelerator( GDK_KEY_BackSpace ) );
++//    GlobalCommands_insert( "DeleteSelection", makeCallbackF(deleteSelection), Accelerator( GDK_KEY_BackSpace ) );
++      GlobalCommands_insert( "DeleteSelection2", makeCallbackF(deleteSelection), Accelerator( GDK_KEY_BackSpace ) );
++      GlobalCommands_insert( "DeleteSelection", makeCallbackF(deleteSelection), Accelerator( 'Z' ) );
 +      GlobalCommands_insert( "ParentSelection", makeCallbackF(Scene_parentSelected) );
-       GlobalCommands_insert( "UnSelectSelection", makeCallbackF(Selection_Deselect), Accelerator( GDK_KEY_Escape ) );
++//    GlobalCommands_insert( "UnSelectSelection", makeCallbackF(Selection_Deselect), Accelerator( GDK_KEY_Escape ) );
++      GlobalCommands_insert( "UnSelectSelection2", makeCallbackF(Selection_Deselect), Accelerator( GDK_KEY_Escape ) );
++      GlobalCommands_insert( "UnSelectSelection", makeCallbackF(Selection_Deselect), Accelerator( 'C' ) );
 +      GlobalCommands_insert( "InvertSelection", makeCallbackF(Select_Invert), Accelerator( 'I' ) );
 +      GlobalCommands_insert( "SelectInside", makeCallbackF(Select_Inside) );
 +      GlobalCommands_insert( "SelectTouching", makeCallbackF(Select_Touching) );
 +      GlobalCommands_insert( "ExpandSelectionToEntities", makeCallbackF(Scene_ExpandSelectionToEntities), Accelerator( 'E', (GdkModifierType)( GDK_MOD1_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "Preferences", makeCallbackF(PreferencesDialog_showDialog), Accelerator( 'P' ) );
 +
 +      GlobalCommands_insert( "ToggleConsole", makeCallbackF(Console_ToggleShow), Accelerator( 'O' ) );
 +      GlobalCommands_insert( "ToggleEntityInspector", makeCallbackF(EntityInspector_ToggleShow), Accelerator( 'N' ) );
 +      GlobalCommands_insert( "EntityList", makeCallbackF(EntityList_toggleShown), Accelerator( 'L' ) );
 +
 +      GlobalCommands_insert( "ShowHidden", makeCallbackF(Select_ShowAllHidden), Accelerator( 'H', (GdkModifierType)GDK_SHIFT_MASK ) );
 +      GlobalCommands_insert( "HideSelected", makeCallbackF(HideSelected), Accelerator( 'H' ) );
 +
 +      GlobalToggles_insert( "DragVertices", makeCallbackF(SelectVertexMode), ToggleItem::AddCallbackCaller( g_vertexMode_button ), Accelerator( 'V' ) );
 +      GlobalToggles_insert( "DragEdges", makeCallbackF(SelectEdgeMode), ToggleItem::AddCallbackCaller( g_edgeMode_button ), Accelerator( 'E' ) );
 +      GlobalToggles_insert( "DragFaces", makeCallbackF(SelectFaceMode), ToggleItem::AddCallbackCaller( g_faceMode_button ), Accelerator( 'F' ) );
 +
 +      GlobalCommands_insert( "MirrorSelectionX", makeCallbackF(Selection_Flipx) );
 +      GlobalCommands_insert( "RotateSelectionX", makeCallbackF(Selection_Rotatex) );
 +      GlobalCommands_insert( "MirrorSelectionY", makeCallbackF(Selection_Flipy) );
 +      GlobalCommands_insert( "RotateSelectionY", makeCallbackF(Selection_Rotatey) );
 +      GlobalCommands_insert( "MirrorSelectionZ", makeCallbackF(Selection_Flipz) );
 +      GlobalCommands_insert( "RotateSelectionZ", makeCallbackF(Selection_Rotatez) );
 +
 +      GlobalCommands_insert( "ArbitraryRotation", makeCallbackF(DoRotateDlg) );
 +      GlobalCommands_insert( "ArbitraryScale", makeCallbackF(DoScaleDlg) );
 +
 +      GlobalCommands_insert( "BuildMenuCustomize", makeCallbackF(DoBuildMenu) );
 +
 +      GlobalCommands_insert( "FindBrush", makeCallbackF(DoFind) );
 +
 +      GlobalCommands_insert( "MapInfo", makeCallbackF(DoMapInfo), Accelerator( 'M' ) );
 +
 +
 +      GlobalToggles_insert( "ToggleClipper", makeCallbackF(ClipperMode), ToggleItem::AddCallbackCaller( g_clipper_button ), Accelerator( 'X' ) );
 +
 +      GlobalToggles_insert( "MouseTranslate", makeCallbackF(TranslateMode), ToggleItem::AddCallbackCaller( g_translatemode_button ), Accelerator( 'W' ) );
 +      GlobalToggles_insert( "MouseRotate", makeCallbackF(RotateMode), ToggleItem::AddCallbackCaller( g_rotatemode_button ), Accelerator( 'R' ) );
 +      GlobalToggles_insert( "MouseScale", makeCallbackF(ScaleMode), ToggleItem::AddCallbackCaller( g_scalemode_button ) );
 +      GlobalToggles_insert( "MouseDrag", makeCallbackF(DragMode), ToggleItem::AddCallbackCaller( g_dragmode_button ), Accelerator( 'Q' ) );
 +
 +      GlobalCommands_insert( "ColorSchemeOriginal", makeCallbackF(ColorScheme_Original) );
 +      GlobalCommands_insert( "ColorSchemeQER", makeCallbackF(ColorScheme_QER) );
 +      GlobalCommands_insert( "ColorSchemeBlackAndGreen", makeCallbackF(ColorScheme_Black) );
 +      GlobalCommands_insert( "ColorSchemeYdnar", makeCallbackF(ColorScheme_Ydnar) );
        GlobalCommands_insert( "ChooseTextureBackgroundColor", makeCallback( g_ColoursMenu.m_textureback ) );
        GlobalCommands_insert( "ChooseGridBackgroundColor", makeCallback( g_ColoursMenu.m_xyback ) );
        GlobalCommands_insert( "ChooseGridMajorColor", makeCallback( g_ColoursMenu.m_gridmajor ) );
Simple merge
diff --cc radiant/patch.h
Simple merge
index 15faff88c81b31ffeb5b5a86c9d2d497e2fa0a37,b2c0b2d6f32a49f2fb1be34f8a9ceb6865f0aa72..644e122af4aa3dbb03ca423516be0eedb9ef7a79
@@@ -222,6 -196,83 +222,85 @@@ void Scene_PatchDeform( scene::Graph& g
  
  }
  
 -      Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) );
+ void Patch_thicken( Patch& patch, scene::Instance& instance, const float thickness, bool seams, const int axis ){
+               // Create a new patch node
+               NodeSmartReference node(g_patchCreator->createPatch());
+               // Insert the node into worldspawn
+               Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(node);
+               // Retrieve the contained patch from the node
+               Patch* targetPatch = Node_getPatch(node);
+               // Create the opposite patch with the given thickness = distance
+               bool no12 = true;
+               bool no34 = true;
+               targetPatch->createThickenedOpposite(patch, thickness, axis, no12, no34);
+               // Now select the newly created patches
+               {
+                       scene::Path patchpath(makeReference(GlobalSceneGraph().root()));
+                       patchpath.push(makeReference(*Map_GetWorldspawn(g_map)));
+                       patchpath.push(makeReference(node.get()));
+                       Instance_getSelectable(*GlobalSceneGraph().find(patchpath))->setSelected(true);
+               }
+               if (seams && thickness != 0.0f) {
+                       int i = 0;
+                       if ( no12 ){
+                               i = 2;
+                       }
+                       int iend = 4;
+                       if ( no34 ){
+                               iend = 2;
+                       }
+                       // Now create the four walls
+                       for ( ; i < iend; i++ ) {
+                               // Allocate new patch
+                               NodeSmartReference node = NodeSmartReference(g_patchCreator->createPatch());
+                               // Insert each node into worldspawn
+                               Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(node);
+                               // Retrieve the contained patch from the node
+                               Patch* wallPatch = Node_getPatch(node);
+                               // Create the wall patch by passing i as wallIndex
+                               wallPatch->createThickenedWall( patch, *targetPatch, i);
+                               if( ( wallPatch->localAABB().extents[0] <= 0.00005 && wallPatch->localAABB().extents[1] <= 0.00005 ) ||
+                                       ( wallPatch->localAABB().extents[1] <= 0.00005 && wallPatch->localAABB().extents[2] <= 0.00005 ) ||
+                                       ( wallPatch->localAABB().extents[0] <= 0.00005 && wallPatch->localAABB().extents[2] <= 0.00005 ) ){
+                                       //globalOutputStream() << "Thicken: Discarding degenerate patch.\n";
+                                       Node_getTraversable( Map_FindOrInsertWorldspawn(g_map) )->erase( node );
+                               }
+                               else
+                               // Now select the newly created patches
+                               {
+                                       scene::Path patchpath(makeReference(GlobalSceneGraph().root()));
+                                       patchpath.push(makeReference(*Map_GetWorldspawn(g_map)));
+                                       patchpath.push(makeReference(node.get()));
+                                       Instance_getSelectable(*GlobalSceneGraph().find(patchpath))->setSelected(true);
+                               }
+                       }
+               }
+               // Invert the target patch so that it faces the opposite direction
+               targetPatch->InvertMatrix();
+ }
+ void Scene_PatchThicken( scene::Graph& graph, const int thickness, bool seams, const int axis )
+ {
+       InstanceVector instances;
++      Scene_forEachVisibleSelectedPatchInstance([&](PatchInstance &patch) {
++              instances.push_back(&patch);
++      });
+       for ( InstanceVector::const_iterator i = instances.begin(); i != instances.end(); ++i )
+       {
+               Patch_thicken( *Node_getPatch( ( *i )->path().top() ), *( *i ), thickness, seams, axis );
+       }
+ }
  Patch* Scene_GetUltimateSelectedVisiblePatch(){
        if ( GlobalSelectionSystem().countSelected() != 0 ) {
                scene::Node& node = GlobalSelectionSystem().ultimateSelected().path().top();
@@@ -578,6 -695,16 +657,13 @@@ void Patch_Deform()
        DoPatchDeformDlg();
  }
  
 -
 -
 -
+ void DoPatchThickenDlg();
+ void Patch_Thicken(){
+       UndoableCommand undo( "patchThicken" );
+       DoPatchThickenDlg();
+ }
  #include "ifilter.h"
  
  
@@@ -649,56 -776,57 +735,57 @@@ void PatchPreferences_construct()
  #include "generic/callback.h"
  
  void Patch_registerCommands(){
 -      GlobalCommands_insert( "InvertCurveTextureX", FreeCaller<Patch_FlipTextureX>(), Accelerator( 'I', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 -      GlobalCommands_insert( "InvertCurveTextureY", FreeCaller<Patch_FlipTextureY>(), Accelerator( 'I', (GdkModifierType)GDK_SHIFT_MASK ) );
 -      GlobalCommands_insert( "IncPatchColumn", FreeCaller<Patch_InsertInsertColumn>(), Accelerator( GDK_KP_Add, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 -      GlobalCommands_insert( "IncPatchRow", FreeCaller<Patch_InsertInsertRow>(), Accelerator( GDK_KP_Add, (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "DecPatchColumn", FreeCaller<Patch_DeleteLastColumn>(), Accelerator( GDK_KP_Subtract, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 -      GlobalCommands_insert( "DecPatchRow", FreeCaller<Patch_DeleteLastRow>(), Accelerator( GDK_KP_Subtract, (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "NaturalizePatch", FreeCaller<Patch_NaturalTexture>(), Accelerator( 'N', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "PatchCylinder", FreeCaller<Patch_Cylinder>() );
 -      GlobalCommands_insert( "PatchDenseCylinder", FreeCaller<Patch_DenseCylinder>() );
 -      GlobalCommands_insert( "PatchVeryDenseCylinder", FreeCaller<Patch_VeryDenseCylinder>() );
 -      GlobalCommands_insert( "PatchSquareCylinder", FreeCaller<Patch_SquareCylinder>() );
 -      GlobalCommands_insert( "PatchXactCylinder", FreeCaller<Patch_XactCylinder>() );
 -      GlobalCommands_insert( "PatchXactSphere", FreeCaller<Patch_XactSphere>() );
 -      GlobalCommands_insert( "PatchXactCone", FreeCaller<Patch_XactCone>() );
 -      GlobalCommands_insert( "PatchEndCap", FreeCaller<Patch_Endcap>() );
 -      GlobalCommands_insert( "PatchBevel", FreeCaller<Patch_Bevel>() );
 -      GlobalCommands_insert( "PatchSquareBevel", FreeCaller<Patch_SquareBevel>() );
 -      GlobalCommands_insert( "PatchSquareEndcap", FreeCaller<Patch_SquareEndcap>() );
 -      GlobalCommands_insert( "PatchCone", FreeCaller<Patch_Cone>() );
 -      GlobalCommands_insert( "PatchSphere", FreeCaller<Patch_Sphere>() );
 -      GlobalCommands_insert( "SimplePatchMesh", FreeCaller<Patch_Plane>(), Accelerator( 'P', (GdkModifierType)GDK_SHIFT_MASK ) );
 -      GlobalCommands_insert( "PatchInsertInsertColumn", FreeCaller<Patch_InsertInsertColumn>() );
 -      GlobalCommands_insert( "PatchInsertAddColumn", FreeCaller<Patch_InsertAddColumn>() );
 -      GlobalCommands_insert( "PatchInsertInsertRow", FreeCaller<Patch_InsertInsertRow>() );
 -      GlobalCommands_insert( "PatchInsertAddRow", FreeCaller<Patch_InsertAddRow>() );
 -      GlobalCommands_insert( "PatchDeleteFirstColumn", FreeCaller<Patch_DeleteFirstColumn>() );
 -      GlobalCommands_insert( "PatchDeleteLastColumn", FreeCaller<Patch_DeleteLastColumn>() );
 -      GlobalCommands_insert( "PatchDeleteFirstRow", FreeCaller<Patch_DeleteFirstRow>() );
 -      GlobalCommands_insert( "PatchDeleteLastRow", FreeCaller<Patch_DeleteLastRow>() );
 -      GlobalCommands_insert( "InvertCurve", FreeCaller<Patch_Invert>(), Accelerator( 'I', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "RedisperseRows", FreeCaller<Patch_RedisperseRows>(), Accelerator( 'E', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "RedisperseCols", FreeCaller<Patch_RedisperseCols>(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 -      GlobalCommands_insert( "SmoothRows", FreeCaller<Patch_SmoothRows>(), Accelerator( 'W', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "SmoothCols", FreeCaller<Patch_SmoothCols>(), Accelerator( 'W', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 -      GlobalCommands_insert( "MatrixTranspose", FreeCaller<Patch_Transpose>(), Accelerator( 'M', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 -      GlobalCommands_insert( "CapCurrentCurve", FreeCaller<Patch_Cap>(), Accelerator( 'C', (GdkModifierType)GDK_SHIFT_MASK ) );
 -      GlobalCommands_insert( "CycleCapTexturePatch", FreeCaller<Patch_CycleProjection>(), Accelerator( 'N', (GdkModifierType)GDK_SHIFT_MASK ) );
 -      GlobalCommands_insert( "MakeOverlayPatch", FreeCaller<Patch_OverlayOn>(), Accelerator( 'Y' ) );
 -      GlobalCommands_insert( "ClearPatchOverlays", FreeCaller<Patch_OverlayOff>(), Accelerator( 'L', (GdkModifierType)GDK_CONTROL_MASK ) );
 -      GlobalCommands_insert( "PatchDeform", FreeCaller<Patch_Deform>() );
 -      GlobalCommands_insert( "PatchThicken", FreeCaller<Patch_Thicken>() );
 -}
 -
 -void Patch_constructToolbar( GtkToolbar* toolbar ){
 -      toolbar_append_button( toolbar, "Put caps on the current patch (SHIFT + C)", "curve_cap.bmp", "CapCurrentCurve" );
 -}
 -
 -void Patch_constructMenu( GtkMenu* menu ){
 +      GlobalCommands_insert( "InvertCurveTextureX", makeCallbackF(Patch_FlipTextureX), Accelerator( 'I', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "InvertCurveTextureY", makeCallbackF(Patch_FlipTextureY), Accelerator( 'I', (GdkModifierType)GDK_SHIFT_MASK ) );
 +      GlobalCommands_insert( "IncPatchColumn", makeCallbackF(Patch_InsertInsertColumn), Accelerator( GDK_KP_Add, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "IncPatchRow", makeCallbackF(Patch_InsertInsertRow), Accelerator( GDK_KP_Add, (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "DecPatchColumn", makeCallbackF(Patch_DeleteLastColumn), Accelerator( GDK_KP_Subtract, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "DecPatchRow", makeCallbackF(Patch_DeleteLastRow), Accelerator( GDK_KP_Subtract, (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "NaturalizePatch", makeCallbackF(Patch_NaturalTexture), Accelerator( 'N', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "PatchCylinder", makeCallbackF(Patch_Cylinder) );
 +      GlobalCommands_insert( "PatchDenseCylinder", makeCallbackF(Patch_DenseCylinder) );
 +      GlobalCommands_insert( "PatchVeryDenseCylinder", makeCallbackF(Patch_VeryDenseCylinder) );
 +      GlobalCommands_insert( "PatchSquareCylinder", makeCallbackF(Patch_SquareCylinder) );
 +      GlobalCommands_insert( "PatchXactCylinder", makeCallbackF(Patch_XactCylinder) );
 +      GlobalCommands_insert( "PatchXactSphere", makeCallbackF(Patch_XactSphere) );
 +      GlobalCommands_insert( "PatchXactCone", makeCallbackF(Patch_XactCone) );
 +      GlobalCommands_insert( "PatchEndCap", makeCallbackF(Patch_Endcap) );
 +      GlobalCommands_insert( "PatchBevel", makeCallbackF(Patch_Bevel) );
 +      GlobalCommands_insert( "PatchSquareBevel", makeCallbackF(Patch_SquareBevel) );
 +      GlobalCommands_insert( "PatchSquareEndcap", makeCallbackF(Patch_SquareEndcap) );
 +      GlobalCommands_insert( "PatchCone", makeCallbackF(Patch_Cone) );
 +      GlobalCommands_insert( "PatchSphere", makeCallbackF(Patch_Sphere) );
 +      GlobalCommands_insert( "SimplePatchMesh", makeCallbackF(Patch_Plane), Accelerator( 'P', (GdkModifierType)GDK_SHIFT_MASK ) );
 +      GlobalCommands_insert( "PatchInsertInsertColumn", makeCallbackF(Patch_InsertInsertColumn), Accelerator( GDK_KEY_KP_Add, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "PatchInsertAddColumn", makeCallbackF(Patch_InsertAddColumn) );
 +      GlobalCommands_insert( "PatchInsertInsertRow", makeCallbackF(Patch_InsertInsertRow), Accelerator( GDK_KEY_KP_Add, (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "PatchInsertAddRow", makeCallbackF(Patch_InsertAddRow) );
 +      GlobalCommands_insert( "PatchDeleteFirstColumn", makeCallbackF(Patch_DeleteFirstColumn) );
 +      GlobalCommands_insert( "PatchDeleteLastColumn", makeCallbackF(Patch_DeleteLastColumn), Accelerator( GDK_KEY_KP_Subtract, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "PatchDeleteFirstRow", makeCallbackF(Patch_DeleteFirstRow), Accelerator( GDK_KEY_KP_Subtract, (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "PatchDeleteLastRow", makeCallbackF(Patch_DeleteLastRow) );
 +      GlobalCommands_insert( "InvertCurve", makeCallbackF(Patch_Invert), Accelerator( 'I', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "RedisperseRows", makeCallbackF(Patch_RedisperseRows), Accelerator( 'E', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "RedisperseCols", makeCallbackF(Patch_RedisperseCols), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "SmoothRows", makeCallbackF(Patch_SmoothRows), Accelerator( 'W', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "SmoothCols", makeCallbackF(Patch_SmoothCols), Accelerator( 'W', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "MatrixTranspose", makeCallbackF(Patch_Transpose), Accelerator( 'M', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "CapCurrentCurve", makeCallbackF(Patch_Cap), Accelerator( 'C', (GdkModifierType)GDK_SHIFT_MASK ) );
 +      GlobalCommands_insert( "CycleCapTexturePatch", makeCallbackF(Patch_CycleProjection), Accelerator( 'N', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
 +      GlobalCommands_insert( "MakeOverlayPatch", makeCallbackF(Patch_OverlayOn), Accelerator( 'Y' ) );
 +      GlobalCommands_insert( "ClearPatchOverlays", makeCallbackF(Patch_OverlayOff), Accelerator( 'L', (GdkModifierType)GDK_CONTROL_MASK ) );
 +      GlobalCommands_insert( "PatchDeform", makeCallbackF(Patch_Deform) );
++      GlobalCommands_insert( "PatchThicken", makeCallbackF(Patch_Thicken) );
 +}
 +
 +void Patch_constructToolbar( ui::Toolbar toolbar ){
 +      toolbar_append_button( toolbar, "Put caps on the current patch (SHIFT + C)", "cap_curve.png", "CapCurrentCurve" );
 +}
 +
 +void Patch_constructMenu( ui::Menu menu ){
        create_menu_item_with_mnemonic( menu, "Cylinder", "PatchCylinder" );
        {
 -              GtkMenu* menu_in_menu = create_sub_menu_with_mnemonic( menu, "More Cylinders" );
 +              auto menu_in_menu = create_sub_menu_with_mnemonic( menu, "More Cylinders" );
                if ( g_Layout_enableDetachableMenus.m_value ) {
                        menu_tearoff( menu_in_menu );
                }
@@@ -1117,3 -1284,128 +1205,128 @@@ EMessageBoxReturn DoCapDlg( ECapDialog
  
        return ret;
  }
 -      GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Patch thicken", G_CALLBACK( dialog_delete_callback ), &dialog );
+ void DoPatchThickenDlg(){
+       ModalDialog dialog;
+       GtkWidget* thicknessW;
+       GtkWidget* seamsW;
+       GtkWidget* radX;
+       GtkWidget* radY;
+       GtkWidget* radZ;
+       GtkWidget* radNormals;
 -              GtkHBox* hbox = create_dialog_hbox( 4, 4 );
++      ui::Window window = create_dialog_window( MainFrame_getWindow(), "Patch thicken", G_CALLBACK( dialog_delete_callback ), &dialog );
+       GtkAccelGroup* accel = gtk_accel_group_new();
+       gtk_window_add_accel_group( window, accel );
+       {
 -                      GtkTable* table = create_dialog_table( 2, 4, 4, 4 );
++              auto hbox = create_dialog_hbox( 4, 4 );
+               gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) );
+               {
 -                      GtkVBox* vbox = create_dialog_vbox( 4 );
 -                      gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 );
++                      auto table = create_dialog_table( 2, 4, 4, 4 );
+                       gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 );
+                       {
+                               GtkLabel* label = GTK_LABEL( gtk_label_new( "Thickness:" ) );
+                               gtk_widget_show( GTK_WIDGET( label ) );
+                               gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1,
+                                                                 (GtkAttachOptions) ( GTK_FILL ),
+                                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
+                               gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
+                       }
+                       {
+                               GtkWidget* entry = gtk_entry_new();
+                               gtk_entry_set_text( GTK_ENTRY( entry ), "16" );
+                               gtk_widget_set_size_request( entry, 40, -1 );
+                               gtk_widget_show( entry );
+                               gtk_table_attach( table, entry, 1, 2, 0, 1,
+                                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
+                               thicknessW = entry;
+                       }
+                       {
+                               // Create the "create seams" label
+                               GtkWidget* _seamsCheckBox = gtk_check_button_new_with_label( "Side walls" );
+                               gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( _seamsCheckBox ), TRUE );
+                               gtk_widget_show( _seamsCheckBox );
+                               gtk_table_attach( table, _seamsCheckBox, 3, 4, 0, 1,
+                                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
+                               seamsW = _seamsCheckBox;
+                       }
+                       {
+                               // Create the radio button group for choosing the extrude axis
+                               GtkWidget* _radNormals = gtk_radio_button_new_with_label( NULL, "Normal" );
+                               GtkWidget* _radX = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_radNormals), "X" );
+                               GtkWidget* _radY = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_radNormals), "Y" );
+                               GtkWidget* _radZ = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_radNormals), "Z" );
+                               gtk_widget_show( _radNormals );
+                               gtk_widget_show( _radX );
+                               gtk_widget_show( _radY );
+                               gtk_widget_show( _radZ );
+                               // Pack the buttons into the table
+                               gtk_table_attach( table, _radNormals, 0, 1, 1, 2,
+                                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
+                               gtk_table_attach( table, _radX, 1, 2, 1, 2,
+                                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
+                               gtk_table_attach( table, _radY, 2, 3, 1, 2,
+                                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
+                               gtk_table_attach( table, _radZ, 3, 4, 1, 2,
+                                                                 (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
+                                                                 (GtkAttachOptions) ( 0 ), 0, 0 );
+                               radX = _radX;
+                               radY = _radY;
+                               radZ = _radZ;
+                               radNormals = _radNormals;
+                       }
+               }
+               {
 -                              GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &dialog );
 -                              gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 );
 -                              widget_make_default( GTK_WIDGET( button ) );
 -                              gtk_widget_grab_focus( GTK_WIDGET( button ) );
 -                              gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
++                      auto vbox = create_dialog_vbox( 4 );
++                      hbox.pack_start( vbox, FALSE, FALSE, 0 );
+                       {
 -                              GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &dialog );
 -                              gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 );
 -                              gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
++                              auto button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &dialog );
++                              vbox.pack_start( button, FALSE, FALSE, 0 );
++                              widget_make_default( button );
++                              gtk_widget_grab_focus( button  );
++                              gtk_widget_add_accelerator( button , "clicked", accel, GDK_KEY_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
+                       }
+                       {
++                              auto button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &dialog );
++                              vbox.pack_start( button, FALSE, FALSE, 0 );
++                              gtk_widget_add_accelerator( button , "clicked", accel, GDK_KEY_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
+                       }
+               }
+       }
+       if ( modal_dialog_show( window, dialog ) == eIDOK ) {
+               int axis;
+               bool seams;
+               float thickness = static_cast<float>( atoi( gtk_entry_get_text( GTK_ENTRY( thicknessW ) ) ) );
+               seams = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( seamsW )) ? true : false;
+               if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radX))) {
+                       axis = 0;
+               }
+               else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radY))) {
+                       axis = 1;
+               }
+               else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radZ))) {
+                       axis = 2;
+               }
+               else  {
+                       // Extrude along normals
+                       axis = 3;
+               }
+               Scene_PatchThicken( GlobalSceneGraph(), thickness, seams, axis );
+       }
+       gtk_widget_destroy( GTK_WIDGET( window ) );
+ }