diff options
author | Campbell Barton <ideasman42@gmail.com> | 2020-01-29 05:51:36 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2020-01-29 05:51:36 +0300 |
commit | 6598f0a25cb0485c6e6fa66964c2d74bf80ff705 (patch) | |
tree | a15f2b63048bffbfc4e26a1db0800e2b005d4a29 /curve_tools | |
parent | 9dde6b34b254a3882a1366023eca9792033f9b6c (diff) |
Cleanup: trailing space
Diffstat (limited to 'curve_tools')
-rw-r--r-- | curve_tools/__init__.py | 40 | ||||
-rw-r--r-- | curve_tools/cad.py | 14 | ||||
-rw-r--r-- | curve_tools/fillet.py | 34 | ||||
-rw-r--r-- | curve_tools/operators.py | 172 | ||||
-rw-r--r-- | curve_tools/outline.py | 34 | ||||
-rw-r--r-- | curve_tools/path_finder.py | 64 | ||||
-rw-r--r-- | curve_tools/remove_doubles.py | 64 | ||||
-rw-r--r-- | curve_tools/show_resolution.py | 38 | ||||
-rw-r--r-- | curve_tools/splines_sequence.py | 72 | ||||
-rw-r--r-- | curve_tools/util.py | 6 |
10 files changed, 269 insertions, 269 deletions
diff --git a/curve_tools/__init__.py b/curve_tools/__init__.py index 8de5b7d3..17108ef1 100644 --- a/curve_tools/__init__.py +++ b/curve_tools/__init__.py @@ -345,11 +345,11 @@ class VIEW3D_PT_CurvePanel(Panel): row.operator("curvetools.scale_reset", text='Scale Reset') row = col.row(align=True) row.operator("curvetools.operatorbirail", text="Birail") - row = col.row(align=True) + row = col.row(align=True) row.operator("curvetools.convert_selected_face_to_bezier", text="Convert selected faces to Bezier") row = col.row(align=True) row.operator("curvetools.convert_bezier_to_surface", text="Convert Bezier to Surface") - + # Extended options box1 = self.layout.box() col = box1.column(align=True) @@ -363,9 +363,9 @@ class VIEW3D_PT_CurvePanel(Panel): row = col.row(align=True) row.operator("curvetools.bezier_cad_subdivide", text="Multi Subdivide") row = col.row(align=True) - row.operator("curvetools.split", text='Split by selected points') + row.operator("curvetools.split", text='Split by selected points') row = col.row(align=True) - row.operator("curvetools.remove_doubles", text='Remove Doubles') + row.operator("curvetools.remove_doubles", text='Remove Doubles') row = col.row(align=True) row.operator("curvetools.add_toolpath_discretize_curve", text="Discretize Curve") row = col.row(align=True) @@ -387,7 +387,7 @@ class VIEW3D_PT_CurvePanel(Panel): row.prop(context.scene.curvetools, "curve_vertcolor", text="") row = col.row(align=True) row.operator("curvetools.show_resolution", text="Run [ESC]") - + # D.1 set spline sequence row = col.row(align=True) row.label(text="Show and rearrange spline sequence:") @@ -444,7 +444,7 @@ class VIEW3D_PT_CurvePanel(Panel): row.label(text="Alt + Shift + mouse click - add spline to select") row = col.row(align=True) row.label(text="A - deselect all") - + # Add-ons Preferences Update Panel # Define Panel classes for updating @@ -492,17 +492,17 @@ class CurveAddonPreferences(AddonPreferences): # Context MENU def curve_tools_context_menu(self, context): bl_label = 'Curve tools' - + self.layout.operator("curvetools.bezier_points_fillet", text="Fillet") self.layout.operator("curvetools.bezier_cad_handle_projection", text='Handle Projection') self.layout.operator("curvetools.bezier_spline_divide", text="Divide") self.layout.operator("curvetools.add_toolpath_offset_curve", text="Offset Curve") self.layout.operator("curvetools.remove_doubles", text='Remove Doubles') self.layout.separator() - + def curve_tools_object_context_menu(self, context): bl_label = 'Curve tools' - + if context.active_object.type == "CURVE": self.layout.operator("curvetools.scale_reset", text="Scale Reset") self.layout.operator("curvetools.add_toolpath_offset_curve", text="Offset Curve") @@ -566,21 +566,21 @@ def register(): default=True, description="Curves Utils" ) - + for cls in classes: bpy.utils.register_class(cls) for panel in panels: bpy.utils.register_class(panel) - + auto_loft.register() - + bpy.types.TOPBAR_MT_file_export.append(menu_file_export) - + bpy.types.Scene.curvetools = bpy.props.PointerProperty(type=curvetoolsSettings) - + update_panel(None, bpy.context) - + bpy.types.VIEW3D_MT_edit_curve_context_menu.prepend(curve_tools_context_menu) bpy.types.VIEW3D_MT_object_context_menu.prepend(curve_tools_object_context_menu) @@ -592,17 +592,17 @@ def unregister(): del bpy.types.Scene.UTAdvancedDrop del bpy.types.Scene.UTExtendedDrop del bpy.types.Scene.UTUtilsDrop - + auto_loft.unregister() - + bpy.types.TOPBAR_MT_file_export.remove(menu_file_export) - + bpy.types.VIEW3D_MT_edit_curve_context_menu.remove(curve_tools_context_menu) bpy.types.VIEW3D_MT_object_context_menu.remove(curve_tools_object_context_menu) - + for panel in panels: bpy.utils.unregister_class(panel) - + for cls in classes: bpy.utils.unregister_class(cls) diff --git a/curve_tools/cad.py b/curve_tools/cad.py index b7478450..8e62e295 100644 --- a/curve_tools/cad.py +++ b/curve_tools/cad.py @@ -70,9 +70,9 @@ class Boolean(bpy.types.Operator): def execute(self, context): current_mode = bpy.context.object.mode - + bpy.ops.object.mode_set(mode = 'EDIT') - + if bpy.context.object.data.dimensions != '2D': self.report({'WARNING'}, 'Can only be applied in 2D') return {'CANCELLED'} @@ -86,9 +86,9 @@ class Boolean(bpy.types.Operator): if not internal.bezierBooleanGeometry(splineA, splineB, self.operation): self.report({'WARNING'}, 'Invalid selection. Only work to selected two spline.') return {'CANCELLED'} - + bpy.ops.object.mode_set (mode = current_mode) - + return {'FINISHED'} class Intersection(bpy.types.Operator): @@ -108,7 +108,7 @@ class Intersection(bpy.types.Operator): internal.bezierMultiIntersection(segments) return {'FINISHED'} - + class HandleProjection(bpy.types.Operator): bl_idname = 'curvetools.bezier_cad_handle_projection' bl_description = bl_label = 'Handle Projection' @@ -191,7 +191,7 @@ class Subdivide(bpy.types.Operator): def execute(self, context): current_mode = bpy.context.object.mode - + bpy.ops.object.mode_set(mode = 'EDIT') segments = internal.bezierSegments(bpy.context.object.data.splines, True) @@ -206,7 +206,7 @@ class Subdivide(bpy.types.Operator): for segment in segments: segment['cuts'].extend(cuts) internal.subdivideBezierSegments(segments) - + bpy.ops.object.mode_set (mode = current_mode) return {'FINISHED'} diff --git a/curve_tools/fillet.py b/curve_tools/fillet.py index 3bb3e492..c9fcb688 100644 --- a/curve_tools/fillet.py +++ b/curve_tools/fillet.py @@ -47,7 +47,7 @@ def remove_handler(handlers): except: pass for handler in handlers: - handlers.remove(handler) + handlers.remove(handler) class Fillet(bpy.types.Operator): @@ -55,44 +55,44 @@ class Fillet(bpy.types.Operator): bl_label = "Curve Fillet" bl_description = "Curve Fillet" bl_options = {'REGISTER', 'UNDO'} - + x: IntProperty(name="x", description="x") y: IntProperty(name="y", description="y") location3D: FloatVectorProperty(name = "", description = "Start location", default = (0.0, 0.0, 0.0), subtype = 'XYZ') - + handlers = [] - + def execute(self, context): self.report({'INFO'}, "ESC or TAB - cancel") bpy.ops.object.mode_set(mode = 'EDIT') - + # color change in the panel self.path_color = bpy.context.scene.curvetools.path_color self.path_thickness = bpy.context.scene.curvetools.path_thickness def modal(self, context, event): context.area.tag_redraw() - + if event.type in {'ESC', 'TAB'}: # Cancel remove_handler(self.handlers) return {'CANCELLED'} - + if event.type in {'X', 'DEL'}: # Cancel remove_handler(self.handlers) - bpy.ops.curve.delete(type='VERT') - return {'RUNNING_MODAL'} - + bpy.ops.curve.delete(type='VERT') + return {'RUNNING_MODAL'} + elif event.alt and event.shift and event.type == 'LEFTMOUSE': click(self, context, event) - + elif event.alt and not event.shift and event.type == 'LEFTMOUSE': remove_handler(self.handlers) bpy.ops.curve.select_all(action='DESELECT') click(self, context, event) - + elif event.alt and event.type == 'RIGHTMOUSE': remove_handler(self.handlers) bpy.ops.curve.select_all(action='DESELECT') @@ -100,12 +100,12 @@ class Fillet(bpy.types.Operator): elif event.alt and not event.shift and event.shift and event.type == 'RIGHTMOUSE': click(self, context, event) - + elif event.type == 'A': remove_handler(self.handlers) bpy.ops.curve.select_all(action='DESELECT') - - elif event.type == 'MOUSEMOVE': # + + elif event.type == 'MOUSEMOVE': # self.x = event.mouse_x self.y = event.mouse_y region = bpy.context.region @@ -115,7 +115,7 @@ class Fillet(bpy.types.Operator): rv3d, (event.mouse_region_x, event.mouse_region_y), (0.0, 0.0, 0.0) - ) + ) return {'PASS_THROUGH'} @@ -123,7 +123,7 @@ class Fillet(bpy.types.Operator): self.execute(context) context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} - + @classmethod def poll(cls, context): return (context.object is not None and diff --git a/curve_tools/operators.py b/curve_tools/operators.py index 191aff08..aeb4672c 100644 --- a/curve_tools/operators.py +++ b/curve_tools/operators.py @@ -151,8 +151,8 @@ class OperatorOriginToSpline0Start(bpy.types.Operator): def execute(self, context): - - + + blCurve = context.active_object blSpline = blCurve.data.splines[0] newOrigin = blCurve.matrix_world @ blSpline.bezier_points[0].co @@ -162,12 +162,12 @@ class OperatorOriginToSpline0Start(bpy.types.Operator): self.report({'INFO'}, "newOrigin: %.6f, %.6f, %.6f" % (newOrigin.x, newOrigin.y, newOrigin.z)) current_mode = bpy.context.object.mode - + bpy.ops.object.mode_set(mode = 'OBJECT') bpy.context.scene.cursor.location = newOrigin bpy.ops.object.origin_set(type='ORIGIN_CURSOR') bpy.context.scene.cursor.location = origOrigin - + bpy.ops.object.mode_set (mode = current_mode) return {'FINISHED'} @@ -212,16 +212,16 @@ class OperatorIntersectCurves(bpy.types.Operator): bpy.ops.object.select_all(action='DESELECT') selected_objects[i].select_set(True) selected_objects[j].select_set(True) - + if selected_objects[i].type == 'CURVE' and selected_objects[j].type == 'CURVE': curveIntersector = intersections.CurvesIntersector.FromSelection() rvIntersectionNrs = curveIntersector.CalcAndApplyIntersections() self.report({'INFO'}, "Active curve points: %d; other curve points: %d" % (rvIntersectionNrs[0], rvIntersectionNrs[1])) - + for obj in selected_objects: obj.select_set(True) - + return {'FINISHED'} # ------------------------------------------------------------ @@ -415,14 +415,14 @@ class OperatorSplinesJoinNeighbouring(bpy.types.Operator): self.report({'INFO'}, "Applied %d joins on %d splines; resulting nrSplines: %d" % (nrJoins, nrSplines, curve.nrSplines)) return {'FINISHED'} - + # ------------------------------------------------------------ # SurfaceFromBezier def SurfaceFromBezier(surfacedata, points, center): - + len_points = len(points) - 1 - + if len_points % 2 == 0: h = mathematics.subdivide_cubic_bezier( points[len_points].co, points[len_points].handle_right, @@ -435,7 +435,7 @@ def SurfaceFromBezier(surfacedata, points, center): points[len_points].co = h[2] points[len_points].handle_right = h[3] points[0].handle_left = h[4] - + half = round((len_points + 1)/2) - 1 # 1 surfacespline1 = surfacedata.splines.new(type='NURBS') @@ -450,7 +450,7 @@ def SurfaceFromBezier(surfacedata, points, center): surfacespline1.use_endpoint_v = True for i in range(0, half): - + if center: # 2 surfacespline2 = surfacedata.splines.new(type='NURBS') @@ -467,7 +467,7 @@ def SurfaceFromBezier(surfacedata, points, center): p.select = True surfacespline2.use_endpoint_u = True surfacespline2.use_endpoint_v = True - + # 3 surfacespline3 = surfacedata.splines.new(type='NURBS') surfacespline3.points.add(3) @@ -483,7 +483,7 @@ def SurfaceFromBezier(surfacedata, points, center): p.select = True surfacespline3.use_endpoint_u = True surfacespline3.use_endpoint_v = True - + # 4 surfacespline4 = surfacedata.splines.new(type='NURBS') surfacespline4.points.add(3) @@ -499,7 +499,7 @@ def SurfaceFromBezier(surfacedata, points, center): p.select = True surfacespline4.use_endpoint_u = True surfacespline4.use_endpoint_v = True - + if center: # 5 surfacespline5 = surfacedata.splines.new(type='NURBS') @@ -516,7 +516,7 @@ def SurfaceFromBezier(surfacedata, points, center): p.select = True surfacespline5.use_endpoint_u = True surfacespline5.use_endpoint_v = True - + # 6 surfacespline6 = surfacedata.splines.new(type='NURBS') surfacespline6.points.add(3) @@ -528,10 +528,10 @@ def SurfaceFromBezier(surfacedata, points, center): p.select = True surfacespline6.use_endpoint_u = True surfacespline6.use_endpoint_v = True - - bpy.ops.object.mode_set(mode = 'EDIT') + + bpy.ops.object.mode_set(mode = 'EDIT') bpy.ops.curve.make_segment() - + for s in surfacedata.splines: s.resolution_u = 4 s.resolution_v = 4 @@ -561,7 +561,7 @@ class ConvertSelectedFacesToBezier(bpy.types.Operator): curvedata = bpy.data.curves.new('Curve' + active_object.name, type='CURVE') curveobject = object_utils.object_data_add(context, curvedata) curvedata.dimensions = '3D' - + for poly in meshdata.polygons: if poly.select: newSpline = curvedata.splines.new(type='BEZIER') @@ -576,9 +576,9 @@ class ConvertSelectedFacesToBezier(bpy.types.Operator): newSpline.bezier_points[npoint].select_left_handle = True newSpline.bezier_points[npoint].select_right_handle = True npoint += 1 - + return {'FINISHED'} - + # ------------------------------------------------------------ # Convert Bezier to Surface @@ -593,7 +593,7 @@ class ConvertBezierToSurface(bpy.types.Operator): default=False, description="Consider center points" ) - + Resolution_U: IntProperty( name="Resolution_U", default=4, @@ -601,7 +601,7 @@ class ConvertBezierToSurface(bpy.types.Operator): soft_min=1, description="Surface resolution U" ) - + Resolution_V: IntProperty( name="Resolution_V", default=4, @@ -609,7 +609,7 @@ class ConvertBezierToSurface(bpy.types.Operator): soft_min=1, description="Surface resolution V" ) - + def draw(self, context): layout = self.layout @@ -618,17 +618,17 @@ class ConvertBezierToSurface(bpy.types.Operator): col.prop(self, 'Center') col.prop(self, 'Resolution_U') col.prop(self, 'Resolution_V') - + @classmethod def poll(cls, context): return util.Selected1OrMoreCurves() def execute(self, context): # main function - bpy.ops.object.mode_set(mode = 'OBJECT') + bpy.ops.object.mode_set(mode = 'OBJECT') active_object = context.active_object curvedata = active_object.data - + surfacedata = bpy.data.curves.new('Surface', type='SURFACE') surfaceobject = object_utils.object_data_add(context, surfacedata) surfaceobject.matrix_world = active_object.matrix_world @@ -636,10 +636,10 @@ class ConvertBezierToSurface(bpy.types.Operator): surfacedata.dimensions = '3D' surfaceobject.show_wire = True surfaceobject.show_in_front = True - + for spline in curvedata.splines: SurfaceFromBezier(surfacedata, spline.bezier_points, self.Center) - + for spline in surfacedata.splines: len_p = len(spline.points) len_devide_4 = round(len_p / 4) + 1 @@ -648,12 +648,12 @@ class ConvertBezierToSurface(bpy.types.Operator): for point_index in range(len_devide_4, len_p - len_devide_4): if point_index != len_devide_2 and point_index != len_devide_2 - 1: spline.points[point_index].select = True - + surfacedata.resolution_u = self.Resolution_U surfacedata.resolution_v = self.Resolution_V return {'FINISHED'} - + # ------------------------------------------------------------ # Fillet @@ -693,10 +693,10 @@ class BezierPointsFillet(bpy.types.Operator): # main function if bpy.ops.object.mode_set.poll(): bpy.ops.object.mode_set(mode='EDIT') - + splines = bpy.context.object.data.splines bpy.ops.curve.spline_type_set(type='BEZIER') - + bpy.ops.curve.handle_type_set(type='VECTOR') s = [] for spline in splines: @@ -719,9 +719,9 @@ class BezierPointsFillet(bpy.types.Operator): jn = 0 for j in ii: j += jn - + bpy.ops.curve.select_all(action='DESELECT') - + if j != 0 and j != n - 1: bezier_points[j].select_control_point = True bezier_points[j + 1].select_control_point = True @@ -730,7 +730,7 @@ class BezierPointsFillet(bpy.types.Operator): bezier_points[j + 1], bezier_points[j + 2]] jn += 1 n += 1 - + elif j == 0: bezier_points[j].select_control_point = True bezier_points[j + 1].select_control_point = True @@ -739,14 +739,14 @@ class BezierPointsFillet(bpy.types.Operator): bezier_points[1], bezier_points[2]] jn += 1 n += 1 - + elif j == n - 1: bezier_points[j].select_control_point = True bezier_points[j - 1].select_control_point = True bpy.ops.curve.subdivide() selected4 = [bezier_points[0], bezier_points[n], bezier_points[n - 1], bezier_points[n - 2]] - + selected4[2].co = selected4[1].co s1 = Vector(selected4[0].co) - Vector(selected4[1].co) s2 = Vector(selected4[3].co) - Vector(selected4[2].co) @@ -756,7 +756,7 @@ class BezierPointsFillet(bpy.types.Operator): s2.normalize() s22 = Vector(selected4[2].co) + s2 * self.Fillet_radius selected4[2].co = s22 - + if self.Fillet_Type == 'Round': if j != n - 1: selected4[2].handle_right_type = 'VECTOR' @@ -829,9 +829,9 @@ class BezierDivide(bpy.types.Operator): if n > 2: jn = 0 for j in ii: - + bpy.ops.curve.select_all(action='DESELECT') - + if (j in ii) and (j + 1 in ii): bezier_points[j + jn].select_control_point = True bezier_points[j + 1 + jn].select_control_point = True @@ -850,7 +850,7 @@ class BezierDivide(bpy.types.Operator): bezier_points[j + 2 + jn].handle_left_type = 'FREE' bezier_points[j + 2 + jn].handle_left = h[4] jn += 1 - + if j == n - 1 and (0 in ii) and spline.use_cyclic_u: bezier_points[j + jn].select_control_point = True bezier_points[0].select_control_point = True @@ -867,12 +867,12 @@ class BezierDivide(bpy.types.Operator): bezier_points[j + 1 + jn].handle_right_type = 'FREE' bezier_points[j + 1 + jn].handle_right = h[3] bezier_points[0].handle_left_type = 'FREE' - bezier_points[0].handle_left = h[4] + bezier_points[0].handle_left = h[4] sn += 1 return {'FINISHED'} - + # ------------------------------------------------------------ # CurveScaleReset Operator @@ -890,25 +890,25 @@ class CurveScaleReset(bpy.types.Operator): def execute(self, context): # main function current_mode = bpy.context.object.mode - + bpy.ops.object.mode_set(mode = 'OBJECT') - + oldCurve = context.active_object oldCurveName = oldCurve.name - + bpy.ops.object.duplicate_move(OBJECT_OT_duplicate=None, TRANSFORM_OT_translate=None) newCurve = context.active_object newCurve.data.splines.clear() newCurve.scale = (1.0, 1.0, 1.0) - + oldCurve.select_set(True) newCurve.select_set(True) bpy.context.view_layer.objects.active = newCurve bpy.ops.object.join() - + joinCurve = context.active_object joinCurve.name = oldCurveName - + bpy.ops.object.mode_set (mode = current_mode) return {'FINISHED'} @@ -927,7 +927,7 @@ class Split(bpy.types.Operator): def execute(self, context): selected_Curves = util.GetSelectedCurves() - + for curve in selected_Curves: spline_points = [] select_points = {} @@ -942,7 +942,7 @@ class Split(bpy.types.Operator): for i in range(len(spline.bezier_points)): bezier_point = spline.bezier_points[i] points[i]=[bezier_point.co[:], bezier_point.handle_left[:], bezier_point.handle_right[:]] - + if spline.bezier_points[i].select_control_point: select_bezier_points[i_bp].append(i) i_bp+=1 @@ -957,24 +957,24 @@ class Split(bpy.types.Operator): select_points[i_p].append(i) i_p+=1 spline_points.append(points) - + curve.data.splines.clear() - + for key in select_bezier_points: - + num=0 - + if select_bezier_points[key][-1] == select_bezier_points[key][0]-1: select_bezier_points[key].pop() - + for i in select_bezier_points[key][1:]+[select_bezier_points[key][0]-1]: if i != 0: spline = curve.data.splines.new('BEZIER') spline.bezier_points.add(i-num) - + for j in range(num, i): bezier_point = spline.bezier_points[j-num] - + bezier_point.co = bezier_spline_points[key][j][0] bezier_point.handle_left = bezier_spline_points[key][j][1] bezier_point.handle_right = bezier_spline_points[key][j][2] @@ -983,29 +983,29 @@ class Split(bpy.types.Operator): bezier_point.handle_left = bezier_spline_points[key][i][1] bezier_point.handle_right = bezier_spline_points[key][i][2] num=i - + for key in select_points: - + num=0 - + if select_points[key][-1] == select_points[key][0]-1: select_points[key].pop() - + for i in select_points[key][1:]+[select_points[key][0]-1]: if i != 0: spline = curve.data.splines.new(spline_points[key][i][1]) spline.points.add(i-num) - + for j in range(num, i): point = spline.points[j-num] - + point.co = spline_points[key][j][0] point = spline.points[-1] point.co = spline_points[key][i][0] num=i - + return {'FINISHED'} - + class SeparateOutline(bpy.types.Operator): bl_idname = "curvetools.sep_outline" bl_label = "Separate Outline" @@ -1021,7 +1021,7 @@ class SeparateOutline(bpy.types.Operator): bpy.ops.curve.separate() return {'FINISHED'} - + class CurveBoolean(bpy.types.Operator): bl_idname = "curvetools.bezier_curve_boolean" bl_description = "Curve Boolean" @@ -1043,7 +1043,7 @@ class CurveBoolean(bpy.types.Operator): @classmethod def poll(cls, context): return util.Selected1OrMoreCurves() - + def draw(self, context): layout = self.layout @@ -1055,27 +1055,27 @@ class CurveBoolean(bpy.types.Operator): def execute(self, context): current_mode = bpy.context.object.mode - + if bpy.ops.object.mode_set.poll(): bpy.ops.object.mode_set(mode = 'OBJECT') - + selected_Curves = util.GetSelectedCurves() len_selected_curves = len(selected_Curves) if len_selected_curves < 2: return {'FINISHED'} - + min_number = 1 - + max_number = 0 for iCurve in range(0, len_selected_curves): len_splines = len(selected_Curves[iCurve].data.splines) max_number += len_splines - + if self.number < min_number: self.number = min_number if self.number > max_number: self.number = max_number - + j = 0 first_curve = 0 first_spline = 0 @@ -1086,14 +1086,14 @@ class CurveBoolean(bpy.types.Operator): first_curve = iCurve first_spline = iSpline j += 1 - + bpy.ops.object.select_all(action='DESELECT') - + spline1 = selected_Curves[first_curve].data.splines[first_spline] matrix_world1 = selected_Curves[first_curve].matrix_world - + len_spline1 = len(spline1.bezier_points) - + dataCurve = bpy.data.curves.new(self.operation, type='CURVE') dataCurve.dimensions = '2D' newSpline1 = dataCurve.splines.new(type='BEZIER') @@ -1105,7 +1105,7 @@ class CurveBoolean(bpy.types.Operator): newSpline1.bezier_points[n].handle_left = matrix_world1 @ spline1.bezier_points[n].handle_left newSpline1.bezier_points[n].handle_right_type = spline1.bezier_points[n].handle_right_type newSpline1.bezier_points[n].handle_right = matrix_world1 @ spline1.bezier_points[n].handle_right - + Curve = object_utils.object_data_add(context, dataCurve) bpy.context.view_layer.objects.active = Curve Curve.select_set(True) @@ -1129,7 +1129,7 @@ class CurveBoolean(bpy.types.Operator): newSpline.bezier_points[n].handle_left = matrix_world @ spline.bezier_points[n].handle_left newSpline.bezier_points[n].handle_right_type = spline.bezier_points[n].handle_right_type newSpline.bezier_points[n].handle_right = matrix_world @ spline.bezier_points[n].handle_right - + bpy.ops.object.mode_set(mode = 'EDIT') bpy.ops.curve.select_all(action='SELECT') splines = internal.getSelectedSplines(True, True) @@ -1138,15 +1138,15 @@ class CurveBoolean(bpy.types.Operator): splineA = splines[0] splineB = splines[1] dataCurve.splines.active = newSpline1 - + if not internal.bezierBooleanGeometry(splineA, splineB, self.operation): self.report({'WARNING'}, 'Invalid selection.') return {'CANCELLED'} - + j += 1 - + bpy.ops.object.mode_set (mode = current_mode) - + return {'FINISHED'} def register(): diff --git a/curve_tools/outline.py b/curve_tools/outline.py index 3975a403..b1f8561e 100644 --- a/curve_tools/outline.py +++ b/curve_tools/outline.py @@ -44,49 +44,49 @@ def createOutline(curve, outline): if len(p) < 2: return out = [] - + n = ((p[0].handle_right - p[0].co).normalized() - (p[0].handle_left - p[0].co).normalized()).normalized() n = Vector((-n[1], n[0], n[2])) o = p[0].co + outline * n out.append(o) - + for i in range(1,len(p)-1): n = ((p[i].handle_right - p[i].co).normalized() - (p[i].handle_left - p[i].co).normalized()).normalized() n = Vector((-n[1], n[0], n[2])) o = intersect_line_line(out[-1], (out[-1]+p[i].co - p[i-1].co), p[i].co, p[i].co + n)[0] out.append(o) - + n = ((p[-1].handle_right - p[-1].co).normalized() - (p[-1].handle_left - p[-1].co).normalized()).normalized() n = Vector((-n[1], n[0], n[2])) o = p[-1].co + outline * n out.append(o) - + curve.data.splines.new(spline.type) if spline.use_cyclic_u: curve.data.splines[-1].use_cyclic_u = True p_out = curve.data.splines[-1].bezier_points p_out.add(len(out)-1) - + for i in range(len(out)): p_out[i].handle_left_type = 'FREE' p_out[i].handle_right_type = 'FREE' - + p_out[i].co = out[i] - + if i<len(out)-1: l = (p[i + 1].co - p[i].co).length l2 = (out[i] - out[i + 1]).length - + if i==0: p_out[i].handle_left = out[i] + ((p[i].handle_left - p[i].co) * l2/l) if i<len(out)-1: p_out[i + 1].handle_left = out[i + 1] + ((p[i + 1].handle_left - p[i + 1].co) * l2/l) p_out[i].handle_right = out[i] + ((p[i].handle_right - p[i].co) * l2/l) - + for i in range(len(p)): p_out[i].handle_left_type = p[i].handle_left_type p_out[i].handle_right_type = p[i].handle_right_type - + else: if len(spline.points) < 2: return @@ -95,32 +95,32 @@ def createOutline(curve, outline): v = Vector((point.co[0], point.co[1], point.co[2])) p.append(v) out = [] - + n = ((p[1] - p[0]).normalized() - (p[-1] - p[0]).normalized()).normalized() n = Vector((-n[1], n[0], n[2])) o = p[0] + outline * n out.append(o) - + for i in range(1,len(p)-1): n = ((p[i+1] - p[i]).normalized() - (p[i-1] - p[i]).normalized()).normalized() n = Vector((-n[1], n[0], n[2])) o = intersect_line_line(out[-1], (out[-1]+p[i] - p[i-1]), p[i], p[i] + n)[0] out.append(o) - + n = ((p[0] - p[-1]).normalized() - (p[-2] - p[-1]).normalized()).normalized() n = Vector((-n[1], n[0], n[2])) o = p[-1] + outline * n out.append(o) - + curve.data.splines.new(spline.type) if spline.use_cyclic_u: curve.data.splines[-1].use_cyclic_u = True p_out = curve.data.splines[-1].points p_out.add(len(out)-1) - - for i in range(len(out)): + + for i in range(len(out)): p_out[i].co = (out[i][0], out[i][1], out[i][2], 0.0) - + return diff --git a/curve_tools/path_finder.py b/curve_tools/path_finder.py index 30c673e0..9093f5f2 100644 --- a/curve_tools/path_finder.py +++ b/curve_tools/path_finder.py @@ -27,7 +27,7 @@ bl_info = { 'wiki_url': '', 'tracker_url': '', 'category': 'Curve'} - + import time import threading @@ -69,7 +69,7 @@ def get_bezier_points(spline, matrix_world): point_list.extend([matrix_world @ spline.bezier_points[0].co]) return point_list - + def get_points(spline, matrix_world): point_list = [] len_points = len(spline.points) @@ -92,25 +92,25 @@ def get_points(spline, matrix_world): return point_list def draw_bezier_points(self, context, spline, matrix_world, path_color, path_thickness): - + points = get_bezier_points(spline, matrix_world) - + shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = batch_for_shader(shader, 'POINTS', {"pos": points}) - + shader.bind() shader.uniform_float("color", path_color) bgl.glEnable(bgl.GL_BLEND) bgl.glLineWidth(path_thickness) batch.draw(shader) - + def draw_points(self, context, spline, matrix_world, path_color, path_thickness): - + points = get_points(spline, matrix_world) - + shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = batch_for_shader(shader, 'POINTS', {"pos": points}) - + shader.bind() shader.uniform_float("color", path_color) bgl.glEnable(bgl.GL_BLEND) @@ -131,7 +131,7 @@ def near(location3D, point, radius): factor += 1 if point.z < (location3D.z + radius): factor += 1 - + return factor def click(self, context, event): @@ -141,9 +141,9 @@ def click(self, context, event): matrix_world = object.matrix_world if object.type == 'CURVE': curvedata = object.data - + radius = bpy.context.scene.curvetools.PathFinderRadius - + for spline in curvedata.splines: len_bezier_points = len(spline.bezier_points) factor_max = 0 @@ -153,7 +153,7 @@ def click(self, context, event): factor = near(self.location3D, co, radius) if factor > factor_max: factor_max = factor - + if i < len_bezier_points - 1: for t in range(0, 100, 2): h = mathematics.subdivide_cubic_bezier(spline.bezier_points[i].co, @@ -186,7 +186,7 @@ def click(self, context, event): bezier_point.select_control_point = True bezier_point.select_left_handle = True bezier_point.select_right_handle = True - + for spline in curvedata.splines: len_points = len(spline.points) factor_max = 0 @@ -219,7 +219,7 @@ def click(self, context, event): if factor_max == 6: args = (self, context, spline, matrix_world, self.path_color, self.path_thickness) self.handlers.append(bpy.types.SpaceView3D.draw_handler_add(draw_points, args, 'WINDOW', 'POST_VIEW')) - + for point in spline.points: point.select = True @@ -230,51 +230,51 @@ def remove_handler(handlers): except: pass for handler in handlers: - handlers.remove(handler) + handlers.remove(handler) class PathFinder(bpy.types.Operator): bl_idname = "curvetools.pathfinder" bl_label = "Path Finder" bl_description = "Path Finder" bl_options = {'REGISTER', 'UNDO'} - + x: IntProperty(name="x", description="x") y: IntProperty(name="y", description="y") location3D: FloatVectorProperty(name = "", description = "Start location", default = (0.0, 0.0, 0.0), subtype = 'XYZ') - + handlers = [] - + def execute(self, context): self.report({'INFO'}, "ESC or TAB - cancel") bpy.ops.object.mode_set(mode = 'EDIT') - + # color change in the panel self.path_color = bpy.context.scene.curvetools.path_color self.path_thickness = bpy.context.scene.curvetools.path_thickness def modal(self, context, event): context.area.tag_redraw() - + if event.type in {'ESC', 'TAB'}: # Cancel remove_handler(self.handlers) return {'CANCELLED'} - + if event.type in {'X', 'DEL'}: # Cancel remove_handler(self.handlers) - bpy.ops.curve.delete(type='VERT') - return {'RUNNING_MODAL'} - + bpy.ops.curve.delete(type='VERT') + return {'RUNNING_MODAL'} + elif event.alt and event.shift and event.type == 'LEFTMOUSE': click(self, context, event) - + elif event.alt and not event.shift and event.type == 'LEFTMOUSE': remove_handler(self.handlers) bpy.ops.curve.select_all(action='DESELECT') click(self, context, event) - + elif event.alt and event.type == 'RIGHTMOUSE': remove_handler(self.handlers) bpy.ops.curve.select_all(action='DESELECT') @@ -282,12 +282,12 @@ class PathFinder(bpy.types.Operator): elif event.alt and not event.shift and event.shift and event.type == 'RIGHTMOUSE': click(self, context, event) - + elif event.type == 'A': remove_handler(self.handlers) bpy.ops.curve.select_all(action='DESELECT') - - elif event.type == 'MOUSEMOVE': # + + elif event.type == 'MOUSEMOVE': # self.x = event.mouse_x self.y = event.mouse_y region = bpy.context.region @@ -297,7 +297,7 @@ class PathFinder(bpy.types.Operator): rv3d, (event.mouse_region_x, event.mouse_region_y), (0.0, 0.0, 0.0) - ) + ) return {'PASS_THROUGH'} @@ -305,7 +305,7 @@ class PathFinder(bpy.types.Operator): self.execute(context) context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} - + @classmethod def poll(cls, context): return util.Selected1OrMoreCurves() diff --git a/curve_tools/remove_doubles.py b/curve_tools/remove_doubles.py index cf955980..d69b3e0a 100644 --- a/curve_tools/remove_doubles.py +++ b/curve_tools/remove_doubles.py @@ -12,70 +12,70 @@ bl_info = { } def main(context, distance = 0.01): - + selected_Curves = util.GetSelectedCurves() if bpy.ops.object.mode_set.poll(): bpy.ops.object.mode_set(mode='EDIT') - + for curve in selected_Curves: bezier_dellist = [] dellist = [] - - for spline in curve.data.splines: + + for spline in curve.data.splines: if spline.type == 'BEZIER': if len(spline.bezier_points) > 1: - for i in range(0, len(spline.bezier_points)): - + for i in range(0, len(spline.bezier_points)): + if i == 0: ii = len(spline.bezier_points) - 1 - else: + else: ii = i - 1 - + dot = spline.bezier_points[i]; - dot1 = spline.bezier_points[ii]; - + dot1 = spline.bezier_points[ii]; + while dot1 in bezier_dellist and i != ii: ii -= 1 - if ii < 0: + if ii < 0: ii = len(spline.bezier_points)-1 dot1 = spline.bezier_points[ii] - - if dot.select_control_point and dot1.select_control_point and (i!=0 or spline.use_cyclic_u): - + + if dot.select_control_point and dot1.select_control_point and (i!=0 or spline.use_cyclic_u): + if (dot.co-dot1.co).length < distance: # remove points and recreate hangles dot1.handle_right_type = "FREE" dot1.handle_right = dot.handle_right dot1.co = (dot.co + dot1.co) / 2 bezier_dellist.append(dot) - + else: # Handles that are on main point position converts to vector, # if next handle are also vector if dot.handle_left_type == 'VECTOR' and (dot1.handle_right - dot1.co).length < distance: dot1.handle_right_type = "VECTOR" if dot1.handle_right_type == 'VECTOR' and (dot.handle_left - dot.co).length < distance: - dot.handle_left_type = "VECTOR" + dot.handle_left_type = "VECTOR" else: if len(spline.points) > 1: - for i in range(0, len(spline.points)): - + for i in range(0, len(spline.points)): + if i == 0: ii = len(spline.points) - 1 - else: + else: ii = i - 1 - + dot = spline.points[i]; - dot1 = spline.points[ii]; - + dot1 = spline.points[ii]; + while dot1 in dellist and i != ii: ii -= 1 - if ii < 0: + if ii < 0: ii = len(spline.points)-1 dot1 = spline.points[ii] - - if dot.select and dot1.select and (i!=0 or spline.use_cyclic_u): - + + if dot.select and dot1.select and (i!=0 or spline.use_cyclic_u): + if (dot.co-dot1.co).length < distance: dot1.co = (dot.co + dot1.co) / 2 dellist.append(dot) @@ -84,19 +84,19 @@ def main(context, distance = 0.01): for dot in bezier_dellist: dot.select_control_point = True - + for dot in dellist: dot.select = True - + bezier_count = len(bezier_dellist) count = len(dellist) - + bpy.ops.curve.delete(type = 'VERT') - + bpy.ops.curve.select_all(action = 'DESELECT') - + return bezier_count + count - + class CurveRemvDbs(bpy.types.Operator): diff --git a/curve_tools/show_resolution.py b/curve_tools/show_resolution.py index 78acc1e3..fc8fdad2 100644 --- a/curve_tools/show_resolution.py +++ b/curve_tools/show_resolution.py @@ -38,41 +38,41 @@ def get_points(spline, matrix_world): bezier_points = spline.bezier_points - if len(bezier_points) < 2: + if len(bezier_points) < 2: return [] r = spline.resolution_u + 1 if r < 2: return [] segments = len(bezier_points) - + if not spline.use_cyclic_u: segments -= 1 - + point_list = [] for i in range(segments): inext = (i + 1) % len(bezier_points) - + bezier_points1 = matrix_world @ bezier_points[i].co handle1 = matrix_world @ bezier_points[i].handle_right handle2 = matrix_world @ bezier_points[inext].handle_left bezier_points2 = matrix_world @ bezier_points[inext].co - + bezier = bezier_points1, handle1, handle2, bezier_points2, r points = interpolate_bezier(*bezier) point_list.extend(points) - + return point_list - + def draw(self, context, splines, curve_vertcolor, matrix_world): - + for spline in splines: points = get_points(spline, matrix_world) - + shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = batch_for_shader(shader, 'POINTS', {"pos": points}) - + shader.bind() shader.uniform_float("color", curve_vertcolor) batch.draw(shader) @@ -82,13 +82,13 @@ class ShowCurveResolution(bpy.types.Operator): bl_idname = "curvetools.show_resolution" bl_label = "Show Curve Resolution" bl_description = "Show curve Resolution / [ESC] - remove" - + handlers = [] - + def modal(self, context, event): context.area.tag_redraw() - if event.type in {'ESC'}: + if event.type in {'ESC'}: for handler in self.handlers: try: bpy.types.SpaceView3D.draw_handler_remove(handler, 'WINDOW') @@ -104,16 +104,16 @@ class ShowCurveResolution(bpy.types.Operator): def invoke(self, context, event): if context.area.type == 'VIEW_3D': - + # color change in the panel curve_vertcolor = bpy.context.scene.curvetools.curve_vertcolor - + splines = context.active_object.data.splines matrix_world = context.active_object.matrix_world - + # the arguments we pass the the callback args = (self, context, splines, curve_vertcolor, matrix_world) - + # Add the region OpenGL drawing callback # draw in view space with 'POST_VIEW' and 'PRE_VIEW' self.handlers.append(bpy.types.SpaceView3D.draw_handler_add(draw, args, 'WINDOW', 'POST_VIEW')) @@ -121,10 +121,10 @@ class ShowCurveResolution(bpy.types.Operator): context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} else: - self.report({'WARNING'}, + self.report({'WARNING'}, "View3D not found, cannot run operator") return {'CANCELLED'} - + @classmethod def poll(cls, context): return (context.object is not None and diff --git a/curve_tools/splines_sequence.py b/curve_tools/splines_sequence.py index 5d11aedf..d861a1ee 100644 --- a/curve_tools/splines_sequence.py +++ b/curve_tools/splines_sequence.py @@ -39,7 +39,7 @@ from bpy.props import ( def draw_number(n, co, font_height): point_list = [] - + numeral = [ [Vector((0, 0, 0)), Vector((0, 2, 0)), Vector((0, 2, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((1, 0, 0)), Vector((1, 0, 0)), Vector((0, 0, 0))], [Vector((0, 1, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((1, 0, 0))], @@ -52,20 +52,20 @@ def draw_number(n, co, font_height): [Vector((0, 1, 0)), Vector((0, 2, 0)), Vector((0, 2, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((1, 0, 0)), Vector((1, 0, 0)), Vector((0, 0, 0)), Vector((0, 0, 0)), Vector((0, 1, 0)), Vector((0, 1, 0)), Vector((1, 1, 0))], [Vector((0, 0, 0)), Vector((1, 1, 0)), Vector((1, 1, 0)), Vector((1, 2, 0)), Vector((1, 2, 0)), Vector((0, 2, 0)), Vector((0, 2, 0)), Vector((0, 1, 0)), Vector((0, 1, 0)), Vector((1, 1, 0))], ] - + for num in numeral[n]: point_list.extend([num * font_height + co]) - + return point_list - + def draw(self, context, splines, sequence_color, font_thickness, font_size, matrix_world): splines_len = len(splines) for n in range(0, splines_len): - + res = [int(x) for x in str(n)] - + i = 0 for r in res: # draw some text @@ -74,14 +74,14 @@ def draw(self, context, splines, sequence_color, font_thickness, font_size, matr else: first_point = matrix_world @ splines[n].points[0].co first_point_co = Vector((first_point.x, first_point.y, first_point.z)) - + first_point_co = Vector((i, 0, 0)) + first_point_co points = draw_number(r, first_point_co, font_size) - + shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = batch_for_shader(shader, 'LINES', {"pos": points}) - + shader.bind() bgl.glLineWidth(font_thickness) shader.uniform_float("color", sequence_color) @@ -92,13 +92,13 @@ class ShowSplinesSequence(bpy.types.Operator): bl_idname = "curvetools.show_splines_sequence" bl_label = "Show Splines Sequence" bl_description = "Show Splines Sequence / [ESC] - remove" - + handlers = [] - + def modal(self, context, event): context.area.tag_redraw() - if event.type in {'ESC'}: + if event.type in {'ESC'}: for handler in self.handlers: try: bpy.types.SpaceView3D.draw_handler_remove(handler, 'WINDOW') @@ -114,18 +114,18 @@ class ShowSplinesSequence(bpy.types.Operator): def invoke(self, context, event): if context.area.type == 'VIEW_3D': - + # color change in the panel sequence_color = bpy.context.scene.curvetools.sequence_color font_thickness = bpy.context.scene.curvetools.font_thickness font_size = bpy.context.scene.curvetools.font_size - + splines = context.active_object.data.splines matrix_world = context.active_object.matrix_world - + # the arguments we pass the the callback args = (self, context, splines, sequence_color, font_thickness, font_size, matrix_world) - + # Add the region OpenGL drawing callback # draw in view space with 'POST_VIEW' and 'PRE_VIEW' self.handlers.append(bpy.types.SpaceView3D.draw_handler_add(draw, args, 'WINDOW', 'POST_VIEW')) @@ -133,7 +133,7 @@ class ShowSplinesSequence(bpy.types.Operator): context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} else: - self.report({'WARNING'}, + self.report({'WARNING'}, "View3D not found, cannot run operator") return {'CANCELLED'} @@ -149,17 +149,17 @@ def rearrangesplines(dataCurve, select_spline1, select_spline2): spline1 = dataCurve.splines[select_spline1] spline2 = dataCurve.splines[select_spline2] - + bpy.ops.curve.select_all(action='SELECT') bpy.ops.curve.spline_type_set(type='BEZIER') bpy.ops.curve.select_all(action='DESELECT') type1 = spline1.type type2 = spline2.type - + len_spline1 = len(spline1.bezier_points) len_spline2 = len(spline2.bezier_points) - + newSpline = dataCurve.splines.new(type=type1) newSpline.bezier_points.add(len_spline1 - 1) newSpline.use_cyclic_u = spline1.use_cyclic_u @@ -170,7 +170,7 @@ def rearrangesplines(dataCurve, select_spline1, select_spline2): newSpline.bezier_points[n].handle_right_type = spline1.bezier_points[n].handle_right_type newSpline.bezier_points[n].handle_right = spline1.bezier_points[n].handle_right spline1.bezier_points[n].select_control_point = True - + spline1.bezier_points[0].select_control_point = False spline1.bezier_points[0].select_left_handle = False spline1.bezier_points[0].select_right_handle = False @@ -178,7 +178,7 @@ def rearrangesplines(dataCurve, select_spline1, select_spline2): spline1.bezier_points[0].select_control_point = True bpy.ops.curve.spline_type_set(type=type2) - + bpy.ops.curve.select_all(action='DESELECT') spline1.bezier_points.add(len_spline2 - 1) @@ -193,12 +193,12 @@ def rearrangesplines(dataCurve, select_spline1, select_spline2): spline1.bezier_points[n].select_left_handle = False spline1.bezier_points[n].select_right_handle = False spline2.bezier_points[n].select_control_point = True - + spline2.bezier_points[0].select_control_point = False spline2.bezier_points[0].select_left_handle = False spline2.bezier_points[0].select_right_handle = False bpy.ops.curve.delete(type='VERT') - + spline2.bezier_points[0].select_control_point = True bpy.ops.curve.spline_type_set(type=type1) @@ -210,29 +210,29 @@ def rearrangesplines(dataCurve, select_spline1, select_spline2): spline2.bezier_points[m].handle_left = newSpline.bezier_points[m].handle_left spline2.bezier_points[m].handle_right_type = newSpline.bezier_points[m].handle_right_type spline2.bezier_points[m].handle_right = newSpline.bezier_points[m].handle_right - + bpy.ops.curve.select_all(action='DESELECT') for point in newSpline.bezier_points: point.select_control_point = True bpy.ops.curve.delete(type='VERT') spline2.bezier_points[0].select_control_point = True - + def rearrange(dataCurve, select_spline, command): len_splines = len(dataCurve.splines) if command == 'NEXT': if select_spline < len_splines - 1: rearrangesplines(dataCurve, select_spline + 1, select_spline) - + if command == 'PREV': if select_spline > 0: rearrangesplines(dataCurve, select_spline, select_spline - 1) - + class RearrangeSpline(bpy.types.Operator): bl_idname = "curvetools.rearrange_spline" bl_label = "Rearrange Spline" bl_description = "Rearrange Spline" - + Types = [('NEXT', "Next", "next"), ('PREV', "Prev", "prev")] command : EnumProperty( @@ -240,17 +240,17 @@ class RearrangeSpline(bpy.types.Operator): description="Command (prev or next)", items=Types ) - + def execute(self, context): bpy.ops.object.mode_set(mode = 'EDIT') bpy.context.view_layer.update() - + dataCurve = context.active_object.data - + splines = context.active_object.data.splines - + select_spline = 0 - + sn = 0 for spline in splines: for bezier_points in spline.bezier_points: @@ -264,9 +264,9 @@ class RearrangeSpline(bpy.types.Operator): if point.select: select_spline = sn sn += 1 - + rearrange(dataCurve, select_spline, self.command) - + return {'FINISHED'} @classmethod diff --git a/curve_tools/util.py b/curve_tools/util.py index 30596697..110b8b83 100644 --- a/curve_tools/util.py +++ b/curve_tools/util.py @@ -12,8 +12,8 @@ def GetSelectedCurves(): pass return rvList - - + + def GetSelectedMeshes(): rvList = [] @@ -84,7 +84,7 @@ def Selected1OrMoreCurves(): pass return False - + def Selected2OrMoreCurves(): try: if len(GetSelectedCurves()) > 1: |