void mergeSelectedBrushes(const cmd::ArgumentList& args) { // Get the current selection BrushPtrVector brushes = selection::algorithm::getSelectedBrushes(); if (brushes.empty()) { rMessage() << _("CSG Merge: No brushes selected.") << std::endl; wxutil::Messagebox::ShowError(_("CSG Merge: No brushes selected.")); return; } if (brushes.size() < 2) { rMessage() << "CSG Merge: At least two brushes have to be selected.\n"; wxutil::Messagebox::ShowError("CSG Merge: At least two brushes have to be selected."); return; } rMessage() << "CSG Merge: Merging " << brushes.size() << " brushes." << std::endl; UndoableCommand undo("mergeSelectedBrushes"); // Take the last selected node as reference for layers and parent scene::INodePtr merged = GlobalSelectionSystem().ultimateSelected(); scene::INodePtr parent = merged->getParent(); assert(parent != NULL); // Create a new BrushNode scene::INodePtr node = GlobalBrushCreator().createBrush(); // Insert the newly created brush into the (same) parent entity parent->addChildNode(node); // Move the new brush to the same layers as the merged one node->assignToLayers(merged->getLayers()); // Get the contained brush Brush* brush = Node_getBrush(node); // Attempt to merge the selected brushes into the new one if (!Brush_merge(*brush, brushes, true)) { rWarning() << "CSG Merge: Failed - result would not be convex." << std::endl; return; } ASSERT_MESSAGE(!brush->empty(), "brush left with no faces after merge"); // Remove the original brushes for (BrushPtrVector::iterator i = brushes.begin(); i != brushes.end(); ++i) { scene::removeNodeFromParent(*i); } // Select the new brush Node_setSelected(node, true); rMessage() << "CSG Merge: Succeeded." << std::endl; SceneChangeNotify(); }
void subtractBrushesFromUnselected(const cmd::ArgumentList& args) { if (registry::getValue<bool>(RKEY_EMIT_CSG_SUBTRACT_WARNING)) { wxutil::Messagebox::Show(_("This Is Not Dromed Warning"), _("Note: be careful when using the CSG tool, as you might end up\n" "with an unnecessary number of tiny brushes and/or leaks.\n" "This popup will not be shown again."), ui::IDialog::MESSAGE_CONFIRM); // Disable this warning registry::setValue(RKEY_EMIT_CSG_SUBTRACT_WARNING, false); } // Collect all selected brushes BrushPtrVector brushes = selection::algorithm::getSelectedBrushes(); if (brushes.empty()) { rMessage() << _("CSG Subtract: No brushes selected.") << std::endl; wxutil::Messagebox::ShowError(_("CSG Subtract: No brushes selected.")); return; } rMessage() << "CSG Subtract: Subtracting " << brushes.size() << " brushes.\n"; UndoableCommand undo("brushSubtract"); // subtract selected from unselected std::size_t before = 0; std::size_t after = 0; // instantiate a scoped walker class { SubtractBrushesFromUnselected walker(brushes, before, after); GlobalSceneGraph().root()->traverse(walker); } rMessage() << "CSG Subtract: Result: " << after << " fragment" << (after == 1 ? "" : "s") << " from " << before << " brush" << (before == 1 ? "" : "es") << ".\n"; SceneChangeNotify(); }