1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
21 # -----------------------------------------------------------------------
22 # Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019
23 # -----------------------------------------------------------------------
25 # ----------------------------------------------
27 # ----------------------------------------------
30 "name": "Precision Drawing Tools (PDT)",
31 "author": "Alan Odom (Clockmender), Rune Morling (ermo)",
33 "blender": (2, 83, 0),
34 "location": "View3D > UI > PDT",
35 "description": "Precision Drawing Tools for Acccurate Modelling",
37 "doc_url": "https://github.com/Clockmender/Precision-Drawing-Tools/wiki",
38 "category": "3D View",
42 # ----------------------------------------------
44 # ----------------------------------------------
48 importlib
.reload(pdt_design
)
49 importlib
.reload(pdt_pivot_point
)
50 importlib
.reload(pdt_menus
)
51 importlib
.reload(pdt_library
)
52 importlib
.reload(pdt_view
)
53 importlib
.reload(pdt_xall
)
54 importlib
.reload(pdt_bix
)
55 importlib
.reload(pdt_etof
)
56 importlib
.reload(pdt_tangent
)
57 importlib
.reload(pdt_trig_waves
)
59 from . import pdt_design
60 from . import pdt_pivot_point
61 from . import pdt_menus
62 from . import pdt_library
63 from . import pdt_view
64 from . import pdt_xall
66 from . import pdt_etof
67 from . import pdt_tangent
68 from . import pdt_trig_waves
72 from pathlib
import Path
73 from bpy
.types
import (
79 from bpy
.props
import (
89 from .pdt_msg_strings
import (
129 from .pdt_command
import command_run
130 from .pdt_functions
import scale_set
133 # Declare enum items variables
140 class PDTPreferences(AddonPreferences
):
141 # This must match the addon name, use '__package__'
142 # when defining this in a submodule of a python package.
147 name
="Enable console debug output from PDT scripts",
149 description
="NOTE: Does not enable debugging globally in Blender (only in PDT scripts)",
152 pdt_ui_width
: IntProperty(
153 name
="UI Width Cut-off",
155 description
="Cutoff width for shrinking items per line in menus",
158 pdt_input_round
: IntProperty(
159 name
="Input Rounding", default
=5, description
="Rounding Factor for Inputs"
162 def draw(self
, context
):
168 row1
.prop(self
, "debug")
169 row2
.prop(self
, "pdt_ui_width")
170 row2
.prop(self
, "pdt_input_round")
173 def enumlist_objects(self
, context
):
174 """Populate Objects List from Parts Library.
176 Creates list of objects that optionally have search string contained in them
177 to populate variable pdt_lib_objects enumerator.
180 context: Blender bpy.context instance.
183 list of Object Names.
186 scene
= context
.scene
188 file_path
= pg
.pdt_library_path
189 path
= Path(bpy
.path
.abspath(file_path
))
190 _pdt_obj_items
.clear()
192 if path
.is_file() and ".blend" in str(path
):
193 with bpy
.data
.libraries
.load(str(path
)) as (data_from
, _
):
194 if len(pg
.object_search_string
) == 0:
195 object_names
= [obj
for obj
in data_from
.objects
]
197 object_names
= [obj
for obj
in data_from
.objects
if pg
.object_search_string
in obj
]
198 for object_name
in object_names
:
199 _pdt_obj_items
.append((object_name
, object_name
, ""))
201 _pdt_obj_items
.append(("MISSING", "Library Not Set", ""))
202 return _pdt_obj_items
205 def enumlist_collections(self
, context
):
206 """Populate Collections List from Parts Library.
208 Creates list of collections that optionally have search string contained in them
209 to populate variable pg.lib_collections enumerator
212 context: Blender bpy.context instance.
215 list of Collections Names.
218 scene
= context
.scene
220 file_path
= pg
.pdt_library_path
221 path
= Path(bpy
.path
.abspath(file_path
))
222 _pdt_col_items
.clear()
224 if path
.is_file() and ".blend" in str(path
):
225 with bpy
.data
.libraries
.load(str(path
)) as (data_from
, _
):
226 if len(pg
.collection_search_string
) == 0:
227 object_names
= [obj
for obj
in data_from
.collections
]
230 obj
for obj
in data_from
.collections
if pg
.collection_search_string
in obj
232 for object_name
in object_names
:
233 _pdt_col_items
.append((object_name
, object_name
, ""))
235 _pdt_col_items
.append(("MISSING", "Library Not Set", ""))
236 return _pdt_col_items
239 def enumlist_materials(self
, context
):
240 """Populate Materials List from Parts Library.
242 Creates list of materials that optionally have search string contained in them
243 to populate variable pg.lib_materials enumerator.
246 context: Blender bpy.context instance.
249 list of Object Names.
252 scene
= context
.scene
254 file_path
= pg
.pdt_library_path
255 path
= Path(bpy
.path
.abspath(file_path
))
256 _pdt_mat_items
.clear()
258 if path
.is_file() and ".blend" in str(path
):
259 with bpy
.data
.libraries
.load(str(path
)) as (data_from
, _
):
260 if len(pg
.material_search_string
) == 0:
261 object_names
= [obj
for obj
in data_from
.materials
]
264 obj
for obj
in data_from
.materials
if pg
.material_search_string
in obj
266 for object_name
in object_names
:
267 _pdt_mat_items
.append((object_name
, object_name
, ""))
269 _pdt_mat_items
.append(("MISSING", "Library Not Set", ""))
270 return _pdt_mat_items
273 class PDTSceneProperties(PropertyGroup
):
274 """Contains all PDT related properties."""
276 pdt_library_path
: StringProperty(
279 description
="Parts Library File",
284 object_search_string
: StringProperty(name
="Search", default
="", description
=PDT_DES_LIBSER
)
285 collection_search_string
: StringProperty(name
="Search", default
="", description
=PDT_DES_LIBSER
)
286 material_search_string
: StringProperty(name
="Search", default
="", description
=PDT_DES_LIBSER
)
288 cartesian_coords
: FloatVectorProperty(
289 name
="Coords", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_COORDS
291 distance
: FloatProperty(
292 name
="Distance", default
=0.0, precision
=5, description
=PDT_DES_OFFDIS
, unit
="LENGTH"
294 angle
: FloatProperty(
295 name
="Angle", min=-180, max=180, default
=0.0, precision
=5, description
=PDT_DES_OFFANG
297 percent
: FloatProperty(name
="Percent", default
=0.0, precision
=5, description
=PDT_DES_OFFPER
)
300 ("XZ", "Front(X-Z)", "Use X-Z Plane"),
301 ("XY", "Top(X-Y)", "Use X-Y Plane"),
302 ("YZ", "Right(Y-Z)", "Use Y-Z Plane"),
303 ("LO", "View", "Use View Plane"),
305 name
="Working Plane",
307 description
=PDT_DES_WORPLANE
,
309 select
: EnumProperty(
311 ("REL", "Current Pos.", "Move Relative to Current Position"),
315 "Move Relative to Selected Object or Vertex (Cursor & Pivot Only)",
320 description
=PDT_DES_MOVESEL
,
322 operation
: EnumProperty(
324 ("CU", "Move Cursor", "This function will Move the Cursor"),
325 ("PP", "Move Pivot Point", "This function will Move the Pivot Point"),
326 ("MV", "Move Entities", "This function will Move selected Vertices or Objects"),
327 ("NV", "Add New Vertex", "This function will Add a New Vertex"),
330 "Extrude Vertex/Vertices",
331 "This function will Extrude Vertex/Vertices Only in EDIT Mode",
333 ("SE", "Split Edges", "This function will Split Edges Only in EDIT Mode"),
336 "Duplicate Geometry",
337 "This function will Duplicate Geometry in EDIT Mode (Delta & Direction Only)",
342 "This function will Extrude Geometry in EDIT Mode (Delta & Direction Only)",
347 description
=PDT_DES_OPMODE
,
351 ("RX-MY", "RotX-MovY", "Rotate X - Move Y"),
352 ("RX-MZ", "RotX-MovZ", "Rotate X - Move Z"),
353 ("RY-MX", "RotY-MovX", "Rotate Y - Move X"),
354 ("RY-MZ", "RotY-MovZ", "Rotate Y - Move Z"),
355 ("RZ-MX", "RotZ-MovX", "Rotate Z - Move X"),
356 ("RZ-MY", "RotZ-MovY", "Rotate Z - Move Y"),
360 description
=PDT_DES_ROTMOVAX
,
363 flip_angle
: BoolProperty(name
="Flip Angle", default
=False, description
=PDT_DES_FLIPANG
)
364 flip_percent
: BoolProperty(name
="Flip %", default
=False, description
=PDT_DES_FLIPPER
)
366 extend
: BoolProperty(name
="Trim/Extend All", default
=False, description
=PDT_DES_TRIM
)
368 lib_objects
: EnumProperty(items
=enumlist_objects
, name
="Objects", description
=PDT_DES_LIBOBS
)
369 lib_collections
: EnumProperty(
370 items
=enumlist_collections
, name
="Collections", description
=PDT_DES_LIBCOLS
372 lib_materials
: EnumProperty(
373 items
=enumlist_materials
, name
="Materials", description
=PDT_DES_LIBMATS
375 lib_mode
: EnumProperty(
377 ("OBJECTS", "Objects", "Use Objects"),
378 ("COLLECTIONS", "Collections", "Use Collections"),
379 ("MATERIALS", "Materials", "Use Materials"),
383 description
=PDT_DES_LIBMODE
,
386 rotation_coords
: FloatVectorProperty(
387 name
="Rotation", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
="Rotation Coordinates"
390 object_order
: EnumProperty(
392 ("1,2,3,4", "1,2,3,4", "Objects 1 & 2 are First Line"),
393 ("1,3,2,4", "1,3,2,4", "Objects 1 & 3 are First Line"),
394 ("1,4,2,3", "1,4,2,3", "Objects 1 & 4 are First Line"),
398 description
=PDT_DES_OBORDER
,
400 vrotangle
: FloatProperty(name
="View Rotate Angle", default
=10, max=180, min=-180)
401 command
: StringProperty(
402 name
="Command", default
="CA0,0,0", update
=command_run
, description
=PDT_DES_VALIDLET
,
404 maths_output
: FloatProperty(
405 name
="Maths output", default
=0, description
=PDT_DES_OUTPUT
,
407 error
: StringProperty(name
="Error", default
="")
409 # Was pivot* -- is now pivot_*
410 pivot_loc
: FloatVectorProperty(
411 name
="Pivot Location", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_PPLOC
,
413 pivot_scale
: FloatVectorProperty(
414 name
="Pivot Scale", default
=(1.0, 1.0, 1.0), subtype
="XYZ", description
=PDT_DES_PPSCALEFAC
416 pivot_size
: FloatProperty(
417 name
="Pivot Factor", min=0.4, max=10, default
=2, precision
=1, description
=PDT_DES_PPSIZE
419 pivot_width
: IntProperty(name
="Width", min=1, max=5, default
=2, description
=PDT_DES_PPWIDTH
)
421 pivot_ang
: FloatProperty(name
="Pivot Angle", min=-180, max=180, default
=0.0)
423 pivot_dis
: FloatProperty(
424 name
="Pivot Dist", default
=0.0, min=0, update
=scale_set
, description
=PDT_DES_PIVOTDIS
,
426 pivot_alpha
: FloatProperty(
427 name
="Alpha", min=0.2, max=1, default
=0.6, precision
=1, description
=PDT_DES_PPTRANS
,
429 pivot_show
: BoolProperty()
432 fillet_radius
: FloatProperty(
433 name
="Fillet Radius", min=0.0, default
=1.0, description
=PDT_DES_FILLETRAD
436 fillet_segments
: IntProperty(
437 name
="Fillet Segments", min=1, default
=4, description
=PDT_DES_FILLETSEG
440 fillet_profile
: FloatProperty(
441 name
="Fillet Profile", min=0.0, max=1.0, default
=0.5, description
=PDT_DES_FILLETPROF
444 fillet_vertices_only
: BoolProperty(
445 name
="Fillet Vertices Only", default
=True, description
=PDT_DES_FILLETVERTS
,
447 fillet_intersect
: BoolProperty(
448 name
="Intersect", default
=False, description
=PDT_DES_FILLINT
,
450 tangent_point0
: FloatVectorProperty(
451 name
="Coordst1", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_TANCEN1
453 tangent_point1
: FloatVectorProperty(
454 name
="Coordst2", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_TANCEN2
456 tangent_radius0
: FloatProperty(
457 name
="Arc Radius 1", min=0.00001, default
=1, description
=PDT_DES_RADIUS1
459 tangent_radius1
: FloatProperty(
460 name
="Arc Radius 2", min=0.00001, default
=1, description
=PDT_DES_RADIUS2
462 tangent_point2
: FloatVectorProperty(
463 name
="Coordst3", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_TANCEN3
465 menu_expand
: BoolProperty(
466 name
="Expand", default
=False, description
=PDT_DES_EXPCOLL
,
468 tangent_mode
: EnumProperty(
470 ("inner", "Inner", "Inner Tangents"),
471 ("outer", "Outer", "Outer Tangents"),
472 ("both", "Inner & Outer", "Inner & Outer Tangents"),
473 ("point", "From Point", "Tangents from Point"),
475 name
="Working Plane",
477 description
=PDT_DES_TANMODE
,
481 trig_type
: EnumProperty(
483 ("sin", "Sine", "Sine Wave"),
484 ("cos", "Cosine", "Cosine Wave"),
485 ("tan", "Tangent", "Tangent Wave"),
489 description
="Trig. Wave Form",
491 trig_cycles
: IntProperty(name
="Cycles #", default
=1, min=1,
492 description
="1 Cycle = 180 Degrees")
493 trig_amp
: FloatProperty(name
="Amplitude", default
=1, min=0.01,
494 description
="Maximum Height of 1 Cycle (forms Basis for Tangents)")
495 trig_len
: FloatProperty(name
="Cycle Length", default
=2, min=0.02,
496 description
="Length in Blender Units of 1 Cycle")
497 trig_obj
: PointerProperty(name
="Object", type=Object
)
498 trig_del
: BoolProperty(name
="Empty Object", default
=False,
499 description
="Delete ALL Vertices in Object First")
500 trig_res
: IntProperty(name
="Resolution", default
=18, min=4, max=72,
501 description
="Number of Vertices per Cycle (180 Degrees)")
502 trig_tanmax
: FloatProperty(name
="Tangent Max", default
=10, min=0.1,
503 description
="Maximum Permitted Tangent Value")
504 trig_off
: FloatVectorProperty(name
="Start Location", default
=(0,0,0),
505 description
="Location in World Space for Origin of Wave")
506 trig_abs
: BoolProperty(name
="Absolute", default
=False,
507 description
="Use Absolute Values Only")
510 # List of All Classes in the Add-on to register
512 # Due to the way PropertyGroups work, this needs to be listed/loaded first
513 # (and unloaded last)
518 pdt_bix
.PDT_OT_LineOnBisection
,
519 pdt_command
.PDT_OT_CommandReRun
,
520 pdt_design
.PDT_OT_PlacementAbs
,
521 pdt_design
.PDT_OT_PlacementDelta
,
522 pdt_design
.PDT_OT_PlacementDis
,
523 pdt_design
.PDT_OT_PlacementCen
,
524 pdt_design
.PDT_OT_PlacementPer
,
525 pdt_design
.PDT_OT_PlacementNormal
,
526 pdt_design
.PDT_OT_PlacementInt
,
527 pdt_design
.PDT_OT_JoinVerts
,
528 pdt_design
.PDT_OT_Angle2
,
529 pdt_design
.PDT_OT_Angle3
,
530 pdt_design
.PDT_OT_Origin
,
531 pdt_design
.PDT_OT_Taper
,
532 pdt_design
.PDT_OT_Fillet
,
533 pdt_etof
.PDT_OT_EdgeToFace
,
534 pdt_library
.PDT_OT_Append
,
535 pdt_library
.PDT_OT_Link
,
536 pdt_library
.PDT_OT_LibShow
,
537 pdt_menus
.PDT_PT_PanelDesign
,
538 pdt_menus
.PDT_PT_PanelTools
,
539 pdt_menus
.PDT_PT_PanelTangent
,
540 pdt_menus
.PDT_PT_PanelCommandLine
,
541 pdt_menus
.PDT_PT_PanelViewControl
,
542 pdt_menus
.PDT_PT_PanelPivotPoint
,
543 pdt_menus
.PDT_PT_PanelPartsLibrary
,
544 pdt_menus
.PDT_PT_PanelTrig
,
545 pdt_pivot_point
.PDT_OT_ModalDrawOperator
,
546 pdt_pivot_point
.PDT_OT_ViewPlaneRotate
,
547 pdt_pivot_point
.PDT_OT_ViewPlaneScale
,
548 pdt_pivot_point
.PDT_OT_PivotToCursor
,
549 pdt_pivot_point
.PDT_OT_CursorToPivot
,
550 pdt_pivot_point
.PDT_OT_PivotSelected
,
551 pdt_pivot_point
.PDT_OT_PivotOrigin
,
552 pdt_pivot_point
.PDT_OT_PivotWrite
,
553 pdt_pivot_point
.PDT_OT_PivotRead
,
554 pdt_tangent
.PDT_OT_TangentOperate
,
555 pdt_tangent
.PDT_OT_TangentOperateSel
,
556 pdt_tangent
.PDT_OT_TangentSet1
,
557 pdt_tangent
.PDT_OT_TangentSet2
,
558 pdt_tangent
.PDT_OT_TangentSet3
,
559 pdt_tangent
.PDT_OT_TangentSet4
,
560 pdt_tangent
.PDT_OT_TangentExpandMenu
,
561 pdt_trig_waves
.PDT_OT_WaveGenerator
,
562 pdt_view
.PDT_OT_ViewRot
,
563 pdt_view
.PDT_OT_ViewRotL
,
564 pdt_view
.PDT_OT_ViewRotR
,
565 pdt_view
.PDT_OT_ViewRotU
,
566 pdt_view
.PDT_OT_ViewRotD
,
567 pdt_view
.PDT_OT_ViewRoll
,
568 pdt_view
.PDT_OT_ViewIso
,
569 pdt_view
.PDT_OT_Reset3DView
,
570 pdt_xall
.PDT_OT_IntersectAllEdges
,
575 """Register Classes and Create Scene Variables.
577 Operates on the classes list defined above.
580 from bpy
.utils
import register_class
587 window_manager
= WindowManager
588 # Register Internal OpenGL Property
590 window_manager
.pdt_run_opengl
= BoolProperty(default
=False)
592 Scene
.pdt_pg
= PointerProperty(type=PDTSceneProperties
)
596 """Unregister Classes and Delete Scene Variables.
598 Operates on the classes list defined above.
601 from bpy
.utils
import unregister_class
604 pdt_pivot_point
.PDT_OT_ModalDrawOperator
.handle_remove(
605 pdt_pivot_point
.PDT_OT_ModalDrawOperator
, bpy
.context
607 window_manager
= bpy
.context
.window_manager
608 pdt_wm
= "pdt_run_opengl"
609 if pdt_wm
in window_manager
:
610 del window_manager
[pdt_wm
]
612 for cls
in reversed(classes
):
613 unregister_class(cls
)
618 if __name__
== "__main__":