Skip to content

Commit a61c1c4

Browse files
committed
Bring back Graft face map output
1 parent 0e47588 commit a61c1c4

File tree

3 files changed

+25
-14
lines changed

3 files changed

+25
-14
lines changed

mesh/attribute_selection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class GRET_OT_attribute_to_selection(bpy.types.Operator):
1111
"""Set the current face selection from a boolean face attribute"""
1212

1313
bl_idname = 'gret.attribute_to_selection'
14-
bl_label = "Select Faces By Values"
14+
bl_label = "Select Faces by Values"
1515
bl_options = {'REGISTER', 'UNDO'}
1616

1717
@classmethod
@@ -50,7 +50,7 @@ class GRET_OT_attribute_from_selection(bpy.types.Operator):
5050
"""Update or create a boolean face attribute from the current edit mode face selection"""
5151

5252
bl_idname = 'gret.attribute_from_selection'
53-
bl_label = "Face Selection To Values"
53+
bl_label = "Face Selection to Values"
5454
bl_context = 'mesh_edit'
5555
bl_options = {'REGISTER', 'UNDO'}
5656

mesh/graft.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
from math import pi
33
import bmesh
44
import bpy
5+
import numpy as np
56

67
from ..math import get_dist_sq
7-
from .helpers import edit_mesh_elements, bmesh_vertex_group_bleed
8+
from .helpers import edit_mesh_elements, bmesh_vertex_group_bleed, get_face_map_attribute
89
from ..helpers import with_object, get_modifier, get_vgroup, select_only, instant_modifier
910
from ..operator import SaveContext
1011

@@ -95,20 +96,13 @@ def do_graft(context, save, obj, dst_obj, expand=0, cuts=0, blend_distance=0.0,
9596
try:
9697
ret = bmesh.ops.bridge_loops(bm, edges=edges1+edges2, use_pairs=False,
9798
use_cyclic=False, use_merge=False, merge_factor=0.5, twist_offset=0)
98-
new_faces = ret['faces']
99+
new_face_indices = [face.index for face in ret['faces']]
99100
# for face in new_faces:
100101
# face.smooth = True
101102
except RuntimeError:
102103
bm.free()
103104
raise GraftError("Couldn't bridge loops.")
104105

105-
# If requested, fill a face map with the new faces
106-
# Disabled for 4.0 since there is no actual replacement for face-based selection haha
107-
# if face_map_name:
108-
# face_map = obj.face_maps.get(face_map_name) or obj.face_maps.new(name=face_map_name)
109-
# for face in new_faces:
110-
# face[fm_layer] = face_map.index
111-
112106
if cuts > 0:
113107
bmesh.ops.subdivide_edges(bm, edges=ret['edges'], smooth=1.0, smooth_falloff='LINEAR', cuts=cuts)
114108

@@ -125,6 +119,14 @@ def do_graft(context, save, obj, dst_obj, expand=0, cuts=0, blend_distance=0.0,
125119
bm.to_mesh(obj.data)
126120
bm.free()
127121

122+
# If requested, fill a face map with the new faces
123+
if face_map_name:
124+
attr = get_face_map_attribute(obj, face_map_name)
125+
values = np.empty(len(attr.data), dtype=bool)
126+
attr.data.foreach_get('value', values)
127+
values[new_face_indices] = True
128+
attr.data.foreach_set('value', values)
129+
128130
# Transfer stuff
129131
if copy_normals:
130132
obj.data.use_auto_smooth = True
@@ -195,8 +197,8 @@ class GRET_OT_graft(bpy.types.Operator):
195197
)
196198
face_map_name: bpy.props.StringProperty(
197199
name="Face Map Name",
198-
description="Optional name of a face map that contains the new geometry",
199-
default="Grafts",
200+
description="Optional name of a boolean face attribute that contains the new geometry",
201+
default="",
200202
)
201203
vertex_group_name: bpy.props.StringProperty(
202204
name="Vertex Group Name",
@@ -312,7 +314,7 @@ def draw(self, context):
312314

313315
# layout.prop_search(self, 'vertex_group_name', obj, 'vertex_groups')
314316
layout.prop(self, 'vertex_group_name', icon='GROUP_VERTEX')
315-
# layout.prop(self, 'face_map_name', icon='FACE_MAPS')
317+
layout.prop(self, 'face_map_name', icon='FACE_MAPS')
316318

317319
row = layout.row(align=True, heading="Copy")
318320
row.prop(self, 'copy_normals', text="Norms.", toggle=1)

mesh/helpers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ def refresh_active_color_attribute(mesh):
117117
if mesh.color_attributes.render_color_index < 0:
118118
mesh.color_attributes.render_color_index = 0
119119

120+
def get_face_map_attribute(obj, name):
121+
"""Ensures that a boolean face attribute with the given name exists."""
122+
123+
assert obj.type == 'MESH'
124+
attr = obj.data.attributes.get(name)
125+
if not attr or attr.domain != 'FACE' or attr.data_type != 'BOOLEAN':
126+
attr = obj.data.attributes.new(name, type='BOOLEAN', domain='FACE')
127+
return attr
128+
120129
def clear_object_data(obj, vertex_groups=True, shape_keys=True, face_maps=True, constraints=True,
121130
custom_properties=True, uv_layers=True, vertex_colors=True, attributes=True, materials=True):
122131
# Clear object data

0 commit comments

Comments
 (0)