From 758e2817f68181c68d09de6f22afb691ba34581a Mon Sep 17 00:00:00 2001 From: "Spivak Vladimir (cwolf3d)" Date: Thu, 17 Oct 2019 00:46:00 +0300 Subject: Addon: BSurfaces: Added convert annotation to curves. Bugs fixed. --- mesh_bsurfaces.py | 316 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 194 insertions(+), 122 deletions(-) (limited to 'mesh_bsurfaces.py') diff --git a/mesh_bsurfaces.py b/mesh_bsurfaces.py index 8af6054c..568ebae4 100644 --- a/mesh_bsurfaces.py +++ b/mesh_bsurfaces.py @@ -20,7 +20,7 @@ bl_info = { "name": "Bsurfaces GPL Edition", "author": "Eclectiel, Spivak Vladimir(cwolf3d)", - "version": (1, 7, 3), + "version": (1, 7, 4), "blender": (2, 80, 0), "location": "View3D EditMode > Sidebar > Edit Tab", "description": "Modeling and retopology tool", @@ -101,15 +101,26 @@ class VIEW3D_PT_tools_SURFSK_mesh(Panel): if scn.SURFSK_guide == 'Curve': col.prop(scn, "SURFSK_curve", text="") col.separator() - props = col.operator("gpencil.surfsk_add_surface", text="Add Surface") + col.separator() + props = col.operator("gpencil.surfsk_add_surface", text="Add Surface") col.operator("gpencil.surfsk_edit_surface", text="Edit Surface") + + col.separator() if scn.SURFSK_guide == 'GPencil': col.operator("gpencil.surfsk_add_strokes", text="Add Strokes") col.operator("gpencil.surfsk_edit_strokes", text="Edit Strokes") + col.separator() col.operator("gpencil.surfsk_strokes_to_curves", text="Strokes to curves") + if scn.SURFSK_guide == 'Annotation': col.operator("gpencil.surfsk_add_annotation", text="Add Annotation") + col.separator() + col.operator("gpencil.surfsk_annotations_to_curves", text="Annotation to curves") + + if scn.SURFSK_guide == 'Curve': + col.operator("gpencil.surfsk_edit_curve", text="Edit curve") + col.separator() col.label(text="Initial settings:") col.prop(scn, "SURFSK_edges_U") @@ -173,11 +184,6 @@ def get_strokes_type(context): strokes_type = "GP_STROKES" except: strokes_type = "NO_STROKES" - - # Check if they are mesh - global global_mesh_object - main_object = bpy.data.objects[global_mesh_object] - total_vert_sel = len([v for v in main_object.data.vertices if v.select]) # Check if they are curves, if there aren't grease pencil strokes if context.scene.bsurfaces.SURFSK_guide == 'Curve': @@ -199,16 +205,23 @@ def get_strokes_type(context): except: strokes_type = "NO_STROKES" - # Check if there is a single stroke without any selection in the object - if strokes_num == 1 and total_vert_sel == 0: - if strokes_type == "EXTERNAL_CURVE": - strokes_type = "SINGLE_CURVE_STROKE_NO_SELECTION" - elif strokes_type == "GP_STROKES": - strokes_type = "SINGLE_GP_STROKE_NO_SELECTION" - - if strokes_num == 0 and total_vert_sel > 0: - strokes_type = "SELECTION_ALONE" - + # Check if they are mesh + try: + global global_mesh_object + self.main_object = bpy.data.objects[global_mesh_object] + total_vert_sel = len([v for v in self.main_object.data.vertices if v.select]) + + # Check if there is a single stroke without any selection in the object + if strokes_num == 1 and total_vert_sel == 0: + if strokes_type == "EXTERNAL_CURVE": + strokes_type = "SINGLE_CURVE_STROKE_NO_SELECTION" + elif strokes_type == "GP_STROKES": + strokes_type = "SINGLE_GP_STROKE_NO_SELECTION" + + if strokes_num == 0 and total_vert_sel > 0: + strokes_type = "SELECTION_ALONE" + except: + pass return strokes_type @@ -3208,7 +3221,8 @@ class GPENCIL_OT_SURFSK_add_surface(Operator): def invoke(self, context, event): - bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT') + if bpy.ops.object.mode_set.poll(): + bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT') bsurfaces_props = bpy.context.scene.bsurfaces self.cyclic_cross = bsurfaces_props.SURFSK_cyclic_cross @@ -3500,6 +3514,7 @@ class GPENCIL_OT_SURFSK_init(Operator): bl_idname = "gpencil.surfsk_init" bl_label = "Bsurfaces initialize" bl_description = "Bsurfaces initialize" + bl_options = {'REGISTER', 'UNDO'} active_object: PointerProperty(type=bpy.types.Object) @@ -3520,13 +3535,17 @@ class GPENCIL_OT_SURFSK_init(Operator): bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') mesh = bpy.data.meshes.new('BSurfaceMesh') mesh_object = object_utils.object_data_add(context, mesh) + bm = bmesh.from_edit_mesh(mesh) + bmesh.update_edit_mesh(mesh) mesh_object.select_set(True) + bpy.context.view_layer.objects.active = mesh_object + mesh_object.show_all_edges = True global_in_front = bpy.context.scene.bsurfaces.SURFSK_in_front mesh_object.show_in_front = global_in_front mesh_object.display_type = 'SOLID' mesh_object.show_wire = True - bpy.context.view_layer.objects.active = mesh_object + global_color = bpy.context.scene.bsurfaces.SURFSK_mesh_color material = makeMaterial("BSurfaceMesh", global_color) mesh_object.data.materials.append(material) @@ -3571,13 +3590,6 @@ class GPENCIL_OT_SURFSK_init(Operator): if context.scene.bsurfaces.SURFSK_guide == 'Annotation': bpy.ops.wm.tool_set_by_id(name="builtin.annotate") bpy.context.scene.tool_settings.annotation_stroke_placement_view3d = 'SURFACE' - - if context.scene.bsurfaces.SURFSK_guide == 'Curve': - #bpy.data.objects[global_mesh_object].data.vertices.add(1) - if bpy.ops.object.mode_set.poll(): - bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='EDIT') - - return {"FINISHED"} def invoke(self, context, event): if bpy.context.active_object: @@ -3594,7 +3606,8 @@ class GPENCIL_OT_SURFSK_init(Operator): class GPENCIL_OT_SURFSK_add_modifiers(Operator): bl_idname = "gpencil.surfsk_add_modifiers" bl_label = "Add Mirror and others modifiers" - bl_description = "Add modifiers: Mirror, Shrinkwrap, Subdivision, Solidify " + bl_description = "Add modifiers: Mirror, Shrinkwrap, Subdivision, Solidify" + bl_options = {'REGISTER', 'UNDO'} active_object: PointerProperty(type=bpy.types.Object) @@ -3675,8 +3688,11 @@ class GPENCIL_OT_SURFSK_edit_surface(Operator): bl_idname = "gpencil.surfsk_edit_surface" bl_label = "Bsurfaces edit surface" bl_description = "Edit surface mesh" + bl_options = {'REGISTER', 'UNDO'} def execute(self, context): + bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT') + bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') bpy.context.scene.bsurfaces.SURFSK_mesh.select_set(True) bpy.context.view_layer.objects.active = bpy.context.scene.bsurfaces.SURFSK_mesh bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='EDIT') @@ -3692,38 +3708,25 @@ class GPENCIL_OT_SURFSK_edit_surface(Operator): self.execute(context) return {"FINISHED"} - + # ---------------------------- # Add strokes operator class GPENCIL_OT_SURFSK_add_strokes(Operator): bl_idname = "gpencil.surfsk_add_strokes" bl_label = "Bsurfaces add strokes" bl_description = "Add the grease pencil strokes" + bl_options = {'REGISTER', 'UNDO'} def execute(self, context): - # Determine the type of the strokes - self.strokes_type = get_strokes_type(context) - # Check if strokes are grease pencil strokes or a curves object - selected_objs = bpy.context.selected_objects - if self.strokes_type == "EXTERNAL_CURVE" or self.strokes_type == "SINGLE_CURVE_STROKE_NO_SELECTION": - for ob in selected_objs: - if ob != bpy.context.view_layer.objects.active: - curve_ob = ob - - bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') + bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT') + bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') - bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') - curve_ob.select_set(True) - bpy.context.view_layer.objects.active = curve_ob + bpy.context.scene.bsurfaces.SURFSK_gpencil.select_set(True) + bpy.context.view_layer.objects.active = bpy.context.scene.bsurfaces.SURFSK_gpencil + bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='PAINT_GPENCIL') + bpy.ops.wm.tool_set_by_id(name="builtin_brush.Draw") - bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') - else: - bpy.context.scene.bsurfaces.SURFSK_gpencil.select_set(True) - bpy.context.view_layer.objects.active = bpy.context.scene.bsurfaces.SURFSK_gpencil - bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='PAINT_GPENCIL') - bpy.ops.wm.tool_set_by_id(name="builtin_brush.Draw") - - return{"FINISHED"} + return{"FINISHED"} def invoke(self, context, event): try: @@ -3742,9 +3745,11 @@ class GPENCIL_OT_SURFSK_edit_strokes(Operator): bl_idname = "gpencil.surfsk_edit_strokes" bl_label = "Bsurfaces edit strokes" bl_description = "Edit the grease pencil strokes" + bl_options = {'REGISTER', 'UNDO'} def execute(self, context): - bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT') + if bpy.ops.object.mode_set.poll(): + bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT') bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') gpencil_object = bpy.context.scene.bsurfaces.SURFSK_gpencil @@ -3753,7 +3758,10 @@ class GPENCIL_OT_SURFSK_edit_strokes(Operator): bpy.context.view_layer.objects.active = gpencil_object bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='EDIT_GPENCIL') - bpy.ops.gpencil.select_all(action='SELECT') + try: + bpy.ops.gpencil.select_all(action='SELECT') + except: + pass def invoke(self, context, event): try: @@ -3767,76 +3775,100 @@ class GPENCIL_OT_SURFSK_edit_strokes(Operator): return {"FINISHED"} # ---------------------------- -# Edit strokes operator -class GPENCIL_OT_SURFSK_strokes_to_curves(Operator): - bl_idname = "gpencil.surfsk_strokes_to_curves" - bl_label = "Convert strokes to curves" - bl_description = "Convert grease pencil strokes to curves for editing" +# Convert annotation to curves operator +class GPENCIL_OT_SURFSK_annotation_to_curves(Operator): + bl_idname = "gpencil.surfsk_annotations_to_curves" + bl_label = "Convert annotation to curves" + bl_description = "Convert annotation to curves for editing" + bl_options = {'REGISTER', 'UNDO'} def execute(self, context): bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT') - # Determine the type of the strokes - self.strokes_type = get_strokes_type(context) - # Check if strokes are grease pencil strokes or a curves object - selected_objs = bpy.context.selected_objects - if self.strokes_type == "EXTERNAL_CURVE" or self.strokes_type == "SINGLE_CURVE_STROKE_NO_SELECTION": - for ob in selected_objs: - if ob != bpy.context.view_layer.objects.active: - curve_ob = ob + # Convert annotation to curve + conver_gpencil_to_curve(self, context, None, 'Annotation') + for ob in bpy.context.selected_objects: + if ob != bpy.context.view_layer.objects.active and ob.name.startswith("GP_Layer"): + ob_gp_strokes = ob - bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') + ob_gp_strokes = bpy.context.object - bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') - curve_ob.select_set(True) - bpy.context.view_layer.objects.active = curve_ob + # Delete annotation strokes + try: + bpy.data.grease_pencils[0].layers.active.clear() + except: + pass - bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') - elif self.strokes_type == "GP_STROKES" or self.strokes_type == "SINGLE_GP_STROKE_NO_SELECTION": - # Convert grease pencil strokes to curve - #bpy.ops.gpencil.convert('INVOKE_REGION_WIN', type='CURVE', use_link_strokes=False) - gp = bpy.context.scene.bsurfaces.SURFSK_gpencil - conver_gpencil_to_curve(self, context, gp, 'GPensil') - for ob in bpy.context.selected_objects: - if ob != bpy.context.view_layer.objects.active and ob.name.startswith("GP_Layer"): - ob_gp_strokes = ob + # Clean up curves + bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') + bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') + ob_gp_strokes.select_set(True) + bpy.context.view_layer.objects.active = ob_gp_strokes - ob_gp_strokes = bpy.context.object + curve_crv = ob_gp_strokes.data + bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') + bpy.ops.curve.spline_type_set('INVOKE_REGION_WIN', type="BEZIER") + bpy.ops.curve.handle_type_set('INVOKE_REGION_WIN', type="AUTOMATIC") + + bpy.ops.wm.tool_set_by_id(name="builtin.select_box") + + return {"FINISHED"} - # Delete grease pencil strokes - try: - bpy.context.scene.bsurfaces.SURFSK_gpencil.data.layers.active.clear() - except: - pass + def invoke(self, context, event): + try: + strokes = bpy.data.grease_pencils[0].layers.active.active_frame.strokes + + strokes_num = len(strokes) + except: + self.report({'WARNING'}, "Not active annotation") + return{"CANCELLED"} - # Clean up curves - bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') - bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') - ob_gp_strokes.select_set(True) - bpy.context.view_layer.objects.active = ob_gp_strokes + self.execute(context) - curve_crv = ob_gp_strokes.data - bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') - bpy.ops.curve.spline_type_set('INVOKE_REGION_WIN', type="BEZIER") - bpy.ops.curve.handle_type_set('INVOKE_REGION_WIN', type="AUTOMATIC") - #curve_crv.show_handles = False - #curve_crv.show_normal_face = False + return {"FINISHED"} - elif self.strokes_type == "EXTERNAL_NO_CURVE": - self.report({'WARNING'}, "The secondary object is not a Curve.") - return{"CANCELLED"} +# ---------------------------- +# Convert strokes to curves operator +class GPENCIL_OT_SURFSK_strokes_to_curves(Operator): + bl_idname = "gpencil.surfsk_strokes_to_curves" + bl_label = "Convert strokes to curves" + bl_description = "Convert grease pencil strokes to curves for editing" + bl_options = {'REGISTER', 'UNDO'} - elif self.strokes_type == "MORE_THAN_ONE_EXTERNAL": - self.report({'WARNING'}, "There shouldn't be more than one secondary object selected.") - return{"CANCELLED"} + def execute(self, context): - elif self.strokes_type == "NO_STROKES" or self.strokes_type == "SELECTION_ALONE": - self.report({'WARNING'}, "There aren't any strokes attached to the object") - return{"CANCELLED"} + bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT') - else: - return{"CANCELLED"} + # Convert grease pencil strokes to curve + gp = bpy.context.scene.bsurfaces.SURFSK_gpencil + conver_gpencil_to_curve(self, context, gp, 'GPensil') + for ob in bpy.context.selected_objects: + if ob != bpy.context.view_layer.objects.active and ob.name.startswith("GP_Layer"): + ob_gp_strokes = ob + + ob_gp_strokes = bpy.context.object + + # Delete grease pencil strokes + try: + bpy.context.scene.bsurfaces.SURFSK_gpencil.data.layers.active.clear() + except: + pass + + # Clean up curves + bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') + bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') + ob_gp_strokes.select_set(True) + bpy.context.view_layer.objects.active = ob_gp_strokes + + curve_crv = ob_gp_strokes.data + bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN') + bpy.ops.curve.spline_type_set('INVOKE_REGION_WIN', type="BEZIER") + bpy.ops.curve.handle_type_set('INVOKE_REGION_WIN', type="AUTOMATIC") + + bpy.ops.wm.tool_set_by_id(name="builtin.select_box") + + return {"FINISHED"} def invoke(self, context, event): try: @@ -3855,6 +3887,7 @@ class GPENCIL_OT_SURFSK_add_annotation(Operator): bl_idname = "gpencil.surfsk_add_annotation" bl_label = "Bsurfaces add annotation" bl_description = "Add annotation" + bl_options = {'REGISTER', 'UNDO'} def execute(self, context): bpy.ops.wm.tool_set_by_id(name="builtin.annotate") @@ -3867,6 +3900,33 @@ class GPENCIL_OT_SURFSK_add_annotation(Operator): self.execute(context) return {"FINISHED"} + + +# ---------------------------- +# Edit curve operator +class GPENCIL_OT_SURFSK_edit_curve(Operator): + bl_idname = "gpencil.surfsk_edit_curve" + bl_label = "Bsurfaces edit curve" + bl_description = "Edit curve" + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT') + bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT') + bpy.context.scene.bsurfaces.SURFSK_curve.select_set(True) + bpy.context.view_layer.objects.active = bpy.context.scene.bsurfaces.SURFSK_curve + bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='EDIT') + + def invoke(self, context, event): + try: + bpy.context.scene.bsurfaces.SURFSK_curve.select_set(True) + except: + self.report({'WARNING'}, "Specify the name of the object with curve") + return{"CANCELLED"} + + self.execute(context) + + return {"FINISHED"} # ---------------------------- # Reorder splines @@ -4248,38 +4308,48 @@ def conver_gpencil_to_curve(self, context, pencil, type): newCurve = bpy.data.curves.new('gpencil_curve', type='CURVE') newCurve.dimensions = '3D' CurveObject = object_utils.object_data_add(context, newCurve) + error = False if type == 'GPensil': - strokes = pencil.data.layers.active.active_frame.strokes + try: + strokes = pencil.data.layers.active.active_frame.strokes + except: + error = True CurveObject.location = pencil.location CurveObject.rotation_euler = pencil.rotation_euler CurveObject.scale = pencil.scale elif type == 'Annotation': grease_pencil = bpy.data.grease_pencils[0] - strokes = grease_pencil.layers.active.active_frame.strokes + try: + strokes = grease_pencil.layers.active.active_frame.strokes + except: + error = True CurveObject.location = (0.0, 0.0, 0.0) CurveObject.rotation_euler = (0.0, 0.0, 0.0) CurveObject.scale = (1.0, 1.0, 1.0) - for i, stroke in enumerate(strokes): - stroke_points = strokes[i].points - data_list = [ (point.co.x, point.co.y, point.co.z) - for point in stroke_points ] - points_to_add = len(data_list)-1 + if not error: + for i, stroke in enumerate(strokes): + stroke_points = strokes[i].points + data_list = [ (point.co.x, point.co.y, point.co.z) + for point in stroke_points ] + points_to_add = len(data_list)-1 - flat_list = [] - for point in data_list: - flat_list.extend(point) + flat_list = [] + for point in data_list: + flat_list.extend(point) - spline = newCurve.splines.new(type='BEZIER') - spline.bezier_points.add(points_to_add) - spline.bezier_points.foreach_set("co", flat_list) + spline = newCurve.splines.new(type='BEZIER') + spline.bezier_points.add(points_to_add) + spline.bezier_points.foreach_set("co", flat_list) - for point in spline.bezier_points: - point.handle_left_type="AUTO" - point.handle_right_type="AUTO" + for point in spline.bezier_points: + point.handle_left_type="AUTO" + point.handle_right_type="AUTO" - return CurveObject + return CurveObject + else: + return None def update_panel(self, context): @@ -4512,7 +4582,9 @@ classes = ( GPENCIL_OT_SURFSK_add_strokes, GPENCIL_OT_SURFSK_edit_strokes, GPENCIL_OT_SURFSK_strokes_to_curves, + GPENCIL_OT_SURFSK_annotation_to_curves, GPENCIL_OT_SURFSK_add_annotation, + GPENCIL_OT_SURFSK_edit_curve, CURVE_OT_SURFSK_reorder_splines, CURVE_OT_SURFSK_first_points, BsurfPreferences, -- cgit v1.2.3