Skip to content

Commit

Permalink
Mesh management
Browse files Browse the repository at this point in the history
  • Loading branch information
chsh2 committed Dec 6, 2022
1 parent aacfd11 commit 95590e4
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 6 deletions.
2 changes: 1 addition & 1 deletion nijigp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"author" : "https://github.com/chsh2/nijiGPen",
"description" : "Tools modifying Grease Pencil strokes in a 2D plane",
"blender" : (3, 3, 0),
"version" : (0, 2, 1),
"version" : (0, 2, 2),
"location" : "View3D > Sidebar > NijiGP, in Draw and Edit mode of Grease Pencil objects",
"warning" : "This addon is still in an early stage of development",
"category" : "Object"
Expand Down
70 changes: 67 additions & 3 deletions nijigp/operator_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,38 @@

MAX_DEPTH = 4096

class MeshManagement(bpy.types.Operator):
"""Manage mesh objects generated from the active GPencil object"""
bl_idname = "gpencil.nijigp_mesh_management"
bl_label = "Generated Mesh Management"
bl_category = 'View'
bl_options = {'REGISTER', 'UNDO'}

action: bpy.props.EnumProperty(
name='Action',
items=[('HIDE', 'Hide', ''),
('SHOW', 'Show', ''),
('CLEAR', 'Clear', '')],
default='SHOW',
description='Actions to perform on children meshes'
)

def draw(self, context):
layout = self.layout
row = layout.row()
row.prop(self, "action", text = "Action")

def execute(self, context):
current_gp_obj = context.object
for obj in current_gp_obj.children:
if 'nijigp_mesh' in obj:
obj.hide_set(self.action == 'HIDE')
obj.hide_render = (self.action == 'HIDE')
if self.action == 'CLEAR':
bpy.data.objects.remove(obj, do_unlink=True)

return {'FINISHED'}

class MeshGenerationByNormal(bpy.types.Operator):
"""Generate a planar mesh with an interpolated normal map calculated from the selected strokes"""
bl_idname = "gpencil.nijigp_mesh_generation_normal"
Expand All @@ -15,11 +47,19 @@ class MeshGenerationByNormal(bpy.types.Operator):
bl_options = {'REGISTER', 'UNDO'}

vertical_gap: bpy.props.FloatProperty(
name='Resolution',
name='Vertical Gap',
default=0.05, 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 @@ -49,6 +89,7 @@ def draw(self, context):
layout.label(text = "Multi-Object Alignment:")
box1 = layout.box()
box1.prop(self, "vertical_gap", text = "Vertical Gap")
box1.prop(self, "ignore_mode")
layout.label(text = "Geometry Options:")
box2 = layout.box()
box2.label(text = "Mesh Style:")
Expand All @@ -66,6 +107,17 @@ def execute(self, context):
self.report({"ERROR"}, "Please install dependencies in the Preferences panel.")
return {'FINISHED'}

current_gp_obj = context.object
# Ignore specific strokes by deselecting them
for i,layer in enumerate(current_gp_obj.data.layers):
if not layer.lock and hasattr(layer.active_frame, "strokes"):
for j,stroke in enumerate(layer.active_frame.strokes):
if stroke.select:
if self.ignore_mode == 'LINE' and is_stroke_line(stroke, current_gp_obj):
stroke.select = False
if self.ignore_mode == 'OPEN' and is_stroke_line(stroke, current_gp_obj) and not stroke.use_cyclic:
stroke.select = False

# Preprocess using Offset operator
# The triangle library may crash in several cases, which should be avoided with every effort
# https://www.cs.cmu.edu/~quake/triangle.trouble.html
Expand All @@ -78,7 +130,6 @@ def execute(self, context):
bpy.ops.gpencil.nijigp_offset_selected()

# Convert selected strokes to 2D polygon point lists
current_gp_obj = context.object
stroke_info = []
stroke_list = []
mesh_names = []
Expand Down Expand Up @@ -411,11 +462,19 @@ class MeshGenerationByOffsetting(bpy.types.Operator):
bl_options = {'REGISTER', 'UNDO'}

vertical_gap: bpy.props.FloatProperty(
name='Resolution',
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 @@ -495,6 +554,7 @@ def draw(self, context):
layout.label(text = "Multi-Object Alignment:")
box1 = layout.box()
box1.prop(self, "vertical_gap", text = "Vertical Gap")
box1.prop(self, "ignore_mode")
layout.label(text = "Geometry Options:")
box2 = layout.box()
box2.prop(self, "offset_amount", text = "Offset Amount")
Expand Down Expand Up @@ -544,6 +604,10 @@ def execute(self, context):
if not layer.lock and hasattr(layer.active_frame, "strokes"):
for j,stroke in enumerate(layer.active_frame.strokes):
if stroke.select:
if self.ignore_mode == 'LINE' and is_stroke_line(stroke, current_gp_obj):
continue
if self.ignore_mode == 'OPEN' and is_stroke_line(stroke, current_gp_obj) and not stroke.use_cyclic:
continue
stroke_info.append([stroke, i, j])
stroke_list.append(stroke)
mesh_names.append('Offset_' + layer.info + '_' + str(j))
Expand Down
26 changes: 24 additions & 2 deletions nijigp/ui_panels.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,37 @@ class NIJIGP_PT_edit_panel_mesh(bpy.types.Panel):

def draw(self, context):
layout = self.layout
scene = context.scene
obj = context.object

layout.label(text="Preprocessing:")
row = layout.row()
row.operator("gpencil.stroke_sample", text="Resample")
row.operator("gpencil.stroke_smooth", text="Smooth")

layout.label(text="Generation Methods:")
row = layout.row()
row.operator("gpencil.nijigp_mesh_generation_offset", text="Frustum by Offset", icon="CONE")
row = layout.row()
row.operator("gpencil.nijigp_mesh_generation_normal", text="Planar with Normals", icon="NORMALS_FACE")

layout.label(text="Mesh Management:")
row = layout.row()
row.operator("gpencil.nijigp_mesh_management", text="Hide").action = 'HIDE'
row.operator("gpencil.nijigp_mesh_management", text="Show").action = 'SHOW'
row.operator("gpencil.nijigp_mesh_management", text="Clear").action = 'CLEAR'

class NIJIGP_PT_draw_panel_mesh(bpy.types.Panel):
bl_idname = 'NIJIGP_PT_draw_panel_mesh'
bl_label = "Strokes to Meshes"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "NijiGP"
bl_context = "greasepencil_paint"

def draw(self, context):
layout = self.layout

layout.label(text="Mesh Management:")
row = layout.row()
row.operator("gpencil.nijigp_mesh_management", text="Hide").action = 'HIDE'
row.operator("gpencil.nijigp_mesh_management", text="Show").action = 'SHOW'
row.operator("gpencil.nijigp_mesh_management", text="Clear").action = 'CLEAR'
8 changes: 8 additions & 0 deletions nijigp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,14 @@ def overlapping_strokes(s1, s2):

return False

def is_stroke_line(stroke, gp_obj):
"""
Check if a stroke does not have fill material
"""
mat_idx = stroke.material_index
material = gp_obj.material_slots[mat_idx].material
return not material.grease_pencil.show_fill

def is_stroke_locked(stroke, gp_obj):
"""
Check if a stroke has the material that is being locked or invisible
Expand Down

0 comments on commit 95590e4

Please sign in to comment.