diff options
author | Spivak Vladimir (cwolf3d) <cwolf3d@gmail.com> | 2019-10-30 12:18:10 +0300 |
---|---|---|
committer | Spivak Vladimir (cwolf3d) <cwolf3d@gmail.com> | 2019-10-30 12:18:10 +0300 |
commit | b6751d4d0390257a4352d449991407065cc29124 (patch) | |
tree | 6ea1e12cdc1734c99830b2155b374496758ce27d /curve_tools | |
parent | acfe2a22e07046564cc5788388c2404486c76fe9 (diff) |
Addon: Curve Tools: Add 2D Curve Boolean. Fixed some errors.
Diffstat (limited to 'curve_tools')
-rw-r--r-- | curve_tools/__init__.py | 2 | ||||
-rw-r--r-- | curve_tools/cad.py | 12 | ||||
-rw-r--r-- | curve_tools/operators.py | 96 | ||||
-rw-r--r-- | curve_tools/path_finder.py | 4 | ||||
-rw-r--r-- | curve_tools/remove_doubles.py | 2 |
5 files changed, 107 insertions, 9 deletions
diff --git a/curve_tools/__init__.py b/curve_tools/__init__.py index 6e60b7b8..bc646780 100644 --- a/curve_tools/__init__.py +++ b/curve_tools/__init__.py @@ -334,6 +334,8 @@ class VIEW3D_PT_CurvePanel(Panel): row = col.row(align=True) row.operator("curvetools.sep_outline", text="Separate Outline or selected") row = col.row(align=True) + row.operator("curvetools.bezier_curve_boolean", text="2D Curve Boolean") + row = col.row(align=True) row.operator("curvetools.bezier_points_fillet", text='Fillet') row = col.row(align=True) row.operator("curvetools.bezier_cad_handle_projection", text='Handle Projection') diff --git a/curve_tools/cad.py b/curve_tools/cad.py index 49ccf171..b7478450 100644 --- a/curve_tools/cad.py +++ b/curve_tools/cad.py @@ -66,7 +66,7 @@ class Boolean(bpy.types.Operator): @classmethod def poll(cls, context): - return util.Selected1OrMoreCurves() + return util.Selected1Curve() def execute(self, context): current_mode = bpy.context.object.mode @@ -80,7 +80,7 @@ class Boolean(bpy.types.Operator): if len(splines) != 2: self.report({'WARNING'}, 'Invalid selection. Only work to selected two spline.') return {'CANCELLED'} - bpy.ops.curvetools.spline_type_set(type='BEZIER') + 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): @@ -169,13 +169,13 @@ class MergeEnds(bpy.types.Operator): points[0].handle_left = handle points[0].co = new_co - bpy.ops.curvetools.select_all(action='DESELECT') + bpy.ops.curve.select_all(action='DESELECT') points[1].select_control_point = True - bpy.ops.curvetools.delete() + bpy.ops.curve.delete() selected_splines[0].bezier_points[-1 if is_last_point[0] else 0].select_control_point = True selected_splines[1].bezier_points[-1 if is_last_point[1] else 0].select_control_point = True - bpy.ops.curvetools.make_segment() - bpy.ops.curvetools.select_all(action='DESELECT') + bpy.ops.curve.make_segment() + bpy.ops.curve.select_all(action='DESELECT') return {'FINISHED'} class Subdivide(bpy.types.Operator): diff --git a/curve_tools/operators.py b/curve_tools/operators.py index e4fe24dd..099b57bb 100644 --- a/curve_tools/operators.py +++ b/curve_tools/operators.py @@ -13,6 +13,7 @@ from . import intersections from . import util from . import surfaces from . import mathematics +from . import internal # 1 CURVE SELECTED # ################ @@ -1020,6 +1021,100 @@ 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" + bl_label = "Curve Boolean" + bl_options = {'REGISTER', 'UNDO'} + + operation: bpy.props.EnumProperty(name='Type', items=[ + ('UNION', 'Union', 'Boolean OR', 0), + ('INTERSECTION', 'Intersection', 'Boolean AND', 1), + ('DIFFERENCE AB', 'Difference AB', 'Active minus Selected', 2), + ('DIFFERENCE BA', 'Difference BA', 'Selected minus Active', 3), + ]) + + @classmethod + def poll(cls, context): + return util.Selected1OrMoreCurves() + + 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) + + bpy.ops.object.select_all(action='DESELECT') + + if len_selected_curves < 2: + return {'FINISHED'} + + spline1 = selected_Curves[0].data.splines[0] + matrix_world1 = selected_Curves[0].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') + newSpline1.use_cyclic_u = True + newSpline1.bezier_points.add(len_spline1 - 1) + for n in range(0, len_spline1): + newSpline1.bezier_points[n].co = matrix_world1 @ spline1.bezier_points[n].co + newSpline1.bezier_points[n].handle_left_type = spline1.bezier_points[n].handle_left_type + 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) + + for iCurve in range(0, len_selected_curves): + matrix_world = selected_Curves[iCurve].matrix_world + len_splines = len(selected_Curves[iCurve].data.splines) + first = 0 + if iCurve == 0: + first = 1 + for ispline in range(first, len_splines): + spline = selected_Curves[iCurve].data.splines[ispline] + len_spline = len(spline.bezier_points) + newSpline = dataCurve.splines.new(type='BEZIER') + newSpline.use_cyclic_u = True + newSpline.bezier_points.add(len_spline - 1) + for n in range(0, len_spline): + newSpline.bezier_points[n].co = matrix_world @ spline.bezier_points[n].co + newSpline.bezier_points[n].handle_left_type = spline.bezier_points[n].handle_left_type + 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) + splineA = splines[0] + splineB = splines[1] + operation = self.operation + dataCurve.splines.active = newSpline1 + if self.operation == 'DIFFERENCE AB': + operation = 'DIFFERENCE' + if self.operation == 'DIFFERENCE BA': + dataCurve.splines.active = newSpline + operation = 'DIFFERENCE' + splineA = splines[1] + splineB = splines[0] + + if not internal.bezierBooleanGeometry(splineA, splineB, operation): + self.report({'WARNING'}, 'Invalid selection.') + return {'CANCELLED'} + + bpy.ops.object.mode_set (mode = current_mode) + + return {'FINISHED'} def register(): for cls in classes: @@ -1053,4 +1148,5 @@ operators = [ CurveScaleReset, Split, SeparateOutline, + CurveBoolean, ] diff --git a/curve_tools/path_finder.py b/curve_tools/path_finder.py index 366f9bcc..30c673e0 100644 --- a/curve_tools/path_finder.py +++ b/curve_tools/path_finder.py @@ -96,7 +96,7 @@ def draw_bezier_points(self, context, spline, matrix_world, path_color, path_thi points = get_bezier_points(spline, matrix_world) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') - batch = batch_for_shader(shader, 'LINES', {"pos": points}) + batch = batch_for_shader(shader, 'POINTS', {"pos": points}) shader.bind() shader.uniform_float("color", path_color) @@ -109,7 +109,7 @@ 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, 'LINES', {"pos": points}) + batch = batch_for_shader(shader, 'POINTS', {"pos": points}) shader.bind() shader.uniform_float("color", path_color) diff --git a/curve_tools/remove_doubles.py b/curve_tools/remove_doubles.py index 151b19b0..cf955980 100644 --- a/curve_tools/remove_doubles.py +++ b/curve_tools/remove_doubles.py @@ -109,7 +109,7 @@ class CurveRemvDbs(bpy.types.Operator): @classmethod def poll(cls, context): - return util.Selected1Curve() + return util.Selected1OrMoreCurves() def execute(self, context): removed=main(context, self.distance) |