How to use the MeshModule of ShapeMap

It can be fixed by aligning the UVs of quad faces:


@jessesn , i think ShapeMap needs those 2 extra components:

  • MeshFaceUV (for checking the directions)
  • AlignMeshUV (for aligning the directions)

You have the file with both C# scripts I did with ChatGPT:
2-2_MeshModule-test 260413BC.gh (98.3 KB)

I am testing on another case.

How do I increase the density? (solved with pinch below)
I want the mesh to be more dense where the nose is.

Perhaps having a pinch component would be useful.



Here’s the code but it’s a bit hard to tune.
Maybe @jessesn , you can write it better.

"""GhPython component

Inputs:
    M       : Mesh
    P       : List[Point3d]   pinch points
    W       : List[float]     weights per point
    R       : float           influence radius (0 or None = auto)
    Pow     : float           outer falloff power
    MaxMove : float           max move scale (0 or None = auto)

Output:
    A       : Mesh
"""

import Rhino
import math


def remap_weights(points, weights):
    if not points:
        return []
    if not weights:
        return [1.0] * len(points)
    if len(weights) == 1 and len(points) > 1:
        return [weights[0]] * len(points)
    if len(weights) < len(points):
        last = weights[-1]
        return list(weights) + [last] * (len(points) - len(weights))
    return list(weights[:len(points)])


def auto_radius(mesh):
    bb = mesh.GetBoundingBox(True)
    return bb.Diagonal.Length * 0.25


def auto_max_move(mesh):
    bb = mesh.GetBoundingBox(True)
    return bb.Diagonal.Length * 0.03


def smoothstep(x):
    if x <= 0.0:
        return 0.0
    if x >= 1.0:
        return 1.0
    return x * x * (3.0 - 2.0 * x)


def pinch_mesh(mesh, points, weights, radius, power, max_move):
    if mesh is None or not mesh.IsValid:
        return None

    if not points or len(points) == 0:
        return mesh.DuplicateMesh()

    if power is None:
        power = 1.0

    if radius is None or radius <= 0:
        radius = auto_radius(mesh)

    if max_move is None or max_move <= 0:
        max_move = auto_max_move(mesh)

    weights = remap_weights(points, weights)

    new_mesh = mesh.DuplicateMesh()
    verts = new_mesh.Vertices

    # inner zone where motion gradually fades to zero near the pinch point
    inner_radius = radius * 0.20

    for i in range(verts.Count):
        v = verts[i]
        vx = v.X
        vy = v.Y
        vz = v.Z

        move_x = 0.0
        move_y = 0.0

        for pt, wt in zip(points, weights):
            dx = pt.X - vx
            dy = pt.Y - vy
            d = math.sqrt(dx * dx + dy * dy)

            if d <= 1e-9 or d >= radius:
                continue

            ux = dx / d
            uy = dy / d

            # outer falloff: 1 near point influence zone, 0 at radius
            t_outer = 1.0 - (d / radius)
            outer_falloff = t_outer ** power

            # inner slowdown: 0 at point, 1 outside the inner zone
            t_inner = d / inner_radius if inner_radius > 1e-9 else 1.0
            inner_slowdown = smoothstep(t_inner)

            # combined effect
            strength = outer_falloff * inner_slowdown

            step = abs(wt) * strength * max_move

            if wt < 0:
                step = -step

            move_x += ux * step
            move_y += uy * step

        verts.SetVertex(i, vx + move_x, vy + move_y, vz)

    new_mesh.Normals.ComputeNormals()
    new_mesh.Compact()
    return new_mesh


A = pinch_mesh(M, P, W, R, Pow, MaxMove)

It looks great, and thanks for your sharing.

Could you share this .gh file? Thank you.

I uploaded an archive with rhino file (baked pinched mesh inside) and gh file with the full definition including UV alignment, pinch and mesh offset.
meshmodule test uvalign pinch and offset 260415BC.rar (15.3 MB)

I also made a small component for fast mesh offset. Could be useful for Shapemap workflow.