implement CSG Make Room, thanks to Garux, <3 Mario 88/head
authorThomas Debesse <dev@illwieckz.net>
Sun, 4 Mar 2018 03:43:35 +0000 (04:43 +0100)
committerThomas Debesse <dev@illwieckz.net>
Tue, 13 Mar 2018 23:52:48 +0000 (00:52 +0100)
- implement CSG Make Room using code by @Garux from !11
- calls this operation “Make Room” like in DarkRadiant
  this is what GTKRadiant calls “CSG Hollow Touch”
- draw the pixmap icon according to the current theme
- greet @Mario

radiant/brushmanip.cpp
radiant/csg.cpp
radiant/csg.h
radiant/mainframe.cpp
setup/data/tools/bitmaps/selection_makeroom.png [new file with mode: 0644]

index 68c8a5b..19e91e0 100644 (file)
@@ -1336,7 +1336,8 @@ void Brush_constructMenu(ui::Menu menu)
         if (g_Layout_enableDetachableMenus.m_value) {
             menu_tearoff(menu_in_menu);
         }
-        create_menu_item_with_mnemonic(menu_in_menu, "Make _Hollow", "CSGHollow");
+        create_menu_item_with_mnemonic(menu_in_menu, "Make _Hollow", "CSGMakeHollow");
+        create_menu_item_with_mnemonic(menu_in_menu, "Make _Room", "CSGMakeRoom");
         create_menu_item_with_mnemonic(menu_in_menu, "CSG _Subtract", "CSGSubtract");
         create_menu_item_with_mnemonic(menu_in_menu, "CSG _Merge", "CSGMerge");
     }
index c294642..fab905a 100644 (file)
@@ -43,6 +43,20 @@ void Face_makeBrush(Face &face, const Brush &brush, brush_vector_t &out, float o
     }
 }
 
+void Face_makeRoom(Face &face, const Brush &brush, brush_vector_t &out, float offset)
+{
+    if (face.contributes()) {
+        face.getPlane().offset(offset);
+        out.push_back(new Brush(brush));
+        face.getPlane().offset(-offset);
+        Face *newFace = out.back()->addFace(face);
+        if (newFace != 0) {
+            newFace->flipWinding();
+            newFace->planeChanged();
+        }
+    }
+}
+
 void Brush_makeHollow(const Brush &brush, brush_vector_t &out, float offset)
 {
     Brush_forEachFace(brush, [&](Face &face) {
@@ -50,11 +64,19 @@ void Brush_makeHollow(const Brush &brush, brush_vector_t &out, float offset)
     });
 }
 
+void Brush_makeRoom(const Brush &brush, brush_vector_t &out, float offset)
+{
+    Brush_forEachFace(brush, [&](Face &face) {
+        Face_makeRoom(face, brush, out, offset);
+    });
+}
+
 class BrushHollowSelectedWalker : public scene::Graph::Walker {
     float m_offset;
+    bool m_makeRoom;
 public:
-    BrushHollowSelectedWalker(float offset)
-            : m_offset(offset)
+    BrushHollowSelectedWalker(float offset, bool makeRoom)
+            : m_offset(offset), m_makeRoom(makeRoom)
     {
     }
 
@@ -66,7 +88,14 @@ public:
                 && Instance_getSelectable(instance)->isSelected()
                 && path.size() > 1) {
                 brush_vector_t out;
-                Brush_makeHollow(*brush, out, m_offset);
+
+                if (m_makeRoom) {
+                    Brush_makeRoom(*brush, out, m_offset);
+                }
+                else {
+                    Brush_makeHollow(*brush, out, m_offset);
+                }
+
                 for (brush_vector_t::const_iterator i = out.begin(); i != out.end(); ++i) {
                     (*i)->removeEmptyFaces();
                     NodeSmartReference node((new BrushNode())->node());
@@ -123,9 +152,9 @@ public:
     }
 };
 
-void Scene_BrushMakeHollow_Selected(scene::Graph &graph)
+void Scene_BrushMakeHollow_Selected(scene::Graph &graph, bool makeRoom)
 {
-    GlobalSceneGraph().traverse(BrushHollowSelectedWalker(GetGridSize()));
+    GlobalSceneGraph().traverse(BrushHollowSelectedWalker(GetGridSize(), makeRoom));
     GlobalSceneGraph().traverse(BrushDeleteSelected());
 }
 
@@ -139,7 +168,16 @@ void CSG_MakeHollow(void)
 {
     UndoableCommand undo("brushHollow");
 
-    Scene_BrushMakeHollow_Selected(GlobalSceneGraph());
+    Scene_BrushMakeHollow_Selected(GlobalSceneGraph(), false);
+
+    SceneChangeNotify();
+}
+
+void CSG_MakeRoom(void)
+{
+    UndoableCommand undo("brushRoom");
+
+    Scene_BrushMakeHollow_Selected(GlobalSceneGraph(), true);
 
     SceneChangeNotify();
 }
index c276534..886680e 100644 (file)
@@ -24,6 +24,8 @@
 
 void CSG_MakeHollow(void);
 
+void CSG_MakeRoom(void);
+
 void CSG_Subtract(void);
 
 void CSG_Merge(void);
index 36794f8..0546464 100644 (file)
@@ -2606,7 +2606,8 @@ 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, "Hollow", "selection_makehollow.png", "CSGHollow");
+    toolbar_append_button(toolbar, "Make Hollow", "selection_makehollow.png", "CSGMakeHollow");
+    toolbar_append_button(toolbar, "Make Room", "selection_makeroom.png", "CSGMakeRoom");
 }
 
 void ComponentModes_constructToolbar(ui::Toolbar toolbar)
@@ -3623,7 +3624,8 @@ void MainFrame_Construct()
     GlobalCommands_insert("CSGSubtract", makeCallbackF(CSG_Subtract),
                           Accelerator('U', (GdkModifierType) GDK_SHIFT_MASK));
     GlobalCommands_insert("CSGMerge", makeCallbackF(CSG_Merge), Accelerator('U', (GdkModifierType) GDK_CONTROL_MASK));
-    GlobalCommands_insert("CSGHollow", makeCallbackF(CSG_MakeHollow));
+    GlobalCommands_insert("CSGMakeHollow", makeCallbackF(CSG_MakeHollow));
+    GlobalCommands_insert("CSGMakeRoom", makeCallbackF(CSG_MakeRoom));
 
     Grid_registerCommands();
 
diff --git a/setup/data/tools/bitmaps/selection_makeroom.png b/setup/data/tools/bitmaps/selection_makeroom.png
new file mode 100644 (file)
index 0000000..c17ee28
Binary files /dev/null and b/setup/data/tools/bitmaps/selection_makeroom.png differ