1 # SPDX-License-Identifier: GPL-2.0-or-later
5 # -----------------------------------------------------------------------
6 # Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019
7 # -----------------------------------------------------------------------
9 # ----------------------------------------------
11 # ----------------------------------------------
14 "name": "Precision Drawing Tools (PDT)",
15 "author": "Alan Odom (Clockmender), Rune Morling (ermo)",
18 "location": "View3D > UI > PDT",
19 "description": "Precision Drawing Tools for Accurate Modelling",
21 "doc_url": "{BLENDER_MANUAL_URL}/addons/3d_view/precision_drawing_tools/index.html",
22 "category": "3D View",
26 # ----------------------------------------------
28 # ----------------------------------------------
32 importlib
.reload(pdt_design
)
33 importlib
.reload(pdt_pivot_point
)
34 importlib
.reload(pdt_menus
)
35 importlib
.reload(pdt_library
)
36 importlib
.reload(pdt_view
)
37 importlib
.reload(pdt_xall
)
38 importlib
.reload(pdt_bix
)
39 importlib
.reload(pdt_etof
)
40 importlib
.reload(pdt_tangent
)
41 importlib
.reload(pdt_trig_waves
)
43 from . import pdt_design
44 from . import pdt_pivot_point
45 from . import pdt_menus
46 from . import pdt_library
47 from . import pdt_view
48 from . import pdt_xall
50 from . import pdt_etof
51 from . import pdt_tangent
52 from . import pdt_trig_waves
56 from pathlib
import Path
57 from bpy
.types
import (
63 from bpy
.props
import (
73 from .pdt_msg_strings
import (
113 from .pdt_command
import command_run
114 from .pdt_functions
import scale_set
117 # Declare enum items variables
124 class PDTPreferences(AddonPreferences
):
125 # This must match the addon name, use '__package__'
126 # when defining this in a submodule of a python package.
131 name
="Enable console debug output from PDT scripts",
133 description
="NOTE: Does not enable debugging globally in Blender (only in PDT scripts)",
136 pdt_ui_width
: IntProperty(
137 name
="UI Width Cut-off",
139 description
="Cutoff width for shrinking items per line in menus",
142 pdt_input_round
: IntProperty(
143 name
="Input Rounding", default
=5, description
="Rounding Factor for Inputs"
146 def draw(self
, context
):
152 row1
.prop(self
, "debug")
153 row2
.prop(self
, "pdt_ui_width")
154 row2
.prop(self
, "pdt_input_round")
157 def enumlist_objects(self
, context
):
158 """Populate Objects List from Parts Library.
160 Creates list of objects that optionally have search string contained in them
161 to populate variable pdt_lib_objects enumerator.
164 context: Blender bpy.context instance.
167 list of Object Names.
170 scene
= context
.scene
172 file_path
= pg
.pdt_library_path
173 path
= Path(bpy
.path
.abspath(file_path
))
174 _pdt_obj_items
.clear()
176 if path
.is_file() and ".blend" in str(path
):
177 with bpy
.data
.libraries
.load(str(path
)) as (data_from
, _
):
178 if len(pg
.object_search_string
) == 0:
179 object_names
= [obj
for obj
in data_from
.objects
]
181 object_names
= [obj
for obj
in data_from
.objects
if pg
.object_search_string
in obj
]
182 for object_name
in object_names
:
183 _pdt_obj_items
.append((object_name
, object_name
, ""))
185 _pdt_obj_items
.append(("MISSING", "Library Not Set", ""))
186 return _pdt_obj_items
189 def enumlist_collections(self
, context
):
190 """Populate Collections List from Parts Library.
192 Creates list of collections that optionally have search string contained in them
193 to populate variable pg.lib_collections enumerator
196 context: Blender bpy.context instance.
199 list of Collections Names.
202 scene
= context
.scene
204 file_path
= pg
.pdt_library_path
205 path
= Path(bpy
.path
.abspath(file_path
))
206 _pdt_col_items
.clear()
208 if path
.is_file() and ".blend" in str(path
):
209 with bpy
.data
.libraries
.load(str(path
)) as (data_from
, _
):
210 if len(pg
.collection_search_string
) == 0:
211 object_names
= [obj
for obj
in data_from
.collections
]
214 obj
for obj
in data_from
.collections
if pg
.collection_search_string
in obj
216 for object_name
in object_names
:
217 _pdt_col_items
.append((object_name
, object_name
, ""))
219 _pdt_col_items
.append(("MISSING", "Library Not Set", ""))
220 return _pdt_col_items
223 def enumlist_materials(self
, context
):
224 """Populate Materials List from Parts Library.
226 Creates list of materials that optionally have search string contained in them
227 to populate variable pg.lib_materials enumerator.
230 context: Blender bpy.context instance.
233 list of Object Names.
236 scene
= context
.scene
238 file_path
= pg
.pdt_library_path
239 path
= Path(bpy
.path
.abspath(file_path
))
240 _pdt_mat_items
.clear()
242 if path
.is_file() and ".blend" in str(path
):
243 with bpy
.data
.libraries
.load(str(path
)) as (data_from
, _
):
244 if len(pg
.material_search_string
) == 0:
245 object_names
= [obj
for obj
in data_from
.materials
]
248 obj
for obj
in data_from
.materials
if pg
.material_search_string
in obj
250 for object_name
in object_names
:
251 _pdt_mat_items
.append((object_name
, object_name
, ""))
253 _pdt_mat_items
.append(("MISSING", "Library Not Set", ""))
254 return _pdt_mat_items
257 class PDTSceneProperties(PropertyGroup
):
258 """Contains all PDT related properties."""
260 pdt_library_path
: StringProperty(
263 description
="Parts Library File",
268 object_search_string
: StringProperty(name
="Search", default
="", description
=PDT_DES_LIBSER
)
269 collection_search_string
: StringProperty(name
="Search", default
="", description
=PDT_DES_LIBSER
)
270 material_search_string
: StringProperty(name
="Search", default
="", description
=PDT_DES_LIBSER
)
272 cartesian_coords
: FloatVectorProperty(
273 name
="Coords", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_COORDS
275 distance
: FloatProperty(
276 name
="Distance", default
=0.0, precision
=5, description
=PDT_DES_OFFDIS
, unit
="LENGTH"
278 angle
: FloatProperty(
279 name
="Angle", min=-180, max=180, default
=0.0, precision
=5, description
=PDT_DES_OFFANG
281 percent
: FloatProperty(name
="Percent", default
=0.0, precision
=5, description
=PDT_DES_OFFPER
)
284 ("XZ", "Front(X-Z)", "Use X-Z Plane"),
285 ("XY", "Top(X-Y)", "Use X-Y Plane"),
286 ("YZ", "Right(Y-Z)", "Use Y-Z Plane"),
287 ("LO", "View", "Use View Plane"),
289 name
="Working Plane",
291 description
=PDT_DES_WORPLANE
,
293 select
: EnumProperty(
295 ("REL", "Current Pos.", "Move Relative to Current Position"),
299 "Move Relative to Selected Object or Vertex (Cursor & Pivot Only)",
304 description
=PDT_DES_MOVESEL
,
306 operation
: EnumProperty(
308 ("CU", "Move Cursor", "This function will Move the Cursor"),
309 ("PP", "Move Pivot Point", "This function will Move the Pivot Point"),
310 ("MV", "Move Entities", "This function will Move selected Vertices or Objects"),
311 ("NV", "Add New Vertex", "This function will Add a New Vertex"),
314 "Extrude Vertex/Vertices",
315 "This function will Extrude Vertex/Vertices Only in EDIT Mode",
317 ("SE", "Split Edges", "This function will Split Edges Only in EDIT Mode"),
320 "Duplicate Geometry",
321 "This function will Duplicate Geometry in EDIT Mode (Delta & Direction Only)",
326 "This function will Extrude Geometry in EDIT Mode (Delta & Direction Only)",
331 description
=PDT_DES_OPMODE
,
335 ("RX-MY", "RotX-MovY", "Rotate X - Move Y"),
336 ("RX-MZ", "RotX-MovZ", "Rotate X - Move Z"),
337 ("RY-MX", "RotY-MovX", "Rotate Y - Move X"),
338 ("RY-MZ", "RotY-MovZ", "Rotate Y - Move Z"),
339 ("RZ-MX", "RotZ-MovX", "Rotate Z - Move X"),
340 ("RZ-MY", "RotZ-MovY", "Rotate Z - Move Y"),
344 description
=PDT_DES_ROTMOVAX
,
347 flip_angle
: BoolProperty(name
="Flip Angle", default
=False, description
=PDT_DES_FLIPANG
)
348 flip_percent
: BoolProperty(name
="Flip %", default
=False, description
=PDT_DES_FLIPPER
)
350 extend
: BoolProperty(name
="Trim/Extend All", default
=False, description
=PDT_DES_TRIM
)
352 lib_objects
: EnumProperty(items
=enumlist_objects
, name
="Objects", description
=PDT_DES_LIBOBS
)
353 lib_collections
: EnumProperty(
354 items
=enumlist_collections
, name
="Collections", description
=PDT_DES_LIBCOLS
356 lib_materials
: EnumProperty(
357 items
=enumlist_materials
, name
="Materials", description
=PDT_DES_LIBMATS
359 lib_mode
: EnumProperty(
361 ("OBJECTS", "Objects", "Use Objects"),
362 ("COLLECTIONS", "Collections", "Use Collections"),
363 ("MATERIALS", "Materials", "Use Materials"),
367 description
=PDT_DES_LIBMODE
,
370 rotation_coords
: FloatVectorProperty(
371 name
="Rotation", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
="Rotation Coordinates"
374 object_order
: EnumProperty(
376 ("1,2,3,4", "1,2,3,4", "Objects 1 & 2 are First Line"),
377 ("1,3,2,4", "1,3,2,4", "Objects 1 & 3 are First Line"),
378 ("1,4,2,3", "1,4,2,3", "Objects 1 & 4 are First Line"),
382 description
=PDT_DES_OBORDER
,
384 vrotangle
: FloatProperty(name
="View Rotate Angle", default
=10, max=180, min=-180)
385 command
: StringProperty(
386 name
="Command", default
="CA0,0,0", update
=command_run
, description
=PDT_DES_VALIDLET
,
388 maths_output
: FloatProperty(
389 name
="Maths output", default
=0, description
=PDT_DES_OUTPUT
,
391 error
: StringProperty(name
="Error", default
="")
393 # Was pivot* -- is now pivot_*
394 pivot_loc
: FloatVectorProperty(
395 name
="Pivot Location", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_PPLOC
,
397 pivot_scale
: FloatVectorProperty(
398 name
="Pivot Scale", default
=(1.0, 1.0, 1.0), subtype
="XYZ", description
=PDT_DES_PPSCALEFAC
400 pivot_size
: FloatProperty(
401 name
="Pivot Factor", min=0.4, max=10, default
=2, precision
=1, description
=PDT_DES_PPSIZE
403 pivot_width
: IntProperty(name
="Width", min=1, max=5, default
=2, description
=PDT_DES_PPWIDTH
)
405 pivot_ang
: FloatProperty(name
="Pivot Angle", min=-180, max=180, default
=0.0)
407 pivot_dis
: FloatProperty(
408 name
="Pivot Dist", default
=0.0, min=0, update
=scale_set
, description
=PDT_DES_PIVOTDIS
,
410 pivot_alpha
: FloatProperty(
411 name
="Alpha", min=0.2, max=1, default
=0.6, precision
=1, description
=PDT_DES_PPTRANS
,
413 pivot_show
: BoolProperty()
416 fillet_radius
: FloatProperty(
417 name
="Fillet Radius", min=0.0, default
=1.0, unit
="LENGTH", description
=PDT_DES_FILLETRAD
420 fillet_segments
: IntProperty(
421 name
="Fillet Segments", min=1, default
=4, description
=PDT_DES_FILLETSEG
424 fillet_profile
: FloatProperty(
425 name
="Fillet Profile", min=0.0, max=1.0, default
=0.5, description
=PDT_DES_FILLETPROF
428 fillet_vertices_only
: BoolProperty(
429 name
="Fillet Vertices Only", default
=True, description
=PDT_DES_FILLETVERTS
,
431 fillet_intersect
: BoolProperty(
432 name
="Intersect", default
=False, description
=PDT_DES_FILLINT
,
434 tangent_point0
: FloatVectorProperty(
435 name
="Coordst1", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_TANCEN1
437 tangent_point1
: FloatVectorProperty(
438 name
="Coordst2", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_TANCEN2
440 tangent_radius0
: FloatProperty(
441 name
="Arc Radius 1", min=0.00001, default
=1, unit
="LENGTH", description
=PDT_DES_RADIUS1
443 tangent_radius1
: FloatProperty(
444 name
="Arc Radius 2", min=0.00001, default
=1, unit
="LENGTH", description
=PDT_DES_RADIUS2
446 tangent_point2
: FloatVectorProperty(
447 name
="Coordst3", default
=(0.0, 0.0, 0.0), subtype
="XYZ", description
=PDT_DES_TANCEN3
449 menu_expand
: BoolProperty(
450 name
="Expand", default
=False, description
=PDT_DES_EXPCOLL
,
452 tangent_mode
: EnumProperty(
454 ("inner", "Inner", "Inner Tangents"),
455 ("outer", "Outer", "Outer Tangents"),
456 ("both", "Inner & Outer", "Inner & Outer Tangents"),
457 ("point", "From Point", "Tangents from Point"),
459 name
="Working Plane",
461 description
=PDT_DES_TANMODE
,
465 trig_type
: EnumProperty(
467 ("sin", "Sine", "Sine Wave"),
468 ("cos", "Cosine", "Cosine Wave"),
469 ("tan", "Tangent", "Tangent Wave"),
473 description
="Trig. Wave Form",
475 trig_cycles
: IntProperty(name
="Cycles #", default
=1, min=1,
476 description
="1 Cycle = 180 Degrees")
477 trig_amp
: FloatProperty(name
="Amplitude", default
=1, min=0.01,
478 description
="Maximum Height of 1 Cycle (forms Basis for Tangents)")
479 trig_len
: FloatProperty(name
="Cycle Length", default
=2, min=0.02,
480 description
="Length in Blender Units of 1 Cycle")
481 trig_obj
: PointerProperty(name
="Object", type=Object
)
482 trig_del
: BoolProperty(name
="Empty Object", default
=False,
483 description
="Delete ALL Vertices in Object First")
484 trig_res
: IntProperty(name
="Resolution", default
=18, min=4, max=72,
485 description
="Number of Vertices per Cycle (180 Degrees)")
486 trig_tanmax
: FloatProperty(name
="Tangent Max", default
=10, min=0.1,
487 description
="Maximum Permitted Tangent Value")
488 trig_off
: FloatVectorProperty(name
="Start Location", default
=(0,0,0),
489 description
="Location in World Space for Origin of Wave")
490 trig_abs
: BoolProperty(name
="Absolute", default
=False,
491 description
="Use Absolute Values Only")
494 # List of All Classes in the Add-on to register
496 # Due to the way PropertyGroups work, this needs to be listed/loaded first
497 # (and unloaded last)
502 pdt_bix
.PDT_OT_LineOnBisection
,
503 pdt_command
.PDT_OT_CommandReRun
,
504 pdt_design
.PDT_OT_PlacementAbs
,
505 pdt_design
.PDT_OT_PlacementDelta
,
506 pdt_design
.PDT_OT_PlacementDis
,
507 pdt_design
.PDT_OT_PlacementView
,
508 pdt_design
.PDT_OT_PlacementCen
,
509 pdt_design
.PDT_OT_PlacementPer
,
510 pdt_design
.PDT_OT_PlacementNormal
,
511 pdt_design
.PDT_OT_PlacementInt
,
512 pdt_design
.PDT_OT_JoinVerts
,
513 pdt_design
.PDT_OT_Angle2
,
514 pdt_design
.PDT_OT_Angle3
,
515 pdt_design
.PDT_OT_Origin
,
516 pdt_design
.PDT_OT_Taper
,
517 pdt_design
.PDT_OT_Fillet
,
518 pdt_etof
.PDT_OT_EdgeToFace
,
519 pdt_library
.PDT_OT_Append
,
520 pdt_library
.PDT_OT_Link
,
521 pdt_library
.PDT_OT_LibShow
,
522 pdt_menus
.PDT_PT_PanelDesign
,
523 pdt_menus
.PDT_PT_PanelTools
,
524 pdt_menus
.PDT_PT_PanelTangent
,
525 pdt_menus
.PDT_PT_PanelCommandLine
,
526 pdt_menus
.PDT_PT_PanelViewControl
,
527 pdt_menus
.PDT_PT_PanelPivotPoint
,
528 pdt_menus
.PDT_PT_PanelPartsLibrary
,
529 pdt_menus
.PDT_PT_PanelTrig
,
530 pdt_pivot_point
.PDT_OT_ModalDrawOperator
,
531 pdt_pivot_point
.PDT_OT_ViewPlaneRotate
,
532 pdt_pivot_point
.PDT_OT_ViewPlaneScale
,
533 pdt_pivot_point
.PDT_OT_PivotToCursor
,
534 pdt_pivot_point
.PDT_OT_CursorToPivot
,
535 pdt_pivot_point
.PDT_OT_PivotSelected
,
536 pdt_pivot_point
.PDT_OT_PivotOrigin
,
537 pdt_pivot_point
.PDT_OT_PivotWrite
,
538 pdt_pivot_point
.PDT_OT_PivotRead
,
539 pdt_tangent
.PDT_OT_TangentOperate
,
540 pdt_tangent
.PDT_OT_TangentOperateSel
,
541 pdt_tangent
.PDT_OT_TangentSet1
,
542 pdt_tangent
.PDT_OT_TangentSet2
,
543 pdt_tangent
.PDT_OT_TangentSet3
,
544 pdt_tangent
.PDT_OT_TangentSet4
,
545 pdt_tangent
.PDT_OT_TangentExpandMenu
,
546 pdt_trig_waves
.PDT_OT_WaveGenerator
,
547 pdt_view
.PDT_OT_ViewRot
,
548 pdt_view
.PDT_OT_ViewRotL
,
549 pdt_view
.PDT_OT_ViewRotR
,
550 pdt_view
.PDT_OT_ViewRotU
,
551 pdt_view
.PDT_OT_ViewRotD
,
552 pdt_view
.PDT_OT_ViewRoll
,
553 pdt_view
.PDT_OT_ViewIso
,
554 pdt_view
.PDT_OT_Reset3DView
,
555 pdt_xall
.PDT_OT_IntersectAllEdges
,
560 """Register Classes and Create Scene Variables.
562 Operates on the classes list defined above.
565 from bpy
.utils
import register_class
572 window_manager
= WindowManager
573 # Register Internal OpenGL Property
575 window_manager
.pdt_run_opengl
= BoolProperty(default
=False)
577 Scene
.pdt_pg
= PointerProperty(type=PDTSceneProperties
)
581 """Unregister Classes and Delete Scene Variables.
583 Operates on the classes list defined above.
586 from bpy
.utils
import unregister_class
589 pdt_pivot_point
.PDT_OT_ModalDrawOperator
.handle_remove(
590 pdt_pivot_point
.PDT_OT_ModalDrawOperator
, bpy
.context
592 window_manager
= bpy
.context
.window_manager
593 pdt_wm
= "pdt_run_opengl"
594 if pdt_wm
in window_manager
:
595 del window_manager
[pdt_wm
]
597 for cls
in reversed(classes
):
598 unregister_class(cls
)
603 if __name__
== "__main__":