Fix T78854: Cell fracture fails in background mode
[blender-addons.git] / precision_drawing_tools / __init__.py
blobc1769062f591c0fc9de2999b2f67f1f93c681a8f
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # <pep8 compliant>
5 # -----------------------------------------------------------------------
6 # Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019
7 # -----------------------------------------------------------------------
9 # ----------------------------------------------
10 # Define Addon info
11 # ----------------------------------------------
13 bl_info = {
14 "name": "Precision Drawing Tools (PDT)",
15 "author": "Alan Odom (Clockmender), Rune Morling (ermo)",
16 "version": (1, 5, 2),
17 "blender": (3, 0, 0),
18 "location": "View3D > UI > PDT",
19 "description": "Precision Drawing Tools for Accurate Modelling",
20 "warning": "",
21 "doc_url": "{BLENDER_MANUAL_URL}/addons/3d_view/precision_drawing_tools/index.html",
22 "category": "3D View",
26 # ----------------------------------------------
27 # Import modules
28 # ----------------------------------------------
29 if "bpy" in locals():
30 import importlib
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)
42 else:
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
49 from . import pdt_bix
50 from . import pdt_etof
51 from . import pdt_tangent
52 from . import pdt_trig_waves
54 import bpy
55 import os
56 from pathlib import Path
57 from bpy.types import (
58 AddonPreferences,
59 PropertyGroup, Scene,
60 WindowManager,
61 Object,
63 from bpy.props import (
64 BoolProperty,
65 CollectionProperty,
66 EnumProperty,
67 FloatProperty,
68 FloatVectorProperty,
69 IntProperty,
70 PointerProperty,
71 StringProperty,
73 from .pdt_msg_strings import (
74 PDT_DES_COORDS,
75 PDT_DES_FILLETPROF,
76 PDT_DES_FILLETRAD,
77 PDT_DES_FILLETSEG,
78 PDT_DES_FILLETVERTS,
79 PDT_DES_FILLINT,
80 PDT_DES_FLIPANG,
81 PDT_DES_FLIPPER,
82 PDT_DES_LIBCOLS,
83 PDT_DES_LIBMATS,
84 PDT_DES_LIBMODE,
85 PDT_DES_LIBOBS,
86 PDT_DES_LIBSER,
87 PDT_DES_MOVESEL,
88 PDT_DES_OBORDER,
89 PDT_DES_OFFANG,
90 PDT_DES_OFFDIS,
91 PDT_DES_OFFPER,
92 PDT_DES_OPMODE,
93 PDT_DES_OUTPUT,
94 PDT_DES_PIVOTDIS,
95 PDT_DES_PPLOC,
96 PDT_DES_PPSCALEFAC,
97 PDT_DES_PPSIZE,
98 PDT_DES_PPTRANS,
99 PDT_DES_PPWIDTH,
100 PDT_DES_ROTMOVAX,
101 PDT_DES_TRIM,
102 PDT_DES_VALIDLET,
103 PDT_DES_WORPLANE,
104 PDT_DES_TANCEN1,
105 PDT_DES_TANCEN2,
106 PDT_DES_TANCEN3,
107 PDT_DES_RADIUS1,
108 PDT_DES_RADIUS2,
109 PDT_DES_TPOINT,
110 PDT_DES_EXPCOLL,
111 PDT_DES_TANMODE,
113 from .pdt_command import command_run
114 from .pdt_functions import scale_set
117 # Declare enum items variables
119 _pdt_obj_items = []
120 _pdt_col_items = []
121 _pdt_mat_items = []
124 class PDTPreferences(AddonPreferences):
125 # This must match the addon name, use '__package__'
126 # when defining this in a submodule of a python package.
128 bl_idname = __name__
130 debug: BoolProperty(
131 name="Enable console debug output from PDT scripts",
132 default=False,
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",
138 default=350,
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):
147 layout = self.layout
149 box = layout.box()
150 row1 = box.row()
151 row2 = box.row()
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.
163 Args:
164 context: Blender bpy.context instance.
166 Returns:
167 list of Object Names.
170 scene = context.scene
171 pg = scene.pdt_pg
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]
180 else:
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, ""))
184 else:
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
195 Args:
196 context: Blender bpy.context instance.
198 Returns:
199 list of Collections Names.
202 scene = context.scene
203 pg = scene.pdt_pg
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]
212 else:
213 object_names = [
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, ""))
218 else:
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.
229 Args:
230 context: Blender bpy.context instance.
232 Returns:
233 list of Object Names.
236 scene = context.scene
237 pg = scene.pdt_pg
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]
246 else:
247 object_names = [
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, ""))
252 else:
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(
261 name="Library",
262 default="",
263 description="Parts Library File",
264 maxlen=1024,
265 subtype="FILE_PATH",
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)
282 plane: EnumProperty(
283 items=(
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",
290 default="XZ",
291 description=PDT_DES_WORPLANE,
293 select: EnumProperty(
294 items=(
295 ("REL", "Current Pos.", "Move Relative to Current Position"),
297 "SEL",
298 "Selected Entities",
299 "Move Relative to Selected Object or Vertex (Cursor & Pivot Only)",
302 name="Move Mode",
303 default="SEL",
304 description=PDT_DES_MOVESEL,
306 operation: EnumProperty(
307 items=(
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"),
313 "EV",
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"),
319 "DG",
320 "Duplicate Geometry",
321 "This function will Duplicate Geometry in EDIT Mode (Delta & Direction Only)",
324 "EG",
325 "Extrude Geometry",
326 "This function will Extrude Geometry in EDIT Mode (Delta & Direction Only)",
329 name="Operation",
330 default="CU",
331 description=PDT_DES_OPMODE,
333 taper: EnumProperty(
334 items=(
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"),
342 name="Axes",
343 default="RX-MY",
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(
360 items=(
361 ("OBJECTS", "Objects", "Use Objects"),
362 ("COLLECTIONS", "Collections", "Use Collections"),
363 ("MATERIALS", "Materials", "Use Materials"),
365 name="Mode",
366 default="OBJECTS",
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(
375 items=(
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"),
380 name="Order",
381 default="1,2,3,4",
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()
415 # Was filletrad
416 fillet_radius: FloatProperty(
417 name="Fillet Radius", min=0.0, default=1.0, unit="LENGTH", description=PDT_DES_FILLETRAD
419 # Was filletnum
420 fillet_segments: IntProperty(
421 name="Fillet Segments", min=1, default=4, description=PDT_DES_FILLETSEG
423 # Was filletpro
424 fillet_profile: FloatProperty(
425 name="Fillet Profile", min=0.0, max=1.0, default=0.5, description=PDT_DES_FILLETPROF
427 # Was filletbool
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(
453 items=(
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",
460 default="both",
461 description=PDT_DES_TANMODE,
464 # For Trig Waves
465 trig_type : EnumProperty(
466 items=(
467 ("sin", "Sine", "Sine Wave"),
468 ("cos", "Cosine", "Cosine Wave"),
469 ("tan", "Tangent", "Tangent Wave"),
471 name="Wave Form",
472 default="sin",
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)
499 classes = (
500 PDTPreferences,
501 PDTSceneProperties,
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,
559 def register():
560 """Register Classes and Create Scene Variables.
562 Operates on the classes list defined above.
565 from bpy.utils import register_class
567 for cls in classes:
568 register_class(cls)
570 # OpenGL flag
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)
580 def unregister():
581 """Unregister Classes and Delete Scene Variables.
583 Operates on the classes list defined above.
586 from bpy.utils import unregister_class
588 # remove OpenGL data
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)
600 del Scene.pdt_pg
603 if __name__ == "__main__":
604 register()