Newer
Older
bpy.ops.object.duplicate('INVOKE_REGION_WIN')
curves_duplicate_2 = bpy.context.object
objects_to_delete.append(curves_duplicate_2)
CoDEmanX
committed
# Duplicate the duplicate and add Shrinkwrap to it, with the grease pencil strokes curve as target
bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT')
bpy.context.view_layer.objects.active = curves_duplicate_2
CoDEmanX
committed
bpy.ops.object.modifier_add('INVOKE_REGION_WIN', type='SHRINKWRAP')
curves_duplicate_2.modifiers["Shrinkwrap"].wrap_method = "NEAREST_VERTEX"
curves_duplicate_2.modifiers["Shrinkwrap"].target = GP_strokes_mesh
bpy.ops.object.modifier_apply('INVOKE_REGION_WIN', modifier='Shrinkwrap')
CoDEmanX
committed
# Get the distance of each vert from its original position to its position with Shrinkwrap
nearest_points_coords = {}
for st_idx in range(len(curves_duplicate_1.data.splines)):
for bp_idx in range(len(curves_duplicate_1.data.splines[st_idx].bezier_points)):
bp_1_co = curves_duplicate_1.matrix_world @ \
curves_duplicate_1.data.splines[st_idx].bezier_points[bp_idx].co
bp_2_co = curves_duplicate_2.matrix_world @ \
curves_duplicate_2.data.splines[st_idx].bezier_points[bp_idx].co
CoDEmanX
committed
if bp_idx == 0:
shortest_dist = (bp_1_co - bp_2_co).length
nearest_points_coords[st_idx] = ("%.4f" % bp_2_co[0],
"%.4f" % bp_2_co[1],
"%.4f" % bp_2_co[2])
CoDEmanX
committed
dist = (bp_1_co - bp_2_co).length
CoDEmanX
committed
nearest_points_coords[st_idx] = ("%.4f" % bp_2_co[0],
"%.4f" % bp_2_co[1],
"%.4f" % bp_2_co[2])
CoDEmanX
committed
# Get all coords of GP strokes points, for comparison
GP_strokes_coords = []
for st_idx in range(len(GP_strokes_curve.data.splines)):
GP_strokes_coords.append(
[("%.4f" % x if "%.4f" % x != "-0.00" else "0.00",
"%.4f" % y if "%.4f" % y != "-0.00" else "0.00",
"%.4f" % z if "%.4f" % z != "-0.00" else "0.00") for
x, y, z in [bp.co for bp in GP_strokes_curve.data.splines[st_idx].bezier_points]]
)
# Check the point of the GP strokes with the same coords as
# the nearest points of the curves (with shrinkwrap)
# Dictionary with GP stroke index as index, and a list as value.
# The list has as index the point index of the GP stroke
# nearest to the spline, and as value the spline index
GP_connection_points = {}
for gp_st_idx in range(len(GP_strokes_coords)):
GPvert_spline_relationship = {}
CoDEmanX
committed
for splines_st_idx in range(len(nearest_points_coords)):
if nearest_points_coords[splines_st_idx] in GP_strokes_coords[gp_st_idx]:
GPvert_spline_relationship[
GP_strokes_coords[gp_st_idx].index(nearest_points_coords[splines_st_idx])
] = splines_st_idx
CoDEmanX
committed
GP_connection_points[gp_st_idx] = GPvert_spline_relationship
CoDEmanX
committed
splines_new_order = []
for i in GP_connection_points:
dict_keys = sorted(GP_connection_points[i].keys()) # Sort dictionaries by key
CoDEmanX
committed
for k in dict_keys:
splines_new_order.append(GP_connection_points[i][k])
CoDEmanX
committed
curve_original_name = self.main_curve.name
CoDEmanX
committed
bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT')
bpy.context.view_layer.objects.active = self.main_curve
CoDEmanX
committed
self.main_curve.name = "SURFSKIO_CRV_ORD"
CoDEmanX
committed
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
bpy.ops.curve.select_all('INVOKE_REGION_WIN', action='DESELECT')
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
CoDEmanX
committed
for _sp_idx in range(len(self.main_curve.data.splines)):
self.main_curve.data.splines[0].bezier_points[0].select_control_point = True
CoDEmanX
committed
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
bpy.ops.curve.separate('EXEC_REGION_WIN')
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
CoDEmanX
committed
# Get the names of the separated splines objects in the original order
splines_unordered = {}
for o in bpy.data.objects:
if o.name.find("SURFSKIO_CRV_ORD") != -1:
spline_order_string = o.name.partition(".")[2]
CoDEmanX
committed
if spline_order_string != "" and int(spline_order_string) > 0:
spline_order_index = int(spline_order_string) - 1
splines_unordered[spline_order_index] = o.name
CoDEmanX
committed
# Join all splines objects in final order
for order_idx in splines_new_order:
bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT')
bpy.data.objects[splines_unordered[order_idx]].select_set(True)
bpy.data.objects["SURFSKIO_CRV_ORD"].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects["SURFSKIO_CRV_ORD"]
CoDEmanX
committed
bpy.ops.object.join('INVOKE_REGION_WIN')
CoDEmanX
committed
# Go back to the original name of the curves object.
bpy.context.object.name = curve_original_name
CoDEmanX
committed
bpy.ops.object.delete({"selected_objects": objects_to_delete})
CoDEmanX
committed
bpy.ops.object.select_all('INVOKE_REGION_WIN', action='DESELECT')
bpy.data.objects[curve_original_name].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects[curve_original_name]
CoDEmanX
committed
bpy.ops.curve.select_all('INVOKE_REGION_WIN', action='DESELECT')
CoDEmanX
committed
bpy.context.scene.bsurfaces.SURFSK_gpencil.data.layers.active.clear()
except:
pass
Spivak Vladimir (cwolf3d)
committed
CoDEmanX
committed
CoDEmanX
committed
self.main_curve = bpy.context.object
there_are_GP_strokes = False
# Get the active grease pencil layer
strokes_num = len(self.main_curve.grease_pencil.layers.active.active_frame.strokes)
CoDEmanX
committed
if strokes_num > 0:
there_are_GP_strokes = True
except:
pass
CoDEmanX
committed
if there_are_GP_strokes:
self.execute(context)
self.report({'INFO'}, "Splines have been reordered")
self.report({'WARNING'}, "Draw grease pencil strokes to connect splines")
CoDEmanX
committed
CoDEmanX
committed
# ----------------------------
# Set first points operator
class CURVE_OT_SURFSK_first_points(Operator):
bl_idname = "curve.surfsk_first_points"
bl_label = "Bsurfaces set first points"
bl_description = "Set the selected points as the first point of each spline"
bl_options = {'REGISTER', 'UNDO'}
CoDEmanX
committed
CoDEmanX
committed
# Check non-cyclic splines to invert
for i in range(len(self.main_curve.data.splines)):
b_points = self.main_curve.data.splines[i].bezier_points
CoDEmanX
committed
if i not in self.cyclic_splines: # Only for non-cyclic splines
if b_points[len(b_points) - 1].select_control_point:
splines_to_invert.append(i)
CoDEmanX
committed
# Reorder points of cyclic splines, and set all handles to "Automatic"
CoDEmanX
committed
cyclic_splines_new_first_pt = {}
for i in self.cyclic_splines:
sp = self.main_curve.data.splines[i]
CoDEmanX
committed
for t in range(len(sp.bezier_points)):
bp = sp.bezier_points[t]
if bp.select_control_point or bp.select_right_handle or bp.select_left_handle:
cyclic_splines_new_first_pt[i] = t
break # To take only one if there are more
CoDEmanX
committed
for spline_idx in cyclic_splines_new_first_pt:
sp = self.main_curve.data.splines[spline_idx]
CoDEmanX
committed
spline_old_coords = []
for bp_old in sp.bezier_points:
coords = (bp_old.co[0], bp_old.co[1], bp_old.co[2])
CoDEmanX
committed
left_handle_type = str(bp_old.handle_left_type)
left_handle_length = float(bp_old.handle_left.length)
left_handle_xyz = (
float(bp_old.handle_left.x),
float(bp_old.handle_left.y),
float(bp_old.handle_left.z)
)
right_handle_type = str(bp_old.handle_right_type)
right_handle_length = float(bp_old.handle_right.length)
right_handle_xyz = (
float(bp_old.handle_right.x),
float(bp_old.handle_right.y),
float(bp_old.handle_right.z)
)
spline_old_coords.append(
[coords, left_handle_type,
right_handle_type, left_handle_length,
right_handle_length, left_handle_xyz,
right_handle_xyz]
)
CoDEmanX
committed
for t in range(len(sp.bezier_points)):
bp = sp.bezier_points
CoDEmanX
committed
if t + cyclic_splines_new_first_pt[spline_idx] + 1 <= len(bp) - 1:
new_index = t + cyclic_splines_new_first_pt[spline_idx] + 1
else:
new_index = t + cyclic_splines_new_first_pt[spline_idx] + 1 - len(bp)
CoDEmanX
committed
bp[t].co = Vector(spline_old_coords[new_index][0])
CoDEmanX
committed
bp[t].handle_left.length = spline_old_coords[new_index][3]
bp[t].handle_right.length = spline_old_coords[new_index][4]
CoDEmanX
committed
bp[t].handle_left_type = "FREE"
bp[t].handle_right_type = "FREE"
CoDEmanX
committed
bp[t].handle_left.x = spline_old_coords[new_index][5][0]
bp[t].handle_left.y = spline_old_coords[new_index][5][1]
bp[t].handle_left.z = spline_old_coords[new_index][5][2]
CoDEmanX
committed
bp[t].handle_right.x = spline_old_coords[new_index][6][0]
bp[t].handle_right.y = spline_old_coords[new_index][6][1]
bp[t].handle_right.z = spline_old_coords[new_index][6][2]
CoDEmanX
committed
bp[t].handle_left_type = spline_old_coords[new_index][1]
bp[t].handle_right_type = spline_old_coords[new_index][2]
CoDEmanX
committed
# Invert the non-cyclic splines designated above
for i in range(len(splines_to_invert)):
bpy.ops.curve.select_all('INVOKE_REGION_WIN', action='DESELECT')
CoDEmanX
committed
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
self.main_curve.data.splines[splines_to_invert[i]].bezier_points[0].select_control_point = True
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
CoDEmanX
committed
bpy.ops.curve.switch_direction()
CoDEmanX
committed
bpy.ops.curve.select_all('INVOKE_REGION_WIN', action='DESELECT')
CoDEmanX
committed
# Keep selected the first vert of each spline
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
for i in range(len(self.main_curve.data.splines)):
if not self.main_curve.data.splines[i].use_cyclic_u:
bp = self.main_curve.data.splines[i].bezier_points[0]
else:
bp = self.main_curve.data.splines[i].bezier_points[
len(self.main_curve.data.splines[i].bezier_points) - 1
]
CoDEmanX
committed
bp.select_control_point = True
bp.select_right_handle = True
bp.select_left_handle = True
CoDEmanX
committed
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
CoDEmanX
committed
CoDEmanX
committed
self.main_curve = bpy.context.object
CoDEmanX
committed
# Check if all curves are Bezier, and detect which ones are cyclic
self.cyclic_splines = []
for i in range(len(self.main_curve.data.splines)):
if self.main_curve.data.splines[i].type != "BEZIER":
self.report({'WARNING'}, "All splines must be Bezier type")
CoDEmanX
committed
return {'CANCELLED'}
else:
if self.main_curve.data.splines[i].use_cyclic_u:
self.cyclic_splines.append(i)
CoDEmanX
committed
self.report({'INFO'}, "First points have been set")
CoDEmanX
committed
Campbell Barton
committed
return {'FINISHED'}
CoDEmanX
committed
# Add-ons Preferences Update Panel
# Define Panel classes for updating
panels = (
VIEW3D_PT_tools_SURFSK_mesh,
VIEW3D_PT_tools_SURFSK_curve
Spivak Vladimir (cwolf3d)
committed
def conver_gpencil_to_curve(self, context, pencil, type):
newCurve = bpy.data.curves.new(type + '_curve', type='CURVE')
CurveObject = object_utils.object_data_add(context, newCurve)
Spivak Vladimir (cwolf3d)
committed
error = False
Spivak Vladimir (cwolf3d)
committed
if type == 'GPensil':
Spivak Vladimir (cwolf3d)
committed
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':
Spivak Vladimir (cwolf3d)
committed
try:
strokes = bpy.context.annotation_data.layers.active.active_frame.strokes
Spivak Vladimir (cwolf3d)
committed
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)
Spivak Vladimir (cwolf3d)
committed
Spivak Vladimir (cwolf3d)
committed
if not error:
for i, _stroke in enumerate(strokes):
Spivak Vladimir (cwolf3d)
committed
stroke_points = strokes[i].points
data_list = [ (point.co.x, point.co.y, point.co.z)
Spivak Vladimir (cwolf3d)
committed
for point in stroke_points ]
points_to_add = len(data_list)-1
Spivak Vladimir (cwolf3d)
committed
Spivak Vladimir (cwolf3d)
committed
flat_list = []
for point in data_list:
flat_list.extend(point)
Spivak Vladimir (cwolf3d)
committed
spline = newCurve.splines.new(type='BEZIER')
spline.bezier_points.add(points_to_add)
spline.bezier_points.foreach_set("co", flat_list)
Spivak Vladimir (cwolf3d)
committed
Spivak Vladimir (cwolf3d)
committed
for point in spline.bezier_points:
point.handle_left_type="AUTO"
point.handle_right_type="AUTO"
Spivak Vladimir (cwolf3d)
committed
return CurveObject
else:
return None
Spivak Vladimir (cwolf3d)
committed
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
def update_panel(self, context):
message = "Bsurfaces GPL Edition: Updating Panel locations has failed"
try:
for panel in panels:
if "bl_rna" in panel.__dict__:
bpy.utils.unregister_class(panel)
for panel in panels:
category = context.preferences.addons[__name__].preferences.category
if category != 'Tool':
panel.bl_category = context.preferences.addons[__name__].preferences.category
else:
context.preferences.addons[__name__].preferences.category = 'Edit'
panel.bl_category = 'Edit'
raise ValueError("You can not install add-ons in the Tool panel")
bpy.utils.register_class(panel)
except Exception as e:
print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e))
pass
Spivak Vladimir (cwolf3d)
committed
Spivak Vladimir (cwolf3d)
committed
def makeMaterial(name, diffuse):
if name in bpy.data.materials:
material = bpy.data.materials[name]
material.diffuse_color = diffuse
else:
material = bpy.data.materials.new(name)
material.diffuse_color = diffuse
return material
def update_mesh(self, context):
try:
bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.update()
global global_mesh_object
global_mesh_object = bpy.context.scene.bsurfaces.SURFSK_mesh.name
bpy.data.objects[global_mesh_object].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects[global_mesh_object]
print("Select mesh object")
def update_gpencil(self, context):
Spivak Vladimir (cwolf3d)
committed
try:
bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.update()
global global_gpencil_object
global_gpencil_object = bpy.context.scene.bsurfaces.SURFSK_gpencil.name
bpy.data.objects[global_gpencil_object].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects[global_gpencil_object]
print("Select gpencil object")
Spivak Vladimir (cwolf3d)
committed
def update_curve(self, context):
Spivak Vladimir (cwolf3d)
committed
try:
bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.update()
global global_curve_object
global_curve_object = bpy.context.scene.bsurfaces.SURFSK_curve.name
bpy.data.objects[global_curve_object].select_set(True)
bpy.context.view_layer.objects.active = bpy.data.objects[global_curve_object]
print("Select curve object")
Spivak Vladimir (cwolf3d)
committed
def update_color(self, context):
Spivak Vladimir (cwolf3d)
committed
try:
Spivak Vladimir (cwolf3d)
committed
global global_color
global global_mesh_object
material = makeMaterial("BSurfaceMesh", bpy.context.scene.bsurfaces.SURFSK_mesh_color)
if bpy.data.objects[global_mesh_object].data.materials:
bpy.data.objects[global_mesh_object].data.materials[0] = material
Spivak Vladimir (cwolf3d)
committed
else:
bpy.data.objects[global_mesh_object].data.materials.append(material)
diffuse_color = material.diffuse_color
global_color = (diffuse_color[0], diffuse_color[1], diffuse_color[2], diffuse_color[3])
print("Select mesh object")
Spivak Vladimir (cwolf3d)
committed
Spivak Vladimir (cwolf3d)
committed
def update_Shrinkwrap_offset(self, context):
try:
Spivak Vladimir (cwolf3d)
committed
global global_offset
global_offset = bpy.context.scene.bsurfaces.SURFSK_Shrinkwrap_offset
global global_mesh_object
modifier = bpy.data.objects[global_mesh_object].modifiers["Shrinkwrap"]
Spivak Vladimir (cwolf3d)
committed
modifier.offset = global_offset
print("Shrinkwrap modifier not found")
Spivak Vladimir (cwolf3d)
committed
Spivak Vladimir (cwolf3d)
committed
def update_in_front(self, context):
try:
Spivak Vladimir (cwolf3d)
committed
global global_in_front
global_in_front = bpy.context.scene.bsurfaces.SURFSK_in_front
global global_mesh_object
bpy.data.objects[global_mesh_object].show_in_front = global_in_front
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
print("Select mesh object")
Spivak Vladimir (cwolf3d)
committed
def update_shade_smooth(self, context):
try:
global global_shade_smooth
global_shade_smooth = bpy.context.scene.bsurfaces.SURFSK_shade_smooth
Spivak Vladimir (cwolf3d)
committed
contex_mode = bpy.context.mode
Spivak Vladimir (cwolf3d)
committed
if bpy.ops.object.mode_set.poll():
bpy.ops.object.mode_set('INVOKE_REGION_WIN', mode='OBJECT')
Spivak Vladimir (cwolf3d)
committed
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)
Spivak Vladimir (cwolf3d)
committed
if global_shade_smooth:
bpy.ops.object.shade_smooth()
else:
bpy.ops.object.shade_flat()
Spivak Vladimir (cwolf3d)
committed
if contex_mode == "EDIT_MESH":
bpy.ops.object.editmode_toggle('INVOKE_REGION_WIN')
Spivak Vladimir (cwolf3d)
committed
print("Select mesh object")
Spivak Vladimir (cwolf3d)
committed
Spivak Vladimir (cwolf3d)
committed
class BsurfPreferences(AddonPreferences):
# this must match the addon name, use '__package__'
# when defining this in a submodule of a python package.
bl_idname = __name__
CoDEmanX
committed
name="Tab Category",
description="Choose a name for the category of the panel",
Spivak Vladimir (cwolf3d)
committed
default="Edit",
def draw(self, context):
layout = self.layout
row = layout.row()
col = row.column()
col.label(text="Tab Category:")
col.prop(self, "category", text="")
CoDEmanX
committed
# Properties
class BsurfacesProps(PropertyGroup):
Spivak Vladimir (cwolf3d)
committed
SURFSK_guide: EnumProperty(
name="Guide:",
items=[
('Annotation', 'Annotation', 'Annotation'),
('GPencil', 'GPencil', 'GPencil'),
('Curve', 'Curve', 'Curve')
],
default="Annotation"
)
SURFSK_edges_U: IntProperty(
name="Cross",
description="Number of face-loops crossing the strokes",
default=5,
min=1,
max=200
)
SURFSK_edges_V: IntProperty(
name="Follow",
description="Number of face-loops following the strokes",
default=1,
min=1,
max=200
)
SURFSK_cyclic_cross: BoolProperty(
name="Cyclic Cross",
description="Make cyclic the face-loops crossing the strokes",
default=False
)
SURFSK_cyclic_follow: BoolProperty(
name="Cyclic Follow",
description="Make cyclic the face-loops following the strokes",
default=False
)
SURFSK_keep_strokes: BoolProperty(
name="Keep strokes",
description="Keeps the sketched strokes or curves after adding the surface",
default=False
)
SURFSK_automatic_join: BoolProperty(
name="Automatic join",
description="Join automatically vertices of either surfaces "
"generated by crosshatching, or from the borders of closed shapes",
default=True
)
SURFSK_loops_on_strokes: BoolProperty(
name="Loops on strokes",
description="Make the loops match the paths of the strokes",
default=True
)
name="Precision",
description="Precision level of the surface calculation",
default=2,
min=1,
max=100
)
Spivak Vladimir (cwolf3d)
committed
SURFSK_mesh: PointerProperty(
name="Mesh of BSurface",
Spivak Vladimir (cwolf3d)
committed
type=bpy.types.Object,
description="Mesh of BSurface",
update=update_mesh,
)
SURFSK_gpencil: PointerProperty(
name="GreasePencil object",
type=bpy.types.Object,
description="GreasePencil object",
update=update_gpencil,
SURFSK_curve: PointerProperty(
name="Curve object",
Spivak Vladimir (cwolf3d)
committed
type=bpy.types.Object,
description="Curve object",
update=update_curve,
Spivak Vladimir (cwolf3d)
committed
)
SURFSK_mesh_color: FloatVectorProperty(
Spivak Vladimir (cwolf3d)
committed
name="Mesh color",
default=(1.0, 0.0, 0.0, 0.3),
Spivak Vladimir (cwolf3d)
committed
size=4,
subtype="COLOR",
min=0,
max=1,
update=update_color,
description="Mesh color",
)
Spivak Vladimir (cwolf3d)
committed
SURFSK_Shrinkwrap_offset: FloatProperty(
Spivak Vladimir (cwolf3d)
committed
name="Shrinkwrap offset",
default=0.01,
precision=3,
description="Distance to keep from the target",
update=update_Shrinkwrap_offset,
)
Spivak Vladimir (cwolf3d)
committed
SURFSK_in_front: BoolProperty(
name="In Front",
description="Make the object draw in front of others",
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,
)
Spivak Vladimir (cwolf3d)
committed
MESH_OT_SURFSK_init,
MESH_OT_SURFSK_add_modifiers,
MESH_OT_SURFSK_add_surface,
MESH_OT_SURFSK_edit_surface,
GPENCIL_OT_SURFSK_add_strokes,
GPENCIL_OT_SURFSK_strokes_to_curves,
Spivak Vladimir (cwolf3d)
committed
GPENCIL_OT_SURFSK_annotation_to_curves,
GPENCIL_OT_SURFSK_add_annotation,
Spivak Vladimir (cwolf3d)
committed
CURVE_OT_SURFSK_edit_curve,
CURVE_OT_SURFSK_reorder_splines,
CURVE_OT_SURFSK_first_points,
BsurfPreferences,
BsurfacesProps
CoDEmanX
committed
def register():
for cls in classes:
bpy.utils.register_class(cls)
Spivak Vladimir (cwolf3d)
committed
for panel in panels:
bpy.utils.register_class(panel)
bpy.types.Scene.bsurfaces = PointerProperty(type=BsurfacesProps)
update_panel(None, bpy.context)
CoDEmanX
committed
for panel in panels:
bpy.utils.unregister_class(panel)
Spivak Vladimir (cwolf3d)
committed
for cls in classes:
bpy.utils.unregister_class(cls)
CoDEmanX
committed
if __name__ == "__main__":