Fix: Occlusion of Curves failing during snapping
The geometry of objects behind Curves was being considered for snapping even when occluded. The occlusion test logic has been reworked and simplified when the snap target is a Curve. As a result, Snap to Face now works correctly for the active Curve.
This commit is contained in:
@@ -577,7 +577,7 @@ static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
|
||||
const Object *ob_eval,
|
||||
const ID *ob_data,
|
||||
const float4x4 &obmat,
|
||||
bool is_object_active,
|
||||
bool /*is_object_active*/,
|
||||
bool use_hide)
|
||||
{
|
||||
bool retval = false;
|
||||
@@ -603,7 +603,13 @@ static eSnapMode raycast_obj_fn(SnapObjectContext *sctx,
|
||||
else if (GS(ob_data->name) != ID_ME) {
|
||||
return SCE_SNAP_TO_NONE;
|
||||
}
|
||||
else if (is_object_active && ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
|
||||
else if (ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF) &&
|
||||
(sctx->runtime.params.edit_mode_type != SNAP_GEOM_FINAL) &&
|
||||
BKE_object_is_in_editmode(ob_eval))
|
||||
{
|
||||
/* The final Curves geometry is generated as a Mesh. Skip this Mesh if the target is not
|
||||
* #SNAP_GEOM_FINAL. This also avoids creating and destroying BVH Trees too frequently while
|
||||
* editing. */
|
||||
return SCE_SNAP_TO_NONE;
|
||||
}
|
||||
else {
|
||||
@@ -715,7 +721,7 @@ static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
|
||||
const Object *ob_eval,
|
||||
const ID *ob_data,
|
||||
const float4x4 &obmat,
|
||||
bool is_object_active,
|
||||
bool /*is_object_active*/,
|
||||
bool use_hide)
|
||||
{
|
||||
eSnapMode retval = SCE_SNAP_TO_NONE;
|
||||
@@ -732,7 +738,13 @@ static eSnapMode nearest_world_object_fn(SnapObjectContext *sctx,
|
||||
else if (GS(ob_data->name) != ID_ME) {
|
||||
return SCE_SNAP_TO_NONE;
|
||||
}
|
||||
else if (is_object_active && ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) {
|
||||
else if (ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF) &&
|
||||
(sctx->runtime.params.edit_mode_type != SNAP_GEOM_FINAL) &&
|
||||
BKE_object_is_in_editmode(ob_eval))
|
||||
{
|
||||
/* The final Curves geometry is generated as a Mesh. Skip this Mesh if the target is not
|
||||
* #SNAP_GEOM_FINAL. This also avoids creating and destroying BVH Trees too frequently while
|
||||
* editing. */
|
||||
return SCE_SNAP_TO_NONE;
|
||||
}
|
||||
else {
|
||||
@@ -885,10 +897,11 @@ static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
if (GS(ob_data->name) == ID_ME) {
|
||||
if (ob_eval->type == OB_CURVES_LEGACY && BKE_object_is_in_editmode(ob_eval)) {
|
||||
/* Sometimes, such as when Mesh is generated by Geometry Nodes, a Curve object may have Mesh
|
||||
* instances.
|
||||
* In these cases, skip the snap to Mesh if the Curve is in edit mode. */
|
||||
if (ELEM(ob_eval->type, OB_CURVES_LEGACY, OB_SURF) &&
|
||||
(sctx->runtime.params.edit_mode_type != SNAP_GEOM_FINAL))
|
||||
{
|
||||
/* The final Curves geometry is generated as a Mesh. Skip this Mesh if the target is not
|
||||
* #SNAP_GEOM_FINAL. */
|
||||
return SCE_SNAP_TO_NONE;
|
||||
}
|
||||
return snap_object_mesh(sctx, ob_eval, ob_data, obmat, sctx->runtime.snap_to_flag, use_hide);
|
||||
@@ -906,19 +919,9 @@ static eSnapMode snap_obj_fn(SnapObjectContext *sctx,
|
||||
case OB_SURF:
|
||||
if (ob_eval->type == OB_CURVES_LEGACY || BKE_object_is_in_editmode(ob_eval)) {
|
||||
retval = snapCurve(sctx, ob_eval, obmat);
|
||||
if (sctx->runtime.params.edit_mode_type != SNAP_GEOM_FINAL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ATTR_FALLTHROUGH;
|
||||
case OB_FONT: {
|
||||
const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
|
||||
if (mesh_eval) {
|
||||
retval |= snap_object_mesh(
|
||||
sctx, ob_eval, (ID *)mesh_eval, obmat, sctx->runtime.snap_to_flag, use_hide);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OB_FONT:
|
||||
case OB_EMPTY:
|
||||
case OB_GPENCIL_LEGACY:
|
||||
case OB_LAMP:
|
||||
@@ -1402,10 +1405,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
|
||||
/* Remove what has already been computed. */
|
||||
sctx->runtime.snap_to_flag &= ~(SCE_SNAP_TO_FACE | SCE_SNAP_INDIVIDUAL_NEAREST);
|
||||
|
||||
if (use_occlusion_plane && has_hit &&
|
||||
/* By convention we only snap to the original elements of a curve. */
|
||||
sctx->ret.ob->type != OB_CURVES_LEGACY)
|
||||
{
|
||||
if (use_occlusion_plane && has_hit) {
|
||||
/* Compute the new clip_pane but do not add it yet. */
|
||||
BLI_ASSERT_UNIT_V3(sctx->ret.no);
|
||||
sctx->runtime.occlusion_plane = occlusion_plane_create(
|
||||
|
||||
Reference in New Issue
Block a user