diff options
author | Spivak Vladimir (cwolf3d) <cwolf3d@gmail.com> | 2019-09-14 20:03:01 +0300 |
---|---|---|
committer | Spivak Vladimir (cwolf3d) <cwolf3d@gmail.com> | 2019-09-14 20:03:01 +0300 |
commit | f31572ecd2ef3b0cb08c175ed8343a97af01dc9c (patch) | |
tree | ce11da6c9ea469a1fed878b52c7a2357a9be2936 | |
parent | 3c3174056501789f3a0d0697c6b614ceae7f336c (diff) |
Curve Tools: many bugs fixed
-rw-r--r-- | curve_tools/Operators.py | 355 | ||||
-rw-r--r-- | curve_tools/PathFinder.py | 4 | ||||
-rw-r--r-- | curve_tools/Properties.py | 8 | ||||
-rw-r--r-- | curve_tools/ShowCurveResolution.py | 17 | ||||
-rw-r--r-- | curve_tools/__init__.py | 97 | ||||
-rw-r--r-- | curve_tools/auto_loft.py | 4 | ||||
-rw-r--r-- | curve_tools/cad.py | 36 |
7 files changed, 414 insertions, 107 deletions
diff --git a/curve_tools/Operators.py b/curve_tools/Operators.py index 6d7bd81d..c0101840 100644 --- a/curve_tools/Operators.py +++ b/curve_tools/Operators.py @@ -17,7 +17,7 @@ from . import Math # 1 CURVE SELECTED # ################ class OperatorCurveInfo(bpy.types.Operator): - bl_idname = "curvetools2.operatorcurveinfo" + bl_idname = "curvetools.operatorcurveinfo" bl_label = "Info" bl_description = "Displays general info about the active/selected curve" @@ -45,7 +45,7 @@ class OperatorCurveInfo(bpy.types.Operator): class OperatorCurveLength(bpy.types.Operator): - bl_idname = "curvetools2.operatorcurvelength" + bl_idname = "curvetools.operatorcurvelength" bl_label = "Length" bl_description = "Calculates the length of the active/selected curve" @@ -65,7 +65,7 @@ class OperatorCurveLength(bpy.types.Operator): class OperatorSplinesInfo(bpy.types.Operator): - bl_idname = "curvetools2.operatorsplinesinfo" + bl_idname = "curvetools.operatorsplinesinfo" bl_label = "Info" bl_description = "Displays general info about the splines of the active/selected curve" @@ -98,7 +98,7 @@ class OperatorSplinesInfo(bpy.types.Operator): class OperatorSegmentsInfo(bpy.types.Operator): - bl_idname = "curvetools2.operatorsegmentsinfo" + bl_idname = "curvetools.operatorsegmentsinfo" bl_label = "Info" bl_description = "Displays general info about the segments of the active/selected curve" @@ -139,7 +139,7 @@ class OperatorSegmentsInfo(bpy.types.Operator): class OperatorOriginToSpline0Start(bpy.types.Operator): - bl_idname = "curvetools2.operatororigintospline0start" + bl_idname = "curvetools.operatororigintospline0start" bl_label = "OriginToSpline0Start" bl_description = "Sets the origin of the active/selected curve to the starting point of the (first) spline. Nice for curve modifiers." @@ -150,19 +150,24 @@ 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 origOrigin = bpy.context.scene.cursor.location.copy() - print("--", "origOrigin: %.6f, %.6f, %.6f" % (origOrigin.x, origOrigin.y, origOrigin.z)) - print("--", "newOrigin: %.6f, %.6f, %.6f" % (newOrigin.x, newOrigin.y, newOrigin.z)) + self.report({'INFO'}, "origOrigin: %.6f, %.6f, %.6f" % (origOrigin.x, origOrigin.y, origOrigin.z)) + 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 - - self.report({'INFO'}, "TODO: OperatorOriginToSpline0Start") + + bpy.ops.object.mode_set (mode = current_mode) return {'FINISHED'} @@ -171,7 +176,7 @@ class OperatorOriginToSpline0Start(bpy.types.Operator): # 2 CURVES SELECTED # ################# class OperatorIntersectCurves(bpy.types.Operator): - bl_idname = "curvetools2.operatorintersectcurves" + bl_idname = "curvetools.operatorintersectcurves" bl_label = "Intersect" bl_description = "Intersects selected curves" @@ -218,9 +223,11 @@ class OperatorIntersectCurves(bpy.types.Operator): return {'FINISHED'} +# ------------------------------------------------------------ +# OperatorLoftCurves class OperatorLoftCurves(bpy.types.Operator): - bl_idname = "curvetools2.operatorloftcurves" + bl_idname = "curvetools.operatorloftcurves" bl_label = "Loft" bl_description = "Lofts selected curves" @@ -241,9 +248,11 @@ class OperatorLoftCurves(bpy.types.Operator): return {'FINISHED'} +# ------------------------------------------------------------ +# OperatorSweepCurves class OperatorSweepCurves(bpy.types.Operator): - bl_idname = "curvetools2.operatorsweepcurves" + bl_idname = "curvetools.operatorsweepcurves" bl_label = "Sweep" bl_description = "Sweeps the active curve along to other curve (rail)" @@ -268,7 +277,7 @@ class OperatorSweepCurves(bpy.types.Operator): # 3 CURVES SELECTED # ################# class OperatorBirail(bpy.types.Operator): - bl_idname = "curvetools2.operatorbirail" + bl_idname = "curvetools.operatorbirail" bl_label = "Birail" bl_description = "Generates a birailed surface from 3 selected curves -- in order: rail1, rail2 and profile" @@ -291,7 +300,7 @@ class OperatorBirail(bpy.types.Operator): # 1 OR MORE CURVES SELECTED # ######################### class OperatorSplinesSetResolution(bpy.types.Operator): - bl_idname = "curvetools2.operatorsplinessetresolution" + bl_idname = "curvetools.operatorsplinessetresolution" bl_label = "SplinesSetResolution" bl_description = "Sets the resolution of all splines" @@ -311,10 +320,11 @@ class OperatorSplinesSetResolution(bpy.types.Operator): return {'FINISHED'} - +# ------------------------------------------------------------ +# OperatorSplinesRemoveZeroSegment class OperatorSplinesRemoveZeroSegment(bpy.types.Operator): - bl_idname = "curvetools2.operatorsplinesremovezerosegment" + bl_idname = "curvetools.operatorsplinesremovezerosegment" bl_label = "SplinesRemoveZeroSegment" bl_description = "Removes splines with no segments -- they seem to creep up, sometimes.." @@ -344,10 +354,11 @@ class OperatorSplinesRemoveZeroSegment(bpy.types.Operator): return {'FINISHED'} - +# ------------------------------------------------------------ +# OperatorSplinesRemoveShort class OperatorSplinesRemoveShort(bpy.types.Operator): - bl_idname = "curvetools2.operatorsplinesremoveshort" + bl_idname = "curvetools.operatorsplinesremoveshort" bl_label = "SplinesRemoveShort" bl_description = "Removes splines with a length smaller than the threshold" @@ -372,10 +383,11 @@ class OperatorSplinesRemoveShort(bpy.types.Operator): return {'FINISHED'} - +# ------------------------------------------------------------ +# OperatorSplinesJoinNeighbouring class OperatorSplinesJoinNeighbouring(bpy.types.Operator): - bl_idname = "curvetools2.operatorsplinesjoinneighbouring" + bl_idname = "curvetools.operatorsplinesjoinneighbouring" bl_label = "SplinesJoinNeighbouring" bl_description = "Joins neighbouring splines within a distance smaller than the threshold" @@ -403,6 +415,9 @@ class OperatorSplinesJoinNeighbouring(bpy.types.Operator): return {'FINISHED'} +# ------------------------------------------------------------ +# SurfaceFromBezier + def SurfaceFromBezier(surfacedata, points, center): len_points = len(points) - 1 @@ -524,8 +539,11 @@ def SurfaceFromBezier(surfacedata, points, center): for p in s.points: p.select = False +# ------------------------------------------------------------ +# Convert selected faces to Bezier + class ConvertSelectedFacesToBezier(bpy.types.Operator): - bl_idname = "curvetools2.convert_selected_face_to_bezier" + bl_idname = "curvetools.convert_selected_face_to_bezier" bl_label = "Convert selected faces to Bezier" bl_description = "Convert selected faces to Bezier" bl_options = {'REGISTER', 'UNDO'} @@ -560,8 +578,11 @@ class ConvertSelectedFacesToBezier(bpy.types.Operator): return {'FINISHED'} +# ------------------------------------------------------------ +# Convert Bezier to Surface + class ConvertBezierToSurface(bpy.types.Operator): - bl_idname = "curvetools2.convert_bezier_to_surface" + bl_idname = "curvetools.convert_bezier_to_surface" bl_label = "Convert Bezier to Surface" bl_description = "Convert Bezier to Surface" bl_options = {'REGISTER', 'UNDO'} @@ -632,3 +653,293 @@ class ConvertBezierToSurface(bpy.types.Operator): surfacedata.resolution_v = self.Resolution_V return {'FINISHED'} + +# ------------------------------------------------------------ +# Fillet + +class BezierPointsFillet(bpy.types.Operator): + bl_idname = "curvetools.bezier_points_fillet" + bl_label = "Bezier points Fillet" + bl_description = "Bezier points Fillet" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + Fillet_radius : FloatProperty( + name="Radius", + default=0.25, + unit='LENGTH', + description="Radius" + ) + Types = [('Round', "Round", "Round"), + ('Chamfer', "Chamfer", "Chamfer")] + Fillet_Type : EnumProperty( + name="Type", + description="Fillet type", + items=Types + ) + + def draw(self, context): + layout = self.layout + + # general options + col = layout.column() + col.prop(self, "Fillet_radius") + col.prop(self, "Fillet_Type", expand=True) + + @classmethod + def poll(cls, context): + return (context.object is not None and + context.object.type == 'CURVE') + + def execute(self, context): + # 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: + n = 0 + ii = [] + for p in spline.bezier_points: + if p.select_control_point: + ii.append(n) + n += 1 + else: + n += 1 + s.append(ii) + + sn = 0 + for spline in splines: + ii = s[sn] + n = len(spline.bezier_points) + if n > 2: + jn = 0 + for j in ii: + + j += jn + + selected_all = [p for p in spline.bezier_points] + + bpy.ops.curve.select_all(action='DESELECT') + + if j != 0 and j != n - 1: + selected_all[j].select_control_point = True + selected_all[j + 1].select_control_point = True + bpy.ops.curve.subdivide() + selected_all = [p for p in spline.bezier_points] + selected4 = [selected_all[j - 1], selected_all[j], + selected_all[j + 1], selected_all[j + 2]] + jn += 1 + n += 1 + + elif j == 0: + selected_all[j].select_control_point = True + selected_all[j + 1].select_control_point = True + bpy.ops.curve.subdivide() + selected_all = [p for p in spline.bezier_points] + selected4 = [selected_all[n], selected_all[0], + selected_all[1], selected_all[2]] + jn += 1 + n += 1 + + elif j == n - 1: + selected_all[j].select_control_point = True + selected_all[j - 1].select_control_point = True + bpy.ops.curve.subdivide() + selected_all = [p for p in spline.bezier_points] + selected4 = [selected_all[0], selected_all[n], + selected_all[n - 1], selected_all[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) + s1.normalize() + s11 = Vector(selected4[1].co) + s1 * self.Fillet_radius + selected4[1].co = s11 + 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' + selected4[1].handle_left_type = 'VECTOR' + selected4[1].handle_right_type = 'ALIGNED' + selected4[2].handle_left_type = 'ALIGNED' + else: + selected4[1].handle_right_type = 'VECTOR' + selected4[2].handle_left_type = 'VECTOR' + selected4[2].handle_right_type = 'ALIGNED' + selected4[1].handle_left_type = 'ALIGNED' + if self.Fillet_Type == 'Chamfer': + selected4[2].handle_right_type = 'VECTOR' + selected4[1].handle_left_type = 'VECTOR' + selected4[1].handle_right_type = 'VECTOR' + selected4[2].handle_left_type = 'VECTOR' + sn += 1 + + return {'FINISHED'} + +# ------------------------------------------------------------ +# BezierDivide Operator + +class BezierDivide(bpy.types.Operator): + bl_idname = "curvetools.bezier_spline_divide" + bl_label = "Bezier Spline Divide" + bl_description = "Bezier Divide (enters edit mode) for Fillet Curves" + bl_options = {'REGISTER', 'UNDO'} + + # align_matrix for the invoke + align_matrix : Matrix() + + Bezier_t : FloatProperty( + name="t (0% - 100%)", + default=50.0, + min=0.0, soft_min=0.0, + max=100.0, soft_max=100.0, + description="t (0% - 100%)" + ) + + @classmethod + def poll(cls, context): + return (context.object is not None and + context.object.type == 'CURVE') + + def execute(self, context): + # main function + if bpy.ops.object.mode_set.poll(): + bpy.ops.object.mode_set(mode='EDIT') + + splines = bpy.context.object.data.splines + s = [] + for spline in splines: + bpy.ops.curve.spline_type_set(type='BEZIER') + + n = 0 + ii = [] + for p in spline.bezier_points: + if p.select_control_point: + ii.append(n) + n += 1 + else: + n += 1 + s.append(ii) + + sn = 0 + for spline in splines: + ii = s[sn] + n = len(spline.bezier_points) + if n > 2: + jn = 0 + for j in ii: + + selected_all = [p for p in spline.bezier_points] + + bpy.ops.curve.select_all(action='DESELECT') + + if (j in ii) and (j + 1 in ii): + selected_all[j + jn].select_control_point = True + selected_all[j + 1 + jn].select_control_point = True + h = Math.subdivide_cubic_bezier( + selected_all[j + jn].co, selected_all[j + jn].handle_right, + selected_all[j + 1 + jn].handle_left, selected_all[j + 1 + jn].co, self.Bezier_t / 100 + ) + bpy.ops.curve.subdivide(1) + selected_all = [p for p in spline.bezier_points] + selected_all[j + jn].handle_right_type = 'FREE' + selected_all[j + jn].handle_right = h[0] + selected_all[j + 1 + jn].co = h[2] + selected_all[j + 1 + jn].handle_left_type = 'FREE' + selected_all[j + 1 + jn].handle_left = h[1] + selected_all[j + 1 + jn].handle_right_type = 'FREE' + selected_all[j + 1 + jn].handle_right = h[3] + selected_all[j + 2 + jn].handle_left_type = 'FREE' + selected_all[j + 2 + jn].handle_left = h[4] + jn += 1 + + if j == n - 1 and (0 in ii) and spline.use_cyclic_u: + selected_all[j + jn].select_control_point = True + selected_all[0].select_control_point = True + h = Math.subdivide_cubic_bezier( + selected_all[j + jn].co, selected_all[j + jn].handle_right, + selected_all[0].handle_left, selected_all[0].co, self.Bezier_t / 100 + ) + bpy.ops.curve.subdivide(1) + selected_all = [p for p in spline.bezier_points] + selected_all[j + jn].handle_right_type = 'FREE' + selected_all[j + jn].handle_right = h[0] + selected_all[j + 1 + jn].co = h[2] + selected_all[j + 1 + jn].handle_left_type = 'FREE' + selected_all[j + 1 + jn].handle_left = h[1] + selected_all[j + 1 + jn].handle_right_type = 'FREE' + selected_all[j + 1 + jn].handle_right = h[3] + selected_all[0].handle_left_type = 'FREE' + selected_all[0].handle_left = h[4] + + sn += 1 + + return {'FINISHED'} + +# ------------------------------------------------------------ +# CurveScaleReset Operator + +class CurveScaleReset(bpy.types.Operator): + bl_idname = "curvetools.scale_reset" + bl_label = "Curve Scale Reset" + bl_description = "Curve Scale Reset" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return (context.object is not None and + context.object.type == 'CURVE') + + 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'} + +operators = [ + OperatorCurveInfo, + OperatorCurveLength, + OperatorSplinesInfo, + OperatorSegmentsInfo, + OperatorOriginToSpline0Start, + OperatorIntersectCurves, + OperatorLoftCurves, + OperatorSweepCurves, + OperatorBirail, + OperatorSplinesSetResolution, + OperatorSplinesRemoveZeroSegment, + OperatorSplinesRemoveShort, + OperatorSplinesJoinNeighbouring, + ConvertSelectedFacesToBezier, + ConvertBezierToSurface, + BezierPointsFillet, + BezierDivide, + CurveScaleReset, + ] diff --git a/curve_tools/PathFinder.py b/curve_tools/PathFinder.py index adc76cba..2f661382 100644 --- a/curve_tools/PathFinder.py +++ b/curve_tools/PathFinder.py @@ -228,7 +228,7 @@ def click(self, context, event): point.select = True class PathFinder(bpy.types.Operator): - bl_idname = "curvetools2.pathfinder" + bl_idname = "curvetools.pathfinder" bl_label = "Path Finder" bl_description = "Path Finder" bl_options = {'REGISTER', 'UNDO'} @@ -322,4 +322,4 @@ def unregister(): bpy.utils.unregister_class(PathFinder) if __name__ == "__main__": - register()
\ No newline at end of file + register() diff --git a/curve_tools/Properties.py b/curve_tools/Properties.py index 37cf72cc..415b3c8b 100644 --- a/curve_tools/Properties.py +++ b/curve_tools/Properties.py @@ -5,7 +5,7 @@ from bpy.props import * -class CurveTools2SelectedObjectHeader(bpy.types.Header): +class curvetoolsSelectedObjectHeader(bpy.types.Header): bl_label = "Selection" bl_space_type = "VIEW_3D" @@ -24,9 +24,9 @@ class CurveTools2SelectedObjectHeader(bpy.types.Header): blenderObjectsToAdd = [] for blenderObject in blenderSelectedObjects: - if not CurveTools2SelectedObject.ListContains(selectedObjects, blenderObject): blenderObjectsToAdd.append(blenderObject) + if not curvetoolsSelectedObject.ListContains(selectedObjects, blenderObject): blenderObjectsToAdd.append(blenderObject) for blenderObject in blenderObjectsToAdd: - newSelectedObject = CurveTools2SelectedObject(blenderObject) + newSelectedObject = curvetoolsSelectedObject(blenderObject) selectedObjects.append(newSelectedObject) @@ -39,7 +39,7 @@ class CurveTools2SelectedObjectHeader(bpy.types.Header): row.label(text="Sel: " + str(nrSelectedObjects)) -class CurveTools2SelectedObject(bpy.types.PropertyGroup): +class curvetoolsSelectedObject(bpy.types.PropertyGroup): name: StringProperty(name = "name", default = "??") diff --git a/curve_tools/ShowCurveResolution.py b/curve_tools/ShowCurveResolution.py index d6fc9c22..97cf310e 100644 --- a/curve_tools/ShowCurveResolution.py +++ b/curve_tools/ShowCurveResolution.py @@ -39,7 +39,7 @@ from bpy_extras.view3d_utils import location_3d_to_region_2d as loc3d2d -def get_points(spline): +def get_points(spline, matrix_world): bezier_points = spline.bezier_points @@ -56,10 +56,10 @@ def get_points(spline): for i in range(segments): inext = (i + 1) % len(bezier_points) - bezier_points1 = bezier_points[i].co - handle1 = bezier_points[i].handle_right - handle2 = bezier_points[inext].handle_left - bezier_points2 = bezier_points[inext].co + 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) @@ -67,9 +67,9 @@ def get_points(spline): return point_list -def draw(self, context, spline, curve_vertcolor): +def draw(self, context, spline, curve_vertcolor, matrix_world): - points = get_points(spline) + points = get_points(spline, matrix_world) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = batch_for_shader(shader, 'POINTS', {"pos": points}) @@ -113,8 +113,9 @@ class ShowCurveResolution(bpy.types.Operator): splines = context.active_object.data.splines + matrix_world = context.active_object.matrix_world for spline in splines: - args = (self, context, spline, curve_vertcolor) + args = (self, context, spline, curve_vertcolor, matrix_world) # Add the region OpenGL drawing callback # draw in view space with 'POST_VIEW' and 'PRE_VIEW' diff --git a/curve_tools/__init__.py b/curve_tools/__init__.py index 09b1c410..2a5abf5b 100644 --- a/curve_tools/__init__.py +++ b/curve_tools/__init__.py @@ -22,7 +22,7 @@ bl_info = { - "name": "Curve Tools 2", + "name": "Curve Tools", "description": "Adds some functionality for bezier/nurbs curve/surface modeling", "author": "Mackraken", "version": (0, 3, 3), @@ -54,7 +54,6 @@ from . import Properties from . import Operators from . import auto_loft from . import curve_outline -from . import curve_remove_doubles from . import PathFinder from . import ShowCurveResolution from . import internal, cad, toolpath, exports @@ -99,10 +98,10 @@ class SeparateOutline(Operator): return {'FINISHED'} -class CurveTools2Settings(PropertyGroup): +class curvetoolsSettings(PropertyGroup): # selection SelectedObjects: CollectionProperty( - type=Properties.CurveTools2SelectedObject + type=Properties.curvetoolsSelectedObject ) NrSelectedObjects: IntProperty( name="NrSelectedObjects", @@ -224,7 +223,7 @@ class CurveTools2Settings(PropertyGroup): class VIEW3D_PT_CurvePanel(Panel): - bl_label = "Curve Tools 2" + bl_label = "Curve Tools" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_options = {'DEFAULT_CLOSED'} @@ -254,22 +253,22 @@ class VIEW3D_PT_CurvePanel(Panel): row = col.row(align=True) # A.1 curve info/length - row.operator("curvetools2.operatorcurveinfo", text="Curve info") + row.operator("curvetools.operatorcurveinfo", text="Curve info") row = col.row(align=True) - row.operator("curvetools2.operatorcurvelength", text="Calc Length") + row.operator("curvetools.operatorcurvelength", text="Calc Length") row.prop(context.scene.curvetools, "CurveLength", text="") # A.2 splines info row = col.row(align=True) - row.operator("curvetools2.operatorsplinesinfo", text="Curve splines info") + row.operator("curvetools.operatorsplinesinfo", text="Curve splines info") # A.3 segments info row = col.row(align=True) - row.operator("curvetools2.operatorsegmentsinfo", text="Curve segments info") + row.operator("curvetools.operatorsegmentsinfo", text="Curve segments info") # A.4 origin to spline0start row = col.row(align=True) - row.operator("curvetools2.operatororigintospline0start", text="Set origin to spline start") + row.operator("curvetools.operatororigintospline0start", text="Set origin to spline start") # Double Curve options box2 = self.layout.box() @@ -283,7 +282,7 @@ class VIEW3D_PT_CurvePanel(Panel): # B.1 curve intersections row = col.row(align=True) - row.operator("curvetools2.operatorintersectcurves", text="Intersect curves") + row.operator("curvetools.operatorintersectcurves", text="Intersect curves") row = col.row(align=True) row.prop(context.scene.curvetools, "LimitDistance", text="LimitDistance") @@ -309,13 +308,13 @@ class VIEW3D_PT_CurvePanel(Panel): wm = context.window_manager scene = context.scene layout = self.layout - layout.operator("curvetools2.create_auto_loft") + layout.operator("curvetools.create_auto_loft") lofters = [o for o in scene.objects if "autoloft" in o.keys()] for o in lofters: layout.label(text=o.name) # layout.prop(o, '["autoloft"]', toggle=True) layout.prop(wm, "auto_loft", toggle=True) - layout.operator("curvetools2.update_auto_loft_curves") + layout.operator("curvetools.update_auto_loft_curves") # Advanced options box1 = self.layout.box() @@ -327,21 +326,19 @@ class VIEW3D_PT_CurvePanel(Panel): row = col.row(align=True) row.operator("object._curve_outline", text="Curve Outline") row = col.row(align=True) - row.operator("object.sep_outline", text="Separate Outline") + row.operator("object.sep_outline", text="Separate Outline or selected") row = col.row(align=True) - row.operator("curve.remove_doubles", text="Remove Doubles") + row.operator("curvetools.bezier_points_fillet", text='Fillet') row = col.row(align=True) - row.operator("curve.bezier_points_fillet", text='Fillet') + row.operator("curvetools.bezier_spline_divide", text='Divide') row = col.row(align=True) - row.operator("curve.bezier_spline_divide", text='Divide') + row.operator("curvetools.scale_reset", text='Scale Reset') row = col.row(align=True) - row.operator("curve.scale_reset", text='Scale Reset') - row = col.row(align=True) - row.operator("curvetools2.operatorbirail", text="Birail") + row.operator("curvetools.operatorbirail", text="Birail") row = col.row(align=True) - row.operator("curvetools2.convert_selected_face_to_bezier", text="Convert selected faces to Bezier") + row.operator("curvetools.convert_selected_face_to_bezier", text="Convert selected faces to Bezier") row = col.row(align=True) - row.operator("curvetools2.convert_bezier_to_surface", text="Convert Bezier to Surface") + row.operator("curvetools.convert_bezier_to_surface", text="Convert Bezier to Surface") # Extended options box1 = self.layout.box() @@ -349,13 +346,16 @@ class VIEW3D_PT_CurvePanel(Panel): row = col.row(align=True) row.prop(scene, "UTExtendedDrop", icon="TRIA_DOWN") if EXTENDEDDROP: - for operator in cad.operators: - row = col.row(align=True) - row.operator(operator.bl_idname) - - for operator in toolpath.operators: - row = col.row(align=True) - row.operator(operator.bl_idname) + row = col.row(align=True) + row.operator("curve.add_toolpath_offset_curve", text="Offset Curve") + row = col.row(align=True) + row.operator("curve.bezier_cad_boolean", text="Boolean 2 selected spline") + row = col.row(align=True) + row.operator("curve.bezier_cad_subdivide", text="Multi Subdivide") + row = col.row(align=True) + row.operator("curve.add_toolpath_discretize_curve", text="Discretize Curve") + row = col.row(align=True) + row.operator("curve.bezier_cad_array", text="Array selected spline") # Utils Curve options box1 = self.layout.box() @@ -367,7 +367,7 @@ class VIEW3D_PT_CurvePanel(Panel): row = col.row(align=True) row.label(text="Show point Resolution:") row = col.row(align=True) - row.operator("curvetools2.operatorsplinessetresolution", text="Set resolution") + row.operator("curvetools.operatorsplinessetresolution", text="Set resolution") row.prop(context.scene.curvetools, "SplineResolution", text="") row = col.row(align=True) row.prop(context.scene.curvetools, "curve_vertcolor", text="") @@ -378,9 +378,9 @@ class VIEW3D_PT_CurvePanel(Panel): row = col.row(align=True) row.label(text="Remove splines:") row = col.row(align=True) - row.operator("curvetools2.operatorsplinesremovezerosegment", text="Remove 0-segments splines") + row.operator("curvetools.operatorsplinesremovezerosegment", text="Remove 0-segments splines") row = col.row(align=True) - row.operator("curvetools2.operatorsplinesremoveshort", text="Remove short splines") + row.operator("curvetools.operatorsplinesremoveshort", text="Remove short splines") row = col.row(align=True) row.prop(context.scene.curvetools, "SplineRemoveLength", text="Threshold remove") @@ -388,7 +388,7 @@ class VIEW3D_PT_CurvePanel(Panel): row = col.row(align=True) row.label(text="Join splines:") row = col.row(align=True) - row.operator("curvetools2.operatorsplinesjoinneighbouring", text="Join neighbouring splines") + row.operator("curvetools.operatorsplinesjoinneighbouring", text="Join neighbouring splines") row = col.row(align=True) row.prop(context.scene.curvetools, "SplineJoinDistance", text="Threshold join") row = col.row(align=True) @@ -404,7 +404,7 @@ class VIEW3D_PT_CurvePanel(Panel): row.prop(context.scene.curvetools, "path_color", text="") row.prop(context.scene.curvetools, "path_thickness", text="") row = col.row(align=True) - row.operator("curvetools2.pathfinder", text="Run Path Finder [ESC]") + row.operator("curvetools.pathfinder", text="Run Path Finder [ESC]") row = col.row(align=True) row.label(text="ESC or TAB - exit from PathFinder") row = col.row(align=True) @@ -424,7 +424,7 @@ panels = ( def update_panel(self, context): - message = "Curve Tools 2: Updating Panel locations has failed" + message = "Curve Tools: Updating Panel locations has failed" try: for panel in panels: if "bl_rna" in panel.__dict__: @@ -468,26 +468,11 @@ def menu_file_import(self, context): self.layout.operator(operator.bl_idname) # REGISTER -classes = cad.operators + toolpath.operators + exports.operators + [ - Properties.CurveTools2SelectedObject, +classes = cad.operators + toolpath.operators + exports.operators + Operators.operators + [ + Properties.curvetoolsSelectedObject, CurveAddonPreferences, - CurveTools2Settings, - Operators.OperatorCurveInfo, - Operators.OperatorCurveLength, - Operators.OperatorSplinesInfo, - Operators.OperatorSegmentsInfo, - Operators.OperatorOriginToSpline0Start, - Operators.OperatorIntersectCurves, - Operators.OperatorLoftCurves, - Operators.OperatorSweepCurves, - Operators.OperatorBirail, - Operators.OperatorSplinesSetResolution, - Operators.OperatorSplinesRemoveZeroSegment, - Operators.OperatorSplinesRemoveShort, - Operators.OperatorSplinesJoinNeighbouring, + curvetoolsSettings, SeparateOutline, - Operators.ConvertSelectedFacesToBezier, - Operators.ConvertBezierToSurface, PathFinder.PathFinder, ShowCurveResolution.ShowCurveResolution, ] @@ -534,11 +519,9 @@ def register(): curve_outline.register() - curve_remove_doubles.register() - bpy.types.TOPBAR_MT_file_export.append(menu_file_export) - bpy.types.Scene.curvetools = bpy.props.PointerProperty(type=CurveTools2Settings) + bpy.types.Scene.curvetools = bpy.props.PointerProperty(type=curvetoolsSettings) update_panel(None, bpy.context) @@ -555,8 +538,6 @@ def unregister(): curve_outline.unregister() - curve_remove_doubles.unregister() - bpy.types.TOPBAR_MT_file_export.remove(menu_file_export) for panel in panels: diff --git a/curve_tools/auto_loft.py b/curve_tools/auto_loft.py index 8cb89245..6675aaf1 100644 --- a/curve_tools/auto_loft.py +++ b/curve_tools/auto_loft.py @@ -7,7 +7,7 @@ from curve_tools import Util class OperatorAutoLoftCurves(Operator): - bl_idname = "curvetools2.create_auto_loft" + bl_idname = "curvetools.create_auto_loft" bl_label = "Loft" bl_description = "Lofts selected curves" @@ -44,7 +44,7 @@ class OperatorAutoLoftCurves(Operator): class AutoLoftModalOperator(Operator): """Auto Loft""" - bl_idname = "curvetools2.update_auto_loft_curves" + bl_idname = "curvetools.update_auto_loft_curves" bl_label = "Update Auto Loft" bl_description = "Update Lofts selected curves" diff --git a/curve_tools/cad.py b/curve_tools/cad.py index e518875e..c71bd46d 100644 --- a/curve_tools/cad.py +++ b/curve_tools/cad.py @@ -28,6 +28,7 @@ bl_info = { import bpy from . import internal +from . import Util class Fillet(bpy.types.Operator): bl_idname = 'curve.bezier_cad_fillet' @@ -40,7 +41,7 @@ class Fillet(bpy.types.Operator): @classmethod def poll(cls, context): - return internal.curveObject() + return Util.Selected1OrMoreCurves() def execute(self, context): splines = internal.getSelectedSplines(True, True, True) @@ -65,22 +66,29 @@ class Boolean(bpy.types.Operator): @classmethod def poll(cls, context): - return internal.curveObject() + return Util.Selected1OrMoreCurves() 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'} splines = internal.getSelectedSplines(True, True) if len(splines) != 2: - self.report({'WARNING'}, 'Invalid selection') + self.report({'WARNING'}, 'Invalid selection. Only work to selected two spline.') return {'CANCELLED'} bpy.ops.curve.spline_type_set(type='BEZIER') splineA = bpy.context.object.data.splines.active splineB = splines[0] if (splines[1] == splineA) else splines[1] if not internal.bezierBooleanGeometry(splineA, splineB, self.operation): - self.report({'WARNING'}, 'Invalid selection') + 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): @@ -90,7 +98,7 @@ class Intersection(bpy.types.Operator): @classmethod def poll(cls, context): - return internal.curveObject() + return Util.Selected1OrMoreCurves() def execute(self, context): segments = internal.bezierSegments(bpy.context.object.data.splines, True) @@ -108,7 +116,7 @@ class MergeEnds(bpy.types.Operator): @classmethod def poll(cls, context): - return internal.curveObject() + return Util.Selected1OrMoreCurves() def execute(self, context): points = [] @@ -161,9 +169,13 @@ class Subdivide(bpy.types.Operator): @classmethod def poll(cls, context): - return internal.curveObject() + return Util.Selected1OrMoreCurves() 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) if len(segments) == 0: self.report({'WARNING'}, 'Nothing selected') @@ -176,6 +188,8 @@ 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'} class Array(bpy.types.Operator): @@ -183,14 +197,14 @@ class Array(bpy.types.Operator): bl_description = bl_label = 'Array' bl_options = {'REGISTER', 'UNDO'} - offset: bpy.props.FloatVectorProperty(name='Offset', unit='LENGTH', description='Vector between to copies', subtype='DIRECTION', default=(0.0, 0.0, -1.0), size=3) + offset: bpy.props.FloatVectorProperty(name='Offset', unit='LENGTH', description='Vector between to copies', subtype='DIRECTION', default=(1.0, 0.0, 0.0), size=3) count: bpy.props.IntProperty(name='Count', description='Number of copies', min=1, default=2) connect: bpy.props.BoolProperty(name='Connect', description='Concatenate individual copies', default=False) serpentine: bpy.props.BoolProperty(name='Serpentine', description='Switch direction of every second copy', default=False) @classmethod def poll(cls, context): - return internal.curveObject() + return Util.Selected1OrMoreCurves() def execute(self, context): splines = internal.getSelectedSplines(True, True) @@ -207,7 +221,7 @@ class Circle(bpy.types.Operator): @classmethod def poll(cls, context): - return internal.curveObject() + return Util.Selected1OrMoreCurves() def execute(self, context): segments = internal.bezierSegments(bpy.context.object.data.splines, True) @@ -231,7 +245,7 @@ class Length(bpy.types.Operator): @classmethod def poll(cls, context): - return internal.curveObject() + return Util.Selected1OrMoreCurves() def execute(self, context): segments = internal.bezierSegments(bpy.context.object.data.splines, True) |