1# ***** BEGIN GPL LICENSE BLOCK ***** 2# 3# 4# This program is free software; you can redistribute it and/or 5# modify it under the terms of the GNU General Public License 6# as published by the Free Software Foundation; either version 2 7# of the License, or (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program; if not, write to the Free Software Foundation, 16# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17# 18# ***** END GPL LICENCE BLOCK ***** 19# 20# ----------------------------------------------------------------------- 21# Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019 22# ----------------------------------------------------------------------- 23# 24import bpy 25from bpy.types import Panel 26from .pdt_msg_strings import ( 27 PDT_LAB_ABS, 28 PDT_LAB_AD2D, 29 PDT_LAB_AD3D, 30 PDT_LAB_ALLACTIVE, 31 PDT_LAB_ANGLEVALUE, 32 PDT_LAB_ARCCENTRE, 33 PDT_LAB_BISECT, 34 PDT_LAB_CVALUE, 35 PDT_LAB_DEL, 36 PDT_LAB_DIR, 37 PDT_LAB_DISVALUE, 38 PDT_LAB_EDGETOEFACE, 39 PDT_LAB_FILLET, 40 PDT_LAB_FLIPANGLE, 41 PDT_LAB_FLIPPERCENT, 42 PDT_LAB_INTERSECT, 43 PDT_LAB_INTERSETALL, 44 PDT_LAB_JOIN2VERTS, 45 PDT_LAB_MODE, 46 PDT_LAB_NOR, 47 PDT_LAB_OPERATION, 48 PDT_LAB_ORDER, 49 PDT_LAB_ORIGINCURSOR, 50 PDT_LAB_PERCENT, 51 PDT_LAB_PERCENTS, 52 PDT_LAB_PIVOTALPHA, 53 PDT_LAB_PIVOTLOC, 54 PDT_LAB_PIVOTLOCH, 55 PDT_LAB_PIVOTSIZE, 56 PDT_LAB_PIVOTWIDTH, 57 PDT_LAB_PLANE, 58 PDT_LAB_PROFILE, 59 PDT_LAB_RADIUS, 60 PDT_LAB_SEGMENTS, 61 PDT_LAB_TAPER, 62 PDT_LAB_TAPERAXES, 63 PDT_LAB_TOOLS, 64 PDT_LAB_USEVERTS, 65 PDT_LAB_VARIABLES 66) 67 68def ui_width(): 69 """Return the Width of the UI Panel. 70 71 Args: 72 None. 73 74 Returns: 75 UI Width. 76 """ 77 78 area = bpy.context.area 79 resolution = bpy.context.preferences.system.ui_scale 80 81 for reg in area.regions: 82 if reg.type == "UI": 83 region_width = reg.width 84 return region_width 85 86# PDT Panel menus 87# 88class PDT_PT_PanelDesign(Panel): 89 bl_idname = "PDT_PT_PanelDesign" 90 bl_label = "PDT Design Operations" 91 bl_space_type = "VIEW_3D" 92 bl_region_type = "UI" 93 bl_category = "PDT" 94 bl_options = {'DEFAULT_CLOSED'} 95 96 def draw(self, context): 97 ui_cutoff = bpy.context.preferences.addons[__package__].preferences.pdt_ui_width 98 layout = self.layout 99 pdt_pg = context.scene.pdt_pg 100 # 101 # Working Plane 102 row = layout.row() 103 row.label(text=f"Working {PDT_LAB_PLANE}:") 104 row.prop(pdt_pg, "plane", text="") 105 # 106 # Move Mode 107 row = layout.row() 108 row.label(text=f"Move {PDT_LAB_MODE}:") 109 row.prop(pdt_pg, "select", text="") 110 # 111 # Active or All Selected 112 row = layout.row() 113 #row.label(text="") 114 row.prop(pdt_pg, "extend", text="All Selected Entities (Off: Active Only)") 115 116 # -------------------- 117 # (1) Select Operation 118 row = layout.row() 119 box_1 = row.box() 120 row = box_1.row() 121 row.label(text=f"(1) Select {PDT_LAB_OPERATION}:") 122 row.prop(pdt_pg, "operation", text="") 123 124 # ----------------------- 125 # (a) Set Coordinates box 126 row = box_1.row() 127 box_1a = row.box() 128 box_1a.label(text=f"(a) Either Set Coordinates + [Place »]") 129 # ^ was PDT_LAB_VARIABLES 130 # 131 # cartesian input coordinates in a box 132 row = box_1a.row() 133 box = row.box() 134 row = box.row() 135 split = row.split(factor=0.35, align=True) 136 split.label(text=PDT_LAB_CVALUE) 137 split.prop(pdt_pg, "cartesian_coords", text="") 138 row = box.row() 139 row.operator("pdt.absolute", icon="EMPTY_AXIS", text=f"{PDT_LAB_ABS} »") 140 row.operator("pdt.delta", icon="EMPTY_AXIS", text=f"{PDT_LAB_DEL} »") 141 # 142 # directional input coordinates in a box 143 row = box_1a.row() 144 box = row.box() 145 #box.label(text="Directional/Polar Coordinates:") 146 row = box.row() 147 row.prop(pdt_pg, "distance", text=PDT_LAB_DISVALUE) 148 row.prop(pdt_pg, "angle", text=PDT_LAB_ANGLEVALUE) 149 row = box.row() 150 row.operator("pdt.distance", icon="EMPTY_AXIS", text=f"{PDT_LAB_DIR} »") 151 row.prop(pdt_pg, "flip_angle", text=PDT_LAB_FLIPANGLE) 152 153 # --------------------- 154 # (b) Miscellaneous box 155 row = box_1.row() 156 box_1b = row.box() 157 box_1b.label(text="(b) Or Select |n| Entities + [Place »]") 158 # 159 # normal or arc centre 160 row = box_1b.row() 161 row.operator("pdt.normal", text=f"|3| {PDT_LAB_NOR} »") 162 row.operator("pdt.centre", text=f"|3| {PDT_LAB_ARCCENTRE} »") 163 # 164 # Intersect 165 box = box_1b.box() 166 row = box.row() 167 row.operator("pdt.intersect", text=f"|4| {PDT_LAB_INTERSECT} »") 168 if ui_width() < ui_cutoff: 169 row = box.row() 170 row.prop(pdt_pg, "object_order", text=PDT_LAB_ORDER) 171 # 172 # percentage row 173 row = box_1b.row() 174 box = row.box() 175 box.label(text=f"Do (1) at % between selected points") 176 row = box.row() 177 row.operator("pdt.percent", text=f"|2| % »") 178 row.prop(pdt_pg, "percent", text=PDT_LAB_PERCENTS) 179 if ui_width() < ui_cutoff: 180 row = box.row() 181 row.prop(pdt_pg, "flip_percent", text=PDT_LAB_FLIPPERCENT) 182 183class PDT_PT_PanelTools(Panel): 184 bl_idname = "PDT_PT_PanelTools" 185 bl_label = "PDT Design Tools" 186 bl_space_type = "VIEW_3D" 187 bl_region_type = "UI" 188 bl_category = "PDT" 189 bl_options = {'DEFAULT_CLOSED'} 190 191 def draw(self, context): 192 ui_cutoff = bpy.context.preferences.addons[__package__].preferences.pdt_ui_width 193 layout = self.layout 194 pdt_pg = context.scene.pdt_pg 195 # ----- 196 # Tools 197 row = layout.row() 198 row.label(text=PDT_LAB_TOOLS) 199 row = layout.row() 200 row.operator("pdt.origin", text=PDT_LAB_ORIGINCURSOR) 201 row = layout.row() 202 row.operator("pdt.angle2", text=PDT_LAB_AD2D) 203 row.operator("pdt.angle3", text=PDT_LAB_AD3D) 204 row = layout.row() 205 row.operator("pdt.join", text=PDT_LAB_JOIN2VERTS) 206 row.operator("pdt.linetobisect", text=PDT_LAB_BISECT) 207 row = layout.row() 208 row.operator("pdt.edge_to_face", text=PDT_LAB_EDGETOEFACE) 209 row.operator("pdt.intersectall", text=PDT_LAB_INTERSETALL) 210 # 211 # Taper tool 212 box = layout.box() 213 row = box.row() 214 row.operator("pdt.taper", text=PDT_LAB_TAPER) 215 row.prop(pdt_pg, "taper", text=PDT_LAB_TAPERAXES) 216 # 217 # Fillet tool 218 box = layout.box() 219 row = box.row() 220 row.operator("pdt.fillet", text=f"{PDT_LAB_FILLET}") 221 row.prop(pdt_pg, "fillet_intersect", text="Intersect") 222 row = box.row() 223 row.prop(pdt_pg, "fillet_radius", text=PDT_LAB_RADIUS) 224 row.prop(pdt_pg, "fillet_profile", text=PDT_LAB_PROFILE) 225 row = box.row() 226 row.prop(pdt_pg, "fillet_segments", text=PDT_LAB_SEGMENTS) 227 row.prop(pdt_pg, "fillet_vertices_only", text=PDT_LAB_USEVERTS) 228 229 230class PDT_PT_PanelPivotPoint(Panel): 231 bl_idname = "PDT_PT_PanelPivotPoint" 232 bl_label = "PDT Pivot Point" 233 bl_space_type = "VIEW_3D" 234 bl_region_type = "UI" 235 bl_category = "PDT" 236 bl_options = {'DEFAULT_CLOSED'} 237 238 def draw(self, context): 239 ui_cutoff = bpy.context.preferences.addons[__package__].preferences.pdt_ui_width 240 pdt_pg = context.scene.pdt_pg 241 layout = self.layout 242 row = layout.row() 243 col = row.column() 244 if context.window_manager.pdt_run_opengl is False: 245 icon = "PLAY" 246 txt = "Show" 247 else: 248 icon = "PAUSE" 249 txt = "Hide" 250 col.operator("pdt.modaldraw", icon=icon, text=txt) 251 col = row.column() 252 col.prop(pdt_pg, "pivot_size", text=PDT_LAB_PIVOTSIZE) 253 if ui_width() < ui_cutoff: 254 row = layout.row() 255 col = row.column() 256 col.prop(pdt_pg, "pivot_width", text=PDT_LAB_PIVOTWIDTH) 257 col = row.column() 258 col.prop(pdt_pg, "pivot_alpha", text=PDT_LAB_PIVOTALPHA) 259 row = layout.row() 260 split = row.split(factor=0.35, align=True) 261 split.label(text=PDT_LAB_PIVOTLOCH) 262 split.prop(pdt_pg, "pivot_loc", text=PDT_LAB_PIVOTLOC) 263 row = layout.row() 264 col = row.column() 265 col.operator("pdt.pivotselected", icon="EMPTY_AXIS", text="Selection") 266 col = row.column() 267 col.operator("pdt.pivotcursor", icon="EMPTY_AXIS", text="Cursor") 268 col = row.column() 269 col.operator("pdt.pivotorigin", icon="EMPTY_AXIS", text="Origin") 270 row = layout.row() 271 col = row.column() 272 col.operator("pdt.viewplanerot", icon="EMPTY_AXIS", text="Rotate") 273 col = row.column() 274 col.prop(pdt_pg, "pivot_ang", text="Angle") 275 row = layout.row() 276 col = row.column() 277 col.operator("pdt.viewscale", icon="EMPTY_AXIS", text="Scale") 278 col = row.column() 279 col.operator("pdt.cursorpivot", icon="EMPTY_AXIS", text="Cursor To Pivot") 280 row = layout.row() 281 col = row.column() 282 col.prop(pdt_pg, "pivot_dis", text="Scale Distance") 283 col = row.column() 284 col.prop(pdt_pg, "distance", text="System Distance") 285 row = layout.row() 286 split = row.split(factor=0.35, align=True) 287 split.label(text="Scale") 288 split.prop(pdt_pg, "pivot_scale", text="") 289 row = layout.row() 290 col = row.column() 291 col.operator("pdt.pivotwrite", icon="FILE_TICK", text="PP Write") 292 col = row.column() 293 col.operator("pdt.pivotread", icon="FILE", text="PP Read") 294 295 296class PDT_PT_PanelPartsLibrary(Panel): 297 bl_idname = "PDT_PT_PanelPartsLibrary" 298 bl_label = "PDT Parts Library" 299 bl_space_type = "VIEW_3D" 300 bl_region_type = "UI" 301 bl_category = "PDT" 302 bl_options = {'DEFAULT_CLOSED'} 303 304 def draw(self, context): 305 ui_cutoff = context.preferences.addons[__package__].preferences.pdt_ui_width 306 layout = self.layout 307 pdt_pg = context.scene.pdt_pg 308 row = layout.row() 309 row.prop(pdt_pg, "pdt_library_path") 310 row = layout.row() 311 col = row.column() 312 col.operator("pdt.append", text="Append") 313 col = row.column() 314 col.operator("pdt.link", text="Link") 315 if ui_width() < ui_cutoff: 316 row = layout.row() 317 col = row.column() 318 col.prop(pdt_pg, "lib_mode", text="") 319 box = layout.box() 320 row = box.row() 321 col = row.column() 322 col.label(text="Objects") 323 col = row.column() 324 col.prop(pdt_pg, "object_search_string") 325 row = box.row() 326 row.prop(pdt_pg, "lib_objects", text="") 327 box = layout.box() 328 row = box.row() 329 col = row.column() 330 col.label(text="Collections") 331 col = row.column() 332 col.prop(pdt_pg, "collection_search_string") 333 row = box.row() 334 row.prop(pdt_pg, "lib_collections", text="") 335 box = layout.box() 336 row = box.row() 337 col = row.column() 338 col.label(text="Materials") 339 col = row.column() 340 col.prop(pdt_pg, "material_search_string") 341 row = box.row() 342 row.prop(pdt_pg, "lib_materials", text="") 343 row = box.row() 344 #row.operator("pdt.lib_show", text="Load Library File", icon='INFO') 345 346 347class PDT_PT_PanelViewControl(Panel): 348 bl_idname = "PDT_PT_PanelViewControl" 349 bl_label = "PDT View Control" 350 bl_space_type = "VIEW_3D" 351 bl_region_type = "UI" 352 bl_category = "PDT" 353 bl_options = {'DEFAULT_CLOSED'} 354 355 # Sub-layout highlight states 356 _ui_groups = [False, False] 357 358 def draw(self, context): 359 ui_cutoff = context.preferences.addons[__package__].preferences.pdt_ui_width 360 layout = self.layout 361 ui_groups = self._ui_groups 362 pdt_pg = context.scene.pdt_pg 363 box = layout.box() 364 row = box.row() 365 col = row.column() 366 col.label(text="View Rotation") 367 col = row.column() 368 col.operator("pdt.viewrot", text="Rotate Abs") 369 row = box.row() 370 split = row.split(factor=0.35, align=True) 371 split.label(text="Rotation") 372 split.prop(pdt_pg, "rotation_coords", text="") 373 row = box.row() 374 col = row.column() 375 col.prop(pdt_pg, "vrotangle", text="Angle") 376 if ui_width() < ui_cutoff: 377 row = box.row() 378 col = row.column() 379 col.operator("pdt.viewleft", text="", icon="TRIA_LEFT") 380 col = row.column() 381 col.operator("pdt.viewright", text="", icon="TRIA_RIGHT") 382 col = row.column() 383 col.operator("pdt.viewup", text="", icon="TRIA_UP") 384 col = row.column() 385 col.operator("pdt.viewdown", text="", icon="TRIA_DOWN") 386 col = row.column() 387 col.operator("pdt.viewroll", text="", icon="RECOVER_LAST") 388 row = box.row() 389 col = row.column() 390 col.operator("pdt.viewiso", text="Isometric") 391 col = row.column() 392 col.operator("pdt.reset_3d_view", text="Reset View") 393 394 395class PDT_PT_PanelCommandLine(Panel): 396 bl_idname = "PDT_PT_PanelCommandLine" 397 bl_label = "PDT Command Line (? for help)" 398 bl_space_type = "VIEW_3D" 399 bl_region_type = "UI" 400 bl_category = "PDT" 401 bl_options = {'DEFAULT_CLOSED'} 402 403 def draw(self, context): 404 layout = self.layout 405 pdt_pg = context.scene.pdt_pg 406 row = layout.row() 407 col = row.column() 408 col.prop(pdt_pg, "plane", text="Plane") 409 col = row.column() 410 col.prop(pdt_pg, "select", text="Mode") 411 row = layout.row() 412 row.label(text="Comand Line, uses Plane & Mode Options") 413 row = layout.row() 414 row.prop(pdt_pg, "command", text="") 415 # Try Re-run 416 row.operator("pdt.command_rerun", text="", icon="LOOP_BACK") 417 row = layout.row() 418 row.prop(pdt_pg, "maths_output", text="Maths Output") 419 420class PDT_PT_PanelTangent(Panel): 421 bl_idname = "PDT_PT_PanelTangent" 422 bl_label = "PDT Tangents" 423 bl_space_type = "VIEW_3D" 424 bl_region_type = "UI" 425 bl_category = "PDT" 426 bl_options = {'DEFAULT_CLOSED'} 427 428 def draw(self,context): 429 layout = self.layout 430 pdt_pg = context.scene.pdt_pg 431 432 if pdt_pg.menu_expand: 433 icon_e = "EVENT_C" 434 else: 435 icon_e = "EVENT_E" 436 row = layout.row() 437 row.label(text=f"Working {PDT_LAB_PLANE}:") 438 row.prop(pdt_pg, "plane", text="") 439 row = layout.row() 440 row.label(text="Tan Mode") 441 row.prop(pdt_pg, "tangent_mode", text="") 442 row = layout.row() 443 row.operator("pdt.tangentoperatesel", text="Tangents from Selection", icon="NONE") 444 row = layout.row() 445 row.label(text="Or Use Tangents From Inputs") 446 row.operator("pdt.tangentexpandmenu", text="", icon=icon_e) 447 448 box = layout.box() 449 row = box.row() 450 split = row.split(factor=0.35, align=True) 451 split.label(text="Tan Point") 452 split.prop(pdt_pg, "tangent_point2", text="") 453 row = box.row() 454 row.operator("pdt.tangentset3", text="from Cursor") 455 row.operator("pdt.tangentset4", text="from Vertex") 456 457 if pdt_pg.menu_expand: 458 box = layout.box() 459 row = box.row() 460 split = row.split(factor=0.35, align=True) 461 split.label(text="Centre 1") 462 split.prop(pdt_pg, "tangent_point0", text="") 463 row = box.row() 464 split = row.split(factor=0.45, align=False) 465 split.operator("pdt.tangentset1", text="Set From Arc") 466 split.prop(pdt_pg, "tangent_radius0", text="") 467 468 # Second Centre & Radius 469 row = box.row() 470 split = row.split(factor=0.35, align=True) 471 split.label(text="Centre 2") 472 split.prop(pdt_pg, "tangent_point1", text="") 473 row = box.row() 474 split = row.split(factor=0.45, align=False) 475 split.operator("pdt.tangentset2", text="Set From Arc") 476 split.prop(pdt_pg, "tangent_radius1", text="") 477 row = box.row() 478 row.operator("pdt.tangentoperate", text="Tangents From Inputs", icon="NONE") 479 480class PDT_PT_PanelTrig(Panel): 481 bl_idname = "PDT_PT_PanelTrig" 482 bl_label = "PDT Trigonometrical Waves" 483 bl_space_type = "VIEW_3D" 484 bl_region_type = "UI" 485 bl_category = "PDT" 486 bl_options = {'DEFAULT_CLOSED'} 487 488 def draw(self,context): 489 layout = self.layout 490 pdt_pg = context.scene.pdt_pg 491 row = layout.row() 492 row.label(text=f"Working {PDT_LAB_PLANE}:") 493 row.prop(pdt_pg, "plane", text="") 494 495 row = layout.row() 496 split = row.split(factor=0.5, align=True) 497 split.prop(pdt_pg, "trig_type") 498 split.prop(pdt_pg, "trig_cycles") 499 row = layout.row() 500 split = row.split(factor=0.5, align=True) 501 split.prop(pdt_pg, "trig_amp") 502 split.prop(pdt_pg, "trig_len") 503 row = layout.row() 504 split = row.split(factor=0.5, align=True) 505 split.prop(pdt_pg, "trig_obj", text="") 506 split.prop(pdt_pg, "trig_del") 507 row = layout.row() 508 split = row.split(factor=0.5, align=True) 509 split.prop(pdt_pg, "trig_res") 510 split.prop(pdt_pg, "trig_tanmax") 511 row = layout.row() 512 row.prop(pdt_pg, "trig_off") 513 row = layout.row() 514 row.operator("pdt.wave_generator", icon="SEQ_LUMA_WAVEFORM") 515 row.prop(pdt_pg, "trig_abs") 516