1
$\begingroup$

A while back, I put together a Geometry Nodes setup that replicates the functionality of the Shrink/Fatten operation.

But it does not include an option to use "Even Thickness" (or now it seems it is called "Offset Even"), the way that you can when performing the operation manually in the viewport.

Now I am wondering what the mathematical difference is with Offset Even, and how that could be coded into a Geometry Nodes tree. Thanks.

$\endgroup$
1
  • $\begingroup$ I've made a 'mitre-even' in 2D,, not sure what the algorithm would be in 3D. I think it's over constrained, and has to be a 'stylistic' compromise? It would be great if somebody could find it in the code, in Solidify. or Alt-S. $\endgroup$
    – Robin Betts
    Commented Jul 4, 2022 at 8:00

1 Answer 1

3
$\begingroup$

Blender calculates coefficient depends on angle between faces. The function is:

#define SMALL_NUMBER 1.e-8f

MINLINE float shell_angle_to_dist(const float angle)
{
  return (UNLIKELY(angle < SMALL_NUMBER)) ? 1.0f : fabsf(1.0f / cosf(angle));
} 

fabsf is the absolute value of 1/cos(angle). SMALL_NUMBER is used to skip calculation if the angle is too small.

Source

And this is used to calculate offset if the even offset is enabled:

/**
 * \param defgrp_index: Vertex group index, -1 for no vertex groups.
 *
 * \note All edge tags must be cleared.
 * \note Behavior matches MOD_solidify.c
 */
void BM_mesh_wireframe(

...

if (use_even_offset) {
    fac_shell *= shell_angle_to_dist(((float)M_PI - BM_loop_calc_face_angle(l)) * 0.5f);
  }

Angle between faces subtracted from PI and divided in half, this is goes to previous function to get the right coefficient for offset.

Source

Here is where Blender gets angle:

/**
 * Calculates the angle between the previous and next loops
 * (angle at this loops face corner).
 *
 * \return angle in radians
 */
float BM_loop_calc_face_angle(const BMLoop *l)
{
  return angle_v3v3v3(l->prev->v->co, l->v->co, l->next->v->co);
}

Source

So the question is limited by how to calculate angle between faces. I'm not sure if it is possible at the moment. But if you find an angle, it should be easy to get even offset.

This is the closest that I can get:

enter image description here

I suppose, that the problem is in conversion between edge angle and point offset. I believe that angle calculates right, until it gets to set position, where it is needed to be converted from edge to vertex domain. Have no ideas how to solve it, maybe you'll find.

$\endgroup$
3
  • $\begingroup$ That's terrific! Thanks for finding it. In 2D, the point-offset is along bisector, proportional to 1/cos(theta/2). In 3D, I'm not getting great results by averaging edge-angles on points, yet. Will compare. $\endgroup$
    – Robin Betts
    Commented Jul 4, 2022 at 10:28
  • 1
    $\begingroup$ Maybe I mess up in the code and got the lnset version of the even offset, need to doublecheck $\endgroup$
    – Crantisz
    Commented Jul 4, 2022 at 10:31
  • 2
    $\begingroup$ As far as I can understand, this is a shared function for solidify operator and modifier. So it should be correct. $\endgroup$
    – Crantisz
    Commented Jul 4, 2022 at 10:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .