Fix #136396: Metaball Cube can't be selected with solid shading

The metaball selection radius was inside the cube and could only
be selected with wire-frame shading.

Resolve by expanding the radius by the dimensions of the cube.
This commit is contained in:
Campbell Barton
2025-06-24 07:56:50 +00:00
parent 32d2bc0a59
commit cda9ce9777
3 changed files with 46 additions and 4 deletions

View File

@@ -4,6 +4,7 @@
#pragma once
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
/** \file
@@ -82,6 +83,15 @@ void BKE_mball_translate(MetaBall *mb, const float offset[3]);
*/
MetaElem *BKE_mball_element_add(MetaBall *mb, int type);
/**
* Calculate & return the display radius & stiffness.
*/
blender::float2 BKE_mball_element_display_radius_calc_with_stiffness(const MetaElem *ml);
/**
* Calculate & return the display radius.
*/
float BKE_mball_element_display_radius_calc(const MetaElem *ml);
/* *** Select functions *** */
int BKE_mball_select_count(const MetaBall *mb);

View File

@@ -228,6 +228,35 @@ MetaElem *BKE_mball_element_add(MetaBall *mb, const int type)
return ml;
}
blender::float2 BKE_mball_element_display_radius_calc_with_stiffness(const MetaElem *ml)
{
blender::float2 radius_stiffness = {
/* Display radius. */
ml->rad,
/* Display stiffness. */
ml->rad * atanf(ml->s) * float(2.0 / blender::math::numbers::pi),
};
if (ml->type == MB_CUBE) {
/* Without this additional size, the cube can't be selected in solid mode.
* Use the minimum size so this doesn't become too large because of one large axis.
* See: #136396. */
const float offset = min_fff(ml->expx, ml->expy, ml->expz) * M_SQRT2;
radius_stiffness[0] += offset;
radius_stiffness[1] += offset;
}
return radius_stiffness;
}
float BKE_mball_element_display_radius_calc(const MetaElem *ml)
{
float radius = ml->rad;
if (ml->type == MB_CUBE) {
const float offset = min_fff(ml->expx, ml->expy, ml->expz) * M_SQRT2;
radius += offset;
}
return radius;
}
bool BKE_mball_is_basis(const Object *ob)
{
/* Meta-Ball Basis Notes from Blender-2.5x

View File

@@ -8,6 +8,8 @@
#pragma once
#include "BKE_mball.hh"
#include "ED_mball.hh"
#include "overlay_base.hh"
@@ -53,16 +55,16 @@ class Metaballs : Overlay {
LISTBASE_FOREACH (MetaElem *, ml, mb.editelems) {
const bool is_selected = (ml->flag & SELECT) != 0;
const bool is_scale_radius = (ml->flag & MB_SCALE_RAD) != 0;
const float stiffness_radius = ml->rad * atanf(ml->s) * 2.0f / math::numbers::pi;
blender::float2 radius_stiffness = BKE_mball_element_display_radius_calc_with_stiffness(ml);
const float3 position = float3(&ml->x);
const select::ID radius_id = res.select_id(ob_ref, MBALLSEL_RADIUS | elem_num);
color = (is_selected && is_scale_radius) ? col_radius_select : col_radius;
circle_buf_.append({ob->object_to_world(), position, ml->rad, color}, radius_id);
circle_buf_.append({ob->object_to_world(), position, radius_stiffness[0], color}, radius_id);
const select::ID stiff_id = res.select_id(ob_ref, MBALLSEL_STIFF | elem_num);
color = (is_selected && !is_scale_radius) ? col_stiffness_select : col_stiffness;
circle_buf_.append({ob->object_to_world(), position, stiffness_radius, color}, stiff_id);
circle_buf_.append({ob->object_to_world(), position, radius_stiffness[1], color}, stiff_id);
elem_num += 1 << 16;
}
}
@@ -81,7 +83,8 @@ class Metaballs : Overlay {
LISTBASE_FOREACH (MetaElem *, ml, &mb->elems) {
const float3 position = float3(&ml->x);
/* Draw radius only. */
circle_buf_.append({ob->object_to_world(), position, ml->rad, color}, select_id);
const float radius = BKE_mball_element_display_radius_calc(ml);
circle_buf_.append({ob->object_to_world(), position, radius, color}, select_id);
}
}