From ff35f5c7f45221da74d74ed0a242a080d531fdcf Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Sun, 13 Jun 2021 13:19:36 +0200 Subject: [PATCH 01/13] allow vertex selections or faces --- tt_operators.py | 83 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index c400500..784aed5 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -22,8 +22,7 @@ def are_two_objects_in_editmode(objs): current_mode = {} -docstring = """\ -select two polygons only, then run this operator. polygons can be on separate objects.""" +docstring = """select two verts or polygons only, then run this operator. selections can be on separate objects.""" class TubeCallbackOps(bpy.types.Operator): @@ -131,6 +130,44 @@ def get_medians_and_normals(oper, context, mode): op2_scale = scale2 / bevel_depth extra_data = bevel_depth, scale2, op2_scale + elif mode == "THREE": + # single object, two verts + obj_main = bpy.context.edit_object + me = obj_main.data + bm = bmesh.from_edit_mesh(me) + verts = [] + for v in bm.verts: + if len(medians) > 2: + break + verts.append(v) + normals.append(v.normal) + medians.append(v.co) + + bevel_depth = ... # (medians[0] - first_coords[0]).length + scale2 = ... # (medians[1] - first_coords[1]).length + op2_scale = scale2 / bevel_depth + extra_data = bevel_depth, scale2, op2_scale + + elif mode == "FOUR": + # two objects, single vert each + obj_one = bpy.context.selected_objects[0] + obj_two = bpy.context.selected_objects[1] + verts = [] + objs = [obj_two, obj_one] if oper.flip_u else [obj_one, obj_two] + for obj in objs: + m = obj.matrix_world + bm = bmesh.from_edit_mesh(obj.data) + + verts.append(v) + normals.append(...) + medians.append(...) + + bevel_depth = ... # (medians[0] - first_coords[0]).length + scale2 = ... # (medians[1] - first_coords[1]).length + op2_scale = scale2 / bevel_depth + extra_data = bevel_depth, scale2, op2_scale + + return medians, normals, extra_data @@ -300,44 +337,50 @@ def prop_n_reset(split, pname, pstr, default, enabled=True): k.fn = 'To Mesh' k.current_name = self.generated_name - # k = col.operator(callback, text="Join") - # k.fn = 'Join' - # k.current_name = self.generated_name - def initialize_new_tube(self, context): - ''' + + """ - create curve - assign default values - add to scene - record given name - ''' + """ + scn = bpy.context.scene obj_main = bpy.context.edit_object objects_main = bpy.context.selected_objects if are_two_objects_in_editmode(bpy.context.selected_objects) else None self_id = hash(self) - current_mode[self_id] = None if obj_main and not objects_main: - if not (obj_main.data.total_face_sel == 2): + # if face mode and single object + if (obj_main.data.total_face_sel == 2): + mw = obj_main.matrix_world + current_mode[self_id] = "ONE" + elif (obj_main.data.total_vert_sel == 2): + mw = obj_main.matrix_world + current_mode[self_id] = "THREE" + else: self.do_not_process = True - self.report({'WARNING'}, 'if only one object is selected, then select two faces only') + self.report({'WARNING'}, 'if only one object is selected, then select two faces or verts only') return - current_mode[self_id] = "ONE" - mw = obj_main.matrix_world + elif objects_main: - if not all((obj.data.total_face_sel == 1) for obj in objects_main): + + if all((obj.data.total_face_sel == 1) for obj in objects_main): + current_mode[self_id] = "TWO" + elif all((obj.data.total_vert_sel == 1) for obj in objects_main): + current_mode[self_id] = "FOUR" + else: self.do_not_process = True self.report({'WARNING'}, 'if two objects are selected, then select one face on each object') return - current_mode[self_id] = "TWO" else: - self.report({'WARNING'}, 'if one object in edit mode, pick 2 faces only. if two objects in edit mode, pick 1 face on each.') + msg = 'if one object in edit mode, pick 2 faces/verts only. if two objects in edit mode, pick 1 face/vertex on each.' + self.report({'WARNING'}, msg) return - - curvedata = bpy.data.curves.new(name=self.base_name, type='CURVE') curvedata.dimensions = '3D' @@ -347,7 +390,7 @@ def initialize_new_tube(self, context): self.generated_name = obj.name print(':::', self.generated_name, current_mode) - if current_mode[self_id] == "ONE": + if current_mode[self_id] in {"ONE", "THREE"}: obj.matrix_world = mw.copy() polyline = curvedata.splines.new('BEZIER') @@ -360,7 +403,7 @@ def initialize_new_tube(self, context): def poll(self, context): # return self.do_not_process obj = bpy.context.edit_object - if obj and obj.data.total_face_sel == 2: + if obj and obj.data.total_face_sel == 2 or obj.data.total_vert_sel == 2: return True return are_two_objects_in_editmode(bpy.context.selected_objects) From 47defbfb3d89e336ce51f36de55a633ffef17949 Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Tue, 15 Jun 2021 15:40:29 +0200 Subject: [PATCH 02/13] adds vertex modes --- tt_operators.py | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index 784aed5..b280b36 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -76,6 +76,13 @@ def execute(self, context): def median(face): return face.calc_center_median() +def avg_edge_length_of_connected_edges(v): + if not v.link_edges: + return 0 + lengths = [e.length for e in v.link_edges] + return sum(lengths) / len(lengths) + + def get_medians_and_normals(oper, context, mode): """ because this is a post hoc implementation to cater for 2.8 ability to multi-select objects in @@ -135,16 +142,20 @@ def get_medians_and_normals(oper, context, mode): obj_main = bpy.context.edit_object me = obj_main.data bm = bmesh.from_edit_mesh(me) - verts = [] + # verts = [] + avg_edge_length = [] for v in bm.verts: if len(medians) > 2: break - verts.append(v) - normals.append(v.normal) - medians.append(v.co) - - bevel_depth = ... # (medians[0] - first_coords[0]).length - scale2 = ... # (medians[1] - first_coords[1]).length + if v.select: + # verts.append(v) + avg_edge_length.append(avg_edge_length_of_connected_edges(v)) + normals.append(v.normal) + medians.append(v.co) + + # use v.link_edges , (average length)/2 of all link_edges + bevel_depth = avg_edge_length[0] / 2 + scale2 = avg_edge_length[1] / 2 op2_scale = scale2 / bevel_depth extra_data = bevel_depth, scale2, op2_scale @@ -153,17 +164,25 @@ def get_medians_and_normals(oper, context, mode): obj_one = bpy.context.selected_objects[0] obj_two = bpy.context.selected_objects[1] verts = [] + avg_edge_length = [] objs = [obj_two, obj_one] if oper.flip_u else [obj_one, obj_two] for obj in objs: - m = obj.matrix_world - bm = bmesh.from_edit_mesh(obj.data) - verts.append(v) - normals.append(...) - medians.append(...) + if len(medians) > 2: + break - bevel_depth = ... # (medians[0] - first_coords[0]).length - scale2 = ... # (medians[1] - first_coords[1]).length + m = obj.matrix_world + bm = bmesh.from_edit_mesh(obj.data) + for v in bm.verts: + if v.select: + verts.append(v) + avg_edge_length.append(avg_edge_length_of_connected_edges(v)) + normals.append(v.normal) + medians.append(v.co) + break + + bevel_depth = avg_edge_length[0] / 2 + scale2 = avg_edge_length[1] / 2 op2_scale = scale2 / bevel_depth extra_data = bevel_depth, scale2, op2_scale From 08be6791a1db29df034ef8879344323763610f15 Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Tue, 15 Jun 2021 15:51:09 +0200 Subject: [PATCH 03/13] adds vertex modes --- tt_operators.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index b280b36..3f53cb4 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -79,7 +79,7 @@ def median(face): def avg_edge_length_of_connected_edges(v): if not v.link_edges: return 0 - lengths = [e.length for e in v.link_edges] + lengths = [e.calc_length() for e in v.link_edges] return sum(lengths) / len(lengths) @@ -177,8 +177,8 @@ def get_medians_and_normals(oper, context, mode): if v.select: verts.append(v) avg_edge_length.append(avg_edge_length_of_connected_edges(v)) - normals.append(v.normal) - medians.append(v.co) + normals.append(v.normal) # not sure why this has weird results with "m @ v.normal" + medians.append(m @ v.co) break bevel_depth = avg_edge_length[0] / 2 From 6f876e95079082c52353530f08441e2c3cae06f5 Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Wed, 16 Jun 2021 10:21:37 +0200 Subject: [PATCH 04/13] wtf? --- tt_operators.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tt_operators.py b/tt_operators.py index 3f53cb4..d1ca484 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -422,6 +422,7 @@ def initialize_new_tube(self, context): def poll(self, context): # return self.do_not_process obj = bpy.context.edit_object + print(f"faces={obj.data.total_face_sel}, verts={obj.data.total_vert_sel}") if obj and obj.data.total_face_sel == 2 or obj.data.total_vert_sel == 2: return True From a46d8230451e92b767b35226764f87d298da4308 Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Wed, 16 Jun 2021 10:50:34 +0200 Subject: [PATCH 05/13] centralize code --- tt_operators.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index d1ca484..6e2fa07 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -15,10 +15,7 @@ IntProperty, FloatProperty, StringProperty, BoolProperty ) -def are_two_objects_in_editmode(objs): - if objs and len(objs) == 2: - if all((obj.type == "MESH" and obj.mode == "EDIT") for obj in objs): - return True + current_mode = {} @@ -223,8 +220,6 @@ def modify_curve(medians, normals, curvename): pointA, pointB = [0, -1] if not oper.flip_v else [-1, 0] - ''' the radii stuff must be tidier before merge to master. ''' - # Point 0 ''' default scale or radius point1 == 1 ''' point1 = polyline.bezier_points[pointA] @@ -289,11 +284,16 @@ class AddSimpleTube(bpy.types.Operator): flip_u: BoolProperty() equal_radii: BoolProperty(default=0) - # joined = BoolProperty(default=0) do_not_process: BoolProperty(default=False) initialized_curve: BoolProperty(default=False) + def are_two_objects_in_editmode(self): + objs = bpy.context.selected_objects + if objs and len(objs) == 2: + if all((obj.type == "MESH" and obj.mode == "EDIT") for obj in objs): + return True + def draw(self, context): layout = self.layout callback = "object.tube_callback" @@ -367,7 +367,7 @@ def initialize_new_tube(self, context): scn = bpy.context.scene obj_main = bpy.context.edit_object - objects_main = bpy.context.selected_objects if are_two_objects_in_editmode(bpy.context.selected_objects) else None + objects_main = bpy.context.selected_objects if self.are_two_objects_in_editmode() else None self_id = hash(self) current_mode[self_id] = None @@ -426,7 +426,7 @@ def poll(self, context): if obj and obj.data.total_face_sel == 2 or obj.data.total_vert_sel == 2: return True - return are_two_objects_in_editmode(bpy.context.selected_objects) + return self.are_two_objects_in_editmode() def make_real(self): objects = bpy.data.objects From 62adc122893de9dd8f9e4d133c92f6365a33e316 Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Wed, 16 Jun 2021 13:14:31 +0200 Subject: [PATCH 06/13] use boolprops/toggle instead of callback operator --- tt_operators.py | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index 6e2fa07..6999853 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -57,13 +57,13 @@ def dispatch(self, context, type_op): elif type_op == "To Mesh": cls.make_real() - else: - # would prefer to be implicit.. but self.default is OK for now. - # ideally, the value is derived from the prop default - # of cls.type_op. but for now it is passed explicitely. - # Barf. Dryheave. - setattr(cls, type_op, self.default) - cls.execute(context) + # else: + # # would prefer to be implicit.. but self.default is OK for now. + # # ideally, the value is derived from the prop default + # # of cls.type_op. but for now it is passed explicitely. + # # Barf. Dryheave. + # setattr(cls, type_op, self.default) + # # cls.execute(context) def execute(self, context): self.dispatch(context, self.fn) @@ -250,6 +250,13 @@ def modify_curve(medians, normals, curvename): # print('generated name:', generated_name) modify_curve(medians, normals, generated_name) +def updateOperator(self, context, origin): + if getattr(self, origin): + print("cm triggered") + setattr(self, origin, False) + prop_name = origin.replace("reset_", "") + self.property_unset(prop_name) + update_simple_tube(self, context) class AddSimpleTube(bpy.types.Operator): @@ -288,6 +295,11 @@ class AddSimpleTube(bpy.types.Operator): do_not_process: BoolProperty(default=False) initialized_curve: BoolProperty(default=False) + reset_handle_ext_1: BoolProperty(default=False, update=lambda s, c: updateOperator(s, c, "reset_handle_ext_1")) + reset_point1_scale: BoolProperty(default=False, update=lambda s, c: updateOperator(s, c, "reset_point1_scale")) + reset_point2_scale: BoolProperty(default=False, update=lambda s, c: updateOperator(s, c, "reset_point2_scale")) + reset_handle_ext_2: BoolProperty(default=False, update=lambda s, c: updateOperator(s, c, "reset_handle_ext_2")) + def are_two_objects_in_editmode(self): objs = bpy.context.selected_objects if objs and len(objs) == 2: @@ -309,26 +321,24 @@ def draw(self, context): col.separator() - def prop_n_reset(split, pname, pstr, default, enabled=True): + def prop_n_reset(split, pname, display_name, enabled=True): ''' I draw a slider and an operator to reset the slider ''' pid = split.row(align=True) pid.enabled = enabled - pid.prop(self, pname, text=pstr) - a = pid.operator(callback, text="", icon="LINKED") - a.fn = pname - a.current_name = self.generated_name - a.default = default + pid.prop(self, pname, text=display_name) + pid.prop(self, "reset_" + pname, text="", icon="LINKED") + er = not self.equal_radii # ROW 1 row = col.row(); split = row.split(factor=0.5) - prop_n_reset(split, "handle_ext_1", "handle 1", 2.0) # left - prop_n_reset(split, "point1_scale", "radius_1", 1.0, er) # right + prop_n_reset(split, "handle_ext_1", "handle 1") # left + prop_n_reset(split, "point1_scale", "radius 1", er) # right # ROW 2 row = col.row(); split = row.split() - prop_n_reset(split, "handle_ext_2", "handle 2", 2.0) # left - prop_n_reset(split, "point2_scale", "radius_2", 1.0, er) # right + prop_n_reset(split, "handle_ext_2", "handle 2") # left + prop_n_reset(split, "point2_scale", "radius 2", er) # right # next row row = layout.row() From 986fffc9b93bd6f1427b5febbc100867d1d84651 Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Wed, 16 Jun 2021 13:33:03 +0200 Subject: [PATCH 07/13] remove dud --- tt_operators.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index 6999853..3a4a1c3 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -57,13 +57,6 @@ def dispatch(self, context, type_op): elif type_op == "To Mesh": cls.make_real() - # else: - # # would prefer to be implicit.. but self.default is OK for now. - # # ideally, the value is derived from the prop default - # # of cls.type_op. but for now it is passed explicitely. - # # Barf. Dryheave. - # setattr(cls, type_op, self.default) - # # cls.execute(context) def execute(self, context): self.dispatch(context, self.fn) From b32ffdc54a6a93fef74a718e91217fb6a40cb3e4 Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Wed, 16 Jun 2021 15:02:54 +0200 Subject: [PATCH 08/13] use different internal triggers --- tt_operators.py | 78 +++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 58 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index 3a4a1c3..9ec7f8a 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -10,58 +10,12 @@ import bmesh from mathutils import Vector from mathutils.geometry import normal - -from bpy.props import ( - IntProperty, FloatProperty, StringProperty, BoolProperty -) - +from bpy.props import IntProperty, FloatProperty, StringProperty, BoolProperty current_mode = {} - docstring = """select two verts or polygons only, then run this operator. selections can be on separate objects.""" -class TubeCallbackOps(bpy.types.Operator): - - bl_idname = "object.tube_callback" - bl_label = "Tube Callback (private)" - bl_options = {"INTERNAL"} - - current_name: StringProperty(default='') - fn: StringProperty(default='') - default: FloatProperty() - - def dispatch(self, context, type_op): - wm = context.window_manager - operators = wm.operators - - # only do this part if also current_name is passed in - if self.current_name: - - cls = None - for k in operators: - if k.bl_idname == 'MESH_OT_add_curvebased_tube': - if k.generated_name == self.current_name: - cls = k - - if not cls: - ''' all callback functions require a valid class reference ''' - return - - if type_op == "Reset radii": - print('attempt reset:', cls.generated_name) - cls.main_scale = 1.0 - cls.point1_scale = 1.0 - cls.point2_scale = 1.0 - - elif type_op == "To Mesh": - cls.make_real() - - - def execute(self, context): - self.dispatch(context, self.fn) - return {'FINISHED'} - def median(face): return face.calc_center_median() @@ -245,7 +199,6 @@ def modify_curve(medians, normals, curvename): def updateOperator(self, context, origin): if getattr(self, origin): - print("cm triggered") setattr(self, origin, False) prop_name = origin.replace("reset_", "") self.property_unset(prop_name) @@ -293,6 +246,22 @@ class AddSimpleTube(bpy.types.Operator): reset_point2_scale: BoolProperty(default=False, update=lambda s, c: updateOperator(s, c, "reset_point2_scale")) reset_handle_ext_2: BoolProperty(default=False, update=lambda s, c: updateOperator(s, c, "reset_handle_ext_2")) + def updateDelegation(self, context): + if self.trigger_bool_make_real: + self.trigger_bool_make_real = False + self.make_real() + + def updateResetRadii(self, context): + if self.trigger_bool_reset_radii: + self.trigger_bool_reset_radii = False + print('attempt reset:', self.generated_name) + self.main_scale = 1.0 + self.point1_scale = 1.0 + self.point2_scale = 1.0 + + trigger_bool_make_real: BoolProperty(default=False, description="Make the tube final", update=updateDelegation) + trigger_bool_reset_radii: BoolProperty(default=False, description="Reset all radii and scale", update=updateResetRadii) + def are_two_objects_in_editmode(self): objs = bpy.context.selected_objects if objs and len(objs) == 2: @@ -350,14 +319,8 @@ def prop_n_reset(split, pname, display_name, enabled=True): right_row.prop(self, "flip_v", text='Normal', toggle=True) col = layout.column() - - k = col.operator(callback, text="Reset radii") - k.fn = "Reset radii" - k.current_name = self.generated_name - - k = col.operator(callback, text="To Mesh") - k.fn = 'To Mesh' - k.current_name = self.generated_name + col.prop(self, "trigger_bool_reset_radii", text="Reset radii", toggle=True) + col.prop(self, "trigger_bool_make_real", text="To Mesh", toggle=True) def initialize_new_tube(self, context): @@ -457,8 +420,7 @@ def execute(self, context): return {'FINISHED'} -TubeCallbackOps.__doc__ = docstring AddSimpleTube.__doc__ = docstring -classes = [TubeCallbackOps, AddSimpleTube] +classes = [AddSimpleTube] register, unregister = bpy.utils.register_classes_factory(classes) From e09e7c167b0cc582db806d89ba89f7c0b16e9fe3 Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Wed, 16 Jun 2021 15:51:03 +0200 Subject: [PATCH 09/13] remove make real for now --- tt_operators.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index 9ec7f8a..9adf6ed 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -320,7 +320,7 @@ def prop_n_reset(split, pname, display_name, enabled=True): col = layout.column() col.prop(self, "trigger_bool_reset_radii", text="Reset radii", toggle=True) - col.prop(self, "trigger_bool_make_real", text="To Mesh", toggle=True) + # col.prop(self, "trigger_bool_make_real", text="To Mesh", toggle=True) def initialize_new_tube(self, context): @@ -394,21 +394,21 @@ def poll(self, context): return self.are_two_objects_in_editmode() - def make_real(self): - objects = bpy.data.objects - obj = objects[self.generated_name] # this curve object - - settings = False - modifiers = True - obj_data = obj.to_mesh() # bpy.context.depsgraph, apply_modifiers=modifiers, calc_undeformed=settings) - - obj_n = objects.new('MESHED_' + obj.name, obj_data) - obj_n.location = (0, 0, 0) - obj_n.matrix_world = obj.matrix_world.copy() - bpy.context.collection.objects.link(obj_n) - obj.hide_render = True - obj.hide_viewport = True - # return obj_n + # def make_real(self): + # objects = bpy.data.objects + # obj = objects[self.generated_name] # this curve object + + # obj_data = obj.to_mesh() # bpy.context.depsgraph, apply_modifiers=modifiers, calc_undeformed=settings) + + # obj_n = objects.new('MESHED_' + obj.name, obj_data) + # obj_n.location = (0, 0, 0) + # obj_n.matrix_world = obj.matrix_world.copy() + # bpy.context.collection.objects.link(obj_n) + # # bpy.ops.object.convert(target='MESH') + + # obj.hide_render = True + # obj.hide_viewport = True + # return obj_n def execute(self, context): From 56020b7c2020addbba1e24d8a191ae51676685fc Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Wed, 16 Jun 2021 17:04:43 +0200 Subject: [PATCH 10/13] prepare for working code --- tt_operators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tt_operators.py b/tt_operators.py index 9adf6ed..5e1beb2 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -392,7 +392,7 @@ def poll(self, context): if obj and obj.data.total_face_sel == 2 or obj.data.total_vert_sel == 2: return True - return self.are_two_objects_in_editmode() + return AddSimpleTube.are_two_objects_in_editmode(None) # def make_real(self): # objects = bpy.data.objects From a82c99c0527e61d852fb5b61cf4af44e7d459c1c Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Thu, 17 Jun 2021 12:51:16 +0200 Subject: [PATCH 11/13] use __class__ --- tt_operators.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index 5e1beb2..3625547 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -385,14 +385,15 @@ def initialize_new_tube(self, context): @classmethod - def poll(self, context): + def poll(cls, context): # return self.do_not_process obj = bpy.context.edit_object print(f"faces={obj.data.total_face_sel}, verts={obj.data.total_vert_sel}") if obj and obj.data.total_face_sel == 2 or obj.data.total_vert_sel == 2: return True - return AddSimpleTube.are_two_objects_in_editmode(None) + # return AddSimpleTube.are_two_objects_in_editmode(None) # __class__.are_two_objects_in_editmode(None) ? + return __class__.are_two_objects_in_editmode(None) # def make_real(self): # objects = bpy.data.objects From cb57778c9b5ae602f58531f3acec84c4e79f0fb4 Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Fri, 18 Jun 2021 13:34:42 +0200 Subject: [PATCH 12/13] apply comment/uncomment.. wow after 7 years! --- tt_operators.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tt_operators.py b/tt_operators.py index 3625547..418f8eb 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -16,6 +16,23 @@ current_mode = {} docstring = """select two verts or polygons only, then run this operator. selections can be on separate objects.""" +def solve_mode_from_current_state(): + descriptor = { + 'objs': [], + 'mode': "" + } + if one_object_selected(): + # possible modes : between verts, between faces + ... + if two_objects_selected(): + # [ ] do both objects have selections? + # [ ] if both objects, proceed normal code + # [ ] else proceed only using one object + ... + else: + # no supported mode + ... + def median(face): return face.calc_center_median() @@ -389,7 +406,7 @@ def poll(cls, context): # return self.do_not_process obj = bpy.context.edit_object print(f"faces={obj.data.total_face_sel}, verts={obj.data.total_vert_sel}") - if obj and obj.data.total_face_sel == 2 or obj.data.total_vert_sel == 2: + if obj and (obj.data.total_face_sel == 2 or obj.data.total_vert_sel == 2): return True # return AddSimpleTube.are_two_objects_in_editmode(None) # __class__.are_two_objects_in_editmode(None) ? From 66f7264b52dc10cdc65afee29c6ac29f1ce1037b Mon Sep 17 00:00:00 2001 From: Dealga McArdle Date: Sun, 9 Jan 2022 15:24:36 +0100 Subject: [PATCH 13/13] no idea --- tt_operators.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/tt_operators.py b/tt_operators.py index 418f8eb..2674599 100644 --- a/tt_operators.py +++ b/tt_operators.py @@ -19,20 +19,15 @@ def solve_mode_from_current_state(): descriptor = { 'objs': [], - 'mode': "" + 'mode': None } - if one_object_selected(): - # possible modes : between verts, between faces - ... - if two_objects_selected(): - # [ ] do both objects have selections? - # [ ] if both objects, proceed normal code - # [ ] else proceed only using one object - ... - else: - # no supported mode - ... + in_edit_mode = bpy.context.edit_object + if not in_edit_mode: + return None + # can have multiple objects in edit mode.. i dont care how many + # but there can only be 2 sets of geometry selected at once. + num_objects_in_edit_mode = len(bpy.context.selected_objects) def median(face): return face.calc_center_median()