Repository: godotengine/godot
File: editor/plugins/mesh_instance_3d_editor_plugin.cpp (C++)

Code before:
	debug_uv_dialog = memnew(AcceptDialog);
	debug_uv_dialog->set_title(TTR("UV Channel Debug"));
	add_child(debug_uv_dialog);
	debug_uv = memnew(Control);
	debug_uv->set_custom_minimum_size(Size2(600, 600) * EDSCALE);
	debug_uv->connect(SceneStringName(draw), callable_mp(this, &MeshInstance3DEditor::_debug_uv_draw));
	debug_uv_dialog->add_child(debug_uv);
}

void MeshInstance3DEditorPlugin::edit(Object *p_object) {
	{
		MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_object);
		if (mi) {
			mesh_editor->edit(mi);
			return;
		}
	}

	Ref<MultiNodeEdit> mne = Ref<MultiNodeEdit>(p_object);
	Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
	if (mne.is_valid() && edited_scene) {
		for (int i = 0; i < mne->get_node_count(); i++) {
			MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(edited_scene->get_node(mne->get_node(i)));
			if (mi) {
				mesh_editor->edit(mi);
				return;
			}
		}
	}
	mesh_editor->edit(nullptr);
}

bool MeshInstance3DEditorPlugin::handles(Object *p_object) const {
	if (Object::cast_to<MeshInstance3D>(p_object)) {
		return true;
	}

	Ref<MultiNodeEdit> mne = Ref<MultiNodeEdit>(p_object);
	Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
	if (mne.is_valid() && edited_scene) {
		bool has_mesh = false;
		for (int i = 0; i < mne->get_node_count(); i++) {
			if (Object::cast_to<MeshInstance3D>(edited_scene->get_node(mne->get_node(i)))) {
				if (has_mesh) {
					return true;
				} else {
					has_mesh = true;
				}
			}
		}
	}

Review comment (bug):
```suggestion
	navigation_mesh_l->set_text(TTR("Before converting a rendering mesh to a navigation mesh, please verify:\n\n- The mesh is two-dimensional.\n- The mesh has no surface overlap.\n- The mesh has no self-intersection.\n- The mesh surfaces have indices.\n\nIf the mesh does not fulfill these requirements, the pathfinding will be broken."));
```

Also, couldn't mesh indices be generated automatically if they are currently missing?

Code after:
	shape_type->set_item_tooltip(-1, TTR("Creates a polygon-based collision shape.\nThis is a performance middle-ground between a single convex collision and a polygon-based collision."));
	shape_dialog_vbc->add_child(shape_type);

	add_child(shape_dialog);
	shape_dialog->connect("confirmed", callable_mp(this, &MeshInstance3DEditor::_create_collision_shape));

	err_dialog = memnew(AcceptDialog);
	add_child(err_dialog);

	debug_uv_dialog = memnew(AcceptDialog);
	debug_uv_dialog->set_title(TTR("UV Channel Debug"));
	add_child(debug_uv_dialog);
	debug_uv = memnew(Control);
	debug_uv->set_custom_minimum_size(Size2(600, 600) * EDSCALE);
	debug_uv->connect(SceneStringName(draw), callable_mp(this, &MeshInstance3DEditor::_debug_uv_draw));
	debug_uv_dialog->add_child(debug_uv);

	navigation_mesh_dialog = memnew(ConfirmationDialog);
	navigation_mesh_dialog->set_title(TTR("Create NavigationMesh"));
	navigation_mesh_dialog->set_ok_button_text(TTR("Create"));

	VBoxContainer *navigation_mesh_dialog_vbc = memnew(VBoxContainer);
	navigation_mesh_dialog->add_child(navigation_mesh_dialog_vbc);

	Label *navigation_mesh_l = memnew(Label);
	navigation_mesh_l->set_text(TTR("Before converting a rendering mesh to a navigation mesh, please verify:\n\n- The mesh is two-dimensional.\n- The mesh has no surface overlap.\n- The mesh has no self-intersection.\n- The mesh surfaces have indices.\n\nIf the mesh does not fulfill these requirements, the pathfinding will be broken."));
	navigation_mesh_dialog_vbc->add_child(navigation_mesh_l);

	add_child(navigation_mesh_dialog);
	navigation_mesh_dialog->connect("confirmed", callable_mp(this, &MeshInstance3DEditor::_create_navigation_mesh));
}

void MeshInstance3DEditorPlugin::edit(Object *p_object) {
	{
		MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_object);
		if (mi) {
			mesh_editor->edit(mi);
			return;
		}
	}

	Ref<MultiNodeEdit> mne = Ref<MultiNodeEdit>(p_object);
	Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
	if (mne.is_valid() && edited_scene) {
		for (int i = 0; i < mne->get_node_count(); i++) {
			MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(edited_scene->get_node(mne->get_node(i)));
			if (mi) {
				mesh_editor->edit(mi);
				return;
			}
		}