예제 #1
0
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();
}
예제 #2
0
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();
}