1# ##### BEGIN GPL LICENSE BLOCK ##### 2# 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. 7# 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. 12# 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. 16# 17# ##### END GPL LICENSE BLOCK ##### 18 19# <pep8 compliant> 20"""User interface for the POV tools""" 21 22import bpy 23import sys # really import here and in render.py? 24import os # really import here and in render.py? 25import addon_utils 26from time import sleep 27from os.path import isfile 28from bpy.app.handlers import persistent 29from bl_operators.presets import AddPresetBase 30from bpy.utils import register_class, unregister_class 31from bpy.types import ( 32 Operator, 33 Menu, 34 UIList, 35 Panel, 36 Brush, 37 Material, 38 Light, 39 World, 40 ParticleSettings, 41 FreestyleLineStyle, 42) 43 44# Example of wrapping every class 'as is' 45from bl_ui import properties_output 46 47for member in dir(properties_output): 48 subclass = getattr(properties_output, member) 49 try: 50 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 51 except: 52 pass 53del properties_output 54 55from bl_ui import properties_freestyle 56for member in dir(properties_freestyle): 57 subclass = getattr(properties_freestyle, member) 58 try: 59 if not (subclass.bl_space_type == 'PROPERTIES' 60 and subclass.bl_context == "render"): 61 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 62 #subclass.bl_parent_id = "RENDER_PT_POV_filter" 63 except: 64 pass 65del properties_freestyle 66 67from bl_ui import properties_view_layer 68 69for member in dir(properties_view_layer): 70 subclass = getattr(properties_view_layer, member) 71 try: 72 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 73 except: 74 pass 75del properties_view_layer 76 77# Use some of the existing buttons. 78from bl_ui import properties_render 79 80# DEPRECATED#properties_render.RENDER_PT_render.COMPAT_ENGINES.add('POVRAY_RENDER') 81# DEPRECATED#properties_render.RENDER_PT_dimensions.COMPAT_ENGINES.add('POVRAY_RENDER') 82# properties_render.RENDER_PT_antialiasing.COMPAT_ENGINES.add('POVRAY_RENDER') 83# TORECREATE##DEPRECATED#properties_render.RENDER_PT_shading.COMPAT_ENGINES.add('POVRAY_RENDER') 84# DEPRECATED#properties_render.RENDER_PT_output.COMPAT_ENGINES.add('POVRAY_RENDER') 85del properties_render 86 87 88# Use only a subset of the world panels 89from bl_ui import properties_world 90 91# TORECREATE##DEPRECATED#properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER') 92properties_world.WORLD_PT_context_world.COMPAT_ENGINES.add('POVRAY_RENDER') 93# TORECREATE##DEPRECATED#properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER') 94# TORECREATE##DEPRECATED#properties_world.WORLD_PT_mist.COMPAT_ENGINES.add('POVRAY_RENDER') 95del properties_world 96 97 98# Example of wrapping every class 'as is' 99from bl_ui import properties_texture 100from bl_ui.properties_texture import context_tex_datablock 101from bl_ui.properties_texture import texture_filter_common 102 103for member in dir(properties_texture): 104 subclass = getattr(properties_texture, member) 105 try: 106 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 107 except: 108 pass 109del properties_texture 110 111# Physics Main wrapping every class 'as is' 112from bl_ui import properties_physics_common 113 114for member in dir(properties_physics_common): 115 subclass = getattr(properties_physics_common, member) 116 try: 117 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 118 except: 119 pass 120del properties_physics_common 121 122# Physics Rigid Bodies wrapping every class 'as is' 123from bl_ui import properties_physics_rigidbody 124 125for member in dir(properties_physics_rigidbody): 126 subclass = getattr(properties_physics_rigidbody, member) 127 try: 128 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 129 except: 130 pass 131del properties_physics_rigidbody 132 133# Physics Rigid Body Constraint wrapping every class 'as is' 134from bl_ui import properties_physics_rigidbody_constraint 135 136for member in dir(properties_physics_rigidbody_constraint): 137 subclass = getattr(properties_physics_rigidbody_constraint, member) 138 try: 139 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 140 except: 141 pass 142del properties_physics_rigidbody_constraint 143 144# Physics Smoke wrapping every class 'as is' 145from bl_ui import properties_physics_fluid 146 147for member in dir(properties_physics_fluid): 148 subclass = getattr(properties_physics_fluid, member) 149 try: 150 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 151 except: 152 pass 153del properties_physics_fluid 154 155# Physics softbody wrapping every class 'as is' 156from bl_ui import properties_physics_softbody 157 158for member in dir(properties_physics_softbody): 159 subclass = getattr(properties_physics_softbody, member) 160 try: 161 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 162 except: 163 pass 164del properties_physics_softbody 165 166# Physics Fluid wrapping every class 'as is' 167from bl_ui import properties_physics_fluid 168 169for member in dir(properties_physics_fluid): 170 subclass = getattr(properties_physics_fluid, member) 171 try: 172 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 173 except: 174 pass 175del properties_physics_fluid 176 177# Physics Field wrapping every class 'as is' 178from bl_ui import properties_physics_field 179 180for member in dir(properties_physics_field): 181 subclass = getattr(properties_physics_field, member) 182 try: 183 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 184 except: 185 pass 186del properties_physics_field 187 188# Physics Cloth wrapping every class 'as is' 189from bl_ui import properties_physics_cloth 190 191for member in dir(properties_physics_cloth): 192 subclass = getattr(properties_physics_cloth, member) 193 try: 194 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 195 except: 196 pass 197del properties_physics_cloth 198 199# Physics Dynamic Paint wrapping every class 'as is' 200from bl_ui import properties_physics_dynamicpaint 201 202for member in dir(properties_physics_dynamicpaint): 203 subclass = getattr(properties_physics_dynamicpaint, member) 204 try: 205 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 206 except: 207 pass 208del properties_physics_dynamicpaint 209 210 211# Example of wrapping every class 'as is' 212from bl_ui import properties_data_modifier 213 214for member in dir(properties_data_modifier): 215 subclass = getattr(properties_data_modifier, member) 216 try: 217 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 218 except: 219 pass 220del properties_data_modifier 221 222# Example of wrapping every class 'as is' except some 223from bl_ui import properties_material 224 225for member in dir(properties_material): 226 subclass = getattr(properties_material, member) 227 try: 228 # mat=bpy.context.active_object.active_material 229 # if (mat and mat.pov.type == "SURFACE" 230 # and not (mat.pov.material_use_nodes or mat.use_nodes)): 231 # and (engine in cls.COMPAT_ENGINES)) if subclasses were sorted 232 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 233 except: 234 pass 235del properties_material 236 237 238from bl_ui import properties_data_camera 239 240for member in dir(properties_data_camera): 241 subclass = getattr(properties_data_camera, member) 242 try: 243 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 244 except: 245 pass 246del properties_data_camera 247 248 249from bl_ui import properties_particle as properties_particle 250 251for member in dir( 252 properties_particle 253): # add all "particle" panels from blender 254 subclass = getattr(properties_particle, member) 255 try: 256 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 257 except: 258 pass 259del properties_particle 260 261 262############# POV-Centric WORSPACE ############# 263@persistent 264def povCentricWorkspace(dummy): 265 """Set up a POV centric Workspace if addon was activated and saved as default renderer 266 267 This would bring a ’_RestrictData’ error because UI needs to be fully loaded before 268 workspace changes so registering this function in bpy.app.handlers is needed. 269 By default handlers are freed when loading new files, but here we want the handler 270 to stay running across multiple files as part of this add-on. That is why the the 271 bpy.app.handlers.persistent decorator is used (@persistent) above. 272 """ 273 274 wsp = bpy.data.workspaces.get('Scripting') 275 context = bpy.context 276 if wsp is not None and context.scene.render.engine == 'POVRAY_RENDER': 277 new_wsp = bpy.ops.workspace.duplicate({'workspace': wsp}) 278 bpy.data.workspaces['Scripting.001'].name='POV' 279 # Already done it would seem, but explicitly make this workspaces the active one 280 context.window.workspace = bpy.data.workspaces['POV'] 281 pov_screen = bpy.data.workspaces['POV'].screens[0] 282 pov_workspace = pov_screen.areas 283 284 285 override = bpy.context.copy() 286 287 for area in pov_workspace: 288 if area.type == 'VIEW_3D': 289 for region in [r for r in area.regions if r.type == 'WINDOW']: 290 for space in area.spaces: 291 if space.type == 'VIEW_3D': 292 #override['screen'] = pov_screen 293 override['area'] = area 294 override['region']= region 295 #bpy.data.workspaces['POV'].screens[0].areas[6].spaces[0].width = 333 # Read only, how do we set ? 296 #This has a glitch: 297 #bpy.ops.screen.area_move(override, x=(area.x + area.width), y=(area.y + 5), delta=100) 298 #bpy.ops.screen.area_move(override, x=(area.x + 5), y=area.y, delta=-100) 299 300 bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'TEXT_EDITOR') 301 space.show_region_ui = True 302 #bpy.ops.screen.region_scale(override) 303 #bpy.ops.screen.region_scale() 304 break 305 306 elif area.type == 'CONSOLE': 307 for region in [r for r in area.regions if r.type == 'WINDOW']: 308 for space in area.spaces: 309 if space.type == 'CONSOLE': 310 #override['screen'] = pov_screen 311 override['area'] = area 312 override['region']= region 313 bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'INFO') 314 315 break 316 elif area.type == 'INFO': 317 for region in [r for r in area.regions if r.type == 'WINDOW']: 318 for space in area.spaces: 319 if space.type == 'INFO': 320 #override['screen'] = pov_screen 321 override['area'] = area 322 override['region']= region 323 bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'CONSOLE') 324 325 break 326 327 elif area.type == 'TEXT_EDITOR': 328 for region in [r for r in area.regions if r.type == 'WINDOW']: 329 for space in area.spaces: 330 if space.type == 'TEXT_EDITOR': 331 #override['screen'] = pov_screen 332 override['area'] = area 333 override['region']= region 334 #bpy.ops.screen.space_type_set_or_cycle(space_type='VIEW_3D') 335 #space.type = 'VIEW_3D' 336 bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'VIEW_3D') 337 338 #bpy.ops.screen.area_join(override, cursor=(area.x, area.y + area.height)) 339 340 break 341 342 343 if area.type == 'VIEW_3D': 344 for region in [r for r in area.regions if r.type == 'WINDOW']: 345 for space in area.spaces: 346 if space.type == 'VIEW_3D': 347 #override['screen'] = pov_screen 348 override['area'] = area 349 override['region']= region 350 bpy.ops.screen.region_quadview(override) 351 space.region_3d.view_perspective = 'CAMERA' 352 #bpy.ops.screen.space_type_set_or_cycle(override, space_type = 'TEXT_EDITOR') 353 #bpy.ops.screen.region_quadview(override) 354 355 356 357 358 359 360 bpy.data.workspaces.update() 361 # Already outliners but invert both types 362 pov_workspace[1].spaces[0].display_mode = 'LIBRARIES' 363 pov_workspace[3].spaces[0].display_mode = 'VIEW_LAYER' 364 365 ''' 366 for window in bpy.context.window_manager.windows: 367 for area in [a for a in window.screen.areas if a.type == 'VIEW_3D']: 368 for region in [r for r in area.regions if r.type == 'WINDOW']: 369 context_override = { 370 'window': window, 371 'screen': window.screen, 372 'area': area, 373 'region': region, 374 'space_data': area.spaces.active, 375 'scene': bpy.context.scene 376 } 377 bpy.ops.view3d.camera_to_view(context_override) 378 ''' 379 380 381 else: 382 print("default 'Scripting' workspace needed for POV centric Workspace") 383 384 385 386 387 388 389 390class WORLD_MT_POV_presets(Menu): 391 bl_label = "World Presets" 392 preset_subdir = "pov/world" 393 preset_operator = "script.execute_preset" 394 draw = bpy.types.Menu.draw_preset 395 396 397class WORLD_OT_POV_add_preset(AddPresetBase, Operator): 398 """Add a World Preset""" 399 400 bl_idname = "object.world_preset_add" 401 bl_label = "Add World Preset" 402 preset_menu = "WORLD_MT_POV_presets" 403 404 # variable used for all preset values 405 preset_defines = ["scene = bpy.context.scene"] 406 407 # properties to store in the preset 408 preset_values = [ 409 "scene.world.use_sky_blend", 410 "scene.world.horizon_color", 411 "scene.world.zenith_color", 412 "scene.world.ambient_color", 413 "scene.world.mist_settings.use_mist", 414 "scene.world.mist_settings.intensity", 415 "scene.world.mist_settings.depth", 416 "scene.world.mist_settings.start", 417 "scene.pov.media_enable", 418 "scene.pov.media_scattering_type", 419 "scene.pov.media_samples", 420 "scene.pov.media_diffusion_scale", 421 "scene.pov.media_diffusion_color", 422 "scene.pov.media_absorption_scale", 423 "scene.pov.media_absorption_color", 424 "scene.pov.media_eccentricity", 425 ] 426 427 # where to store the preset 428 preset_subdir = "pov/world" 429 430 431def check_material(mat): 432 if mat is not None: 433 if mat.use_nodes: 434 if ( 435 not mat.node_tree 436 ): # FORMERLY : #mat.active_node_material is not None: 437 return True 438 return False 439 return True 440 return False 441 442 443def simple_material(mat): 444 """Test if a material uses nodes""" 445 if (mat is not None) and (not mat.use_nodes): 446 return True 447 return False 448 449 450def check_add_mesh_extra_objects(): 451 """Test if Add mesh extra objects addon is activated 452 453 This addon is currently used to generate the proxy for POV parametric 454 surface which is almost the same priciple as its Math xyz surface 455 """ 456 if "add_mesh_extra_objects" in bpy.context.preferences.addons.keys(): 457 return True 458 return False 459 460def check_render_freestyle_svg(): 461 """Test if Freestyle SVG Exporter addon is activated 462 463 This addon is currently used to generate the SVG lines file 464 when Freestyle is enabled alongside POV 465 """ 466 if "render_freestyle_svg" in bpy.context.preferences.addons.keys(): 467 return True 468 return False 469 470def locate_docpath(): 471 """POV can be installed with some include files. 472 473 Get their path as defined in user preferences or registry keys for 474 the user to be able to invoke them.""" 475 476 addon_prefs = bpy.context.preferences.addons[__package__].preferences 477 # Use the system preference if its set. 478 pov_documents = addon_prefs.docpath_povray 479 if pov_documents: 480 if os.path.exists(pov_documents): 481 return pov_documents 482 else: 483 print( 484 "User Preferences path to povray documents %r NOT FOUND, checking $PATH" 485 % pov_documents 486 ) 487 488 # Windows Only 489 if sys.platform[:3] == "win": 490 import winreg 491 492 try: 493 win_reg_key = winreg.OpenKey( 494 winreg.HKEY_CURRENT_USER, "Software\\POV-Ray\\v3.7\\Windows" 495 ) 496 win_docpath = winreg.QueryValueEx(win_reg_key, "DocPath")[0] 497 pov_documents = os.path.join(win_docpath, "Insert Menu") 498 if os.path.exists(pov_documents): 499 return pov_documents 500 except FileNotFoundError: 501 return "" 502 # search the path all os's 503 pov_documents_default = "include" 504 505 os_path_ls = os.getenv("PATH").split(':') + [""] 506 507 for dir_name in os_path_ls: 508 pov_documents = os.path.join(dir_name, pov_documents_default) 509 if os.path.exists(pov_documents): 510 return pov_documents 511 return "" 512 513 514def pov_context_tex_datablock(context): 515 """Texture context type recreated as deprecated in blender 2.8""" 516 517 idblock = context.brush 518 if idblock and context.scene.texture_context == 'OTHER': 519 return idblock 520 521 # idblock = bpy.context.active_object.active_material 522 idblock = context.view_layer.objects.active.active_material 523 if idblock and context.scene.texture_context == 'MATERIAL': 524 return idblock 525 526 idblock = context.scene.world 527 if idblock and context.scene.texture_context == 'WORLD': 528 return idblock 529 530 idblock = context.light 531 if idblock and context.scene.texture_context == 'LIGHT': 532 return idblock 533 534 if context.particle_system and context.scene.texture_context == 'PARTICLES': 535 idblock = context.particle_system.settings 536 537 return idblock 538 539 idblock = context.line_style 540 if idblock and context.scene.texture_context == 'LINESTYLE': 541 return idblock 542 543 544class RenderButtonsPanel: 545 """Use this class to define buttons from the render tab of 546 properties window.""" 547 548 bl_space_type = 'PROPERTIES' 549 bl_region_type = 'WINDOW' 550 bl_context = "render" 551 # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here 552 553 @classmethod 554 def poll(cls, context): 555 rd = context.scene.render 556 return rd.engine in cls.COMPAT_ENGINES 557 558 559class ModifierButtonsPanel: 560 """Use this class to define buttons from the modifier tab of 561 properties window.""" 562 563 bl_space_type = 'PROPERTIES' 564 bl_region_type = 'WINDOW' 565 bl_context = "modifier" 566 # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here 567 568 @classmethod 569 def poll(cls, context): 570 mods = context.object.modifiers 571 rd = context.scene.render 572 return mods and (rd.engine in cls.COMPAT_ENGINES) 573 574 575class MaterialButtonsPanel: 576 """Use this class to define buttons from the material tab of 577 properties window.""" 578 579 bl_space_type = 'PROPERTIES' 580 bl_region_type = 'WINDOW' 581 bl_context = "material" 582 # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here 583 584 @classmethod 585 def poll(cls, context): 586 mat = context.material 587 rd = context.scene.render 588 return mat and (rd.engine in cls.COMPAT_ENGINES) 589 590 591class TextureButtonsPanel: 592 """Use this class to define buttons from the texture tab of 593 properties window.""" 594 595 bl_space_type = 'PROPERTIES' 596 bl_region_type = 'WINDOW' 597 bl_context = "texture" 598 # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here 599 600 @classmethod 601 def poll(cls, context): 602 tex = context.texture 603 rd = context.scene.render 604 return tex and (rd.engine in cls.COMPAT_ENGINES) 605 606 607# class TextureTypePanel(TextureButtonsPanel): 608 609# @classmethod 610# def poll(cls, context): 611# tex = context.texture 612# engine = context.scene.render.engine 613# return tex and ((tex.type == cls.tex_type and not tex.use_nodes) and (engine in cls.COMPAT_ENGINES)) 614 615 616class ObjectButtonsPanel: 617 """Use this class to define buttons from the object tab of 618 properties window.""" 619 620 bl_space_type = 'PROPERTIES' 621 bl_region_type = 'WINDOW' 622 bl_context = "object" 623 # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here 624 625 @classmethod 626 def poll(cls, context): 627 obj = context.object 628 rd = context.scene.render 629 return obj and (rd.engine in cls.COMPAT_ENGINES) 630 631 632class CameraDataButtonsPanel: 633 """Use this class to define buttons from the camera data tab of 634 properties window.""" 635 636 bl_space_type = 'PROPERTIES' 637 bl_region_type = 'WINDOW' 638 bl_context = "data" 639 # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here 640 641 @classmethod 642 def poll(cls, context): 643 cam = context.camera 644 rd = context.scene.render 645 return cam and (rd.engine in cls.COMPAT_ENGINES) 646 647 648class WorldButtonsPanel: 649 """Use this class to define buttons from the world tab of 650 properties window.""" 651 652 bl_space_type = 'PROPERTIES' 653 bl_region_type = 'WINDOW' 654 bl_context = "world" 655 # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here 656 657 @classmethod 658 def poll(cls, context): 659 wld = context.world 660 rd = context.scene.render 661 return wld and (rd.engine in cls.COMPAT_ENGINES) 662 663 664class TextButtonsPanel: 665 """Use this class to define buttons from the side tab of 666 text window.""" 667 668 bl_space_type = 'TEXT_EDITOR' 669 bl_region_type = 'UI' 670 bl_label = "POV-Ray" 671 # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here 672 673 @classmethod 674 def poll(cls, context): 675 text = context.space_data 676 rd = context.scene.render 677 return text and (rd.engine in cls.COMPAT_ENGINES) 678 679 680from bl_ui import properties_data_mesh 681 682# These panels are kept 683properties_data_mesh.DATA_PT_custom_props_mesh.COMPAT_ENGINES.add( 684 'POVRAY_RENDER' 685) 686properties_data_mesh.DATA_PT_context_mesh.COMPAT_ENGINES.add('POVRAY_RENDER') 687 688## make some native panels contextual to some object variable 689## by recreating custom panels inheriting their properties 690 691 692class PovDataButtonsPanel(properties_data_mesh.MeshButtonsPanel): 693 """Use this class to define buttons from the edit data tab of 694 properties window.""" 695 696 COMPAT_ENGINES = {'POVRAY_RENDER'} 697 POV_OBJECT_TYPES = { 698 'PLANE', 699 'BOX', 700 'SPHERE', 701 'CYLINDER', 702 'CONE', 703 'TORUS', 704 'BLOB', 705 'ISOSURFACE', 706 'SUPERELLIPSOID', 707 'SUPERTORUS', 708 'HEIGHT_FIELD', 709 'PARAMETRIC', 710 'POLYCIRCLE', 711 } 712 713 @classmethod 714 def poll(cls, context): 715 engine = context.scene.render.engine 716 obj = context.object 717 # We use our parent class poll func too, avoids to re-define too much things... 718 return ( 719 super(PovDataButtonsPanel, cls).poll(context) 720 and obj 721 and obj.pov.object_as not in cls.POV_OBJECT_TYPES 722 ) 723 724 725# We cannot inherit from RNA classes (like e.g. properties_data_mesh.DATA_PT_vertex_groups). 726# Complex py/bpy/rna interactions (with metaclass and all) simply do not allow it to work. 727# So we simply have to explicitly copy here the interesting bits. ;) 728class DATA_PT_POV_normals(PovDataButtonsPanel, Panel): 729 bl_label = properties_data_mesh.DATA_PT_normals.bl_label 730 731 draw = properties_data_mesh.DATA_PT_normals.draw 732 733 734class DATA_PT_POV_texture_space(PovDataButtonsPanel, Panel): 735 bl_label = properties_data_mesh.DATA_PT_texture_space.bl_label 736 bl_options = properties_data_mesh.DATA_PT_texture_space.bl_options 737 738 draw = properties_data_mesh.DATA_PT_texture_space.draw 739 740 741class DATA_PT_POV_vertex_groups(PovDataButtonsPanel, Panel): 742 bl_label = properties_data_mesh.DATA_PT_vertex_groups.bl_label 743 744 draw = properties_data_mesh.DATA_PT_vertex_groups.draw 745 746 747class DATA_PT_POV_shape_keys(PovDataButtonsPanel, Panel): 748 bl_label = properties_data_mesh.DATA_PT_shape_keys.bl_label 749 750 draw = properties_data_mesh.DATA_PT_shape_keys.draw 751 752 753class DATA_PT_POV_uv_texture(PovDataButtonsPanel, Panel): 754 bl_label = properties_data_mesh.DATA_PT_uv_texture.bl_label 755 756 draw = properties_data_mesh.DATA_PT_uv_texture.draw 757 758 759class DATA_PT_POV_vertex_colors(PovDataButtonsPanel, Panel): 760 bl_label = properties_data_mesh.DATA_PT_vertex_colors.bl_label 761 762 draw = properties_data_mesh.DATA_PT_vertex_colors.draw 763 764 765class DATA_PT_POV_customdata(PovDataButtonsPanel, Panel): 766 bl_label = properties_data_mesh.DATA_PT_customdata.bl_label 767 bl_options = properties_data_mesh.DATA_PT_customdata.bl_options 768 draw = properties_data_mesh.DATA_PT_customdata.draw 769 770 771del properties_data_mesh 772 773 774################################################################################ 775# from bl_ui import properties_data_light 776# for member in dir(properties_data_light): 777# subclass = getattr(properties_data_light, member) 778# try: 779# subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 780# except: 781# pass 782# del properties_data_light 783#########################LIGHTS################################ 784 785from bl_ui import properties_data_light 786 787# These panels are kept 788properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add( 789 'POVRAY_RENDER' 790) 791properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add('POVRAY_RENDER') 792 793## make some native panels contextual to some object variable 794## by recreating custom panels inheriting their properties 795class PovLampButtonsPanel(properties_data_light.DataButtonsPanel): 796 """Use this class to define buttons from the light data tab of 797 properties window.""" 798 799 COMPAT_ENGINES = {'POVRAY_RENDER'} 800 POV_OBJECT_TYPES = {'RAINBOW'} 801 802 @classmethod 803 def poll(cls, context): 804 engine = context.scene.render.engine 805 obj = context.object 806 # We use our parent class poll func too, avoids to re-define too much things... 807 return ( 808 super(PovLampButtonsPanel, cls).poll(context) 809 and obj 810 and obj.pov.object_as not in cls.POV_OBJECT_TYPES 811 ) 812 813 814# We cannot inherit from RNA classes (like e.g. properties_data_mesh.DATA_PT_vertex_groups). 815# Complex py/bpy/rna interactions (with metaclass and all) simply do not allow it to work. 816# So we simply have to explicitly copy here the interesting bits. ;) 817 818 819class LIGHT_PT_POV_preview(PovLampButtonsPanel, Panel): 820 bl_label = properties_data_light.DATA_PT_preview.bl_label 821 822 draw = properties_data_light.DATA_PT_preview.draw 823 824 825class LIGHT_PT_POV_light(PovLampButtonsPanel, Panel): 826 bl_label = properties_data_light.DATA_PT_light.bl_label 827 828 draw = properties_data_light.DATA_PT_light.draw 829 830 831class LIGHT_MT_POV_presets(Menu): 832 """Use this class to define preset menu for pov lights.""" 833 834 bl_label = "Lamp Presets" 835 preset_subdir = "pov/light" 836 preset_operator = "script.execute_preset" 837 draw = bpy.types.Menu.draw_preset 838 839 840class LIGHT_OT_POV_add_preset(AddPresetBase, Operator): 841 """Use this class to define pov world buttons.""" 842 843 '''Add a Light Preset''' 844 bl_idname = "object.light_preset_add" 845 bl_label = "Add Light Preset" 846 preset_menu = "LIGHT_MT_POV_presets" 847 848 # variable used for all preset values 849 preset_defines = ["lightdata = bpy.context.object.data"] 850 851 # properties to store in the preset 852 preset_values = ["lightdata.type", "lightdata.color"] 853 854 # where to store the preset 855 preset_subdir = "pov/light" 856 857 858# Draw into the existing light panel 859def light_panel_func(self, context): 860 layout = self.layout 861 862 row = layout.row(align=True) 863 row.menu(LIGHT_MT_POV_presets.__name__, text=LIGHT_MT_POV_presets.bl_label) 864 row.operator(LIGHT_OT_POV_add_preset.bl_idname, text="", icon='ADD') 865 row.operator( 866 LIGHT_OT_POV_add_preset.bl_idname, text="", icon='REMOVE' 867 ).remove_active = True 868 869 870'''#TORECREATE##DEPRECATED# 871class LIGHT_PT_POV_sunsky(PovLampButtonsPanel, Panel): 872 bl_label = properties_data_light.DATA_PT_sunsky.bl_label 873 874 @classmethod 875 def poll(cls, context): 876 lamp = context.light 877 engine = context.scene.render.engine 878 return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES) 879 880 draw = properties_data_light.DATA_PT_sunsky.draw 881 882''' 883 884 885class LIGHT_PT_POV_shadow(PovLampButtonsPanel, Panel): 886 bl_label = "Shadow" 887 COMPAT_ENGINES = {'POVRAY_RENDER'} 888 889 @classmethod 890 def poll(cls, context): 891 lamp = context.lamp 892 engine = context.scene.render.engine 893 return lamp and (engine in cls.COMPAT_ENGINES) 894 895 def draw(self, context): 896 layout = self.layout 897 898 lamp = context.lamp 899 900 layout.row().prop(lamp, "shadow_method", expand=True) 901 902 split = layout.split() 903 904 col = split.column() 905 sub = col.column() 906 sub.prop(lamp, "spot_size", text="Size") 907 sub.prop(lamp, "spot_blend", text="Blend", slider=True) 908 col.prop(lamp, "use_square") 909 col.prop(lamp, "show_cone") 910 911 col = split.column() 912 913 col.active = ( 914 lamp.shadow_method != 'BUFFER_SHADOW' 915 or lamp.shadow_buffer_type != 'DEEP' 916 ) 917 col.prop(lamp, "use_halo") 918 sub = col.column(align=True) 919 sub.active = lamp.use_halo 920 sub.prop(lamp, "halo_intensity", text="Intensity") 921 if lamp.shadow_method == 'BUFFER_SHADOW': 922 sub.prop(lamp, "halo_step", text="Step") 923 if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA': 924 split = layout.split() 925 926 col = split.column() 927 col.label(text="Form factor sampling:") 928 929 sub = col.row(align=True) 930 931 if lamp.shape == 'SQUARE': 932 sub.prop(lamp, "shadow_ray_samples_x", text="Samples") 933 elif lamp.shape == 'RECTANGLE': 934 sub.prop(lamp.pov, "shadow_ray_samples_x", text="Samples X") 935 sub.prop(lamp.pov, "shadow_ray_samples_y", text="Samples Y") 936 937 if lamp.shadow_method != 'NOSHADOW': 938 split = layout.split() 939 940 col = split.column() 941 col.prop(lamp, "shadow_color", text="") 942 943 col = split.column() 944 col.prop(lamp, "use_shadow_layer", text="This Layer Only") 945 col.prop(lamp, "use_only_shadow") 946 947 if lamp.shadow_method == 'RAY_SHADOW': 948 split = layout.split() 949 950 col = split.column() 951 col.label(text="Sampling:") 952 953 if lamp.type in {'POINT', 'SUN', 'SPOT'}: 954 sub = col.row() 955 956 sub.prop(lamp, "shadow_ray_samples", text="Samples") 957 sub.prop(lamp, "shadow_soft_size", text="Soft Size") 958 959 elif lamp.type == 'AREA': 960 sub = col.row(align=True) 961 962 if lamp.shape == 'SQUARE': 963 sub.prop(lamp, "shadow_ray_samples_x", text="Samples") 964 elif lamp.shape == 'RECTANGLE': 965 sub.prop(lamp, "shadow_ray_samples_x", text="Samples X") 966 sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y") 967 968 969''' 970 if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA': 971 split = layout.split() 972 973 col = split.column() 974 col.label(text="Form factor sampling:") 975 976 sub = col.row(align=True) 977 978 if lamp.shape == 'SQUARE': 979 sub.prop(lamp, "shadow_ray_samples_x", text="Samples") 980 elif lamp.shape == 'RECTANGLE': 981 sub.prop(lamp, "shadow_ray_samples_x", text="Samples X") 982 sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y") 983 984 if lamp.shadow_method != 'NOSHADOW': 985 split = layout.split() 986 987 col = split.column() 988 col.prop(lamp, "shadow_color", text="") 989 990 col = split.column() 991 col.prop(lamp, "use_shadow_layer", text="This Layer Only") 992 col.prop(lamp, "use_only_shadow") 993 994 if lamp.shadow_method == 'RAY_SHADOW': 995 split = layout.split() 996 997 col = split.column() 998 col.label(text="Sampling:") 999 1000 if lamp.type in {'POINT', 'SUN', 'SPOT'}: 1001 sub = col.row() 1002 1003 sub.prop(lamp, "shadow_ray_samples", text="Samples") 1004 sub.prop(lamp, "shadow_soft_size", text="Soft Size") 1005 1006 elif lamp.type == 'AREA': 1007 sub = col.row(align=True) 1008 1009 if lamp.shape == 'SQUARE': 1010 sub.prop(lamp, "shadow_ray_samples_x", text="Samples") 1011 elif lamp.shape == 'RECTANGLE': 1012 sub.prop(lamp, "shadow_ray_samples_x", text="Samples X") 1013 sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y") 1014 1015 col.row().prop(lamp, "shadow_ray_sample_method", expand=True) 1016 1017 if lamp.shadow_ray_sample_method == 'ADAPTIVE_QMC': 1018 layout.prop(lamp, "shadow_adaptive_threshold", text="Threshold") 1019 1020 if lamp.type == 'AREA' and lamp.shadow_ray_sample_method == 'CONSTANT_JITTERED': 1021 row = layout.row() 1022 row.prop(lamp, "use_umbra") 1023 row.prop(lamp, "use_dither") 1024 row.prop(lamp, "use_jitter") 1025 1026 elif lamp.shadow_method == 'BUFFER_SHADOW': 1027 col = layout.column() 1028 col.label(text="Buffer Type:") 1029 col.row().prop(lamp, "shadow_buffer_type", expand=True) 1030 1031 if lamp.shadow_buffer_type in {'REGULAR', 'HALFWAY', 'DEEP'}: 1032 split = layout.split() 1033 1034 col = split.column() 1035 col.label(text="Filter Type:") 1036 col.prop(lamp, "shadow_filter_type", text="") 1037 sub = col.column(align=True) 1038 sub.prop(lamp, "shadow_buffer_soft", text="Soft") 1039 sub.prop(lamp, "shadow_buffer_bias", text="Bias") 1040 1041 col = split.column() 1042 col.label(text="Sample Buffers:") 1043 col.prop(lamp, "shadow_sample_buffers", text="") 1044 sub = col.column(align=True) 1045 sub.prop(lamp, "shadow_buffer_size", text="Size") 1046 sub.prop(lamp, "shadow_buffer_samples", text="Samples") 1047 if lamp.shadow_buffer_type == 'DEEP': 1048 col.prop(lamp, "compression_threshold") 1049 1050 elif lamp.shadow_buffer_type == 'IRREGULAR': 1051 layout.prop(lamp, "shadow_buffer_bias", text="Bias") 1052 1053 split = layout.split() 1054 1055 col = split.column() 1056 col.prop(lamp, "use_auto_clip_start", text="Autoclip Start") 1057 sub = col.column() 1058 sub.active = not lamp.use_auto_clip_start 1059 sub.prop(lamp, "shadow_buffer_clip_start", text="Clip Start") 1060 1061 col = split.column() 1062 col.prop(lamp, "use_auto_clip_end", text="Autoclip End") 1063 sub = col.column() 1064 sub.active = not lamp.use_auto_clip_end 1065 sub.prop(lamp, "shadow_buffer_clip_end", text=" Clip End") 1066''' 1067 1068 1069class LIGHT_PT_POV_area(PovLampButtonsPanel, Panel): 1070 bl_label = properties_data_light.DATA_PT_area.bl_label 1071 1072 @classmethod 1073 def poll(cls, context): 1074 lamp = context.light 1075 engine = context.scene.render.engine 1076 return (lamp and lamp.type == 'AREA') and (engine in cls.COMPAT_ENGINES) 1077 1078 draw = properties_data_light.DATA_PT_area.draw 1079 1080 1081class LIGHT_PT_POV_spot(PovLampButtonsPanel, Panel): 1082 bl_label = properties_data_light.DATA_PT_spot.bl_label 1083 1084 @classmethod 1085 def poll(cls, context): 1086 lamp = context.light 1087 engine = context.scene.render.engine 1088 return (lamp and lamp.type == 'SPOT') and (engine in cls.COMPAT_ENGINES) 1089 1090 draw = properties_data_light.DATA_PT_spot.draw 1091 1092 1093class LIGHT_PT_POV_falloff_curve(PovLampButtonsPanel, Panel): 1094 bl_label = properties_data_light.DATA_PT_falloff_curve.bl_label 1095 bl_options = properties_data_light.DATA_PT_falloff_curve.bl_options 1096 1097 @classmethod 1098 def poll(cls, context): 1099 lamp = context.light 1100 engine = context.scene.render.engine 1101 1102 return ( 1103 lamp 1104 and lamp.type in {'POINT', 'SPOT'} 1105 and lamp.falloff_type == 'CUSTOM_CURVE' 1106 ) and (engine in cls.COMPAT_ENGINES) 1107 1108 draw = properties_data_light.DATA_PT_falloff_curve.draw 1109 1110 1111class OBJECT_PT_POV_rainbow(PovLampButtonsPanel, Panel): 1112 """Use this class to define buttons from the rainbow panel of 1113 properties window. inheriting lamp buttons panel class""" 1114 1115 bl_label = "POV-Ray Rainbow" 1116 COMPAT_ENGINES = {'POVRAY_RENDER'} 1117 # bl_options = {'HIDE_HEADER'} 1118 @classmethod 1119 def poll(cls, context): 1120 engine = context.scene.render.engine 1121 obj = context.object 1122 return ( 1123 obj 1124 and obj.pov.object_as == 'RAINBOW' 1125 and (engine in cls.COMPAT_ENGINES) 1126 ) 1127 1128 def draw(self, context): 1129 layout = self.layout 1130 1131 obj = context.object 1132 1133 col = layout.column() 1134 1135 if obj.pov.object_as == 'RAINBOW': 1136 if obj.pov.unlock_parameters == False: 1137 col.prop( 1138 obj.pov, 1139 "unlock_parameters", 1140 text="Exported parameters below", 1141 icon='LOCKED', 1142 ) 1143 col.label( 1144 text="Rainbow projection angle: " + str(obj.data.spot_size) 1145 ) 1146 col.label(text="Rainbow width: " + str(obj.data.spot_blend)) 1147 col.label( 1148 text="Rainbow distance: " 1149 + str(obj.data.shadow_buffer_clip_start) 1150 ) 1151 col.label(text="Rainbow arc angle: " + str(obj.pov.arc_angle)) 1152 col.label( 1153 text="Rainbow falloff angle: " + str(obj.pov.falloff_angle) 1154 ) 1155 1156 else: 1157 col.prop( 1158 obj.pov, 1159 "unlock_parameters", 1160 text="Edit exported parameters", 1161 icon='UNLOCKED', 1162 ) 1163 col.label(text="3D view proxy may get out of synch") 1164 col.active = obj.pov.unlock_parameters 1165 1166 layout.operator( 1167 "pov.cone_update", text="Update", icon="MESH_CONE" 1168 ) 1169 1170 # col.label(text="Parameters:") 1171 col.prop(obj.data, "spot_size", text="Rainbow Projection Angle") 1172 col.prop(obj.data, "spot_blend", text="Rainbow width") 1173 col.prop( 1174 obj.data, 1175 "shadow_buffer_clip_start", 1176 text="Visibility distance", 1177 ) 1178 col.prop(obj.pov, "arc_angle") 1179 col.prop(obj.pov, "falloff_angle") 1180 1181 1182del properties_data_light 1183############################################################################### 1184 1185 1186class WORLD_PT_POV_world(WorldButtonsPanel, Panel): 1187 """Use this class to define pov world buttons.""" 1188 1189 bl_label = "World" 1190 COMPAT_ENGINES = {'POVRAY_RENDER'} 1191 1192 def draw(self, context): 1193 layout = self.layout 1194 1195 world = context.world.pov 1196 1197 row = layout.row(align=True) 1198 row.menu( 1199 WORLD_MT_POV_presets.__name__, text=WORLD_MT_POV_presets.bl_label 1200 ) 1201 row.operator(WORLD_OT_POV_add_preset.bl_idname, text="", icon='ADD') 1202 row.operator( 1203 WORLD_OT_POV_add_preset.bl_idname, text="", icon='REMOVE' 1204 ).remove_active = True 1205 1206 row = layout.row() 1207 row.prop(world, "use_sky_paper") 1208 row.prop(world, "use_sky_blend") 1209 row.prop(world, "use_sky_real") 1210 1211 row = layout.row() 1212 row.column().prop(world, "horizon_color") 1213 col = row.column() 1214 col.prop(world, "zenith_color") 1215 col.active = world.use_sky_blend 1216 row.column().prop(world, "ambient_color") 1217 1218 # row = layout.row() 1219 # row.prop(world, "exposure") #Re-implement later as a light multiplier 1220 # row.prop(world, "color_range") 1221 1222 1223class WORLD_PT_POV_mist(WorldButtonsPanel, Panel): 1224 """Use this class to define pov mist buttons.""" 1225 1226 bl_label = "Mist" 1227 bl_options = {'DEFAULT_CLOSED'} 1228 COMPAT_ENGINES = {'POVRAY_RENDER'} 1229 1230 def draw_header(self, context): 1231 world = context.world 1232 1233 self.layout.prop(world.mist_settings, "use_mist", text="") 1234 1235 def draw(self, context): 1236 layout = self.layout 1237 1238 world = context.world 1239 1240 layout.active = world.mist_settings.use_mist 1241 1242 split = layout.split() 1243 1244 col = split.column() 1245 col.prop(world.mist_settings, "intensity") 1246 col.prop(world.mist_settings, "start") 1247 1248 col = split.column() 1249 col.prop(world.mist_settings, "depth") 1250 col.prop(world.mist_settings, "height") 1251 1252 layout.prop(world.mist_settings, "falloff") 1253 1254 1255class RENDER_PT_POV_export_settings(RenderButtonsPanel, Panel): 1256 """Use this class to define pov ini settingss buttons.""" 1257 bl_options = {'DEFAULT_CLOSED'} 1258 bl_label = "Auto Start" 1259 COMPAT_ENGINES = {'POVRAY_RENDER'} 1260 1261 def draw_header(self, context): 1262 scene = context.scene 1263 if scene.pov.tempfiles_enable: 1264 self.layout.prop( 1265 scene.pov, "tempfiles_enable", text="", icon='AUTO' 1266 ) 1267 else: 1268 self.layout.prop( 1269 scene.pov, "tempfiles_enable", text="", icon='CONSOLE' 1270 ) 1271 1272 def draw(self, context): 1273 1274 layout = self.layout 1275 1276 scene = context.scene 1277 1278 layout.active = scene.pov.max_trace_level != 0 1279 split = layout.split() 1280 1281 col = split.column() 1282 col.label(text="Command line switches:") 1283 col.prop(scene.pov, "command_line_switches", text="") 1284 split = layout.split() 1285 1286 #layout.active = not scene.pov.tempfiles_enable 1287 if not scene.pov.tempfiles_enable: 1288 split.prop(scene.pov, "deletefiles_enable", text="Delete files") 1289 split.prop(scene.pov, "pov_editor", text="POV Editor") 1290 1291 col = layout.column() 1292 col.prop(scene.pov, "scene_name", text="Name") 1293 col.prop(scene.pov, "scene_path", text="Path to files") 1294 # col.prop(scene.pov, "scene_path", text="Path to POV-file") 1295 # col.prop(scene.pov, "renderimage_path", text="Path to image") 1296 1297 split = layout.split() 1298 split.prop(scene.pov, "indentation_character", text="Indent") 1299 if scene.pov.indentation_character == 'SPACE': 1300 split.prop(scene.pov, "indentation_spaces", text="Spaces") 1301 1302 row = layout.row() 1303 row.prop(scene.pov, "comments_enable", text="Comments") 1304 row.prop(scene.pov, "list_lf_enable", text="Line breaks in lists") 1305 1306 1307class RENDER_PT_POV_render_settings(RenderButtonsPanel, Panel): 1308 """Use this class to define pov render settings buttons.""" 1309 1310 bl_label = "Global Settings" 1311 bl_icon = 'SETTINGS' 1312 bl_options = {'DEFAULT_CLOSED'} 1313 COMPAT_ENGINES = {'POVRAY_RENDER'} 1314 1315 def draw_header(self, context): 1316 scene = context.scene 1317 if scene.pov.global_settings_advanced: 1318 self.layout.prop( 1319 scene.pov, "global_settings_advanced", text="", icon='SETTINGS' 1320 ) 1321 else: 1322 self.layout.prop( 1323 scene.pov, 1324 "global_settings_advanced", 1325 text="", 1326 icon='PREFERENCES', 1327 ) 1328 1329 def draw(self, context): 1330 layout = self.layout 1331 1332 scene = context.scene 1333 rd = context.scene.render 1334 # layout.active = (scene.pov.max_trace_level != 0) 1335 1336 if sys.platform[:3] != "win": 1337 layout.prop( 1338 scene.pov, "sdl_window_enable", text="POV-Ray SDL Window" 1339 ) 1340 1341 col = layout.column() 1342 col.label(text="Main Path Tracing:") 1343 col.prop(scene.pov, "max_trace_level", text="Ray Depth") 1344 align = True 1345 layout.active = scene.pov.global_settings_advanced 1346 # Deprecated (autodetected in pov3.8): 1347 # layout.prop(scene.pov, "charset") 1348 row = layout.row(align=align) 1349 row.prop(scene.pov, "adc_bailout") 1350 row = layout.row(align=align) 1351 row.prop(scene.pov, "ambient_light") 1352 row = layout.row(align=align) 1353 row.prop(scene.pov, "irid_wavelength") 1354 row = layout.row(align=align) 1355 row.prop(scene.pov, "max_intersections") 1356 row = layout.row(align=align) 1357 row.prop(scene.pov, "number_of_waves") 1358 row = layout.row(align=align) 1359 row.prop(scene.pov, "noise_generator") 1360 1361 split = layout.split() 1362 split.label(text="Shading:") 1363 split = layout.split() 1364 1365 row = split.row(align=align) 1366 row.prop(scene.pov, "use_shadows") 1367 row.prop(scene.pov, "alpha_mode") 1368 1369 1370class RENDER_PT_POV_photons(RenderButtonsPanel, Panel): 1371 """Use this class to define pov photons buttons.""" 1372 1373 bl_label = "Photons" 1374 bl_options = {'DEFAULT_CLOSED'} 1375 COMPAT_ENGINES = {'POVRAY_RENDER'} 1376 1377 # def draw_header(self, context): 1378 # self.layout.label(icon='SETTINGS') 1379 1380 def draw_header(self, context): 1381 scene = context.scene 1382 if scene.pov.photon_enable: 1383 self.layout.prop( 1384 scene.pov, "photon_enable", text="", icon='PMARKER_ACT' 1385 ) 1386 else: 1387 self.layout.prop( 1388 scene.pov, "photon_enable", text="", icon='PMARKER' 1389 ) 1390 1391 def draw(self, context): 1392 scene = context.scene 1393 layout = self.layout 1394 layout.active = scene.pov.photon_enable 1395 col = layout.column() 1396 # col.label(text="Global Photons:") 1397 col.prop(scene.pov, "photon_max_trace_level", text="Photon Depth") 1398 1399 split = layout.split() 1400 1401 col = split.column() 1402 col.prop(scene.pov, "photon_spacing", text="Spacing") 1403 col.prop(scene.pov, "photon_gather_min") 1404 1405 col = split.column() 1406 col.prop(scene.pov, "photon_adc_bailout", text="Photon ADC") 1407 col.prop(scene.pov, "photon_gather_max") 1408 1409 box = layout.box() 1410 box.label(text='Photon Map File:') 1411 row = box.row() 1412 row.prop(scene.pov, "photon_map_file_save_load", expand=True) 1413 if scene.pov.photon_map_file_save_load in {'save'}: 1414 box.prop(scene.pov, "photon_map_dir") 1415 box.prop(scene.pov, "photon_map_filename") 1416 if scene.pov.photon_map_file_save_load in {'load'}: 1417 box.prop(scene.pov, "photon_map_file") 1418 # end main photons 1419 1420 1421class RENDER_PT_POV_antialias(RenderButtonsPanel, Panel): 1422 """Use this class to define pov antialiasing buttons.""" 1423 1424 bl_label = "Anti-Aliasing" 1425 bl_options = {'DEFAULT_CLOSED'} 1426 COMPAT_ENGINES = {'POVRAY_RENDER'} 1427 1428 def draw_header(self, context): 1429 prefs = bpy.context.preferences.addons[__package__].preferences 1430 scene = context.scene 1431 if ( 1432 prefs.branch_feature_set_povray != 'uberpov' 1433 and scene.pov.antialias_method == '2' 1434 ): 1435 self.layout.prop( 1436 scene.pov, "antialias_enable", text="", icon='ERROR' 1437 ) 1438 elif scene.pov.antialias_enable: 1439 self.layout.prop( 1440 scene.pov, "antialias_enable", text="", icon='ANTIALIASED' 1441 ) 1442 else: 1443 self.layout.prop( 1444 scene.pov, "antialias_enable", text="", icon='ALIASED' 1445 ) 1446 1447 def draw(self, context): 1448 prefs = bpy.context.preferences.addons[__package__].preferences 1449 layout = self.layout 1450 scene = context.scene 1451 1452 layout.active = scene.pov.antialias_enable 1453 1454 row = layout.row() 1455 row.prop(scene.pov, "antialias_method", text="") 1456 1457 if ( 1458 prefs.branch_feature_set_povray != 'uberpov' 1459 and scene.pov.antialias_method == '2' 1460 ): 1461 col = layout.column() 1462 col.alignment = 'CENTER' 1463 col.label(text="Stochastic Anti Aliasing is") 1464 col.label(text="Only Available with UberPOV") 1465 col.label(text="Feature Set in User Preferences.") 1466 col.label(text="Using Type 2 (recursive) instead") 1467 else: 1468 row.prop(scene.pov, "jitter_enable", text="Jitter") 1469 1470 split = layout.split() 1471 col = split.column() 1472 col.prop(scene.pov, "antialias_depth", text="AA Depth") 1473 sub = split.column() 1474 sub.prop(scene.pov, "jitter_amount", text="Jitter Amount") 1475 if scene.pov.jitter_enable: 1476 sub.enabled = True 1477 else: 1478 sub.enabled = False 1479 1480 row = layout.row() 1481 row.prop(scene.pov, "antialias_threshold", text="AA Threshold") 1482 row.prop(scene.pov, "antialias_gamma", text="AA Gamma") 1483 1484 if prefs.branch_feature_set_povray == 'uberpov': 1485 row = layout.row() 1486 row.prop( 1487 scene.pov, "antialias_confidence", text="AA Confidence" 1488 ) 1489 if scene.pov.antialias_method == '2': 1490 row.enabled = True 1491 else: 1492 row.enabled = False 1493 1494 1495class RENDER_PT_POV_radiosity(RenderButtonsPanel, Panel): 1496 """Use this class to define pov radiosity buttons.""" 1497 1498 bl_label = "Diffuse Radiosity" 1499 bl_options = {'DEFAULT_CLOSED'} 1500 COMPAT_ENGINES = {'POVRAY_RENDER'} 1501 1502 def draw_header(self, context): 1503 scene = context.scene 1504 if scene.pov.radio_enable: 1505 self.layout.prop( 1506 scene.pov, 1507 "radio_enable", 1508 text="", 1509 icon='OUTLINER_OB_LIGHTPROBE', 1510 ) 1511 else: 1512 self.layout.prop( 1513 scene.pov, "radio_enable", text="", icon='LIGHTPROBE_CUBEMAP' 1514 ) 1515 1516 def draw(self, context): 1517 layout = self.layout 1518 1519 scene = context.scene 1520 1521 layout.active = scene.pov.radio_enable 1522 1523 split = layout.split() 1524 1525 col = split.column() 1526 col.prop(scene.pov, "radio_count", text="Rays") 1527 col.prop(scene.pov, "radio_recursion_limit", text="Recursions") 1528 1529 split.prop(scene.pov, "radio_error_bound", text="Error Bound") 1530 1531 layout.prop(scene.pov, "radio_display_advanced") 1532 1533 if scene.pov.radio_display_advanced: 1534 split = layout.split() 1535 1536 col = split.column() 1537 col.prop(scene.pov, "radio_adc_bailout", slider=True) 1538 col.prop(scene.pov, "radio_minimum_reuse", text="Min Reuse") 1539 col.prop(scene.pov, "radio_gray_threshold", slider=True) 1540 col.prop(scene.pov, "radio_pretrace_start", slider=True) 1541 col.prop(scene.pov, "radio_low_error_factor", slider=True) 1542 1543 col = split.column() 1544 col.prop(scene.pov, "radio_brightness") 1545 col.prop(scene.pov, "radio_maximum_reuse", text="Max Reuse") 1546 col.prop(scene.pov, "radio_nearest_count") 1547 col.prop(scene.pov, "radio_pretrace_end", slider=True) 1548 1549 col = layout.column() 1550 col.label(text="Estimation Influence:") 1551 col.prop(scene.pov, "radio_always_sample") 1552 col.prop(scene.pov, "radio_normal") 1553 col.prop(scene.pov, "radio_media") 1554 col.prop(scene.pov, "radio_subsurface") 1555 1556 1557class POV_RADIOSITY_MT_presets(Menu): 1558 """Use this class to define pov radiosity presets menu.""" 1559 1560 bl_label = "Radiosity Presets" 1561 preset_subdir = "pov/radiosity" 1562 preset_operator = "script.execute_preset" 1563 draw = bpy.types.Menu.draw_preset 1564 1565 1566class RENDER_OT_POV_radiosity_add_preset(AddPresetBase, Operator): 1567 """Use this class to define pov radiosity add presets button.""" 1568 1569 '''Add a Radiosity Preset''' 1570 bl_idname = "scene.radiosity_preset_add" 1571 bl_label = "Add Radiosity Preset" 1572 preset_menu = "POV_RADIOSITY_MT_presets" 1573 1574 # variable used for all preset values 1575 preset_defines = ["scene = bpy.context.scene"] 1576 1577 # properties to store in the preset 1578 preset_values = [ 1579 "scene.pov.radio_display_advanced", 1580 "scene.pov.radio_adc_bailout", 1581 "scene.pov.radio_always_sample", 1582 "scene.pov.radio_brightness", 1583 "scene.pov.radio_count", 1584 "scene.pov.radio_error_bound", 1585 "scene.pov.radio_gray_threshold", 1586 "scene.pov.radio_low_error_factor", 1587 "scene.pov.radio_media", 1588 "scene.pov.radio_subsurface", 1589 "scene.pov.radio_minimum_reuse", 1590 "scene.pov.radio_maximum_reuse", 1591 "scene.pov.radio_nearest_count", 1592 "scene.pov.radio_normal", 1593 "scene.pov.radio_recursion_limit", 1594 "scene.pov.radio_pretrace_start", 1595 "scene.pov.radio_pretrace_end", 1596 ] 1597 1598 # where to store the preset 1599 preset_subdir = "pov/radiosity" 1600 1601 1602# Draw into an existing panel 1603def rad_panel_func(self, context): 1604 layout = self.layout 1605 1606 row = layout.row(align=True) 1607 row.menu( 1608 POV_RADIOSITY_MT_presets.__name__, 1609 text=POV_RADIOSITY_MT_presets.bl_label, 1610 ) 1611 row.operator( 1612 RENDER_OT_POV_radiosity_add_preset.bl_idname, text="", icon='ADD' 1613 ) 1614 row.operator( 1615 RENDER_OT_POV_radiosity_add_preset.bl_idname, text="", icon='REMOVE' 1616 ).remove_active = True 1617 1618 1619class RENDER_PT_POV_media(WorldButtonsPanel, Panel): 1620 """Use this class to define a pov global atmospheric media buttons.""" 1621 1622 bl_label = "Atmosphere Media" 1623 COMPAT_ENGINES = {'POVRAY_RENDER'} 1624 1625 def draw_header(self, context): 1626 scene = context.scene 1627 1628 self.layout.prop(scene.pov, "media_enable", text="") 1629 1630 def draw(self, context): 1631 layout = self.layout 1632 1633 scene = context.scene 1634 1635 layout.active = scene.pov.media_enable 1636 1637 col = layout.column() 1638 col.prop(scene.pov, "media_scattering_type", text="") 1639 col = layout.column() 1640 col.prop(scene.pov, "media_samples", text="Samples") 1641 split = layout.split() 1642 col = split.column(align=True) 1643 col.label(text="Scattering:") 1644 col.prop(scene.pov, "media_diffusion_scale") 1645 col.prop(scene.pov, "media_diffusion_color", text="") 1646 col = split.column(align=True) 1647 col.label(text="Absorption:") 1648 col.prop(scene.pov, "media_absorption_scale") 1649 col.prop(scene.pov, "media_absorption_color", text="") 1650 if scene.pov.media_scattering_type == '5': 1651 col = layout.column() 1652 col.prop(scene.pov, "media_eccentricity", text="Eccentricity") 1653 1654 1655##class RENDER_PT_povray_baking(RenderButtonsPanel, Panel): 1656## bl_label = "Baking" 1657## COMPAT_ENGINES = {'POVRAY_RENDER'} 1658## 1659## def draw_header(self, context): 1660## scene = context.scene 1661## 1662## self.layout.prop(scene.pov, "baking_enable", text="") 1663## 1664## def draw(self, context): 1665## layout = self.layout 1666## 1667## scene = context.scene 1668## rd = scene.render 1669## 1670## layout.active = scene.pov.baking_enable 1671 1672 1673class MODIFIERS_PT_POV_modifiers(ModifierButtonsPanel, Panel): 1674 """Use this class to define pov modifier buttons. (For booleans)""" 1675 1676 bl_label = "POV-Ray" 1677 COMPAT_ENGINES = {'POVRAY_RENDER'} 1678 1679 # def draw_header(self, context): 1680 # scene = context.scene 1681 # self.layout.prop(scene.pov, "boolean_mod", text="") 1682 1683 def draw(self, context): 1684 scene = context.scene 1685 layout = self.layout 1686 ob = context.object 1687 mod = ob.modifiers 1688 col = layout.column() 1689 # Find Boolean Modifiers for displaying CSG option 1690 onceCSG = 0 1691 for mod in ob.modifiers: 1692 if onceCSG == 0: 1693 if mod: 1694 if mod.type == 'BOOLEAN': 1695 col.prop(ob.pov, "boolean_mod") 1696 onceCSG = 1 1697 1698 if ob.pov.boolean_mod == "POV": 1699 split = layout.split() 1700 col = layout.column() 1701 # Inside Vector for CSG 1702 col.prop(ob.pov, "inside_vector") 1703 1704 1705class MATERIAL_MT_POV_sss_presets(Menu): 1706 """Use this class to define pov sss preset menu.""" 1707 1708 bl_label = "SSS Presets" 1709 preset_subdir = "pov/material/sss" 1710 preset_operator = "script.execute_preset" 1711 draw = bpy.types.Menu.draw_preset 1712 1713 1714class MATERIAL_OT_POV_sss_add_preset(AddPresetBase, Operator): 1715 """Add an SSS Preset""" 1716 1717 bl_idname = "material.sss_preset_add" 1718 bl_label = "Add SSS Preset" 1719 preset_menu = "MATERIAL_MT_POV_sss_presets" 1720 1721 # variable used for all preset values 1722 preset_defines = ["material = bpy.context.material"] 1723 1724 # properties to store in the preset 1725 preset_values = [ 1726 "material.pov_subsurface_scattering.radius", 1727 "material.pov_subsurface_scattering.color", 1728 ] 1729 1730 # where to store the preset 1731 preset_subdir = "pov/material/sss" 1732 1733 1734class MATERIAL_PT_POV_sss(MaterialButtonsPanel, Panel): 1735 """Use this class to define pov sss buttons panel.""" 1736 1737 bl_label = "Subsurface Scattering" 1738 bl_options = {'DEFAULT_CLOSED'} 1739 COMPAT_ENGINES = {'POVRAY_RENDER'} 1740 1741 @classmethod 1742 def poll(cls, context): 1743 mat = context.material 1744 engine = context.scene.render.engine 1745 return ( 1746 check_material(mat) 1747 and (mat.pov.type in {'SURFACE', 'WIRE'}) 1748 and (engine in cls.COMPAT_ENGINES) 1749 ) 1750 1751 def draw_header(self, context): 1752 mat = context.material # FORMERLY : #active_node_mat(context.material) 1753 sss = mat.pov_subsurface_scattering 1754 1755 self.layout.active = not mat.pov.use_shadeless 1756 self.layout.prop(sss, "use", text="") 1757 1758 def draw(self, context): 1759 layout = self.layout 1760 1761 mat = context.material # FORMERLY : #active_node_mat(context.material) 1762 sss = mat.pov_subsurface_scattering 1763 1764 layout.active = (sss.use) and (not mat.pov.use_shadeless) 1765 1766 row = layout.row().split() 1767 sub = row.row(align=True).split(align=True, factor=0.75) 1768 sub.menu( 1769 MATERIAL_MT_POV_sss_presets.__name__, 1770 text=MATERIAL_MT_POV_sss_presets.bl_label, 1771 ) 1772 sub.operator( 1773 MATERIAL_OT_POV_sss_add_preset.bl_idname, text="", icon='ADD' 1774 ) 1775 sub.operator( 1776 MATERIAL_OT_POV_sss_add_preset.bl_idname, text="", icon='REMOVE' 1777 ).remove_active = True 1778 1779 split = layout.split() 1780 1781 col = split.column() 1782 col.prop(sss, "ior") 1783 col.prop(sss, "scale") 1784 col.prop(sss, "color", text="") 1785 col.prop(sss, "radius", text="RGB Radius", expand=True) 1786 1787 col = split.column() 1788 sub = col.column(align=True) 1789 sub.label(text="Blend:") 1790 sub.prop(sss, "color_factor", text="Color") 1791 sub.prop(sss, "texture_factor", text="Texture") 1792 sub.label(text="Scattering Weight:") 1793 sub.prop(sss, "front") 1794 sub.prop(sss, "back") 1795 col.separator() 1796 col.prop(sss, "error_threshold", text="Error") 1797 1798 1799class MATERIAL_PT_POV_activate_node(MaterialButtonsPanel, Panel): 1800 """Use this class to define an activate pov nodes button.""" 1801 1802 bl_label = "Activate Node Settings" 1803 bl_context = "material" 1804 bl_options = {'HIDE_HEADER'} 1805 COMPAT_ENGINES = {'POVRAY_RENDER'} 1806 1807 @classmethod 1808 def poll(cls, context): 1809 engine = context.scene.render.engine 1810 mat = context.material 1811 ob = context.object 1812 return ( 1813 mat 1814 and mat.pov.type == "SURFACE" 1815 and (engine in cls.COMPAT_ENGINES) 1816 and not (mat.pov.material_use_nodes or mat.use_nodes) 1817 ) 1818 1819 def draw(self, context): 1820 layout = self.layout 1821 # layout.operator("pov.material_use_nodes", icon='SOUND')#'NODETREE') 1822 # the above replaced with a context hook below: 1823 layout.operator( 1824 "WM_OT_context_toggle", text="Use POV-Ray Nodes", icon='NODETREE' 1825 ).data_path = "material.pov.material_use_nodes" 1826 1827 1828class MATERIAL_PT_POV_active_node(MaterialButtonsPanel, Panel): 1829 """Use this class to show pov active node properties buttons.""" 1830 1831 bl_label = "Active Node Settings" 1832 bl_context = "material" 1833 bl_options = {'HIDE_HEADER'} 1834 COMPAT_ENGINES = {'POVRAY_RENDER'} 1835 1836 @classmethod 1837 def poll(cls, context): 1838 engine = context.scene.render.engine 1839 mat = context.material 1840 ob = context.object 1841 return ( 1842 mat 1843 and mat.pov.type == "SURFACE" 1844 and (engine in cls.COMPAT_ENGINES) 1845 and mat.pov.material_use_nodes 1846 ) 1847 1848 def draw(self, context): 1849 layout = self.layout 1850 mat = context.material 1851 node_tree = mat.node_tree 1852 if node_tree: 1853 node = node_tree.nodes.active 1854 if mat.use_nodes: 1855 if node: 1856 layout.prop(mat.pov, "material_active_node") 1857 if node.bl_idname == "PovrayMaterialNode": 1858 layout.context_pointer_set("node", node) 1859 if hasattr(node, "draw_buttons_ext"): 1860 node.draw_buttons_ext(context, layout) 1861 elif hasattr(node, "draw_buttons"): 1862 node.draw_buttons(context, layout) 1863 value_inputs = [ 1864 socket 1865 for socket in node.inputs 1866 if socket.enabled and not socket.is_linked 1867 ] 1868 if value_inputs: 1869 layout.separator() 1870 layout.label(text="Inputs:") 1871 for socket in value_inputs: 1872 row = layout.row() 1873 socket.draw(context, row, node, socket.name) 1874 else: 1875 layout.context_pointer_set("node", node) 1876 if hasattr(node, "draw_buttons_ext"): 1877 node.draw_buttons_ext(context, layout) 1878 elif hasattr(node, "draw_buttons"): 1879 node.draw_buttons(context, layout) 1880 value_inputs = [ 1881 socket 1882 for socket in node.inputs 1883 if socket.enabled and not socket.is_linked 1884 ] 1885 if value_inputs: 1886 layout.separator() 1887 layout.label(text="Inputs:") 1888 for socket in value_inputs: 1889 row = layout.row() 1890 socket.draw(context, row, node, socket.name) 1891 else: 1892 layout.label(text="No active nodes!") 1893 1894class MATERIAL_PT_POV_specular(MaterialButtonsPanel, Panel): 1895 """Use this class to define standard material specularity (highlights) buttons.""" 1896 1897 bl_label = "Specular" 1898 COMPAT_ENGINES = {'POVRAY_RENDER'} 1899 1900 @classmethod 1901 def poll(cls, context): 1902 mat = context.material 1903 engine = context.scene.render.engine 1904 return ( 1905 check_material(mat) 1906 and (mat.pov.type in {'SURFACE', 'WIRE'}) 1907 and (engine in cls.COMPAT_ENGINES) 1908 ) 1909 def draw(self, context): 1910 layout = self.layout 1911 1912 mat = context.material.pov 1913 1914 layout.active = (not mat.use_shadeless) 1915 1916 split = layout.split() 1917 1918 col = split.column() 1919 col.prop(mat, "specular_color", text="") 1920 col.prop(mat, "specular_intensity", text="Intensity") 1921 1922 col = split.column() 1923 col.prop(mat, "specular_shader", text="") 1924 col.prop(mat, "use_specular_ramp", text="Ramp") 1925 1926 col = layout.column() 1927 if mat.specular_shader in {'COOKTORR', 'PHONG'}: 1928 col.prop(mat, "specular_hardness", text="Hardness") 1929 elif mat.specular_shader == 'BLINN': 1930 row = col.row() 1931 row.prop(mat, "specular_hardness", text="Hardness") 1932 row.prop(mat, "specular_ior", text="IOR") 1933 elif mat.specular_shader == 'WARDISO': 1934 col.prop(mat, "specular_slope", text="Slope") 1935 elif mat.specular_shader == 'TOON': 1936 row = col.row() 1937 row.prop(mat, "specular_toon_size", text="Size") 1938 row.prop(mat, "specular_toon_smooth", text="Smooth") 1939 1940 if mat.use_specular_ramp: 1941 layout.separator() 1942 layout.template_color_ramp(mat, "specular_ramp", expand=True) 1943 layout.separator() 1944 1945 row = layout.row() 1946 row.prop(mat, "specular_ramp_input", text="Input") 1947 row.prop(mat, "specular_ramp_blend", text="Blend") 1948 1949 layout.prop(mat, "specular_ramp_factor", text="Factor") 1950 1951class MATERIAL_PT_POV_mirror(MaterialButtonsPanel, Panel): 1952 """Use this class to define standard material reflectivity (mirror) buttons.""" 1953 1954 bl_label = "Mirror" 1955 bl_options = {'DEFAULT_CLOSED'} 1956 bl_idname = "MATERIAL_PT_POV_raytrace_mirror" 1957 COMPAT_ENGINES = {'POVRAY_RENDER'} 1958 1959 @classmethod 1960 def poll(cls, context): 1961 mat = context.material 1962 engine = context.scene.render.engine 1963 return ( 1964 check_material(mat) 1965 and (mat.pov.type in {'SURFACE', 'WIRE'}) 1966 and (engine in cls.COMPAT_ENGINES) 1967 ) 1968 1969 def draw_header(self, context): 1970 mat = context.material 1971 raym = mat.pov_raytrace_mirror 1972 1973 self.layout.prop(raym, "use", text="") 1974 1975 def draw(self, context): 1976 layout = self.layout 1977 1978 mat = ( 1979 context.material 1980 ) # Formerly : #mat = active_node_mat(context.material) 1981 raym = mat.pov_raytrace_mirror 1982 1983 layout.active = raym.use 1984 1985 split = layout.split() 1986 1987 col = split.column() 1988 col.prop(raym, "reflect_factor") 1989 col.prop(raym, "mirror_color", text="") 1990 1991 col = split.column() 1992 col.prop(raym, "fresnel") 1993 sub = col.column() 1994 sub.active = raym.fresnel > 0.0 1995 sub.prop(raym, "fresnel_factor", text="Blend") 1996 1997 split = layout.split() 1998 1999 col = split.column() 2000 col.separator() 2001 col.prop(raym, "depth") 2002 col.prop(raym, "distance", text="Max Dist") 2003 col.separator() 2004 sub = col.split(factor=0.4) 2005 sub.active = raym.distance > 0.0 2006 sub.label(text="Fade To:") 2007 sub.prop(raym, "fade_to", text="") 2008 2009 col = split.column() 2010 col.label(text="Gloss:") 2011 col.prop(raym, "gloss_factor", text="Amount") 2012 sub = col.column() 2013 sub.active = raym.gloss_factor < 1.0 2014 sub.prop(raym, "gloss_threshold", text="Threshold") 2015 sub.prop(raym, "gloss_samples", text="Noise") 2016 sub.prop(raym, "gloss_anisotropic", text="Anisotropic") 2017 2018 2019class MATERIAL_PT_POV_transp(MaterialButtonsPanel, Panel): 2020 """Use this class to define pov material transparency (alpha) buttons.""" 2021 2022 bl_label = "Transparency" 2023 COMPAT_ENGINES = {'POVRAY_RENDER'} 2024 2025 @classmethod 2026 def poll(cls, context): 2027 mat = context.material 2028 engine = context.scene.render.engine 2029 return ( 2030 check_material(mat) 2031 and (mat.pov.type in {'SURFACE', 'WIRE'}) 2032 and (engine in cls.COMPAT_ENGINES) 2033 ) 2034 2035 def draw_header(self, context): 2036 mat = context.material 2037 2038 if simple_material(mat): 2039 self.layout.prop(mat.pov, "use_transparency", text="") 2040 2041 def draw(self, context): 2042 layout = self.layout 2043 2044 base_mat = context.material 2045 mat = context.material # FORMERLY active_node_mat(context.material) 2046 rayt = mat.pov_raytrace_transparency 2047 2048 if simple_material(base_mat): 2049 row = layout.row() 2050 row.active = mat.pov.use_transparency 2051 row.prop(mat.pov, "transparency_method", expand=True) 2052 2053 split = layout.split() 2054 split.active = base_mat.pov.use_transparency 2055 2056 col = split.column() 2057 col.prop(mat.pov, "alpha") 2058 row = col.row() 2059 row.active = (base_mat.pov.transparency_method != 'MASK') and ( 2060 not mat.pov.use_shadeless 2061 ) 2062 row.prop(mat.pov, "specular_alpha", text="Specular") 2063 2064 col = split.column() 2065 col.active = not mat.pov.use_shadeless 2066 col.prop(rayt, "fresnel") 2067 sub = col.column() 2068 sub.active = rayt.fresnel > 0.0 2069 sub.prop(rayt, "fresnel_factor", text="Blend") 2070 2071 if base_mat.pov.transparency_method == 'RAYTRACE': 2072 layout.separator() 2073 split = layout.split() 2074 split.active = base_mat.pov.use_transparency 2075 2076 col = split.column() 2077 col.prop(rayt, "ior") 2078 col.prop(rayt, "filter") 2079 col.prop(rayt, "falloff") 2080 col.prop(rayt, "depth_max") 2081 col.prop(rayt, "depth") 2082 2083 col = split.column() 2084 col.label(text="Gloss:") 2085 col.prop(rayt, "gloss_factor", text="Amount") 2086 sub = col.column() 2087 sub.active = rayt.gloss_factor < 1.0 2088 sub.prop(rayt, "gloss_threshold", text="Threshold") 2089 sub.prop(rayt, "gloss_samples", text="Samples") 2090 2091 2092class MATERIAL_PT_POV_reflection(MaterialButtonsPanel, Panel): 2093 """Use this class to define more pov specific reflectivity buttons.""" 2094 2095 bl_label = "POV-Ray Reflection" 2096 bl_parent_id = "MATERIAL_PT_POV_raytrace_mirror" 2097 COMPAT_ENGINES = {'POVRAY_RENDER'} 2098 2099 @classmethod 2100 def poll(cls, context): 2101 engine = context.scene.render.engine 2102 mat = context.material 2103 ob = context.object 2104 return ( 2105 mat 2106 and mat.pov.type == "SURFACE" 2107 and (engine in cls.COMPAT_ENGINES) 2108 and not (mat.pov.material_use_nodes or mat.use_nodes) 2109 ) 2110 2111 def draw(self, context): 2112 layout = self.layout 2113 mat = context.material 2114 col = layout.column() 2115 col.prop(mat.pov, "irid_enable") 2116 if mat.pov.irid_enable: 2117 col = layout.column() 2118 col.prop(mat.pov, "irid_amount", slider=True) 2119 col.prop(mat.pov, "irid_thickness", slider=True) 2120 col.prop(mat.pov, "irid_turbulence", slider=True) 2121 col.prop(mat.pov, "conserve_energy") 2122 col2 = col.split().column() 2123 2124 if not mat.pov_raytrace_mirror.use: 2125 col2.label(text="Please Check Mirror settings :") 2126 col2.active = mat.pov_raytrace_mirror.use 2127 col2.prop(mat.pov, "mirror_use_IOR") 2128 if mat.pov.mirror_use_IOR: 2129 col2.alignment = 'CENTER' 2130 col2.label(text="The current Raytrace ") 2131 col2.label(text="Transparency IOR is: " + str(mat.pov.ior)) 2132 col2.prop(mat.pov, "mirror_metallic") 2133 2134 2135''' 2136#group some native Blender (SSS) and POV (Fade)settings under such a parent panel? 2137class MATERIAL_PT_POV_interior(MaterialButtonsPanel, Panel): 2138 bl_label = "POV-Ray Interior" 2139 bl_idname = "material.pov_interior" 2140 #bl_parent_id = "material.absorption" 2141 COMPAT_ENGINES = {'POVRAY_RENDER'} 2142 @classmethod 2143 def poll(cls, context): 2144 engine = context.scene.render.engine 2145 mat=context.material 2146 ob = context.object 2147 return mat and mat.pov.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and not (mat.pov.material_use_nodes or mat.use_nodes) 2148 2149 2150 def draw_header(self, context): 2151 mat = context.material 2152''' 2153 2154 2155class MATERIAL_PT_POV_fade_color(MaterialButtonsPanel, Panel): 2156 """Use this class to define pov fading (absorption) color buttons.""" 2157 2158 bl_label = "POV-Ray Absorption" 2159 COMPAT_ENGINES = {'POVRAY_RENDER'} 2160 # bl_parent_id = "material.pov_interior" 2161 2162 @classmethod 2163 def poll(cls, context): 2164 engine = context.scene.render.engine 2165 mat = context.material 2166 ob = context.object 2167 return ( 2168 mat 2169 and mat.pov.type == "SURFACE" 2170 and (engine in cls.COMPAT_ENGINES) 2171 and not (mat.pov.material_use_nodes or mat.use_nodes) 2172 ) 2173 2174 def draw_header(self, context): 2175 mat = context.material 2176 2177 self.layout.prop(mat.pov, "interior_fade_color", text="") 2178 2179 def draw(self, context): 2180 layout = self.layout 2181 mat = context.material 2182 # layout.active = mat.pov.interior_fade_color 2183 if mat.pov.interior_fade_color != (0.0, 0.0, 0.0): 2184 layout.label(text="Raytrace transparency") 2185 layout.label(text="depth max Limit needs") 2186 layout.label(text="to be non zero to fade") 2187 2188 pass 2189 2190 2191class MATERIAL_PT_POV_caustics(MaterialButtonsPanel, Panel): 2192 """Use this class to define pov caustics buttons.""" 2193 2194 bl_label = "Caustics" 2195 COMPAT_ENGINES = {'POVRAY_RENDER'} 2196 2197 @classmethod 2198 def poll(cls, context): 2199 engine = context.scene.render.engine 2200 mat = context.material 2201 ob = context.object 2202 return ( 2203 mat 2204 and mat.pov.type == "SURFACE" 2205 and (engine in cls.COMPAT_ENGINES) 2206 and not (mat.pov.material_use_nodes or mat.use_nodes) 2207 ) 2208 2209 def draw_header(self, context): 2210 mat = context.material 2211 if mat.pov.caustics_enable: 2212 self.layout.prop( 2213 mat.pov, "caustics_enable", text="", icon="PMARKER_SEL" 2214 ) 2215 else: 2216 self.layout.prop( 2217 mat.pov, "caustics_enable", text="", icon="PMARKER" 2218 ) 2219 2220 def draw(self, context): 2221 2222 layout = self.layout 2223 2224 mat = context.material 2225 layout.active = mat.pov.caustics_enable 2226 col = layout.column() 2227 if mat.pov.caustics_enable: 2228 col.prop(mat.pov, "refraction_caustics") 2229 if mat.pov.refraction_caustics: 2230 2231 col.prop(mat.pov, "refraction_type", text="") 2232 2233 if mat.pov.refraction_type == "1": 2234 col.prop(mat.pov, "fake_caustics_power", slider=True) 2235 elif mat.pov.refraction_type == "2": 2236 col.prop(mat.pov, "photons_dispersion", slider=True) 2237 col.prop(mat.pov, "photons_dispersion_samples", slider=True) 2238 col.prop(mat.pov, "photons_reflection") 2239 2240 if ( 2241 not mat.pov.refraction_caustics 2242 and not mat.pov.photons_reflection 2243 ): 2244 col = layout.column() 2245 col.alignment = 'CENTER' 2246 col.label(text="Caustics override is on, ") 2247 col.label(text="but you didn't chose any !") 2248 2249 2250class MATERIAL_PT_strand(MaterialButtonsPanel, Panel): 2251 """Use this class to define Blender strand antialiasing buttons.""" 2252 2253 bl_label = "Strand" 2254 bl_options = {'DEFAULT_CLOSED'} 2255 COMPAT_ENGINES = {'POVRAY_RENDER'} 2256 2257 @classmethod 2258 def poll(cls, context): 2259 mat = context.material 2260 engine = context.scene.render.engine 2261 return ( 2262 mat 2263 and (mat.pov.type in {'SURFACE', 'WIRE', 'HALO'}) 2264 and (engine in cls.COMPAT_ENGINES) 2265 ) 2266 2267 def draw(self, context): 2268 layout = self.layout 2269 2270 mat = context.material # don't use node material 2271 tan = mat.strand 2272 2273 split = layout.split() 2274 2275 col = split.column() 2276 sub = col.column(align=True) 2277 sub.label(text="Size:") 2278 sub.prop(tan, "root_size", text="Root") 2279 sub.prop(tan, "tip_size", text="Tip") 2280 sub.prop(tan, "size_min", text="Minimum") 2281 sub.prop(tan, "use_blender_units") 2282 sub = col.column() 2283 sub.active = not mat.pov.use_shadeless 2284 sub.prop(tan, "use_tangent_shading") 2285 col.prop(tan, "shape") 2286 2287 col = split.column() 2288 col.label(text="Shading:") 2289 col.prop(tan, "width_fade") 2290 ob = context.object 2291 if ob and ob.type == 'MESH': 2292 col.prop_search( 2293 tan, "uv_layer", ob.data, "tessface_uv_textures", text="" 2294 ) 2295 else: 2296 col.prop(tan, "uv_layer", text="") 2297 col.separator() 2298 sub = col.column() 2299 sub.active = not mat.pov.use_shadeless 2300 sub.label(text="Surface diffuse:") 2301 sub = col.column() 2302 sub.prop(tan, "blend_distance", text="Distance") 2303 2304 2305class MATERIAL_PT_POV_replacement_text(MaterialButtonsPanel, Panel): 2306 """Use this class to define pov custom code declared name field.""" 2307 2308 bl_label = "Custom POV Code" 2309 COMPAT_ENGINES = {'POVRAY_RENDER'} 2310 2311 def draw(self, context): 2312 layout = self.layout 2313 2314 mat = context.material 2315 2316 col = layout.column() 2317 col.label(text="Replace properties with:") 2318 col.prop(mat.pov, "replacement_text", text="") 2319 2320 2321class TEXTURE_MT_POV_specials(Menu): 2322 """Use this class to define pov texture slot operations buttons.""" 2323 2324 bl_label = "Texture Specials" 2325 COMPAT_ENGINES = {'POVRAY_RENDER'} 2326 2327 def draw(self, context): 2328 layout = self.layout 2329 2330 layout.operator("texture.slot_copy", icon='COPYDOWN') 2331 layout.operator("texture.slot_paste", icon='PASTEDOWN') 2332 2333 2334class WORLD_TEXTURE_SLOTS_UL_POV_layerlist(UIList): 2335 """Use this class to show pov texture slots list.""" # XXX Not used yet 2336 2337 index: bpy.props.IntProperty(name='index') 2338 def draw_item( 2339 self, context, layout, data, item, icon, active_data, active_propname 2340 ): 2341 world = context.scene.world # .pov 2342 active_data = world.pov 2343 # tex = context.texture #may be needed later? 2344 2345 # We could write some code to decide which icon to use here... 2346 custom_icon = 'TEXTURE' 2347 2348 ob = data 2349 slot = item 2350 # ma = slot.name 2351 # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code. 2352 if self.layout_type in {'DEFAULT', 'COMPACT'}: 2353 # You should always start your row layout by a label (icon + text), or a non-embossed text field, 2354 # this will also make the row easily selectable in the list! The later also enables ctrl-click rename. 2355 # We use icon_value of label, as our given icon is an integer value, not an enum ID. 2356 # Note "data" names should never be translated! 2357 if slot: 2358 layout.prop( 2359 item, "texture", text="", emboss=False, icon='TEXTURE' 2360 ) 2361 else: 2362 layout.label(text="New", translate=False, icon_value=icon) 2363 # 'GRID' layout type should be as compact as possible (typically a single icon!). 2364 elif self.layout_type in {'GRID'}: 2365 layout.alignment = 'CENTER' 2366 layout.label(text="", icon_value=icon) 2367 2368 2369class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(UIList): 2370 """Use this class to show pov texture slots list.""" 2371 2372 # texture_slots: 2373 index: bpy.props.IntProperty(name='index') 2374 # foo = random prop 2375 def draw_item( 2376 self, context, layout, data, item, icon, active_data, active_propname 2377 ): 2378 ob = data 2379 slot = item 2380 # ma = slot.name 2381 # draw_item must handle the three layout types... Usually 'DEFAULT' and 'COMPACT' can share the same code. 2382 if self.layout_type in {'DEFAULT', 'COMPACT'}: 2383 # You should always start your row layout by a label (icon + text), or a non-embossed text field, 2384 # this will also make the row easily selectable in the list! The later also enables ctrl-click rename. 2385 # We use icon_value of label, as our given icon is an integer value, not an enum ID. 2386 # Note "data" names should never be translated! 2387 if slot: 2388 layout.prop( 2389 item, "texture", text="", emboss=False, icon='TEXTURE' 2390 ) 2391 else: 2392 layout.label(text="New", translate=False, icon_value=icon) 2393 # 'GRID' layout type should be as compact as possible (typically a single icon!). 2394 elif self.layout_type in {'GRID'}: 2395 layout.alignment = 'CENTER' 2396 layout.label(text="", icon_value=icon) 2397 2398# Rewrite an existing class to modify. 2399# register but not unregistered because 2400# the modified parts concern only POVRAY_RENDER 2401class TEXTURE_PT_context(TextureButtonsPanel, Panel): 2402 bl_label = "" 2403 bl_context = "texture" 2404 bl_options = {'HIDE_HEADER'} 2405 COMPAT_ENGINES = {'POVRAY_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} 2406 2407 @classmethod 2408 def poll(cls, context): 2409 return ( 2410 (context.scene.texture_context 2411 not in('MATERIAL','WORLD','LIGHT','PARTICLES','LINESTYLE') 2412 or context.scene.render.engine != 'POVRAY_RENDER') 2413 ) 2414 def draw(self, context): 2415 layout = self.layout 2416 tex = context.texture 2417 space = context.space_data 2418 pin_id = space.pin_id 2419 use_pin_id = space.use_pin_id 2420 user = context.texture_user 2421 2422 col = layout.column() 2423 2424 if not (use_pin_id and isinstance(pin_id, bpy.types.Texture)): 2425 pin_id = None 2426 2427 if not pin_id: 2428 col.template_texture_user() 2429 2430 if user or pin_id: 2431 col.separator() 2432 2433 if pin_id: 2434 col.template_ID(space, "pin_id") 2435 else: 2436 propname = context.texture_user_property.identifier 2437 col.template_ID(user, propname, new="texture.new") 2438 2439 if tex: 2440 col.separator() 2441 2442 split = col.split(factor=0.2) 2443 split.label(text="Type") 2444 split.prop(tex, "type", text="") 2445 2446class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel): 2447 """Use this class to show pov texture context buttons.""" 2448 2449 bl_label = "" 2450 bl_options = {'HIDE_HEADER'} 2451 COMPAT_ENGINES = {'POVRAY_RENDER'} 2452 2453 @classmethod 2454 def poll(cls, context): 2455 engine = context.scene.render.engine 2456 return engine in cls.COMPAT_ENGINES 2457 # if not (hasattr(context, "pov_texture_slot") or hasattr(context, "texture_node")): 2458 # return False 2459 return ( 2460 context.material 2461 or context.scene.world 2462 or context.light 2463 or context.texture 2464 or context.line_style 2465 or context.particle_system 2466 or isinstance(context.space_data.pin_id, ParticleSettings) 2467 or context.texture_user 2468 ) and (engine in cls.COMPAT_ENGINES) 2469 2470 def draw(self, context): 2471 layout = self.layout 2472 2473 scene = context.scene 2474 mat = context.view_layer.objects.active.active_material 2475 wld = context.scene.world 2476 2477 layout.prop(scene, "texture_context", expand=True) 2478 if scene.texture_context == 'MATERIAL' and mat is not None: 2479 2480 row = layout.row() 2481 row.template_list( 2482 "MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist", 2483 "", 2484 mat, 2485 "pov_texture_slots", 2486 mat.pov, 2487 "active_texture_index", 2488 rows=2, 2489 maxrows=16, 2490 type="DEFAULT" 2491 ) 2492 col = row.column(align=True) 2493 col.operator("pov.textureslotadd", icon='ADD', text='') 2494 col.operator("pov.textureslotremove", icon='REMOVE', text='') 2495 #todo: recreate for pov_texture_slots? 2496 #col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' 2497 #col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' 2498 col.separator() 2499 2500 if mat.pov_texture_slots: 2501 index = mat.pov.active_texture_index 2502 slot = mat.pov_texture_slots[index] 2503 povtex = slot.texture#slot.name 2504 tex = bpy.data.textures[povtex] 2505 col.prop(tex, 'use_fake_user', text='') 2506 #layout.label(text='Linked Texture data browser:') 2507 propname = slot.texture_search 2508 # if slot.texture was a pointer to texture data rather than just a name string: 2509 # layout.template_ID(povtex, "texture", new="texture.new") 2510 2511 layout.prop_search( 2512 slot, 'texture_search', bpy.data, 'textures', text='', icon='TEXTURE' 2513 ) 2514 try: 2515 bpy.context.tool_settings.image_paint.brush.texture = bpy.data.textures[slot.texture_search] 2516 bpy.context.tool_settings.image_paint.brush.mask_texture = bpy.data.textures[slot.texture_search] 2517 except KeyError: 2518 # texture not hand-linked by user 2519 pass 2520 2521 if tex: 2522 layout.separator() 2523 split = layout.split(factor=0.2) 2524 split.label(text="Type") 2525 split.prop(tex, "type", text="") 2526 2527 # else: 2528 # for i in range(18): # length of material texture slots 2529 # mat.pov_texture_slots.add() 2530 elif scene.texture_context == 'WORLD' and wld is not None: 2531 2532 row = layout.row() 2533 row.template_list( 2534 "WORLD_TEXTURE_SLOTS_UL_POV_layerlist", 2535 "", 2536 wld, 2537 "pov_texture_slots", 2538 wld.pov, 2539 "active_texture_index", 2540 rows=2, 2541 maxrows=16, 2542 type="DEFAULT" 2543 ) 2544 col = row.column(align=True) 2545 col.operator("pov.textureslotadd", icon='ADD', text='') 2546 col.operator("pov.textureslotremove", icon='REMOVE', text='') 2547 2548 #todo: recreate for pov_texture_slots? 2549 #col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' 2550 #col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' 2551 col.separator() 2552 2553 if wld.pov_texture_slots: 2554 index = wld.pov.active_texture_index 2555 slot = wld.pov_texture_slots[index] 2556 povtex = slot.texture#slot.name 2557 tex = bpy.data.textures[povtex] 2558 col.prop(tex, 'use_fake_user', text='') 2559 #layout.label(text='Linked Texture data browser:') 2560 propname = slot.texture_search 2561 # if slot.texture was a pointer to texture data rather than just a name string: 2562 # layout.template_ID(povtex, "texture", new="texture.new") 2563 2564 layout.prop_search( 2565 slot, 'texture_search', bpy.data, 'textures', text='', icon='TEXTURE' 2566 ) 2567 try: 2568 bpy.context.tool_settings.image_paint.brush.texture = bpy.data.textures[slot.texture_search] 2569 bpy.context.tool_settings.image_paint.brush.mask_texture = bpy.data.textures[slot.texture_search] 2570 except KeyError: 2571 # texture not hand-linked by user 2572 pass 2573 2574 if tex: 2575 layout.separator() 2576 split = layout.split(factor=0.2) 2577 split.label(text="Type") 2578 split.prop(tex, "type", text="") 2579 2580# Commented out below is a reminder of what existed in Blender Internal 2581# attributes need to be recreated 2582''' 2583 slot = getattr(context, "texture_slot", None) 2584 node = getattr(context, "texture_node", None) 2585 space = context.space_data 2586 2587 #attempt at replacing removed space_data 2588 mtl = getattr(context, "material", None) 2589 if mtl != None: 2590 spacedependant = mtl 2591 wld = getattr(context, "world", None) 2592 if wld != None: 2593 spacedependant = wld 2594 lgt = getattr(context, "light", None) 2595 if lgt != None: 2596 spacedependant = lgt 2597 2598 2599 #idblock = context.particle_system.settings 2600 2601 tex = getattr(context, "texture", None) 2602 if tex != None: 2603 spacedependant = tex 2604 2605 2606 2607 scene = context.scene 2608 idblock = scene.pov#pov_context_tex_datablock(context) 2609 pin_id = space.pin_id 2610 2611 #spacedependant.use_limited_texture_context = True 2612 2613 if space.use_pin_id and not isinstance(pin_id, Texture): 2614 idblock = id_tex_datablock(pin_id) 2615 pin_id = None 2616 2617 if not space.use_pin_id: 2618 layout.row().prop(spacedependant, "texture_context", expand=True) 2619 pin_id = None 2620 2621 if spacedependant.texture_context == 'OTHER': 2622 if not pin_id: 2623 layout.template_texture_user() 2624 user = context.texture_user 2625 if user or pin_id: 2626 layout.separator() 2627 2628 row = layout.row() 2629 2630 if pin_id: 2631 row.template_ID(space, "pin_id") 2632 else: 2633 propname = context.texture_user_property.identifier 2634 row.template_ID(user, propname, new="texture.new") 2635 2636 if tex: 2637 split = layout.split(factor=0.2) 2638 if tex.use_nodes: 2639 if slot: 2640 split.label(text="Output:") 2641 split.prop(slot, "output_node", text="") 2642 else: 2643 split.label(text="Type:") 2644 split.prop(tex, "type", text="") 2645 return 2646 2647 tex_collection = (pin_id is None) and (node is None) and (spacedependant.texture_context not in ('LINESTYLE','OTHER')) 2648 2649 if tex_collection: 2650 2651 pov = getattr(context, "pov", None) 2652 active_texture_index = getattr(spacedependant, "active_texture_index", None) 2653 print (pov) 2654 print(idblock) 2655 print(active_texture_index) 2656 row = layout.row() 2657 2658 row.template_list("TEXTURE_UL_texslots", "", idblock, "texture_slots", 2659 idblock, "active_texture_index", rows=2, maxrows=16, type="DEFAULT") 2660 2661 # row.template_list("WORLD_TEXTURE_SLOTS_UL_List", "texture_slots", world, 2662 # world.texture_slots, world, "active_texture_index", rows=2) 2663 2664 col = row.column(align=True) 2665 col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP' 2666 col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN' 2667 col.menu("TEXTURE_MT_POV_specials", icon='DOWNARROW_HLT', text="") 2668 2669 if tex_collection: 2670 layout.template_ID(idblock, "active_texture", new="texture.new") 2671 elif node: 2672 layout.template_ID(node, "texture", new="texture.new") 2673 elif idblock: 2674 layout.template_ID(idblock, "texture", new="texture.new") 2675 2676 if pin_id: 2677 layout.template_ID(space, "pin_id") 2678 2679 if tex: 2680 split = layout.split(factor=0.2) 2681 if tex.use_nodes: 2682 if slot: 2683 split.label(text="Output:") 2684 split.prop(slot, "output_node", text="") 2685 else: 2686 split.label(text="Type:") 2687''' 2688 2689 2690class TEXTURE_PT_colors(TextureButtonsPanel, Panel): 2691 """Use this class to show pov color ramps.""" 2692 2693 bl_label = "Colors" 2694 bl_options = {'DEFAULT_CLOSED'} 2695 COMPAT_ENGINES = {'POVRAY_RENDER'} 2696 2697 def draw(self, context): 2698 layout = self.layout 2699 2700 tex = context.texture 2701 2702 layout.prop(tex, "use_color_ramp", text="Ramp") 2703 if tex.use_color_ramp: 2704 layout.template_color_ramp(tex, "color_ramp", expand=True) 2705 2706 split = layout.split() 2707 2708 col = split.column() 2709 col.label(text="RGB Multiply:") 2710 sub = col.column(align=True) 2711 sub.prop(tex, "factor_red", text="R") 2712 sub.prop(tex, "factor_green", text="G") 2713 sub.prop(tex, "factor_blue", text="B") 2714 2715 col = split.column() 2716 col.label(text="Adjust:") 2717 col.prop(tex, "intensity") 2718 col.prop(tex, "contrast") 2719 col.prop(tex, "saturation") 2720 2721 col = layout.column() 2722 col.prop(tex, "use_clamp", text="Clamp") 2723 2724 2725# Texture Slot Panels # 2726 2727 2728class TEXTURE_OT_POV_texture_slot_add(Operator): 2729 """Use this class for the add texture slot button.""" 2730 2731 bl_idname = "pov.textureslotadd" 2732 bl_label = "Add" 2733 bl_description = "Add texture_slot" 2734 bl_options = {'REGISTER', 'UNDO'} 2735 COMPAT_ENGINES = {'POVRAY_RENDER'} 2736 2737 def execute(self, context): 2738 idblock = pov_context_tex_datablock(context) 2739 tex = bpy.data.textures.new(name='Texture', type='IMAGE') 2740 #tex.use_fake_user = True 2741 #mat = context.view_layer.objects.active.active_material 2742 slot = idblock.pov_texture_slots.add() 2743 slot.name = tex.name 2744 slot.texture = tex.name 2745 slot.texture_search = tex.name 2746 # Switch paint brush and paint brush mask 2747 # to this texture so settings remain contextual 2748 bpy.context.tool_settings.image_paint.brush.texture = tex 2749 bpy.context.tool_settings.image_paint.brush.mask_texture = tex 2750 idblock.pov.active_texture_index = (len(idblock.pov_texture_slots)-1) 2751 2752 #for area in bpy.context.screen.areas: 2753 #if area.type in ['PROPERTIES']: 2754 #area.tag_redraw() 2755 2756 2757 return {'FINISHED'} 2758 2759 2760class TEXTURE_OT_POV_texture_slot_remove(Operator): 2761 """Use this class for the remove texture slot button.""" 2762 2763 bl_idname = "pov.textureslotremove" 2764 bl_label = "Remove" 2765 bl_description = "Remove texture_slot" 2766 bl_options = {'REGISTER', 'UNDO'} 2767 COMPAT_ENGINES = {'POVRAY_RENDER'} 2768 2769 def execute(self, context): 2770 idblock = pov_context_tex_datablock(context) 2771 #mat = context.view_layer.objects.active.active_material 2772 tex_slot = idblock.pov_texture_slots.remove(idblock.pov.active_texture_index) 2773 if idblock.pov.active_texture_index > 0: 2774 idblock.pov.active_texture_index -= 1 2775 try: 2776 tex = idblock.pov_texture_slots[idblock.pov.active_texture_index].texture 2777 except IndexError: 2778 # No more slots 2779 return {'FINISHED'} 2780 # Switch paint brush to previous texture so settings remain contextual 2781 # if 'tex' in locals(): # Would test is the tex variable is assigned / exists 2782 bpy.context.tool_settings.image_paint.brush.texture = bpy.data.textures[tex] 2783 bpy.context.tool_settings.image_paint.brush.mask_texture = bpy.data.textures[tex] 2784 2785 return {'FINISHED'} 2786 2787class TextureSlotPanel(TextureButtonsPanel): 2788 """Use this class to show pov texture slots panel.""" 2789 2790 COMPAT_ENGINES = {'POVRAY_RENDER'} 2791 2792 @classmethod 2793 def poll(cls, context): 2794 if not hasattr(context, "pov_texture_slot"): 2795 return False 2796 2797 engine = context.scene.render.engine 2798 return TextureButtonsPanel.poll(cls, context) and ( 2799 engine in cls.COMPAT_ENGINES 2800 ) 2801 2802 2803class TEXTURE_PT_POV_type(TextureButtonsPanel, Panel): 2804 """Use this class to define pov texture type buttons.""" 2805 2806 bl_label = "POV Textures" 2807 COMPAT_ENGINES = {'POVRAY_RENDER'} 2808 bl_options = {'HIDE_HEADER'} 2809 2810 def draw(self, context): 2811 layout = self.layout 2812 world = context.world 2813 tex = context.texture 2814 2815 split = layout.split(factor=0.2) 2816 split.label(text="Pattern") 2817 split.prop(tex.pov, "tex_pattern_type", text="") 2818 2819 # row = layout.row() 2820 # row.template_list("WORLD_TEXTURE_SLOTS_UL_List", "texture_slots", world, 2821 # world.texture_slots, world, "active_texture_index") 2822 2823 2824class TEXTURE_PT_POV_preview(TextureButtonsPanel, Panel): 2825 """Use this class to define pov texture preview panel.""" 2826 2827 bl_label = "Preview" 2828 COMPAT_ENGINES = {'POVRAY_RENDER'} 2829 bl_options = {'HIDE_HEADER'} 2830 2831 @classmethod 2832 def poll(cls, context): 2833 engine = context.scene.render.engine 2834 if not hasattr(context, "pov_texture_slot"): 2835 return False 2836 tex = context.texture 2837 mat = bpy.context.active_object.active_material 2838 return ( 2839 tex 2840 and (tex.pov.tex_pattern_type != 'emulator') 2841 and (engine in cls.COMPAT_ENGINES) 2842 ) 2843 2844 def draw(self, context): 2845 tex = context.texture 2846 slot = getattr(context, "pov_texture_slot", None) 2847 idblock = pov_context_tex_datablock(context) 2848 layout = self.layout 2849 # if idblock: 2850 # layout.template_preview(tex, parent=idblock, slot=slot) 2851 if tex.pov.tex_pattern_type != 'emulator': 2852 layout.operator("tex.preview_update") 2853 else: 2854 layout.template_preview(tex, slot=slot) 2855 2856 2857class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel): 2858 """Use this class to define pov texture pattern buttons.""" 2859 2860 bl_label = "POV Pattern Options" 2861 bl_options = {'HIDE_HEADER'} 2862 COMPAT_ENGINES = {'POVRAY_RENDER'} 2863 2864 def draw(self, context): 2865 mat = bpy.context.active_object.active_material 2866 layout = self.layout 2867 tex = context.texture 2868 align = True 2869 if tex is not None and tex.pov.tex_pattern_type != 'emulator': 2870 if tex.pov.tex_pattern_type == 'agate': 2871 layout.prop( 2872 tex.pov, "modifier_turbulence", text="Agate Turbulence" 2873 ) 2874 if tex.pov.tex_pattern_type in {'spiral1', 'spiral2'}: 2875 layout.prop(tex.pov, "modifier_numbers", text="Number of arms") 2876 if tex.pov.tex_pattern_type == 'tiling': 2877 layout.prop(tex.pov, "modifier_numbers", text="Pattern number") 2878 if tex.pov.tex_pattern_type == 'magnet': 2879 layout.prop(tex.pov, "magnet_style", text="Magnet style") 2880 if tex.pov.tex_pattern_type == 'quilted': 2881 row = layout.row(align=align) 2882 row.prop(tex.pov, "modifier_control0", text="Control0") 2883 row.prop(tex.pov, "modifier_control1", text="Control1") 2884 if tex.pov.tex_pattern_type == 'brick': 2885 col = layout.column(align=align) 2886 row = col.row() 2887 row.prop(tex.pov, "brick_size_x", text="Brick size X") 2888 row.prop(tex.pov, "brick_size_y", text="Brick size Y") 2889 row = col.row() 2890 row.prop(tex.pov, "brick_size_z", text="Brick size Z") 2891 row.prop(tex.pov, "brick_mortar", text="Brick mortar") 2892 if tex.pov.tex_pattern_type in {'julia', 'mandel', 'magnet'}: 2893 col = layout.column(align=align) 2894 if tex.pov.tex_pattern_type == 'julia': 2895 row = col.row() 2896 row.prop(tex.pov, "julia_complex_1", text="Complex 1") 2897 row.prop(tex.pov, "julia_complex_2", text="Complex 2") 2898 if ( 2899 tex.pov.tex_pattern_type == 'magnet' 2900 and tex.pov.magnet_style == 'julia' 2901 ): 2902 row = col.row() 2903 row.prop(tex.pov, "julia_complex_1", text="Complex 1") 2904 row.prop(tex.pov, "julia_complex_2", text="Complex 2") 2905 row = col.row() 2906 if tex.pov.tex_pattern_type in {'julia', 'mandel'}: 2907 row.prop(tex.pov, "f_exponent", text="Exponent") 2908 if tex.pov.tex_pattern_type == 'magnet': 2909 row.prop(tex.pov, "magnet_type", text="Type") 2910 row.prop(tex.pov, "f_iter", text="Iterations") 2911 row = col.row() 2912 row.prop(tex.pov, "f_ior", text="Interior") 2913 row.prop(tex.pov, "f_ior_fac", text="Factor I") 2914 row = col.row() 2915 row.prop(tex.pov, "f_eor", text="Exterior") 2916 row.prop(tex.pov, "f_eor_fac", text="Factor E") 2917 if tex.pov.tex_pattern_type == 'gradient': 2918 layout.label(text="Gradient orientation:") 2919 column_flow = layout.column_flow(columns=3, align=True) 2920 column_flow.prop(tex.pov, "grad_orient_x", text="X") 2921 column_flow.prop(tex.pov, "grad_orient_y", text="Y") 2922 column_flow.prop(tex.pov, "grad_orient_z", text="Z") 2923 if tex.pov.tex_pattern_type == 'pavement': 2924 layout.prop( 2925 tex.pov, "pave_sides", text="Pavement:number of sides" 2926 ) 2927 col = layout.column(align=align) 2928 column_flow = col.column_flow(columns=3, align=True) 2929 column_flow.prop(tex.pov, "pave_tiles", text="Tiles") 2930 if tex.pov.pave_sides == '4' and tex.pov.pave_tiles == 6: 2931 column_flow.prop(tex.pov, "pave_pat_35", text="Pattern") 2932 if tex.pov.pave_sides == '6' and tex.pov.pave_tiles == 5: 2933 column_flow.prop(tex.pov, "pave_pat_22", text="Pattern") 2934 if tex.pov.pave_sides == '4' and tex.pov.pave_tiles == 5: 2935 column_flow.prop(tex.pov, "pave_pat_12", text="Pattern") 2936 if tex.pov.pave_sides == '3' and tex.pov.pave_tiles == 6: 2937 column_flow.prop(tex.pov, "pave_pat_12", text="Pattern") 2938 if tex.pov.pave_sides == '6' and tex.pov.pave_tiles == 4: 2939 column_flow.prop(tex.pov, "pave_pat_7", text="Pattern") 2940 if tex.pov.pave_sides == '4' and tex.pov.pave_tiles == 4: 2941 column_flow.prop(tex.pov, "pave_pat_5", text="Pattern") 2942 if tex.pov.pave_sides == '3' and tex.pov.pave_tiles == 5: 2943 column_flow.prop(tex.pov, "pave_pat_4", text="Pattern") 2944 if tex.pov.pave_sides == '6' and tex.pov.pave_tiles == 3: 2945 column_flow.prop(tex.pov, "pave_pat_3", text="Pattern") 2946 if tex.pov.pave_sides == '3' and tex.pov.pave_tiles == 4: 2947 column_flow.prop(tex.pov, "pave_pat_3", text="Pattern") 2948 if tex.pov.pave_sides == '4' and tex.pov.pave_tiles == 3: 2949 column_flow.prop(tex.pov, "pave_pat_2", text="Pattern") 2950 if tex.pov.pave_sides == '6' and tex.pov.pave_tiles == 6: 2951 column_flow.label(text="!!! 5 tiles!") 2952 column_flow.prop(tex.pov, "pave_form", text="Form") 2953 if tex.pov.tex_pattern_type == 'function': 2954 layout.prop(tex.pov, "func_list", text="Functions") 2955 if ( 2956 tex.pov.tex_pattern_type == 'function' 2957 and tex.pov.func_list != "NONE" 2958 ): 2959 func = None 2960 if tex.pov.func_list in {"f_noise3d", "f_ph", "f_r", "f_th"}: 2961 func = 0 2962 if tex.pov.func_list in { 2963 "f_comma", 2964 "f_crossed_trough", 2965 "f_cubic_saddle", 2966 "f_cushion", 2967 "f_devils_curve", 2968 "f_enneper", 2969 "f_glob", 2970 "f_heart", 2971 "f_hex_x", 2972 "f_hex_y", 2973 "f_hunt_surface", 2974 "f_klein_bottle", 2975 "f_kummer_surface_v1", 2976 "f_lemniscate_of_gerono", 2977 "f_mitre", 2978 "f_nodal_cubic", 2979 "f_noise_generator", 2980 "f_odd", 2981 "f_paraboloid", 2982 "f_pillow", 2983 "f_piriform", 2984 "f_quantum", 2985 "f_quartic_paraboloid", 2986 "f_quartic_saddle", 2987 "f_sphere", 2988 "f_steiners_roman", 2989 "f_torus_gumdrop", 2990 "f_umbrella", 2991 }: 2992 func = 1 2993 if tex.pov.func_list in { 2994 "f_bicorn", 2995 "f_bifolia", 2996 "f_boy_surface", 2997 "f_superellipsoid", 2998 "f_torus", 2999 }: 3000 func = 2 3001 if tex.pov.func_list in { 3002 "f_ellipsoid", 3003 "f_folium_surface", 3004 "f_hyperbolic_torus", 3005 "f_kampyle_of_eudoxus", 3006 "f_parabolic_torus", 3007 "f_quartic_cylinder", 3008 "f_torus2", 3009 }: 3010 func = 3 3011 if tex.pov.func_list in { 3012 "f_blob2", 3013 "f_cross_ellipsoids", 3014 "f_flange_cover", 3015 "f_isect_ellipsoids", 3016 "f_kummer_surface_v2", 3017 "f_ovals_of_cassini", 3018 "f_rounded_box", 3019 "f_spikes_2d", 3020 "f_strophoid", 3021 }: 3022 func = 4 3023 if tex.pov.func_list in { 3024 "f_algbr_cyl1", 3025 "f_algbr_cyl2", 3026 "f_algbr_cyl3", 3027 "f_algbr_cyl4", 3028 "f_blob", 3029 "f_mesh1", 3030 "f_poly4", 3031 "f_spikes", 3032 }: 3033 func = 5 3034 if tex.pov.func_list in { 3035 "f_devils_curve_2d", 3036 "f_dupin_cyclid", 3037 "f_folium_surface_2d", 3038 "f_hetero_mf", 3039 "f_kampyle_of_eudoxus_2d", 3040 "f_lemniscate_of_gerono_2d", 3041 "f_polytubes", 3042 "f_ridge", 3043 "f_ridged_mf", 3044 "f_spiral", 3045 "f_witch_of_agnesi", 3046 }: 3047 func = 6 3048 if tex.pov.func_list in { 3049 "f_helix1", 3050 "f_helix2", 3051 "f_piriform_2d", 3052 "f_strophoid_2d", 3053 }: 3054 func = 7 3055 if tex.pov.func_list == "f_helical_torus": 3056 func = 8 3057 column_flow = layout.column_flow(columns=3, align=True) 3058 column_flow.label(text="X") 3059 column_flow.prop(tex.pov, "func_plus_x", text="") 3060 column_flow.prop(tex.pov, "func_x", text="Value") 3061 column_flow = layout.column_flow(columns=3, align=True) 3062 column_flow.label(text="Y") 3063 column_flow.prop(tex.pov, "func_plus_y", text="") 3064 column_flow.prop(tex.pov, "func_y", text="Value") 3065 column_flow = layout.column_flow(columns=3, align=True) 3066 column_flow.label(text="Z") 3067 column_flow.prop(tex.pov, "func_plus_z", text="") 3068 column_flow.prop(tex.pov, "func_z", text="Value") 3069 row = layout.row(align=align) 3070 if func > 0: 3071 row.prop(tex.pov, "func_P0", text="P0") 3072 if func > 1: 3073 row.prop(tex.pov, "func_P1", text="P1") 3074 row = layout.row(align=align) 3075 if func > 2: 3076 row.prop(tex.pov, "func_P2", text="P2") 3077 if func > 3: 3078 row.prop(tex.pov, "func_P3", text="P3") 3079 row = layout.row(align=align) 3080 if func > 4: 3081 row.prop(tex.pov, "func_P4", text="P4") 3082 if func > 5: 3083 row.prop(tex.pov, "func_P5", text="P5") 3084 row = layout.row(align=align) 3085 if func > 6: 3086 row.prop(tex.pov, "func_P6", text="P6") 3087 if func > 7: 3088 row.prop(tex.pov, "func_P7", text="P7") 3089 row = layout.row(align=align) 3090 row.prop(tex.pov, "func_P8", text="P8") 3091 row.prop(tex.pov, "func_P9", text="P9") 3092 ###################################################End Patterns############################ 3093 3094 layout.prop(tex.pov, "warp_types", text="Warp types") # warp 3095 if tex.pov.warp_types == "TOROIDAL": 3096 layout.prop( 3097 tex.pov, "warp_tor_major_radius", text="Major radius" 3098 ) 3099 if tex.pov.warp_types not in {"CUBIC", "NONE"}: 3100 layout.prop( 3101 tex.pov, "warp_orientation", text="Warp orientation" 3102 ) 3103 col = layout.column(align=align) 3104 row = col.row() 3105 row.prop(tex.pov, "warp_dist_exp", text="Distance exponent") 3106 row = col.row() 3107 row.prop(tex.pov, "modifier_frequency", text="Frequency") 3108 row.prop(tex.pov, "modifier_phase", text="Phase") 3109 3110 row = layout.row() 3111 3112 row.label(text="Offset:") 3113 row.label(text="Scale:") 3114 row.label(text="Rotate:") 3115 col = layout.column(align=align) 3116 row = col.row() 3117 row.prop(tex.pov, "tex_mov_x", text="X") 3118 row.prop(tex.pov, "tex_scale_x", text="X") 3119 row.prop(tex.pov, "tex_rot_x", text="X") 3120 row = col.row() 3121 row.prop(tex.pov, "tex_mov_y", text="Y") 3122 row.prop(tex.pov, "tex_scale_y", text="Y") 3123 row.prop(tex.pov, "tex_rot_y", text="Y") 3124 row = col.row() 3125 row.prop(tex.pov, "tex_mov_z", text="Z") 3126 row.prop(tex.pov, "tex_scale_z", text="Z") 3127 row.prop(tex.pov, "tex_rot_z", text="Z") 3128 row = layout.row() 3129 3130 row.label(text="Turbulence:") 3131 col = layout.column(align=align) 3132 row = col.row() 3133 row.prop(tex.pov, "warp_turbulence_x", text="X") 3134 row.prop(tex.pov, "modifier_octaves", text="Octaves") 3135 row = col.row() 3136 row.prop(tex.pov, "warp_turbulence_y", text="Y") 3137 row.prop(tex.pov, "modifier_lambda", text="Lambda") 3138 row = col.row() 3139 row.prop(tex.pov, "warp_turbulence_z", text="Z") 3140 row.prop(tex.pov, "modifier_omega", text="Omega") 3141 3142class TEXTURE_PT_POV_mapping(TextureSlotPanel, Panel): 3143 """Use this class to define POV texture mapping buttons""" 3144 bl_label = "Mapping" 3145 COMPAT_ENGINES = {'POVRAY_RENDER'} 3146 bl_space_type = 'PROPERTIES' 3147 bl_region_type = 'WINDOW' 3148 3149 @classmethod 3150 def poll(cls, context): 3151 idblock = pov_context_tex_datablock(context) 3152 if isinstance(idblock, Brush) and not context.sculpt_object: 3153 return False 3154 3155 if not getattr(context, "texture_slot", None): 3156 return False 3157 3158 engine = context.scene.render.engine 3159 return (engine in cls.COMPAT_ENGINES) 3160 3161 def draw(self, context): 3162 layout = self.layout 3163 3164 idblock = pov_context_tex_datablock(context) 3165 3166 #tex = context.texture_slot 3167 tex = mat.pov_texture_slots[ 3168 mat.active_texture_index 3169 ] 3170 if not isinstance(idblock, Brush): 3171 split = layout.split(percentage=0.3) 3172 col = split.column() 3173 col.label(text="Coordinates:") 3174 col = split.column() 3175 col.prop(tex, "texture_coords", text="") 3176 3177 if tex.texture_coords == 'ORCO': 3178 """ 3179 ob = context.object 3180 if ob and ob.type == 'MESH': 3181 split = layout.split(percentage=0.3) 3182 split.label(text="Mesh:") 3183 split.prop(ob.data, "texco_mesh", text="") 3184 """ 3185 elif tex.texture_coords == 'UV': 3186 split = layout.split(percentage=0.3) 3187 split.label(text="Map:") 3188 ob = context.object 3189 if ob and ob.type == 'MESH': 3190 split.prop_search(tex, "uv_layer", ob.data, "uv_textures", text="") 3191 else: 3192 split.prop(tex, "uv_layer", text="") 3193 3194 elif tex.texture_coords == 'OBJECT': 3195 split = layout.split(percentage=0.3) 3196 split.label(text="Object:") 3197 split.prop(tex, "object", text="") 3198 3199 elif tex.texture_coords == 'ALONG_STROKE': 3200 split = layout.split(percentage=0.3) 3201 split.label(text="Use Tips:") 3202 split.prop(tex, "use_tips", text="") 3203 3204 if isinstance(idblock, Brush): 3205 if context.sculpt_object or context.image_paint_object: 3206 brush_texture_settings(layout, idblock, context.sculpt_object) 3207 else: 3208 if isinstance(idblock, FreestyleLineStyle): 3209 split = layout.split(percentage=0.3) 3210 split.label(text="Projection:") 3211 split.prop(tex, "mapping", text="") 3212 3213 split = layout.split(percentage=0.3) 3214 split.separator() 3215 row = split.row() 3216 row.prop(tex, "mapping_x", text="") 3217 row.prop(tex, "mapping_y", text="") 3218 row.prop(tex, "mapping_z", text="") 3219 3220 elif isinstance(idblock, Material): 3221 split = layout.split(percentage=0.3) 3222 split.label(text="Projection:") 3223 split.prop(tex, "mapping", text="") 3224 3225 split = layout.split() 3226 3227 col = split.column() 3228 if tex.texture_coords in {'ORCO', 'UV'}: 3229 col.prop(tex, "use_from_dupli") 3230 if (idblock.type == 'VOLUME' and tex.texture_coords == 'ORCO'): 3231 col.prop(tex, "use_map_to_bounds") 3232 elif tex.texture_coords == 'OBJECT': 3233 col.prop(tex, "use_from_original") 3234 if (idblock.type == 'VOLUME'): 3235 col.prop(tex, "use_map_to_bounds") 3236 else: 3237 col.label() 3238 3239 col = split.column() 3240 row = col.row() 3241 row.prop(tex, "mapping_x", text="") 3242 row.prop(tex, "mapping_y", text="") 3243 row.prop(tex, "mapping_z", text="") 3244 3245 row = layout.row() 3246 row.column().prop(tex, "offset") 3247 row.column().prop(tex, "scale") 3248 3249class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel): 3250 """Use this class to define pov texture influence buttons.""" 3251 3252 bl_label = "Influence" 3253 COMPAT_ENGINES = {'POVRAY_RENDER'} 3254 bl_space_type = 'PROPERTIES' 3255 bl_region_type = 'WINDOW' 3256 #bl_context = 'texture' 3257 @classmethod 3258 def poll(cls, context): 3259 idblock = pov_context_tex_datablock(context) 3260 if ( 3261 # isinstance(idblock, Brush) and # Brush used for everything since 2.8 3262 context.scene.texture_context == 'OTHER' 3263 ): # XXX replace by isinstance(idblock, bpy.types.Brush) and ... 3264 return False 3265 3266 # Specify below also for pov_world_texture_slots, lights etc. 3267 # to display for various types of slots but only when any 3268 if not getattr(idblock, "pov_texture_slots", None): 3269 return False 3270 3271 engine = context.scene.render.engine 3272 return engine in cls.COMPAT_ENGINES 3273 3274 def draw(self, context): 3275 3276 layout = self.layout 3277 3278 idblock = pov_context_tex_datablock(context) 3279 # tex = context.pov_texture_slot 3280 #mat = bpy.context.active_object.active_material 3281 texslot = idblock.pov_texture_slots[ 3282 idblock.pov.active_texture_index 3283 ] # bpy.data.textures[mat.active_texture_index] 3284 tex = bpy.data.textures[ 3285 idblock.pov_texture_slots[idblock.pov.active_texture_index].texture 3286 ] 3287 3288 def factor_but(layout, toggle, factor, name): 3289 row = layout.row(align=True) 3290 row.prop(texslot, toggle, text="") 3291 sub = row.row(align=True) 3292 sub.active = getattr(texslot, toggle) 3293 sub.prop(texslot, factor, text=name, slider=True) 3294 return sub # XXX, temp. use_map_normal needs to override. 3295 3296 if isinstance(idblock, Material): 3297 split = layout.split() 3298 3299 col = split.column() 3300 if idblock.pov.type in {'SURFACE', 'WIRE'}: 3301 3302 split = layout.split() 3303 3304 col = split.column() 3305 col.label(text="Diffuse:") 3306 factor_but( 3307 col, "use_map_diffuse", "diffuse_factor", "Intensity" 3308 ) 3309 factor_but( 3310 col, 3311 "use_map_color_diffuse", 3312 "diffuse_color_factor", 3313 "Color", 3314 ) 3315 factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") 3316 factor_but( 3317 col, 3318 "use_map_translucency", 3319 "translucency_factor", 3320 "Translucency", 3321 ) 3322 3323 col.label(text="Specular:") 3324 factor_but( 3325 col, "use_map_specular", "specular_factor", "Intensity" 3326 ) 3327 factor_but( 3328 col, "use_map_color_spec", "specular_color_factor", "Color" 3329 ) 3330 factor_but( 3331 col, "use_map_hardness", "hardness_factor", "Hardness" 3332 ) 3333 3334 col = split.column() 3335 col.label(text="Shading:") 3336 factor_but(col, "use_map_ambient", "ambient_factor", "Ambient") 3337 factor_but(col, "use_map_emit", "emit_factor", "Emit") 3338 factor_but(col, "use_map_mirror", "mirror_factor", "Mirror") 3339 factor_but(col, "use_map_raymir", "raymir_factor", "Ray Mirror") 3340 3341 col.label(text="Geometry:") 3342 # XXX replace 'or' when displacement is fixed to not rely on normal influence value. 3343 sub_tmp = factor_but( 3344 col, "use_map_normal", "normal_factor", "Normal" 3345 ) 3346 sub_tmp.active = ( 3347 texslot.use_map_normal or texslot.use_map_displacement 3348 ) 3349 # END XXX 3350 3351 factor_but(col, "use_map_warp", "warp_factor", "Warp") 3352 factor_but( 3353 col, 3354 "use_map_displacement", 3355 "displacement_factor", 3356 "Displace", 3357 ) 3358 3359 # ~ sub = col.column() 3360 # ~ sub.active = texslot.use_map_translucency or texslot.map_emit or texslot.map_alpha or texslot.map_raymir or texslot.map_hardness or texslot.map_ambient or texslot.map_specularity or texslot.map_reflection or texslot.map_mirror 3361 # ~ sub.prop(texslot, "default_value", text="Amount", slider=True) 3362 elif idblock.pov.type == 'HALO': 3363 layout.label(text="Halo:") 3364 3365 split = layout.split() 3366 3367 col = split.column() 3368 factor_but( 3369 col, 3370 "use_map_color_diffuse", 3371 "diffuse_color_factor", 3372 "Color", 3373 ) 3374 factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") 3375 3376 col = split.column() 3377 factor_but(col, "use_map_raymir", "raymir_factor", "Size") 3378 factor_but( 3379 col, "use_map_hardness", "hardness_factor", "Hardness" 3380 ) 3381 factor_but( 3382 col, "use_map_translucency", "translucency_factor", "Add" 3383 ) 3384 elif idblock.pov.type == 'VOLUME': 3385 layout.label(text="Volume:") 3386 3387 split = layout.split() 3388 3389 col = split.column() 3390 factor_but(col, "use_map_density", "density_factor", "Density") 3391 factor_but( 3392 col, "use_map_emission", "emission_factor", "Emission" 3393 ) 3394 factor_but( 3395 col, "use_map_scatter", "scattering_factor", "Scattering" 3396 ) 3397 factor_but( 3398 col, "use_map_reflect", "reflection_factor", "Reflection" 3399 ) 3400 3401 col = split.column() 3402 col.label(text=" ") 3403 factor_but( 3404 col, 3405 "use_map_color_emission", 3406 "emission_color_factor", 3407 "Emission Color", 3408 ) 3409 factor_but( 3410 col, 3411 "use_map_color_transmission", 3412 "transmission_color_factor", 3413 "Transmission Color", 3414 ) 3415 factor_but( 3416 col, 3417 "use_map_color_reflection", 3418 "reflection_color_factor", 3419 "Reflection Color", 3420 ) 3421 3422 layout.label(text="Geometry:") 3423 3424 split = layout.split() 3425 3426 col = split.column() 3427 factor_but(col, "use_map_warp", "warp_factor", "Warp") 3428 3429 col = split.column() 3430 factor_but( 3431 col, 3432 "use_map_displacement", 3433 "displacement_factor", 3434 "Displace", 3435 ) 3436 3437 elif isinstance(idblock, Light): 3438 split = layout.split() 3439 3440 col = split.column() 3441 factor_but(col, "use_map_color", "color_factor", "Color") 3442 3443 col = split.column() 3444 factor_but(col, "use_map_shadow", "shadow_factor", "Shadow") 3445 3446 elif isinstance(idblock, World): 3447 split = layout.split() 3448 3449 col = split.column() 3450 factor_but(col, "use_map_blend", "blend_factor", "Blend") 3451 factor_but(col, "use_map_horizon", "horizon_factor", "Horizon") 3452 3453 col = split.column() 3454 factor_but( 3455 col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up" 3456 ) 3457 factor_but( 3458 col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down" 3459 ) 3460 elif isinstance(idblock, ParticleSettings): 3461 split = layout.split() 3462 3463 col = split.column() 3464 col.label(text="General:") 3465 factor_but(col, "use_map_time", "time_factor", "Time") 3466 factor_but(col, "use_map_life", "life_factor", "Lifetime") 3467 factor_but(col, "use_map_density", "density_factor", "Density") 3468 factor_but(col, "use_map_size", "size_factor", "Size") 3469 3470 col = split.column() 3471 col.label(text="Physics:") 3472 factor_but(col, "use_map_velocity", "velocity_factor", "Velocity") 3473 factor_but(col, "use_map_damp", "damp_factor", "Damp") 3474 factor_but(col, "use_map_gravity", "gravity_factor", "Gravity") 3475 factor_but(col, "use_map_field", "field_factor", "Force Fields") 3476 3477 layout.label(text="Hair:") 3478 3479 split = layout.split() 3480 3481 col = split.column() 3482 factor_but(col, "use_map_length", "length_factor", "Length") 3483 factor_but(col, "use_map_clump", "clump_factor", "Clump") 3484 factor_but(col, "use_map_twist", "twist_factor", "Twist") 3485 3486 col = split.column() 3487 factor_but( 3488 col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude" 3489 ) 3490 factor_but( 3491 col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency" 3492 ) 3493 factor_but(col, "use_map_rough", "rough_factor", "Rough") 3494 3495 elif isinstance(idblock, FreestyleLineStyle): 3496 split = layout.split() 3497 3498 col = split.column() 3499 factor_but( 3500 col, "use_map_color_diffuse", "diffuse_color_factor", "Color" 3501 ) 3502 col = split.column() 3503 factor_but(col, "use_map_alpha", "alpha_factor", "Alpha") 3504 3505 layout.separator() 3506 3507 if not isinstance(idblock, ParticleSettings): 3508 split = layout.split() 3509 3510 col = split.column() 3511 # col.prop(tex, "blend_type", text="Blend") #deprecated since 2.8 3512 # col.prop(tex, "use_rgb_to_intensity") #deprecated since 2.8 3513 # color is used on gray-scale textures even when use_rgb_to_intensity is disabled. 3514 # col.prop(tex, "color", text="") #deprecated since 2.8 3515 3516 col = split.column() 3517 # col.prop(tex, "invert", text="Negative") #deprecated since 2.8 3518 # col.prop(tex, "use_stencil") #deprecated since 2.8 3519 3520 # if isinstance(idblock, (Material, World)): 3521 # col.prop(tex, "default_value", text="DVar", slider=True) 3522 3523 3524class TEXTURE_PT_POV_tex_gamma(TextureButtonsPanel, Panel): 3525 """Use this class to define pov texture gamma buttons.""" 3526 3527 bl_label = "Image Gamma" 3528 COMPAT_ENGINES = {'POVRAY_RENDER'} 3529 3530 def draw_header(self, context): 3531 tex = context.texture 3532 3533 self.layout.prop( 3534 tex.pov, "tex_gamma_enable", text="", icon='SEQ_LUMA_WAVEFORM' 3535 ) 3536 3537 def draw(self, context): 3538 layout = self.layout 3539 3540 tex = context.texture 3541 3542 layout.active = tex.pov.tex_gamma_enable 3543 layout.prop(tex.pov, "tex_gamma_value", text="Gamma Value") 3544 3545 3546# commented out below UI for texture only custom code inside exported material: 3547# class TEXTURE_PT_povray_replacement_text(TextureButtonsPanel, Panel): 3548# bl_label = "Custom POV Code" 3549# COMPAT_ENGINES = {'POVRAY_RENDER'} 3550 3551# def draw(self, context): 3552# layout = self.layout 3553 3554# tex = context.texture 3555 3556# col = layout.column() 3557# col.label(text="Replace properties with:") 3558# col.prop(tex.pov, "replacement_text", text="") 3559 3560 3561class OBJECT_PT_POV_obj_parameters(ObjectButtonsPanel, Panel): 3562 """Use this class to define pov specific object level options buttons.""" 3563 3564 bl_label = "POV" 3565 COMPAT_ENGINES = {'POVRAY_RENDER'} 3566 3567 @classmethod 3568 def poll(cls, context): 3569 3570 engine = context.scene.render.engine 3571 return engine in cls.COMPAT_ENGINES 3572 3573 def draw(self, context): 3574 layout = self.layout 3575 3576 obj = context.object 3577 3578 split = layout.split() 3579 3580 col = split.column(align=True) 3581 3582 col.label(text="Radiosity:") 3583 col.prop(obj.pov, "importance_value", text="Importance") 3584 col.label(text="Photons:") 3585 col.prop(obj.pov, "collect_photons", text="Receive Photon Caustics") 3586 if obj.pov.collect_photons: 3587 col.prop( 3588 obj.pov, "spacing_multiplier", text="Photons Spacing Multiplier" 3589 ) 3590 3591 split = layout.split() 3592 3593 col = split.column() 3594 col.prop(obj.pov, "hollow") 3595 col.prop(obj.pov, "double_illuminate") 3596 3597 if obj.type == 'META' or obj.pov.curveshape == 'lathe': 3598 # if obj.pov.curveshape == 'sor' 3599 col.prop(obj.pov, "sturm") 3600 col.prop(obj.pov, "no_shadow") 3601 col.prop(obj.pov, "no_image") 3602 col.prop(obj.pov, "no_reflection") 3603 col.prop(obj.pov, "no_radiosity") 3604 col.prop(obj.pov, "inverse") 3605 col.prop(obj.pov, "hierarchy") 3606 # col.prop(obj.pov,"boundorclip",text="Bound / Clip") 3607 # if obj.pov.boundorclip != "none": 3608 # col.prop_search(obj.pov,"boundorclipob",context.blend_data,"objects",text="Object") 3609 # text = "Clipped by" 3610 # if obj.pov.boundorclip == "clipped_by": 3611 # text = "Bounded by" 3612 # col.prop(obj.pov,"addboundorclip",text=text) 3613 3614 3615class OBJECT_PT_POV_obj_sphere(PovDataButtonsPanel, Panel): 3616 """Use this class to define pov sphere primitive parameters buttons.""" 3617 3618 bl_label = "POV Sphere" 3619 COMPAT_ENGINES = {'POVRAY_RENDER'} 3620 # bl_options = {'HIDE_HEADER'} 3621 @classmethod 3622 def poll(cls, context): 3623 engine = context.scene.render.engine 3624 obj = context.object 3625 return ( 3626 obj 3627 and obj.pov.object_as == 'SPHERE' 3628 and (engine in cls.COMPAT_ENGINES) 3629 ) 3630 3631 def draw(self, context): 3632 layout = self.layout 3633 3634 obj = context.object 3635 3636 col = layout.column() 3637 3638 if obj.pov.object_as == 'SPHERE': 3639 if obj.pov.unlock_parameters == False: 3640 col.prop( 3641 obj.pov, 3642 "unlock_parameters", 3643 text="Exported parameters below", 3644 icon='LOCKED', 3645 ) 3646 col.label(text="Sphere radius: " + str(obj.pov.sphere_radius)) 3647 3648 else: 3649 col.prop( 3650 obj.pov, 3651 "unlock_parameters", 3652 text="Edit exported parameters", 3653 icon='UNLOCKED', 3654 ) 3655 col.label(text="3D view proxy may get out of synch") 3656 col.active = obj.pov.unlock_parameters 3657 3658 layout.operator( 3659 "pov.sphere_update", text="Update", icon="SHADING_RENDERED" 3660 ) 3661 3662 # col.label(text="Parameters:") 3663 col.prop(obj.pov, "sphere_radius", text="Radius of Sphere") 3664 3665 3666class OBJECT_PT_POV_obj_cylinder(PovDataButtonsPanel, Panel): 3667 """Use this class to define pov cylinder primitive parameters buttons.""" 3668 3669 bl_label = "POV Cylinder" 3670 COMPAT_ENGINES = {'POVRAY_RENDER'} 3671 # bl_options = {'HIDE_HEADER'} 3672 @classmethod 3673 def poll(cls, context): 3674 engine = context.scene.render.engine 3675 obj = context.object 3676 return ( 3677 obj 3678 and obj.pov.object_as == 'CYLINDER' 3679 and (engine in cls.COMPAT_ENGINES) 3680 ) 3681 3682 def draw(self, context): 3683 layout = self.layout 3684 3685 obj = context.object 3686 3687 col = layout.column() 3688 3689 if obj.pov.object_as == 'CYLINDER': 3690 if obj.pov.unlock_parameters == False: 3691 col.prop( 3692 obj.pov, 3693 "unlock_parameters", 3694 text="Exported parameters below", 3695 icon='LOCKED', 3696 ) 3697 col.label( 3698 text="Cylinder radius: " + str(obj.pov.cylinder_radius) 3699 ) 3700 col.label( 3701 text="Cylinder cap location: " 3702 + str(obj.pov.cylinder_location_cap) 3703 ) 3704 3705 else: 3706 col.prop( 3707 obj.pov, 3708 "unlock_parameters", 3709 text="Edit exported parameters", 3710 icon='UNLOCKED', 3711 ) 3712 col.label(text="3D view proxy may get out of synch") 3713 col.active = obj.pov.unlock_parameters 3714 3715 layout.operator( 3716 "pov.cylinder_update", text="Update", icon="MESH_CYLINDER" 3717 ) 3718 3719 # col.label(text="Parameters:") 3720 col.prop(obj.pov, "cylinder_radius") 3721 col.prop(obj.pov, "cylinder_location_cap") 3722 3723 3724class OBJECT_PT_POV_obj_cone(PovDataButtonsPanel, Panel): 3725 """Use this class to define pov cone primitive parameters buttons.""" 3726 3727 bl_label = "POV Cone" 3728 COMPAT_ENGINES = {'POVRAY_RENDER'} 3729 # bl_options = {'HIDE_HEADER'} 3730 @classmethod 3731 def poll(cls, context): 3732 engine = context.scene.render.engine 3733 obj = context.object 3734 return ( 3735 obj 3736 and obj.pov.object_as == 'CONE' 3737 and (engine in cls.COMPAT_ENGINES) 3738 ) 3739 3740 def draw(self, context): 3741 layout = self.layout 3742 3743 obj = context.object 3744 3745 col = layout.column() 3746 3747 if obj.pov.object_as == 'CONE': 3748 if obj.pov.unlock_parameters == False: 3749 col.prop( 3750 obj.pov, 3751 "unlock_parameters", 3752 text="Exported parameters below", 3753 icon='LOCKED', 3754 ) 3755 col.label( 3756 text="Cone base radius: " + str(obj.pov.cone_base_radius) 3757 ) 3758 col.label( 3759 text="Cone cap radius: " + str(obj.pov.cone_cap_radius) 3760 ) 3761 col.label( 3762 text="Cone proxy segments: " + str(obj.pov.cone_segments) 3763 ) 3764 col.label(text="Cone height: " + str(obj.pov.cone_height)) 3765 else: 3766 col.prop( 3767 obj.pov, 3768 "unlock_parameters", 3769 text="Edit exported parameters", 3770 icon='UNLOCKED', 3771 ) 3772 col.label(text="3D view proxy may get out of synch") 3773 col.active = obj.pov.unlock_parameters 3774 3775 layout.operator( 3776 "pov.cone_update", text="Update", icon="MESH_CONE" 3777 ) 3778 3779 # col.label(text="Parameters:") 3780 col.prop( 3781 obj.pov, "cone_base_radius", text="Radius of Cone Base" 3782 ) 3783 col.prop(obj.pov, "cone_cap_radius", text="Radius of Cone Cap") 3784 col.prop( 3785 obj.pov, "cone_segments", text="Segmentation of Cone proxy" 3786 ) 3787 col.prop(obj.pov, "cone_height", text="Height of the cone") 3788 3789 3790class OBJECT_PT_POV_obj_superellipsoid(PovDataButtonsPanel, Panel): 3791 """Use this class to define pov superellipsoid primitive parameters buttons.""" 3792 3793 bl_label = "POV Superquadric ellipsoid" 3794 COMPAT_ENGINES = {'POVRAY_RENDER'} 3795 # bl_options = {'HIDE_HEADER'} 3796 @classmethod 3797 def poll(cls, context): 3798 engine = context.scene.render.engine 3799 obj = context.object 3800 return ( 3801 obj 3802 and obj.pov.object_as == 'SUPERELLIPSOID' 3803 and (engine in cls.COMPAT_ENGINES) 3804 ) 3805 3806 def draw(self, context): 3807 layout = self.layout 3808 3809 obj = context.object 3810 3811 col = layout.column() 3812 3813 if obj.pov.object_as == 'SUPERELLIPSOID': 3814 if obj.pov.unlock_parameters == False: 3815 col.prop( 3816 obj.pov, 3817 "unlock_parameters", 3818 text="Exported parameters below", 3819 icon='LOCKED', 3820 ) 3821 col.label(text="Radial segmentation: " + str(obj.pov.se_u)) 3822 col.label(text="Lateral segmentation: " + str(obj.pov.se_v)) 3823 col.label(text="Ring shape: " + str(obj.pov.se_n1)) 3824 col.label(text="Cross-section shape: " + str(obj.pov.se_n2)) 3825 col.label(text="Fill up and down: " + str(obj.pov.se_edit)) 3826 else: 3827 col.prop( 3828 obj.pov, 3829 "unlock_parameters", 3830 text="Edit exported parameters", 3831 icon='UNLOCKED', 3832 ) 3833 col.label(text="3D view proxy may get out of synch") 3834 col.active = obj.pov.unlock_parameters 3835 3836 layout.operator( 3837 "pov.superellipsoid_update", 3838 text="Update", 3839 icon="MOD_SUBSURF", 3840 ) 3841 3842 # col.label(text="Parameters:") 3843 col.prop(obj.pov, "se_u") 3844 col.prop(obj.pov, "se_v") 3845 col.prop(obj.pov, "se_n1") 3846 col.prop(obj.pov, "se_n2") 3847 col.prop(obj.pov, "se_edit") 3848 3849 3850class OBJECT_PT_POV_obj_torus(PovDataButtonsPanel, Panel): 3851 """Use this class to define pov torus primitive parameters buttons.""" 3852 3853 bl_label = "POV Torus" 3854 COMPAT_ENGINES = {'POVRAY_RENDER'} 3855 # bl_options = {'HIDE_HEADER'} 3856 @classmethod 3857 def poll(cls, context): 3858 engine = context.scene.render.engine 3859 obj = context.object 3860 return ( 3861 obj 3862 and obj.pov.object_as == 'TORUS' 3863 and (engine in cls.COMPAT_ENGINES) 3864 ) 3865 3866 def draw(self, context): 3867 layout = self.layout 3868 3869 obj = context.object 3870 3871 col = layout.column() 3872 3873 if obj.pov.object_as == 'TORUS': 3874 if obj.pov.unlock_parameters == False: 3875 col.prop( 3876 obj.pov, 3877 "unlock_parameters", 3878 text="Exported parameters below", 3879 icon='LOCKED', 3880 ) 3881 col.label( 3882 text="Torus major radius: " 3883 + str(obj.pov.torus_major_radius) 3884 ) 3885 col.label( 3886 text="Torus minor radius: " 3887 + str(obj.pov.torus_minor_radius) 3888 ) 3889 col.label( 3890 text="Torus major segments: " 3891 + str(obj.pov.torus_major_segments) 3892 ) 3893 col.label( 3894 text="Torus minor segments: " 3895 + str(obj.pov.torus_minor_segments) 3896 ) 3897 else: 3898 col.prop( 3899 obj.pov, 3900 "unlock_parameters", 3901 text="Edit exported parameters", 3902 icon='UNLOCKED', 3903 ) 3904 col.label(text="3D view proxy may get out of synch") 3905 col.active = obj.pov.unlock_parameters 3906 3907 layout.operator( 3908 "pov.torus_update", text="Update", icon="MESH_TORUS" 3909 ) 3910 3911 # col.label(text="Parameters:") 3912 col.prop(obj.pov, "torus_major_radius") 3913 col.prop(obj.pov, "torus_minor_radius") 3914 col.prop(obj.pov, "torus_major_segments") 3915 col.prop(obj.pov, "torus_minor_segments") 3916 3917 3918class OBJECT_PT_POV_obj_supertorus(PovDataButtonsPanel, Panel): 3919 """Use this class to define pov supertorus primitive parameters buttons.""" 3920 3921 bl_label = "POV SuperTorus" 3922 COMPAT_ENGINES = {'POVRAY_RENDER'} 3923 # bl_options = {'HIDE_HEADER'} 3924 @classmethod 3925 def poll(cls, context): 3926 engine = context.scene.render.engine 3927 obj = context.object 3928 return ( 3929 obj 3930 and obj.pov.object_as == 'SUPERTORUS' 3931 and (engine in cls.COMPAT_ENGINES) 3932 ) 3933 3934 def draw(self, context): 3935 layout = self.layout 3936 3937 obj = context.object 3938 3939 col = layout.column() 3940 3941 if obj.pov.object_as == 'SUPERTORUS': 3942 if obj.pov.unlock_parameters == False: 3943 col.prop( 3944 obj.pov, 3945 "unlock_parameters", 3946 text="Exported parameters below", 3947 icon='LOCKED', 3948 ) 3949 col.label( 3950 text="SuperTorus major radius: " 3951 + str(obj.pov.st_major_radius) 3952 ) 3953 col.label( 3954 text="SuperTorus minor radius: " 3955 + str(obj.pov.st_minor_radius) 3956 ) 3957 col.label( 3958 text="SuperTorus major segments: " + str(obj.pov.st_u) 3959 ) 3960 col.label( 3961 text="SuperTorus minor segments: " + str(obj.pov.st_v) 3962 ) 3963 3964 col.label( 3965 text="SuperTorus Ring Manipulator: " + str(obj.pov.st_ring) 3966 ) 3967 col.label( 3968 text="SuperTorus Cross Manipulator: " 3969 + str(obj.pov.st_cross) 3970 ) 3971 col.label( 3972 text="SuperTorus Internal And External radii: " 3973 + str(obj.pov.st_ie) 3974 ) 3975 3976 col.label( 3977 text="SuperTorus accuracy: " + str(ob.pov.st_accuracy) 3978 ) 3979 col.label( 3980 text="SuperTorus max gradient: " 3981 + str(ob.pov.st_max_gradient) 3982 ) 3983 3984 else: 3985 col.prop( 3986 obj.pov, 3987 "unlock_parameters", 3988 text="Edit exported parameters", 3989 icon='UNLOCKED', 3990 ) 3991 col.label(text="3D view proxy may get out of synch") 3992 col.active = obj.pov.unlock_parameters 3993 3994 layout.operator( 3995 "pov.supertorus_update", text="Update", icon="MESH_TORUS" 3996 ) 3997 3998 # col.label(text="Parameters:") 3999 col.prop(obj.pov, "st_major_radius") 4000 col.prop(obj.pov, "st_minor_radius") 4001 col.prop(obj.pov, "st_u") 4002 col.prop(obj.pov, "st_v") 4003 col.prop(obj.pov, "st_ring") 4004 col.prop(obj.pov, "st_cross") 4005 col.prop(obj.pov, "st_ie") 4006 # col.prop(obj.pov, "st_edit") #? 4007 col.prop(obj.pov, "st_accuracy") 4008 col.prop(obj.pov, "st_max_gradient") 4009 4010 4011class OBJECT_PT_POV_obj_parametric(PovDataButtonsPanel, Panel): 4012 """Use this class to define pov parametric surface primitive parameters buttons.""" 4013 4014 bl_label = "POV Parametric surface" 4015 COMPAT_ENGINES = {'POVRAY_RENDER'} 4016 # bl_options = {'HIDE_HEADER'} 4017 @classmethod 4018 def poll(cls, context): 4019 engine = context.scene.render.engine 4020 obj = context.object 4021 return ( 4022 obj 4023 and obj.pov.object_as == 'PARAMETRIC' 4024 and (engine in cls.COMPAT_ENGINES) 4025 ) 4026 4027 def draw(self, context): 4028 layout = self.layout 4029 4030 obj = context.object 4031 4032 col = layout.column() 4033 4034 if obj.pov.object_as == 'PARAMETRIC': 4035 if obj.pov.unlock_parameters == False: 4036 col.prop( 4037 obj.pov, 4038 "unlock_parameters", 4039 text="Exported parameters below", 4040 icon='LOCKED', 4041 ) 4042 col.label(text="Minimum U: " + str(obj.pov.u_min)) 4043 col.label(text="Minimum V: " + str(obj.pov.v_min)) 4044 col.label(text="Maximum U: " + str(obj.pov.u_max)) 4045 col.label(text="Minimum V: " + str(obj.pov.v_min)) 4046 col.label(text="X Function: " + str(obj.pov.x_eq)) 4047 col.label(text="Y Function: " + str(obj.pov.y_eq)) 4048 col.label(text="Z Function: " + str(obj.pov.x_eq)) 4049 4050 else: 4051 col.prop( 4052 obj.pov, 4053 "unlock_parameters", 4054 text="Edit exported parameters", 4055 icon='UNLOCKED', 4056 ) 4057 col.label(text="3D view proxy may get out of synch") 4058 col.active = obj.pov.unlock_parameters 4059 4060 layout.operator( 4061 "pov.parametric_update", text="Update", icon="SCRIPTPLUGINS" 4062 ) 4063 4064 col.prop(obj.pov, "u_min", text="Minimum U") 4065 col.prop(obj.pov, "v_min", text="Minimum V") 4066 col.prop(obj.pov, "u_max", text="Maximum U") 4067 col.prop(obj.pov, "v_max", text="Minimum V") 4068 col.prop(obj.pov, "x_eq", text="X Function") 4069 col.prop(obj.pov, "y_eq", text="Y Function") 4070 col.prop(obj.pov, "z_eq", text="Z Function") 4071 4072 4073class OBJECT_PT_povray_replacement_text(ObjectButtonsPanel, Panel): 4074 """Use this class to define pov object replacement field.""" 4075 4076 bl_label = "Custom POV Code" 4077 COMPAT_ENGINES = {'POVRAY_RENDER'} 4078 4079 def draw(self, context): 4080 layout = self.layout 4081 4082 obj = context.object 4083 4084 col = layout.column() 4085 col.label(text="Replace properties with:") 4086 col.prop(obj.pov, "replacement_text", text="") 4087 4088 4089############################################################################### 4090# Add Povray Objects 4091############################################################################### 4092 4093 4094class VIEW_MT_POV_primitives_add(Menu): 4095 """Define the primitives menu with presets""" 4096 4097 bl_idname = "VIEW_MT_POV_primitives_add" 4098 bl_label = "Povray" 4099 COMPAT_ENGINES = {'POVRAY_RENDER'} 4100 4101 @classmethod 4102 def poll(cls, context): 4103 engine = context.scene.render.engine 4104 return engine == 'POVRAY_RENDER' 4105 4106 def draw(self, context): 4107 layout = self.layout 4108 layout.operator_context = 'INVOKE_REGION_WIN' 4109 layout.menu( 4110 VIEW_MT_POV_Basic_Shapes.bl_idname, text="Primitives", icon="GROUP" 4111 ) 4112 layout.menu(VIEW_MT_POV_import.bl_idname, text="Import", icon="IMPORT") 4113 4114 4115class VIEW_MT_POV_Basic_Shapes(Menu): 4116 """Use this class to sort simple primitives menu entries.""" 4117 4118 bl_idname = "POVRAY_MT_basic_shape_tools" 4119 bl_label = "Basic_shapes" 4120 4121 def draw(self, context): 4122 layout = self.layout 4123 layout.operator_context = 'INVOKE_REGION_WIN' 4124 layout.operator( 4125 "pov.addplane", text="Infinite Plane", icon='MESH_PLANE' 4126 ) 4127 layout.operator("pov.addbox", text="Box", icon='MESH_CUBE') 4128 layout.operator("pov.addsphere", text="Sphere", icon='SHADING_RENDERED') 4129 layout.operator( 4130 "pov.addcylinder", text="Cylinder", icon="MESH_CYLINDER" 4131 ) 4132 layout.operator("pov.cone_add", text="Cone", icon="MESH_CONE") 4133 layout.operator("pov.addtorus", text="Torus", icon='MESH_TORUS') 4134 layout.separator() 4135 layout.operator("pov.addrainbow", text="Rainbow", icon="COLOR") 4136 layout.operator("pov.addlathe", text="Lathe", icon='MOD_SCREW') 4137 layout.operator("pov.addprism", text="Prism", icon='MOD_SOLIDIFY') 4138 layout.operator( 4139 "pov.addsuperellipsoid", 4140 text="Superquadric Ellipsoid", 4141 icon='MOD_SUBSURF', 4142 ) 4143 layout.operator( 4144 "pov.addheightfield", text="Height Field", icon="RNDCURVE" 4145 ) 4146 layout.operator( 4147 "pov.addspheresweep", text="Sphere Sweep", icon='FORCE_CURVE' 4148 ) 4149 layout.separator() 4150 layout.operator( 4151 "pov.addblobsphere", text="Blob Sphere", icon='META_DATA' 4152 ) 4153 layout.separator() 4154 layout.label(text="Isosurfaces") 4155 layout.operator( 4156 "pov.addisosurfacebox", text="Isosurface Box", icon="META_CUBE" 4157 ) 4158 layout.operator( 4159 "pov.addisosurfacesphere", 4160 text="Isosurface Sphere", 4161 icon="META_BALL", 4162 ) 4163 layout.operator( 4164 "pov.addsupertorus", text="Supertorus", icon="SURFACE_NTORUS" 4165 ) 4166 layout.separator() 4167 layout.label(text="Macro based") 4168 layout.operator( 4169 "pov.addpolygontocircle", 4170 text="Polygon To Circle Blending", 4171 icon="MOD_CAST", 4172 ) 4173 layout.operator("pov.addloft", text="Loft", icon="SURFACE_NSURFACE") 4174 layout.separator() 4175 # Warning if the Add Advanced Objects addon containing 4176 # Add mesh extra objects is not enabled 4177 if not check_add_mesh_extra_objects(): 4178 # col = box.column() 4179 layout.label( 4180 text="Please enable Add Mesh: Extra Objects addon", icon="INFO" 4181 ) 4182 # layout.separator() 4183 layout.operator( 4184 "preferences.addon_show", 4185 text="Go to Add Mesh: Extra Objects addon", 4186 icon="PREFERENCES", 4187 ).module = "add_mesh_extra_objects" 4188 4189 # layout.separator() 4190 return 4191 else: 4192 layout.operator( 4193 "pov.addparametric", text="Parametric", icon='SCRIPTPLUGINS' 4194 ) 4195 4196 4197class VIEW_MT_POV_import(Menu): 4198 """Use this class for the import menu.""" 4199 4200 bl_idname = "POVRAY_MT_import_tools" 4201 bl_label = "Import" 4202 4203 def draw(self, context): 4204 layout = self.layout 4205 layout.operator_context = 'INVOKE_REGION_WIN' 4206 layout.operator("import_scene.pov", icon="FORCE_LENNARDJONES") 4207 4208 4209def menu_func_add(self, context): 4210 engine = context.scene.render.engine 4211 if engine == 'POVRAY_RENDER': 4212 self.layout.menu("VIEW_MT_POV_primitives_add", icon="PLUGIN") 4213 4214 4215def menu_func_import(self, context): 4216 engine = context.scene.render.engine 4217 if engine == 'POVRAY_RENDER': 4218 self.layout.operator("import_scene.pov", icon="FORCE_LENNARDJONES") 4219 4220 4221##############Nodes 4222 4223# def find_node_input(node, name): 4224# for input in node.inputs: 4225# if input.name == name: 4226# return input 4227 4228# def panel_node_draw(layout, id_data, output_type, input_name): 4229# if not id_data.use_nodes: 4230# #layout.operator("pov.material_use_nodes", icon='SOUND')#'NODETREE') 4231# #layout.operator("pov.use_shading_nodes", icon='NODETREE') 4232# layout.operator("WM_OT_context_toggle", icon='NODETREE').data_path = \ 4233# "material.pov.material_use_nodes" 4234# return False 4235 4236# ntree = id_data.node_tree 4237 4238# node = find_node(id_data, output_type) 4239# if not node: 4240# layout.label(text="No output node") 4241# else: 4242# input = find_node_input(node, input_name) 4243# layout.template_node_view(ntree, node, input) 4244 4245# return True 4246 4247 4248class NODE_MT_POV_map_create(Menu): 4249 """Create maps""" 4250 4251 bl_idname = "POVRAY_MT_node_map_create" 4252 bl_label = "Create map" 4253 4254 def draw(self, context): 4255 layout = self.layout 4256 layout.operator("node.map_create") 4257 4258 4259def menu_func_nodes(self, context): 4260 ob = context.object 4261 if hasattr(ob, 'active_material'): 4262 mat = context.object.active_material 4263 if mat and context.space_data.tree_type == 'ObjectNodeTree': 4264 self.layout.prop(mat.pov, "material_use_nodes") 4265 self.layout.menu(NODE_MT_POV_map_create.bl_idname) 4266 self.layout.operator("wm.updatepreviewkey") 4267 if ( 4268 hasattr(mat, 'active_texture') 4269 and context.scene.render.engine == 'POVRAY_RENDER' 4270 ): 4271 tex = mat.active_texture 4272 if tex and context.space_data.tree_type == 'TextureNodeTree': 4273 self.layout.prop(tex.pov, "texture_use_nodes") 4274 4275 4276############################################################################### 4277# Camera Povray Settings 4278############################################################################### 4279class CAMERA_PT_POV_cam_dof(CameraDataButtonsPanel, Panel): 4280 """Use this class for camera depth of field focal blur buttons.""" 4281 4282 bl_label = "POV Aperture" 4283 COMPAT_ENGINES = {'POVRAY_RENDER'} 4284 bl_parent_id = "DATA_PT_camera_dof_aperture" 4285 bl_options = {'HIDE_HEADER'} 4286 # def draw_header(self, context): 4287 # cam = context.camera 4288 4289 # self.layout.prop(cam.pov, "dof_enable", text="") 4290 4291 def draw(self, context): 4292 layout = self.layout 4293 4294 cam = context.camera 4295 4296 layout.active = cam.dof.use_dof 4297 layout.use_property_split = True # Active single-column layout 4298 4299 flow = layout.grid_flow( 4300 row_major=True, 4301 columns=0, 4302 even_columns=True, 4303 even_rows=False, 4304 align=False, 4305 ) 4306 4307 col = flow.column() 4308 col.label(text="F-Stop value will export as") 4309 col.label( 4310 text="POV aperture : " 4311 + "%.3f" % (1 / cam.dof.aperture_fstop * 1000) 4312 ) 4313 4314 col = flow.column() 4315 col.prop(cam.pov, "dof_samples_min") 4316 col.prop(cam.pov, "dof_samples_max") 4317 col.prop(cam.pov, "dof_variance") 4318 col.prop(cam.pov, "dof_confidence") 4319 4320 4321class CAMERA_PT_POV_cam_nor(CameraDataButtonsPanel, Panel): 4322 """Use this class for camera normal perturbation buttons.""" 4323 4324 bl_label = "POV Perturbation" 4325 COMPAT_ENGINES = {'POVRAY_RENDER'} 4326 4327 def draw_header(self, context): 4328 cam = context.camera 4329 4330 self.layout.prop(cam.pov, "normal_enable", text="") 4331 4332 def draw(self, context): 4333 layout = self.layout 4334 4335 cam = context.camera 4336 4337 layout.active = cam.pov.normal_enable 4338 4339 layout.prop(cam.pov, "normal_patterns") 4340 layout.prop(cam.pov, "cam_normal") 4341 layout.prop(cam.pov, "turbulence") 4342 layout.prop(cam.pov, "scale") 4343 4344 4345class CAMERA_PT_POV_replacement_text(CameraDataButtonsPanel, Panel): 4346 """Use this class for camera text replacement field.""" 4347 4348 bl_label = "Custom POV Code" 4349 COMPAT_ENGINES = {'POVRAY_RENDER'} 4350 4351 def draw(self, context): 4352 layout = self.layout 4353 4354 cam = context.camera 4355 4356 col = layout.column() 4357 col.label(text="Replace properties with:") 4358 col.prop(cam.pov, "replacement_text", text="") 4359 4360 4361############################################################################### 4362# Text Povray Settings 4363############################################################################### 4364 4365 4366class TEXT_OT_POV_insert(Operator): 4367 """Use this class to create blender text editor operator to insert pov snippets like other pov IDEs.""" 4368 4369 bl_idname = "text.povray_insert" 4370 bl_label = "Insert" 4371 4372 filepath: bpy.props.StringProperty(name="Filepath", subtype='FILE_PATH') 4373 4374 @classmethod 4375 def poll(cls, context): 4376 # context.area.type == 'TEXT_EDITOR' 4377 return bpy.ops.text.insert.poll() 4378 4379 def execute(self, context): 4380 if self.filepath and isfile(self.filepath): 4381 file = open(self.filepath, "r") 4382 bpy.ops.text.insert(text=file.read()) 4383 4384 # places the cursor at the end without scrolling -.- 4385 # context.space_data.text.write(file.read()) 4386 file.close() 4387 return {'FINISHED'} 4388 4389 4390def validinsert(ext): 4391 return ext in {".txt", ".inc", ".pov"} 4392 4393 4394class TEXT_MT_POV_insert(Menu): 4395 """Use this class to create a menu launcher in text editor for the TEXT_OT_POV_insert operator .""" 4396 4397 bl_label = "Insert" 4398 bl_idname = "TEXT_MT_POV_insert" 4399 4400 def draw(self, context): 4401 pov_documents = locate_docpath() 4402 prop = self.layout.operator( 4403 "wm.path_open", text="Open folder", icon='FILE_FOLDER' 4404 ) 4405 prop.filepath = pov_documents 4406 self.layout.separator() 4407 4408 list = [] 4409 for root, dirs, files in os.walk(pov_documents): 4410 list.append(root) 4411 print(list) 4412 self.path_menu( 4413 list, 4414 "text.povray_insert", 4415 # {"internal": True}, 4416 filter_ext=validinsert, 4417 ) 4418 4419 4420class TEXT_PT_POV_custom_code(TextButtonsPanel, Panel): 4421 """Use this class to create a panel in text editor for the user to decide if he renders text only or adds to 3d scene.""" 4422 4423 bl_label = "POV" 4424 COMPAT_ENGINES = {'POVRAY_RENDER'} 4425 4426 def draw(self, context): 4427 layout = self.layout 4428 4429 text = context.space_data.text 4430 4431 pov_documents = locate_docpath() 4432 if not pov_documents: 4433 layout.label(text="Please configure ", icon="INFO") 4434 layout.label(text="default pov include path ") 4435 layout.label(text="in addon preferences") 4436 # layout.separator() 4437 layout.operator( 4438 "preferences.addon_show", 4439 text="Go to Render: Persistence of Vision addon", 4440 icon="PREFERENCES", 4441 ).module = "render_povray" 4442 4443 # layout.separator() 4444 else: 4445 # print(pov_documents) 4446 layout.menu(TEXT_MT_POV_insert.bl_idname) 4447 4448 if text: 4449 box = layout.box() 4450 box.label(text='Source to render:', icon='RENDER_STILL') 4451 row = box.row() 4452 row.prop(text.pov, "custom_code", expand=True) 4453 if text.pov.custom_code in {'3dview'}: 4454 box.operator("render.render", icon='OUTLINER_DATA_ARMATURE') 4455 if text.pov.custom_code in {'text'}: 4456 rtext = bpy.context.space_data.text 4457 box.operator("text.run", icon='ARMATURE_DATA') 4458 # layout.prop(text.pov, "custom_code") 4459 elif text.pov.custom_code in {'both'}: 4460 box.operator("render.render", icon='POSE_HLT') 4461 layout.label(text="Please specify declared", icon="INFO") 4462 layout.label(text="items in properties ") 4463 # layout.label(text="") 4464 layout.label(text="replacement fields") 4465 4466 4467############################################### 4468# Text editor templates from header menu 4469 4470 4471class TEXT_MT_POV_templates(Menu): 4472 """Use this class to create a menu for the same pov templates scenes as other pov IDEs.""" 4473 4474 bl_label = "POV" 4475 4476 # We list templates on file evaluation, we can assume they are static data, 4477 # and better avoid running this on every draw call. 4478 import os 4479 4480 template_paths = [os.path.join(os.path.dirname(__file__), "templates_pov")] 4481 4482 def draw(self, context): 4483 self.path_menu( 4484 self.template_paths, "text.open", props_default={"internal": True} 4485 ) 4486 4487 4488def menu_func_templates(self, context): 4489 # Do not depend on POV being active renderer here... 4490 self.layout.menu("TEXT_MT_POV_templates") 4491 4492############################################################################### 4493# Freestyle 4494############################################################################### 4495#import addon_utils 4496#addon_utils.paths()[0] 4497#addon_utils.modules() 4498#mod.bl_info['name'] == 'Freestyle SVG Exporter': 4499bpy.utils.script_paths("addons") 4500#render_freestyle_svg = os.path.join(bpy.utils.script_paths("addons"), "render_freestyle_svg.py") 4501 4502render_freestyle_svg = bpy.context.preferences.addons.get('render_freestyle_svg') 4503 #mpath=addon_utils.paths()[0].render_freestyle_svg 4504 #import mpath 4505 #from mpath import render_freestyle_svg #= addon_utils.modules(['Freestyle SVG Exporter']) 4506 #from scripts\\addons import render_freestyle_svg 4507if check_render_freestyle_svg(): 4508 ''' 4509 snippetsWIP 4510 import myscript 4511 import importlib 4512 4513 importlib.reload(myscript) 4514 myscript.main() 4515 ''' 4516 for member in dir(render_freestyle_svg): 4517 subclass = getattr(render_freestyle_svg, member) 4518 try: 4519 subclass.COMPAT_ENGINES.add('POVRAY_RENDER') 4520 if subclass.bl_idname == "RENDER_PT_SVGExporterPanel": 4521 subclass.bl_parent_id = "RENDER_PT_POV_filter" 4522 subclass.bl_options = {'HIDE_HEADER'} 4523 #subclass.bl_order = 11 4524 print(subclass.bl_info) 4525 except: 4526 pass 4527 4528 #del render_freestyle_svg.RENDER_PT_SVGExporterPanel.bl_parent_id 4529 4530 4531class RENDER_PT_POV_filter(RenderButtonsPanel, Panel): 4532 """Use this class to invoke stuff like Freestyle UI.""" 4533 4534 bl_label = "Freestyle" 4535 bl_options = {'DEFAULT_CLOSED'} 4536 COMPAT_ENGINES = {'POVRAY_RENDER'} 4537 4538 @classmethod 4539 def poll(cls, context): 4540 with_freestyle = bpy.app.build_options.freestyle 4541 engine = context.scene.render.engine 4542 return(with_freestyle and engine == 'POVRAY_RENDER') 4543 def draw_header(self, context): 4544 4545 #scene = context.scene 4546 rd = context.scene.render 4547 layout = self.layout 4548 4549 if rd.use_freestyle: 4550 layout.prop( 4551 rd, "use_freestyle", text="", icon='LINE_DATA' 4552 ) 4553 4554 else: 4555 layout.prop( 4556 rd, "use_freestyle", text="", icon='OUTLINER_OB_IMAGE' 4557 ) 4558 4559 def draw(self, context): 4560 rd = context.scene.render 4561 layout = self.layout 4562 layout.active = rd.use_freestyle 4563 layout.use_property_split = True 4564 layout.use_property_decorate = False # No animation. 4565 flow = layout.grid_flow( 4566 row_major=True, 4567 columns=0, 4568 even_columns=True, 4569 even_rows=False, 4570 align=True, 4571 ) 4572 4573 flow.prop(rd, "line_thickness_mode", expand=True) 4574 4575 if rd.line_thickness_mode == 'ABSOLUTE': 4576 flow.prop(rd, "line_thickness") 4577 4578 # Warning if the Freestyle SVG Exporter addon is not enabled 4579 if not check_render_freestyle_svg(): 4580 # col = box.column() 4581 layout.label( 4582 text="Please enable Freestyle SVG Exporter addon", icon="INFO" 4583 ) 4584 # layout.separator() 4585 layout.operator( 4586 "preferences.addon_show", 4587 text="Go to Render: Freestyle SVG Exporter addon", 4588 icon="PREFERENCES", 4589 ).module = "render_freestyle_svg" 4590 4591classes = ( 4592 WORLD_PT_POV_world, 4593 WORLD_MT_POV_presets, 4594 WORLD_OT_POV_add_preset, 4595 WORLD_TEXTURE_SLOTS_UL_POV_layerlist, 4596 #WORLD_TEXTURE_SLOTS_UL_List, 4597 WORLD_PT_POV_mist, 4598 # RenderButtonsPanel, 4599 # ModifierButtonsPanel, 4600 # MaterialButtonsPanel, 4601 # TextureButtonsPanel, 4602 # ObjectButtonsPanel, 4603 # CameraDataButtonsPanel, 4604 # WorldButtonsPanel, 4605 # TextButtonsPanel, 4606 # PovDataButtonsPanel, 4607 DATA_PT_POV_normals, 4608 DATA_PT_POV_texture_space, 4609 DATA_PT_POV_vertex_groups, 4610 DATA_PT_POV_shape_keys, 4611 DATA_PT_POV_uv_texture, 4612 DATA_PT_POV_vertex_colors, 4613 DATA_PT_POV_customdata, 4614 # PovLampButtonsPanel, 4615 LIGHT_PT_POV_preview, 4616 LIGHT_PT_POV_light, 4617 LIGHT_MT_POV_presets, 4618 LIGHT_OT_POV_add_preset, 4619 OBJECT_PT_POV_rainbow, 4620 RENDER_PT_POV_export_settings, 4621 RENDER_PT_POV_render_settings, 4622 RENDER_PT_POV_photons, 4623 RENDER_PT_POV_antialias, 4624 RENDER_PT_POV_radiosity, 4625 RENDER_PT_POV_filter, 4626 POV_RADIOSITY_MT_presets, 4627 RENDER_OT_POV_radiosity_add_preset, 4628 RENDER_PT_POV_media, 4629 MODIFIERS_PT_POV_modifiers, 4630 MATERIAL_PT_POV_sss, 4631 MATERIAL_MT_POV_sss_presets, 4632 MATERIAL_OT_POV_sss_add_preset, 4633 MATERIAL_PT_strand, 4634 MATERIAL_PT_POV_activate_node, 4635 MATERIAL_PT_POV_active_node, 4636 MATERIAL_PT_POV_specular, 4637 MATERIAL_PT_POV_mirror, 4638 MATERIAL_PT_POV_transp, 4639 MATERIAL_PT_POV_reflection, 4640 # MATERIAL_PT_POV_interior, 4641 MATERIAL_PT_POV_fade_color, 4642 MATERIAL_PT_POV_caustics, 4643 MATERIAL_PT_POV_replacement_text, 4644 TEXTURE_MT_POV_specials, 4645 TEXTURE_PT_POV_context_texture, 4646 TEXTURE_PT_POV_type, 4647 TEXTURE_PT_POV_preview, 4648 TEXTURE_PT_POV_parameters, 4649 TEXTURE_PT_POV_tex_gamma, 4650 OBJECT_PT_POV_obj_parameters, 4651 OBJECT_PT_POV_obj_sphere, 4652 OBJECT_PT_POV_obj_cylinder, 4653 OBJECT_PT_POV_obj_cone, 4654 OBJECT_PT_POV_obj_superellipsoid, 4655 OBJECT_PT_POV_obj_torus, 4656 OBJECT_PT_POV_obj_supertorus, 4657 OBJECT_PT_POV_obj_parametric, 4658 OBJECT_PT_povray_replacement_text, 4659 VIEW_MT_POV_primitives_add, 4660 VIEW_MT_POV_Basic_Shapes, 4661 VIEW_MT_POV_import, 4662 NODE_MT_POV_map_create, 4663 CAMERA_PT_POV_cam_dof, 4664 CAMERA_PT_POV_cam_nor, 4665 CAMERA_PT_POV_replacement_text, 4666 TEXT_OT_POV_insert, 4667 TEXT_MT_POV_insert, 4668 TEXT_PT_POV_custom_code, 4669 TEXT_MT_POV_templates, 4670 #TEXTURE_PT_POV_povray_texture_slots, 4671 #TEXTURE_UL_POV_texture_slots, 4672 MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist, 4673 TEXTURE_OT_POV_texture_slot_add, 4674 TEXTURE_OT_POV_texture_slot_remove, 4675 TEXTURE_PT_POV_influence, 4676 TEXTURE_PT_POV_mapping, 4677) 4678 4679 4680def register(): 4681 # from bpy.utils import register_class 4682 4683 for cls in classes: 4684 register_class(cls) 4685 4686 bpy.types.VIEW3D_MT_add.prepend(menu_func_add) 4687 bpy.types.TOPBAR_MT_file_import.append(menu_func_import) 4688 bpy.types.TEXT_MT_templates.append(menu_func_templates) 4689 bpy.types.RENDER_PT_POV_radiosity.prepend(rad_panel_func) 4690 bpy.types.LIGHT_PT_POV_light.prepend(light_panel_func) 4691 # bpy.types.WORLD_PT_POV_world.prepend(world_panel_func) 4692 # was used for parametric objects but made the other addon unreachable on 4693 # unregister for other tools to use created a user action call instead 4694 # addon_utils.enable("add_mesh_extra_objects", default_set=False, persistent=True) 4695 # bpy.types.TEXTURE_PT_context_texture.prepend(TEXTURE_PT_POV_type) 4696 4697 if not povCentricWorkspace in bpy.app.handlers.load_post: 4698 # print("Adding POV wentric workspace on load handlers list") 4699 bpy.app.handlers.load_post.append(povCentricWorkspace) 4700 4701def unregister(): 4702 if povCentricWorkspace in bpy.app.handlers.load_post: 4703 # print("Removing POV wentric workspace from load handlers list") 4704 bpy.app.handlers.load_post.remove(povCentricWorkspace) 4705 4706 # from bpy.utils import unregister_class 4707 4708 # bpy.types.TEXTURE_PT_context_texture.remove(TEXTURE_PT_POV_type) 4709 # addon_utils.disable("add_mesh_extra_objects", default_set=False) 4710 # bpy.types.WORLD_PT_POV_world.remove(world_panel_func) 4711 bpy.types.LIGHT_PT_POV_light.remove(light_panel_func) 4712 bpy.types.RENDER_PT_POV_radiosity.remove(rad_panel_func) 4713 bpy.types.TEXT_MT_templates.remove(menu_func_templates) 4714 bpy.types.TOPBAR_MT_file_import.remove(menu_func_import) 4715 bpy.types.VIEW3D_MT_add.remove(menu_func_add) 4716 4717 for cls in reversed(classes): 4718 if cls != TEXTURE_PT_context: 4719 unregister_class(cls) 4720