diff --git a/precision_drawing_tools/__init__.py b/precision_drawing_tools/__init__.py index c2fbf64766db0bddf3d44d91325afc698a6e069e..62de72b67f8f782779e549d5ca27b0cda49958d9 100644 --- a/precision_drawing_tools/__init__.py +++ b/precision_drawing_tools/__init__.py @@ -29,8 +29,8 @@ bl_info = { "name": "Precision Drawing Tools (PDT)", "author": "Alan Odom (Clockmender), Rune Morling (ermo)", - "version": (1, 3, 0), - "blender": (2, 82, 0), + "version": (1, 4, 0), + "blender": (2, 83, 0), "location": "View3D > UI > PDT", "description": "Precision Drawing Tools for Acccurate Modelling", "warning": "", @@ -54,6 +54,7 @@ if "bpy" in locals(): importlib.reload(pdt_bix) importlib.reload(pdt_etof) importlib.reload(pdt_tangent) + importlib.reload(pdt_trig_waves) else: from . import pdt_design from . import pdt_pivot_point @@ -64,11 +65,17 @@ else: from . import pdt_bix from . import pdt_etof from . import pdt_tangent + from . import pdt_trig_waves import bpy import os from pathlib import Path -from bpy.types import AddonPreferences, PropertyGroup, Scene, WindowManager +from bpy.types import ( + AddonPreferences, + PropertyGroup, Scene, + WindowManager, + Object, +) from bpy.props import ( BoolProperty, CollectionProperty, @@ -130,6 +137,39 @@ _pdt_col_items = [] _pdt_mat_items = [] +class PDTPreferences(AddonPreferences): + # This must match the addon name, use '__package__' + # when defining this in a submodule of a python package. + + bl_idname = __name__ + + debug: BoolProperty( + name="Enable console debug output from PDT scripts", + default=False, + description="NOTE: Does not enable debugging globally in Blender (only in PDT scripts)", + ) + + pdt_ui_width: IntProperty( + name="UI Width Cut-off", + default=350, + description="Cutoff width for shrinking items per line in menus", + ) + + pdt_input_round: IntProperty( + name="Input Rounding", default=5, description="Rounding Factor for Inputs" + ) + + def draw(self, context): + layout = self.layout + + box = layout.box() + row1 = box.row() + row2 = box.row() + row1.prop(self, "debug") + row2.prop(self, "pdt_ui_width") + row2.prop(self, "pdt_input_round") + + def enumlist_objects(self, context): """Populate Objects List from Parts Library. @@ -145,8 +185,8 @@ def enumlist_objects(self, context): scene = context.scene pg = scene.pdt_pg - file_path = context.preferences.addons[__package__].preferences.pdt_library_path - path = Path(file_path) + file_path = pg.pdt_library_path + path = Path(bpy.path.abspath(file_path)) _pdt_obj_items.clear() if path.is_file() and ".blend" in str(path): @@ -158,7 +198,7 @@ def enumlist_objects(self, context): for object_name in object_names: _pdt_obj_items.append((object_name, object_name, "")) else: - _pdt_obj_items.append(("MISSING", "Library is Missing", "")) + _pdt_obj_items.append(("MISSING", "Library Not Set", "")) return _pdt_obj_items @@ -177,8 +217,8 @@ def enumlist_collections(self, context): scene = context.scene pg = scene.pdt_pg - file_path = context.preferences.addons[__package__].preferences.pdt_library_path - path = Path(file_path) + file_path = pg.pdt_library_path + path = Path(bpy.path.abspath(file_path)) _pdt_col_items.clear() if path.is_file() and ".blend" in str(path): @@ -192,7 +232,7 @@ def enumlist_collections(self, context): for object_name in object_names: _pdt_col_items.append((object_name, object_name, "")) else: - _pdt_col_items.append(("MISSING", "Library is Missing", "")) + _pdt_col_items.append(("MISSING", "Library Not Set", "")) return _pdt_col_items @@ -211,8 +251,8 @@ def enumlist_materials(self, context): scene = context.scene pg = scene.pdt_pg - file_path = context.preferences.addons[__package__].preferences.pdt_library_path - path = Path(file_path) + file_path = pg.pdt_library_path + path = Path(bpy.path.abspath(file_path)) _pdt_mat_items.clear() if path.is_file() and ".blend" in str(path): @@ -226,13 +266,21 @@ def enumlist_materials(self, context): for object_name in object_names: _pdt_mat_items.append((object_name, object_name, "")) else: - _pdt_mat_items.append(("MISSING", "Library is Missing", "")) + _pdt_mat_items.append(("MISSING", "Library Not Set", "")) return _pdt_mat_items class PDTSceneProperties(PropertyGroup): """Contains all PDT related properties.""" + pdt_library_path: StringProperty( + name="Library", + default="", + description="Parts Library File", + maxlen=1024, + subtype="FILE_PATH", + ) + object_search_string: StringProperty(name="Search", default="", description=PDT_DES_LIBSER) collection_search_string: StringProperty(name="Search", default="", description=PDT_DES_LIBSER) material_search_string: StringProperty(name="Search", default="", description=PDT_DES_LIBSER) @@ -429,48 +477,34 @@ class PDTSceneProperties(PropertyGroup): description=PDT_DES_TANMODE, ) - -class PDTPreferences(AddonPreferences): - # This must match the addon name, use '__package__' - # when defining this in a submodule of a python package. - - bl_idname = __name__ - - pdt_library_path: StringProperty( - name="Parts Library", - default="", - description="Parts Library File", - maxlen=1024, - subtype="FILE_PATH", - ) - - debug: BoolProperty( - name="Enable console debug output from PDT scripts", - default=False, - description="NOTE: Does not enable debugging globally in Blender (only in PDT scripts)", - ) - - pdt_ui_width: IntProperty( - name="UI Width Cut-off", - default=350, - description="Cutoff width for shrinking items per line in menus", - ) - - pdt_input_round: IntProperty( - name="Input Rounding", default=5, description="Rounding Factor for Inputs" - ) - - def draw(self, context): - layout = self.layout - - box = layout.box() - row1 = box.row() - row2 = box.row() - row3 = box.row() - row1.prop(self, "debug") - row2.prop(self, "pdt_ui_width") - row2.prop(self, "pdt_input_round") - row3.prop(self, "pdt_library_path") + # For Trig Waves + trig_type : EnumProperty( + items=( + ("sin", "Sine", "Sine Wave"), + ("cos", "Cosine", "Cosine Wave"), + ("tan", "Tangent", "Tangent Wave"), + ), + name="Wave Form", + default="sin", + description="Trig. Wave Form", + ) + trig_cycles : IntProperty(name="Cycles #", default=1, min=1, + description="1 Cycle = 180 Degrees") + trig_amp : FloatProperty(name="Amplitude", default=1, min=0.01, + description="Maximum Height of 1 Cycle (forms Basis for Tangents)") + trig_len : FloatProperty(name="Cycle Length", default=2, min=0.02, + description="Length in Blender Units of 1 Cycle") + trig_obj : PointerProperty(name="Object", type=Object) + trig_del : BoolProperty(name="Empty Object", default=False, + description="Delete ALL Vertices in Object First") + trig_res : IntProperty(name="Resolution", default=18, min=4, max=72, + description="Number of Vertices per Cycle (180 Degrees)") + trig_tanmax : FloatProperty(name="Tangent Max", default=10, min=0.1, + description="Maximum Permitted Tangent Value") + trig_off : FloatVectorProperty(name="Start Loc", default=(0,0,0), + description="Location in World Space for Origin of Wave") + trig_abs : BoolProperty(name="Absolute", default=False, + description="Use Absolute Values Only") # List of All Classes in the Add-on to register @@ -479,8 +513,8 @@ class PDTPreferences(AddonPreferences): # (and unloaded last) # classes = ( - PDTSceneProperties, PDTPreferences, + PDTSceneProperties, pdt_bix.PDT_OT_LineOnBisection, pdt_command.PDT_OT_CommandReRun, pdt_design.PDT_OT_PlacementAbs, @@ -507,6 +541,7 @@ classes = ( pdt_menus.PDT_PT_PanelViewControl, pdt_menus.PDT_PT_PanelPivotPoint, pdt_menus.PDT_PT_PanelPartsLibrary, + pdt_menus.PDT_PT_PanelTrig, pdt_pivot_point.PDT_OT_ModalDrawOperator, pdt_pivot_point.PDT_OT_ViewPlaneRotate, pdt_pivot_point.PDT_OT_ViewPlaneScale, @@ -523,6 +558,7 @@ classes = ( pdt_tangent.PDT_OT_TangentSet3, pdt_tangent.PDT_OT_TangentSet4, pdt_tangent.PDT_OT_TangentExpandMenu, + pdt_trig_waves.PDT_OT_WaveGenerator, pdt_view.PDT_OT_ViewRot, pdt_view.PDT_OT_ViewRotL, pdt_view.PDT_OT_ViewRotR, diff --git a/precision_drawing_tools/pdt_library.py b/precision_drawing_tools/pdt_library.py index a0b1a6be96b03e99a6c6a69604cd20ccf1a4c26b..4850481b01d21ffe0f059d148b10a54262e8f9ab 100644 --- a/precision_drawing_tools/pdt_library.py +++ b/precision_drawing_tools/pdt_library.py @@ -48,7 +48,7 @@ class PDT_OT_LibShow(Operator): scene = context.scene pg = scene.pdt_pg - file_path = context.preferences.addons[__package__].preferences.pdt_library_path + file_path = pg.pdt_library_path pg.error = str(Path(file_path)) debug("PDT Parts Library:") debug(f"{pg.error}") @@ -89,10 +89,10 @@ class PDT_OT_Append(Operator): return {"FINISHED"} obj_names = [o.name for o in context.view_layer.objects].copy() - file_path = context.preferences.addons[__package__].preferences.pdt_library_path + file_path = pg.pdt_library_path path = Path(file_path) - if path.is_file() and ".blend" in str(path): + if path.is_file() and str(path).endswith(".blend"): if pg.lib_mode == "OBJECTS": bpy.ops.wm.append( filepath=str(path), @@ -170,9 +170,10 @@ class PDT_OT_Link(Operator): self.report({"ERROR"}, error_message) return {"FINISHED"} - file_path = context.preferences.addons[__package__].preferences.pdt_library_path + file_path = pg.pdt_library_path path = Path(file_path) - if path.is_file() and ".blend" in str(path): + + if path.is_file() and str(path).endswith(".blend"): if pg.lib_mode == "OBJECTS": bpy.ops.wm.link( filepath=str(path), diff --git a/precision_drawing_tools/pdt_menus.py b/precision_drawing_tools/pdt_menus.py index c42d18c9e67acb52ffb556ef1338a8d6c21cefd4..be452f018038ba1f3158c44fcdb81281a22340b9 100644 --- a/precision_drawing_tools/pdt_menus.py +++ b/precision_drawing_tools/pdt_menus.py @@ -306,6 +306,8 @@ class PDT_PT_PanelPartsLibrary(Panel): layout = self.layout pdt_pg = context.scene.pdt_pg row = layout.row() + row.prop(pdt_pg, "pdt_library_path") + row = layout.row() col = row.column() col.operator("pdt.append", text="Append") col = row.column() @@ -339,7 +341,7 @@ class PDT_PT_PanelPartsLibrary(Panel): row = box.row() row.prop(pdt_pg, "lib_materials", text="") row = box.row() - row.operator("pdt.lib_show", text="Show Library File", icon='INFO') + #row.operator("pdt.lib_show", text="Load Library File", icon='INFO') class PDT_PT_PanelViewControl(Panel): @@ -474,3 +476,40 @@ class PDT_PT_PanelTangent(Panel): split.prop(pdt_pg, "tangent_radius1", text="") row = box.row() row.operator("pdt.tangentoperate", text="Tangents From Inputs", icon="NONE") + +class PDT_PT_PanelTrig(Panel): + bl_idname = "PDT_PT_PanelTrig" + bl_label = "PDT Trigonometrical Waves" + bl_space_type = "VIEW_3D" + bl_region_type = "UI" + bl_category = "PDT" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self,context): + layout = self.layout + pdt_pg = context.scene.pdt_pg + row = layout.row() + row.label(text=f"Working {PDT_LAB_PLANE}:") + row.prop(pdt_pg, "plane", text="") + + row = layout.row() + split = row.split(factor=0.5, align=True) + split.prop(pdt_pg, "trig_type") + split.prop(pdt_pg, "trig_cycles") + row = layout.row() + split = row.split(factor=0.5, align=True) + split.prop(pdt_pg, "trig_amp") + split.prop(pdt_pg, "trig_len") + row = layout.row() + split = row.split(factor=0.5, align=True) + split.prop(pdt_pg, "trig_obj", text="") + split.prop(pdt_pg, "trig_del") + row = layout.row() + split = row.split(factor=0.5, align=True) + split.prop(pdt_pg, "trig_res") + split.prop(pdt_pg, "trig_tanmax") + row = layout.row() + row.prop(pdt_pg, "trig_off") + row = layout.row() + row.operator("pdt.wave_generator", icon="SEQ_LUMA_WAVEFORM") + row.prop(pdt_pg, "trig_abs") diff --git a/precision_drawing_tools/pdt_msg_strings.py b/precision_drawing_tools/pdt_msg_strings.py index 8d01abb206cf38f092f744f31cdb3a549f9e7c25..7d0cc2bc6604519472795f4c64bfccd29f07c415 100644 --- a/precision_drawing_tools/pdt_msg_strings.py +++ b/precision_drawing_tools/pdt_msg_strings.py @@ -94,8 +94,8 @@ PDT_ERR_VERT_MODE = "Work in Vertex Mode for this Function" PDT_ERR_NOPPLOC = ( "Custom Property PDT_PP_LOC for this object not found, have you Written it yet?" ) -PDT_ERR_NO_LIBRARY = ("PDT Library Blend File (parts_library.blend) is Missing " - + "from Addons/clockworxpdt Folder") +PDT_ERR_NO_LIBRARY = ("PDT Library Blend File is Missing " + + "or not Correctly Set to a Blend File") PDT_ERR_SEL_1_VERTI = "Select at least 1 Vertex Individually (Currently selected:" PDT_ERR_SEL_1_VERT = "Select at least 1 Vertex (Currently selected:" diff --git a/precision_drawing_tools/pdt_tangent.py b/precision_drawing_tools/pdt_tangent.py index d743d3ebd104783b39f0b1e9f35ae52629aaf078..22b34c7a2a3efddf11766543f7c29c55773e6bd7 100644 --- a/precision_drawing_tools/pdt_tangent.py +++ b/precision_drawing_tools/pdt_tangent.py @@ -114,6 +114,8 @@ def get_tangent_points(context, hloc_0, vloc_0, radius_0, hloc_p, vloc_p): vloc_t2: Vertical Location of Second Tangent Point """ + # Uses basic Pythagorus' theorem to compute locations + # numerator = (radius_0 ** 2 * (hloc_p - hloc_0)) + ( radius_0 * (vloc_p - vloc_0) @@ -186,6 +188,8 @@ def make_vectors(coords, a1, a2, a3, pg): tangent_vector_o4[a3] = coords[8] if pg.plane == "LO": + # Reset coordinates from view local (Horiz, Vert, depth) to World XYZ. + # tangent_vector_o1 = view_coords( tangent_vector_o1[a1], tangent_vector_o1[a2], tangent_vector_o1[a3] ) @@ -223,6 +227,8 @@ def tangent_setup(context, pg, plane, obj_data, centre_0, centre_1, centre_2, ra a1, a2, a3 = set_mode(plane) mode = pg.tangent_mode if plane == "LO": + # Translate world cordinates into view local (horiz, vert, depth) + # centre_0 = view_coords_i(centre_0[a1], centre_0[a2], centre_0[a3]) centre_1 = view_coords_i(centre_1[a1], centre_1[a2], centre_1[a3]) centre_2 = view_coords_i(centre_2[a1], centre_2[a2], centre_2[a3]) @@ -239,6 +245,7 @@ def tangent_setup(context, pg, plane, obj_data, centre_0, centre_1, centre_2, ra (distance <= radius_0 or distance <= radius_1 and mode in {"outer", "both"}) ): # Cannot execute, centres are too close. + # pg.error = f"{PDT_ERR_BADDISTANCE}" context.window_manager.popup_menu(oops, title="Error", icon="ERROR") return {"FINISHED"} @@ -260,6 +267,7 @@ def tangent_setup(context, pg, plane, obj_data, centre_0, centre_1, centre_2, ra context.window_manager.popup_menu(oops, title="Error", icon="ERROR") return {"FINISHED"} # Point Tangents + # tangent_vector_o1 = Vector((0, 0, 0)) tangent_vector_o1[a1] = hloc_to1 tangent_vector_o1[a2] = vloc_to1 @@ -269,6 +277,8 @@ def tangent_setup(context, pg, plane, obj_data, centre_0, centre_1, centre_2, ra tangent_vector_o2[a2] = vloc_to2 tangent_vector_o2[a3] = centre_2[a3] if pg.plane == "LO": + # Translate view local coordinates (horiz, vert, depth) into World XYZ + # centre_2 = view_coords(centre_2[a1], centre_2[a2], centre_2[a3]) tangent_vector_o1 = view_coords( tangent_vector_o1[a1], tangent_vector_o1[a2], tangent_vector_o1[a3] @@ -287,8 +297,11 @@ def tangent_setup(context, pg, plane, obj_data, centre_0, centre_1, centre_2, ra """ if mode in {"outer", "both"}: + # Uses basic trigonometry and Pythagorus' theorem to compute locations + # if radius_0 == radius_1: # No intersection point for outer tangents + # sin_angle = (centre_1[a2] - centre_0[a2]) / distance cos_angle = (centre_1[a1] - centre_0[a1]) / distance hloc_to1 = centre_0[a1] + (radius_0 * sin_angle) @@ -342,6 +355,8 @@ def tangent_setup(context, pg, plane, obj_data, centre_0, centre_1, centre_2, ra """ if mode in {"inner", "both"}: + # Uses basic trigonometry and Pythagorus' theorem to compute locations + # hloc_pi, vloc_pi = get_tangent_intersect_inner( centre_0[a1], centre_0[a2], centre_1[a1], centre_1[a2], radius_0, radius_1 ) @@ -442,6 +457,8 @@ def analyse_arc(context, pg): context.window_manager.popup_menu(oops, title="Error", icon="ERROR") raise PDT_SelectionError vector_a = verts[0].co + # Get the nearest to middle vertex of the arc + # vector_b = verts[int(floor(len(verts) / 2))].co vector_c = verts[-1].co vector_delta, radius = arc_centre(vector_a, vector_b, vector_c) @@ -484,6 +501,7 @@ class PDT_OT_TangentOperate(Operator): Returns: Nothing. """ + scene = context.scene pg = scene.pdt_pg plane = pg.plane @@ -521,7 +539,7 @@ class PDT_OT_TangentOperateSel(Operator): bl_idname = "pdt.tangentoperatesel" bl_label = "Calculate Tangents" bl_options = {"REGISTER", "UNDO"} - bl_description = "Calculate Tangents to Arcs from 2 Selected Vertices, or 1 & Point" + bl_description = "Calculate Tangents to Arcs from 2 Selected Vertices, or 1 & Point in Menu" @classmethod def poll(cls, context): @@ -601,6 +619,8 @@ class PDT_OT_TangentOperateSel(Operator): e.select_set(False) bmesh.update_edit_mesh(obj.data) bm.select_history.clear() + # Select the nearest to middle vertex in the arc + # verts1 = [verts1[0].co, verts1[int(floor(len(verts1) / 2))].co, verts1[-1].co] vertsn = [vertsn[0].co, vertsn[int(floor(len(vertsn) / 2))].co, vertsn[-1].co] centre_0, radius_0 = arc_centre(verts1[0], verts1[1], verts1[2]) @@ -756,6 +776,9 @@ class PDT_OT_TangentExpandMenu(Operator): def execute(self, context): """Expand/Collapse Tangent Menu. + Note: + This is used to add further options to the menu. + Args: context: Blender bpy.context instance. diff --git a/precision_drawing_tools/pdt_trig_waves.py b/precision_drawing_tools/pdt_trig_waves.py new file mode 100644 index 0000000000000000000000000000000000000000..535ac85a9a55fc535cdf89d43df609d492ab8f4a --- /dev/null +++ b/precision_drawing_tools/pdt_trig_waves.py @@ -0,0 +1,150 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ***** END GPL LICENCE BLOCK ***** +# +# ----------------------------------------------------------------------- +# Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019 +# ----------------------------------------------------------------------- +# +import bpy +import bmesh +from math import sin, cos, tan, pi +from mathutils import Vector +from .pdt_functions import ( + set_mode, + view_coords, +) + +class PDT_OT_WaveGenerator(bpy.types.Operator): + """Generate Trig Waves in Active Object""" + bl_idname = "pdt.wave_generator" + bl_label = "Generate Waves" + bl_options = {"REGISTER", "UNDO"} + + @classmethod + def poll(cls, context): + pg = context.scene.pdt_pg + return pg.trig_obj is not None + + def execute(self, context): + """Generate Trig Waves in Active Object. + + Note: + Uses all the PDT trig_* variables. + + This function will draw a trigonometrical wave based upon cycle length + One cycle is assumed to be 180 degrees, so half a revolution of an imaginary + rotating object. If a full cycle from 0 to 360 degrees is required, the cycles + number should be set to 2. + + Args: + context: Blender bpy.context instance. + + Returns: + Nothing. + """ + + pg = context.scene.pdt_pg + plane = pg.plane + # Find the horizontal, vertical and depth axes in the view from working plane. + # Order is: H, V, D. + # + a1, a2, a3 = set_mode(plane) + # Make sure object selected in the UI is the active object. + # + for obj in bpy.data.objects: + obj.select_set(state=False) + context.view_layer.objects.active = pg.trig_obj + # x_inc is the increase in X (Horiz axis) per unit of resolution of the wave, so if + # resolution is 9, nine points will be drawn in each cycle representing increases of + # 20 degrees and 1/9th of the cycle length. + # + x_inc = pg.trig_len / pg.trig_res + + if pg.trig_del: + # Delete all existing vertices first. + # + bpy.ops.object.mode_set(mode='EDIT') + for v in pg.trig_obj.data.vertices: + v.select = True + bpy.ops.mesh.delete(type='VERT') + bpy.ops.object.mode_set(mode='OBJECT') + + if pg.trig_obj.mode != "EDIT": + bpy.ops.object.mode_set(mode='EDIT') + bm = bmesh.from_edit_mesh(pg.trig_obj.data) + + # Loop for each point in the number of cycles times the resolution value. + # Uses basic trigonomtry to calculate the wave locations. + # If Absolute has been set, all values are made positive. + # z_val is assumed to be the offset from the horizontal axis of the wave. + # These values will be offset by the Offset Vector given in the UI. + # + for i in range((pg.trig_res * pg.trig_cycles) + 1): + # Uses a calculation of trig function angle of imaginary object times maximum amplitude + # of wave. So with reolution at 9, angular increments are 20 degrees. + # Angles must be in Radians for this calcultion. + # + if pg.trig_type == "sin": + if pg.trig_abs: + z_val = abs(sin((i / pg.trig_res) * pi) * pg.trig_amp) + else: + z_val = sin((i / pg.trig_res) * pi) * pg.trig_amp + elif pg.trig_type == "cos": + if pg.trig_abs: + z_val = abs(cos((i / pg.trig_res) * pi) * pg.trig_amp) + else: + z_val = cos((i / pg.trig_res) * pi) * pg.trig_amp + else: + if pg.trig_abs: + z_val = abs(tan((i / pg.trig_res) * pi) * pg.trig_amp) + else: + z_val = tan((i / pg.trig_res) * pi) * pg.trig_amp + + if abs(z_val) > pg.trig_tanmax: + if z_val >= 0: + z_val = pg.trig_tanmax + else: + if pg.trig_abs: + z_val = pg.trig_tanmax + else: + z_val = -pg.trig_tanmax + + # Start with Offset Vector from UI and add wave offsets to it. + # Axis a3 (depth) is never changed from offset vector in UI. + # + vert_loc = Vector(pg.trig_off) + vert_loc[a1] = vert_loc[a1] + (i * x_inc) + vert_loc[a2] = vert_loc[a2] + z_val + if plane == "LO": + # Translate view local coordinates (horiz, vert, depth) into World XYZ + # + vert_loc = view_coords(vert_loc[a1], vert_loc[a2], vert_loc[a3]) + vertex_new = bm.verts.new(vert_loc) + # Refresh Vertices list in object data. + # + bm.verts.ensure_lookup_table() + if i > 0: + # Make an edge from last two vertices in object data. + # + bm.edges.new([bm.verts[-2], vertex_new]) + + bmesh.update_edit_mesh(pg.trig_obj.data) + bpy.ops.object.mode_set(mode='OBJECT') + + return {"FINISHED"}