Skip to content

Commit

Permalink
Reorganize functions
Browse files Browse the repository at this point in the history
  • Loading branch information
chsh2 committed Jul 8, 2023
1 parent 59ed4be commit 3f97456
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 152 deletions.
6 changes: 3 additions & 3 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ def register():
items=[('X-Z', 'Front (X-Z)', ''),
('Y-Z', 'Side (Y-Z)', ''),
('X-Y', 'Top (X-Y)', ''),
('VIEW', 'View (Beta)', ''),
('AUTO', 'Auto (Beta)', '')],
default='X-Z',
('VIEW', 'View', 'Use the current view as the 2D working plane'),
('AUTO', 'Auto', 'Calculate the 2D plane automatically based on input points and view angle')],
default='AUTO',
description='The 2D (local) plane that most add-on operators are working on'
)
bpy.types.Scene.nijigp_working_plane_layer_transform = bpy.props.BoolProperty(
Expand Down
6 changes: 4 additions & 2 deletions operators/operator_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def fit_2d_strokes(strokes, search_radius, smoothness_factor = 1, pressure_delta
empty_result = None, None, None, None, None, None, None, None
try:
from scipy.interpolate import splprep, splev
from ..solvers.graph import get_mst_longest_path_from_triangles
from ..solvers.graph import TriangleMst
except:
if operator:
operator.report({"ERROR"}, "Please install Scikit-Image in the Preferences panel.")
Expand Down Expand Up @@ -84,7 +84,9 @@ def fit_2d_strokes(strokes, search_radius, smoothness_factor = 1, pressure_delta
# Triangulation and spanning tree conversion
tr_output = {}
tr_output['vertices'], _, tr_output['triangles'], _,_,_ = geometry.delaunay_2d_cdt(tr_input['vertices'], [], [], 0, 1e-9)
total_length, path_whole = get_mst_longest_path_from_triangles(tr_output)
mst_builder = TriangleMst()
mst_builder.build_mst(tr_output)
total_length, path_whole = mst_builder.get_longest_path()

# The fitting method needs at least 4 points
if len(path_whole)<4:
Expand Down
149 changes: 64 additions & 85 deletions operators/operator_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,32 @@

MAX_DEPTH = 4096

def get_mixed_color(gp_obj, stroke, point_idx = None):
"""Get the displayed color by jointly considering the material and vertex colors"""
res = [0,0,0,0]
mat_gp = gp_obj.data.materials[stroke.material_index].grease_pencil
if not point_idx:
# Case of fill color
if gp_obj.data.materials[stroke.material_index].grease_pencil.show_fill:
for i in range(4):
res[i] = mat_gp.fill_color[i]
if hasattr(stroke,'vertex_color_fill'):
alpha = stroke.vertex_color_fill[3]
for i in range(3):
res[i] = linear_to_srgb(res[i] * (1-alpha) + alpha * stroke.vertex_color_fill[i])
return res
else:
# Case of line point color
point = stroke.points[point_idx]
if gp_obj.data.materials[stroke.material_index].grease_pencil.show_stroke:
for i in range(4):
res[i] = mat_gp.color[i]
if hasattr(point,'vertex_color'):
alpha = point.vertex_color[3]
for i in range(3):
res[i] = linear_to_srgb(res[i] * (1-alpha) + alpha * point.vertex_color[i])
return res

def apply_mirror_in_depth(obj, inv_mat, loc = (0,0,0)):
"""Apply a Mirror modifier in the Object mode with given center and axis"""
obj.modifiers.new(name="nijigp_Mirror", type='MIRROR')
Expand All @@ -26,6 +52,37 @@ def apply_mirror_in_depth(obj, inv_mat, loc = (0,0,0)):
bpy.ops.object.modifier_apply("EXEC_DEFAULT", modifier = "nijigp_Mirror")
bpy.data.objects.remove(empty_object)

class CommonMeshConfig:
postprocess_double_sided: bpy.props.BoolProperty(
name='Double-Sided',
default=True,
description='Make the mesh symmetric to the working plane'
)
vertical_gap: bpy.props.FloatProperty(
name='Vertical Gap',
default=0.01, min=0,
unit='LENGTH',
description='Mininum vertical space between generated meshes'
)
ignore_mode: bpy.props.EnumProperty(
name='Ignore',
items=[('NONE', 'None', ''),
('LINE', 'All Lines', ''),
('OPEN', 'All Open Lines', '')],
default='NONE',
description='Skip strokes without fill'
)
reuse_material: bpy.props.BoolProperty(
name='Reuse Materials',
default=True,
description='Do not create a new material if it exists'
)
keep_original: bpy.props.BoolProperty(
name='Keep Original',
default=True,
description='Do not delete the original stroke'
)

class MeshManagement(bpy.types.Operator):
"""Manage mesh objects generated from the active GPencil object"""
bl_idname = "gpencil.nijigp_mesh_management"
Expand Down Expand Up @@ -58,7 +115,7 @@ def execute(self, context):

return {'FINISHED'}

class MeshGenerationByNormal(bpy.types.Operator):
class MeshGenerationByNormal(CommonMeshConfig, bpy.types.Operator):
"""Generate a planar mesh with an interpolated normal map calculated from the selected strokes"""
bl_idname = "gpencil.nijigp_mesh_generation_normal"
bl_label = "Convert to Meshes by Normal Interpolation"
Expand All @@ -72,25 +129,6 @@ class MeshGenerationByNormal(bpy.types.Operator):
default='NORMAL',
description='Generate either a normal map or real 3D structure'
)
postprocess_double_sided: bpy.props.BoolProperty(
name='Double-Sided',
default=True,
description='Make the mesh symmetric to the working plane'
)
vertical_gap: bpy.props.FloatProperty(
name='Vertical Gap',
default=0.01, min=0,
unit='LENGTH',
description='Mininum vertical space between generated meshes'
)
ignore_mode: bpy.props.EnumProperty(
name='Ignore',
items=[('NONE', 'None', ''),
('LINE', 'All Lines', ''),
('OPEN', 'All Open Lines', '')],
default='NONE',
description='Skip strokes without fill'
)
mesh_style: bpy.props.EnumProperty(
name='Mesh Style',
items=[('TRI', 'Delaunay Triangulation', ''),
Expand Down Expand Up @@ -146,16 +184,6 @@ class MeshGenerationByNormal(bpy.types.Operator):
default='Principled BSDF',
search=lambda self, context, edit_text: get_material_list(self.mesh_type, bpy.context.engine)
)
reuse_material: bpy.props.BoolProperty(
name='Reuse Materials',
default=True,
description='Do not create a new material if it exists'
)
keep_original: bpy.props.BoolProperty(
name='Keep Original',
default=True,
description='Do not delete the original stroke'
)

def draw(self, context):
layout = self.layout
Expand Down Expand Up @@ -422,7 +450,7 @@ def process_single_stroke(i, co_list, mask_indices = []):
else:
bm.faces.new(v_list)

# Normal and height calculation
# Attribute interpolation based on 2D distance
maxmin_dist = 0.
depth_offset = np.cos(self.max_vertical_angle) / np.sqrt(1 +
(self.vertical_scale**2 - 1) *
Expand Down Expand Up @@ -460,19 +488,9 @@ def process_single_stroke(i, co_list, mask_indices = []):
(co_2d[1]-v_min)/(v_max-v_min))

# Set vertex color from the stroke's both vertex and material fill colors
fill_base_color = [1,1,1,1]
if current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.show_fill:
fill_base_color[0] = current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.fill_color[0]
fill_base_color[1] = current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.fill_color[1]
fill_base_color[2] = current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.fill_color[2]
fill_base_color[3] = current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.fill_color[3]
if hasattr(stroke_list[i],'vertex_color_fill'):
alpha = stroke_list[i].vertex_color_fill[3]
fill_base_color[0] = fill_base_color[0] * (1-alpha) + alpha * stroke_list[i].vertex_color_fill[0]
fill_base_color[1] = fill_base_color[1] * (1-alpha) + alpha * stroke_list[i].vertex_color_fill[1]
fill_base_color[2] = fill_base_color[2] * (1-alpha) + alpha * stroke_list[i].vertex_color_fill[2]
fill_base_color = get_mixed_color(current_gp_obj, stroke_list[i])
for v in bm.verts:
v[vertex_color_layer] = [linear_to_srgb(fill_base_color[0]), linear_to_srgb(fill_base_color[1]), linear_to_srgb(fill_base_color[2]), fill_base_color[3]]
v[vertex_color_layer] = fill_base_color
v[vertex_start_frame_layer] = frame_range[0]
v[vertex_end_frame_layer] = frame_range[1]

Expand Down Expand Up @@ -577,27 +595,13 @@ def process_single_stroke(i, co_list, mask_indices = []):
bpy.ops.object.mode_set(mode='OBJECT')
return {'FINISHED'}

class MeshGenerationByOffsetting(bpy.types.Operator):
class MeshGenerationByOffsetting(CommonMeshConfig, bpy.types.Operator):
"""Generate an embossed mesh by offsetting the selected strokes"""
bl_idname = "gpencil.nijigp_mesh_generation_offset"
bl_label = "Convert to Meshes by Offsetting"
bl_category = 'View'
bl_options = {'REGISTER', 'UNDO'}

vertical_gap: bpy.props.FloatProperty(
name='Vertical Gap',
default=0, min=0,
unit='LENGTH',
description='Mininum vertical space between generated meshes'
)
ignore_mode: bpy.props.EnumProperty(
name='Ignore',
items=[('NONE', 'None', ''),
('LINE', 'All Lines', ''),
('OPEN', 'All Open Lines', '')],
default='NONE',
description='Skip strokes without fill'
)
offset_amount: bpy.props.FloatProperty(
name='Offset',
default=0.1, soft_min=0, unit='LENGTH',
Expand Down Expand Up @@ -631,16 +635,6 @@ class MeshGenerationByOffsetting(bpy.types.Operator):
default='DEFAULT',
description='Method of creating side faces'
)
keep_original: bpy.props.BoolProperty(
name='Keep Original',
default=True,
description='Do not delete the original stroke'
)
postprocess_double_sided: bpy.props.BoolProperty(
name='Double-Sided',
default=True,
description='Make the mesh symmetric to the working plane'
)
postprocess_shade_smooth: bpy.props.BoolProperty(
name='Shade Smooth',
default=False,
Expand Down Expand Up @@ -676,11 +670,6 @@ class MeshGenerationByOffsetting(bpy.types.Operator):
default='Principled BSDF',
search=lambda self, context, edit_text: get_material_list('MESH', bpy.context.engine)
)
reuse_material: bpy.props.BoolProperty(
name='Reuse Materials',
default=True,
description='Do not create a new material if it exists'
)

def draw(self, context):
layout = self.layout
Expand Down Expand Up @@ -912,19 +901,9 @@ def process_single_stroke(i, co_list):
bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=self.merge_distance)

# Set vertex attributes
fill_base_color = [1,1,1,1]
if current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.show_fill:
fill_base_color[0] = current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.fill_color[0]
fill_base_color[1] = current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.fill_color[1]
fill_base_color[2] = current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.fill_color[2]
fill_base_color[3] = current_gp_obj.data.materials[stroke_list[i].material_index].grease_pencil.fill_color[3]
if hasattr(stroke_list[i],'vertex_color_fill'):
alpha = stroke_list[i].vertex_color_fill[3]
fill_base_color[0] = fill_base_color[0] * (1-alpha) + alpha * stroke_list[i].vertex_color_fill[0]
fill_base_color[1] = fill_base_color[1] * (1-alpha) + alpha * stroke_list[i].vertex_color_fill[1]
fill_base_color[2] = fill_base_color[2] * (1-alpha) + alpha * stroke_list[i].vertex_color_fill[2]
fill_base_color = get_mixed_color(current_gp_obj, stroke_list[i])
for v in bm.verts:
v[vertex_color_layer] = [linear_to_srgb(fill_base_color[0]), linear_to_srgb(fill_base_color[1]), linear_to_srgb(fill_base_color[2]), fill_base_color[3]]
v[vertex_color_layer] = fill_base_color
v[vertex_start_frame_layer] = frame_range[0]
v[vertex_end_frame_layer] = frame_range[1]

Expand Down
Loading

0 comments on commit 3f97456

Please sign in to comment.