Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mesh_bsurfaces.py')
-rw-r--r--mesh_bsurfaces.py500
1 files changed, 333 insertions, 167 deletions
diff --git a/mesh_bsurfaces.py b/mesh_bsurfaces.py
index 9e9ae09d..d896d71f 100644
--- a/mesh_bsurfaces.py
+++ b/mesh_bsurfaces.py
@@ -20,11 +20,12 @@
bl_info = {
"name": "Bsurfaces GPL Edition",
"author": "Eclectiel, Spivak Vladimir(cwolf3d)",
- "version": (1, 7, 1),
+ "version": (1, 7, 5),
"blender": (2, 80, 0),
"location": "View3D EditMode > Sidebar > Edit Tab",
"description": "Modeling and retopology tool",
- "wiki_url": "https://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Bsurfaces_1.5",
+ "wiki_url": "https://docs.blender.org/manual/nb/dev/addons/"
+ "mesh/bsurfaces.html",
"category": "Mesh",
}
@@ -62,9 +63,11 @@ from bpy.types import (
# ----------------------------
# GLOBAL
-global_color = [1.0, 0.0, 0.0, 1.0]
+global_color = [1.0, 0.0, 0.0, 0.3]
global_offset = 0.01
global_in_front = False
+global_shade_smooth = False
+global_show_wire = True
global_mesh_object = ""
global_gpencil_object = ""
global_curve_object = ""
@@ -92,6 +95,8 @@ class VIEW3D_PT_tools_SURFSK_mesh(Panel):
col.prop(scn, "SURFSK_mesh_color")
col.prop(scn, "SURFSK_Shrinkwrap_offset")
col.prop(scn, "SURFSK_in_front")
+ col.prop(scn, "SURFSK_shade_smooth")
+ col.prop(scn, "SURFSK_show_wire")
col.label(text="Guide strokes:")
col.row().prop(scn, "SURFSK_guide", expand=True)
@@ -101,14 +106,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")
@@ -172,11 +189,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':
@@ -198,16 +210,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
@@ -1042,6 +1061,8 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='EDIT')
bpy.ops.mesh.normals_make_consistent(inside=False)
bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
+
+ self.update()
return num_faces_created
@@ -1383,6 +1404,8 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
for m_idx in range(len(self.main_object.modifiers)):
self.main_object.modifiers[m_idx].show_viewport = self.modifiers_prev_viewport_state[m_idx]
+ self.update()
+
return
# Part of the Crosshatch process that is repeated when the operator is tweaked
@@ -1665,7 +1688,7 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
# on the original verts, and get them selected
crosshatch_verts_to_merge = []
if self.automatic_join:
- for i in range(len(ob_surface.data.vertices)):
+ for i in range(len(ob_surface.data.vertices)-1):
# Calculate the distance from each of the connected verts to the actual vert,
# and compare it with the distance they would have if joined.
# If they don't change much, that vert can be joined
@@ -1753,6 +1776,8 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
for m_idx in range(len(self.main_object.modifiers)):
self.main_object.modifiers[m_idx].show_viewport = self.modifiers_prev_viewport_state[m_idx]
+ self.update()
+
return {'FINISHED'}
def rectangular_surface(self, context):
@@ -3054,6 +3079,8 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
bpy.ops.mesh.normals_make_consistent('INVOKE_REGION_WIN', inside=False)
bpy.ops.mesh.select_all('INVOKE_REGION_WIN', action='DESELECT')
+ self.update()
+
return{'FINISHED'}
def update(self):
@@ -3073,25 +3100,44 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
else:
self.main_object.data.materials.append(material)
bpy.context.scene.bsurfaces.SURFSK_mesh_color = global_color
+ except:
+ pass
+ try:
global global_in_front
self.main_object.show_in_front = global_in_front
bpy.context.scene.bsurfaces.SURFSK_in_front = global_in_front
except:
pass
+
+ try:
+ global global_show_wire
+ self.main_object.show_wire = global_show_wire
+ bpy.context.scene.bsurfaces.SURFSK_show_wire = global_show_wire
+ except:
+ pass
+
+ try:
+ global global_shade_smooth
+ if global_shade_smooth:
+ bpy.ops.object.shade_smooth()
+ else:
+ bpy.ops.object.shade_flat()
+ bpy.context.scene.bsurfaces.SURFSK_shade_smooth = global_shade_smooth
+ except:
+ pass
return{'FINISHED'}
def execute(self, context):
- bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
-
- global global_mesh_object
-
- bsurfaces_props = bpy.context.scene.bsurfaces
- self.main_object = bpy.data.objects[global_mesh_object]
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
try:
+ global global_mesh_object
+ bsurfaces_props = bpy.context.scene.bsurfaces
+ self.main_object = bpy.data.objects[global_mesh_object]
self.main_object.select_set(True)
except:
self.report({'WARNING'}, "Specify the name of the object with retopology")
@@ -3143,16 +3189,20 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
strokes_for_rectangular_surface = True
strokes_for_crosshatch = False
- bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT')
- self.main_object.select_set(True)
- bpy.context.view_layer.objects.active = self.main_object
-
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
if strokes_for_rectangular_surface:
self.rectangular_surface(context)
elif strokes_for_crosshatch:
- self.crosshatch_surface_execute()
+ self.crosshatch_surface_execute(context)
+
+ #Set Shade smooth to new polygons
+ bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
+ global global_shade_smooth
+ if global_shade_smooth:
+ bpy.ops.object.shade_smooth()
+ else:
+ bpy.ops.object.shade_flat()
# Delete main splines
bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
@@ -3205,7 +3255,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
@@ -3248,22 +3299,12 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
global global_gpencil_object
gp = bpy.data.objects[global_gpencil_object]
self.original_curve = conver_gpencil_to_curve(self, context, gp, 'GPensil')
- gplayer_prefix_translated = bpy.app.translations.pgettext_data('GP_Layer')
- for ob in bpy.context.selected_objects:
- if ob != bpy.context.view_layer.objects.active and \
- ob.name.startswith((gplayer_prefix_translated, 'GP_Layer')):
- self.original_curve = ob
self.using_external_curves = False
elif self.strokes_type == "GP_ANNOTATION":
# Convert grease pencil strokes to curve
gp = bpy.data.grease_pencils["Annotations"]
self.original_curve = conver_gpencil_to_curve(self, context, gp, 'Annotation')
- gplayer_prefix_translated = bpy.app.translations.pgettext_data('GP_Layer')
- for ob in bpy.context.selected_objects:
- if ob != bpy.context.view_layer.objects.active and \
- ob.name.startswith((gplayer_prefix_translated, 'GP_Layer')):
- self.original_curve = ob
self.using_external_curves = False
elif self.strokes_type == "EXTERNAL_CURVE":
@@ -3271,19 +3312,12 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
self.original_curve = bpy.data.objects[global_curve_object]
self.using_external_curves = True
- bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
-
# Make sure there are no objects left from erroneous
# executions of this operator, with the reserved names used here
for o in bpy.data.objects:
if o.name.find("SURFSKIO_") != -1:
bpy.ops.object.delete({"selected_objects": [o]})
- try:
- self.original_curve.select_set(True)
- except:
- self.report({'WARNING'}, "Specify the name of the object with curve")
- return{"CANCELLED"}
bpy.context.view_layer.objects.active = self.original_curve
bpy.ops.object.duplicate('INVOKE_REGION_WIN')
@@ -3422,32 +3456,28 @@ class GPENCIL_OT_SURFSK_add_surface(Operator):
# Delete temporary strokes curve object
bpy.ops.object.delete({"selected_objects": [self.temporary_curve]})
- # If "Keep strokes" option is not active, delete original strokes curve object
- if not self.stopping_errors or self.is_crosshatch:
- bpy.ops.object.delete({"selected_objects": [self.original_curve]})
-
- # Delete grease pencil strokes
- if self.strokes_type == "GP_STROKES" and not self.stopping_errors:
- try:
- bpy.context.scene.bsurfaces.SURFSK_gpencil.data.layers.active.clear()
- except:
- pass
-
- # Delete annotation strokes
- if self.strokes_type == "GP_ANNOTATION" and not self.stopping_errors:
- try:
- bpy.data.grease_pencils[0].layers.active.clear()
- except:
- pass
-
- bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT')
- self.main_object.select_set(True)
- bpy.context.view_layer.objects.active = self.main_object
-
# Set again since "execute()" will turn it again to its initial value
self.execute(context)
if not self.stopping_errors:
+ # Delete grease pencil strokes
+ if self.strokes_type == "GP_STROKES":
+ try:
+ bpy.context.scene.bsurfaces.SURFSK_gpencil.data.layers.active.clear()
+ except:
+ pass
+
+ # Delete annotation strokes
+ elif self.strokes_type == "GP_ANNOTATION":
+ try:
+ bpy.data.grease_pencils[0].layers.active.clear()
+ except:
+ pass
+
+ bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
+ bpy.ops.object.delete({"selected_objects": [self.original_curve]})
+ bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
+
return {"FINISHED"}
else:
return{"CANCELLED"}
@@ -3495,6 +3525,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)
@@ -3502,11 +3533,14 @@ class GPENCIL_OT_SURFSK_init(Operator):
bs = bpy.context.scene.bsurfaces
- 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')
global global_color
global global_offset
global global_in_front
+ global global_show_wire
+ global global_shade_smooth
global global_mesh_object
global global_gpencil_object
@@ -3515,12 +3549,23 @@ class GPENCIL_OT_SURFSK_init(Operator):
mesh = bpy.data.meshes.new('BSurfaceMesh')
mesh_object = object_utils.object_data_add(context, 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_shade_smooth = bpy.context.scene.bsurfaces.SURFSK_shade_smooth
+ if global_shade_smooth:
+ bpy.ops.object.shade_smooth()
+ else:
+ bpy.ops.object.shade_flat()
+
+ global_show_wire = bpy.context.scene.bsurfaces.SURFSK_show_wire
+ mesh_object.show_wire = global_show_wire
+
global_color = bpy.context.scene.bsurfaces.SURFSK_mesh_color
material = makeMaterial("BSurfaceMesh", global_color)
mesh_object.data.materials.append(material)
@@ -3565,11 +3610,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)
-
- return {"FINISHED"}
def invoke(self, context, event):
if bpy.context.active_object:
@@ -3586,7 +3626,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)
@@ -3594,7 +3635,8 @@ class GPENCIL_OT_SURFSK_add_modifiers(Operator):
bs = bpy.context.scene.bsurfaces
- 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')
if bs.SURFSK_mesh == None:
self.report({'ERROR_INVALID_INPUT'}, "Please select Mesh of BSurface or click Initialize")
@@ -3667,8 +3709,12 @@ 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):
+ 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')
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')
@@ -3684,38 +3730,26 @@ 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')
+ 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')
- 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:
@@ -3733,69 +3767,112 @@ class GPENCIL_OT_SURFSK_add_strokes(Operator):
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 or curves used"
+ bl_description = "Edit 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
+ 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
+
+ gpencil_object.select_set(True)
+ bpy.context.view_layer.objects.active = gpencil_object
+
+ bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='EDIT_GPENCIL')
+ try:
+ bpy.ops.gpencil.select_all(action='SELECT')
+ except:
+ pass
- bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
+ def invoke(self, context, event):
+ try:
+ bpy.context.scene.bsurfaces.SURFSK_gpencil.select_set(True)
+ except:
+ self.report({'WARNING'}, "Specify the name of the object with strokes")
+ return{"CANCELLED"}
- bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT')
- curve_ob.select_set(True)
- bpy.context.view_layer.objects.active = curve_ob
+ self.execute(context)
- 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.object.editmode_toggle('INVOKE_REGION_WIN')
- #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
+ return {"FINISHED"}
- ob_gp_strokes = bpy.context.object
+# ----------------------------
+# 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'}
- # Delete grease pencil strokes
+ def execute(self, context):
+
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
+
+ # Convert annotation to curve
+ curve = conver_gpencil_to_curve(self, context, None, 'Annotation')
+
+ if curve != None:
+ # Delete annotation strokes
try:
- bpy.context.scene.bsurfaces.SURFSK_gpencil.data.layers.active.clear()
+ bpy.data.grease_pencils[0].layers.active.clear()
except:
pass
# Clean up curves
- 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")
- #curve_crv.show_handles = False
- #curve_crv.show_normal_face = False
+ curve.select_set(True)
+ bpy.context.view_layer.objects.active = curve
+
+ bpy.ops.wm.tool_set_by_id(name="builtin.select_box")
+
+ return {"FINISHED"}
- elif self.strokes_type == "EXTERNAL_NO_CURVE":
- self.report({'WARNING'}, "The secondary object is not a Curve.")
+ 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"}
- elif self.strokes_type == "MORE_THAN_ONE_EXTERNAL":
- self.report({'WARNING'}, "There shouldn't be more than one secondary object selected.")
- return{"CANCELLED"}
+ self.execute(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"}
+ return {"FINISHED"}
- else:
- 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'}
+
+ def execute(self, context):
+
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
+
+ # Convert grease pencil strokes to curve
+ gp = bpy.context.scene.bsurfaces.SURFSK_gpencil
+ curve = conver_gpencil_to_curve(self, context, gp, 'GPensil')
+
+ if curve != None:
+ # Delete grease pencil strokes
+ try:
+ bpy.context.scene.bsurfaces.SURFSK_gpencil.data.layers.active.clear()
+ except:
+ pass
+
+ # Clean up curves
+
+ curve.select_set(True)
+ bpy.context.view_layer.objects.active = curve
+
+ bpy.ops.wm.tool_set_by_id(name="builtin.select_box")
+
+ return {"FINISHED"}
def invoke(self, context, event):
try:
@@ -3814,6 +3891,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")
@@ -3826,6 +3904,34 @@ 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):
+ 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')
+ 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
@@ -4204,41 +4310,51 @@ panels = (
def conver_gpencil_to_curve(self, context, pencil, type):
- newCurve = bpy.data.curves.new('gpencil_curve', type='CURVE')
+ newCurve = bpy.data.curves.new(type + '_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):
@@ -4341,6 +4457,41 @@ def update_in_front(self, context):
bpy.data.objects[global_mesh_object].show_in_front = global_in_front
except Exception as e:
print("Select mesh object")
+
+def update_show_wire(self, context):
+ try:
+ global global_show_wire
+ global_show_wire = bpy.context.scene.bsurfaces.SURFSK_show_wire
+ global global_mesh_object
+ bpy.data.objects[global_mesh_object].show_wire = global_show_wire
+ except Exception as e:
+ print("Select mesh object")
+
+def update_shade_smooth(self, context):
+ try:
+ global global_shade_smooth
+ global_shade_smooth = bpy.context.scene.bsurfaces.SURFSK_shade_smooth
+
+ contex_mode = bpy.context.mode
+
+ if bpy.ops.object.mode_set.poll():
+ bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
+
+ bpy.ops.object.select_all(action='DESELECT')
+ global global_mesh_object
+ global_mesh_object = bpy.context.scene.bsurfaces.SURFSK_mesh.name
+ bpy.data.objects[global_mesh_object].select_set(True)
+
+ if global_shade_smooth:
+ bpy.ops.object.shade_smooth()
+ else:
+ bpy.ops.object.shade_flat()
+
+ if contex_mode == "EDIT_MESH":
+ bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
+
+ except Exception as e:
+ print("Select mesh object")
class BsurfPreferences(AddonPreferences):
@@ -4441,7 +4592,7 @@ class BsurfacesProps(PropertyGroup):
)
SURFSK_mesh_color: FloatVectorProperty(
name="Mesh color",
- default=(1.0, 0.0, 0.0, 1.0),
+ default=(1.0, 0.0, 0.0, 0.3),
size=4,
subtype="COLOR",
min=0,
@@ -4462,6 +4613,18 @@ class BsurfacesProps(PropertyGroup):
default=False,
update=update_in_front,
)
+ SURFSK_show_wire: BoolProperty(
+ name="Show wire",
+ description="Add the object’s wireframe over solid drawing",
+ default=False,
+ update=update_show_wire,
+ )
+ SURFSK_shade_smooth: BoolProperty(
+ name="Shade smooth",
+ description="Render and display faces smooth, using interpolated Vertex Normals",
+ default=False,
+ update=update_shade_smooth,
+ )
classes = (
GPENCIL_OT_SURFSK_init,
@@ -4470,7 +4633,10 @@ classes = (
GPENCIL_OT_SURFSK_edit_surface,
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,