Cleanup: quiet float argument to in type warning
[blender-addons.git] / render_povray / model_gui.py
blobde10c95b3777a26ef9b5711fae4f7d3d08504873
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 """User interface for the POV tools"""
5 import bpy
7 import os
9 from bpy.utils import register_class, unregister_class, register_tool, unregister_tool
10 from bpy.types import (
11 # Operator,
12 Menu,
13 Panel,
14 WorkSpaceTool,
17 # Example of wrapping every class 'as is'
18 from bl_ui import properties_data_modifier
20 for member in dir(properties_data_modifier):
21 subclass = getattr(properties_data_modifier, member)
22 if hasattr(subclass, "COMPAT_ENGINES"):
23 subclass.COMPAT_ENGINES.add("POVRAY_RENDER")
24 del properties_data_modifier
27 from bl_ui import properties_data_mesh
29 # These panels are kept
30 properties_data_mesh.DATA_PT_custom_props_mesh.COMPAT_ENGINES.add("POVRAY_RENDER")
31 properties_data_mesh.DATA_PT_context_mesh.COMPAT_ENGINES.add("POVRAY_RENDER")
33 # make some native panels contextual to some object variable
34 # by recreating custom panels inheriting their properties
37 from .scripting_gui import VIEW_MT_POV_import
40 class ModifierButtonsPanel:
41 """Use this class to define buttons from the modifier tab of
42 properties window."""
44 bl_space_type = "PROPERTIES"
45 bl_region_type = "WINDOW"
46 bl_context = "modifier"
47 COMPAT_ENGINES = {"POVRAY_RENDER"}
49 @classmethod
50 def poll(cls, context):
51 mods = context.object.modifiers
52 rd = context.scene.render
53 return mods and (rd.engine in cls.COMPAT_ENGINES)
56 class ObjectButtonsPanel:
57 """Use this class to define buttons from the object tab of
58 properties window."""
60 bl_space_type = "PROPERTIES"
61 bl_region_type = "WINDOW"
62 bl_context = "object"
63 COMPAT_ENGINES = {"POVRAY_RENDER"}
65 @classmethod
66 def poll(cls, context):
67 obj = context.object
68 rd = context.scene.render
69 return obj and (rd.engine in cls.COMPAT_ENGINES)
72 class PovDataButtonsPanel(properties_data_mesh.MeshButtonsPanel):
73 """Use this class to define buttons from the edit data tab of
74 properties window."""
76 COMPAT_ENGINES = {"POVRAY_RENDER"}
77 POV_OBJECT_TYPES = {
78 "PLANE",
79 "BOX",
80 "SPHERE",
81 "CYLINDER",
82 "CONE",
83 "TORUS",
84 "BLOB",
85 "ISOSURFACE_NODE",
86 "ISOSURFACE_VIEW",
87 "SUPERELLIPSOID",
88 "SUPERTORUS",
89 "HEIGHT_FIELD",
90 "PARAMETRIC",
91 "POLYCIRCLE",
94 @classmethod
95 def poll(cls, context):
96 # engine = context.scene.render.engine # XXX Unused
97 obj = context.object
98 # We use our parent class poll func too, avoids to re-define too much things...
99 return (
100 super(PovDataButtonsPanel, cls).poll(context)
101 and obj
102 and obj.pov.object_as not in cls.POV_OBJECT_TYPES
106 # We cannot inherit from RNA classes (like e.g. properties_data_mesh.DATA_PT_vertex_groups).
107 # Complex py/bpy/rna interactions (with metaclass and all) simply do not allow it to work.
108 # So we simply have to explicitly copy here the interesting bits. ;)
109 class DATA_PT_POV_normals(PovDataButtonsPanel, Panel):
110 bl_label = properties_data_mesh.DATA_PT_normals.bl_label
112 draw = properties_data_mesh.DATA_PT_normals.draw
115 class DATA_PT_POV_texture_space(PovDataButtonsPanel, Panel):
116 bl_label = properties_data_mesh.DATA_PT_texture_space.bl_label
117 bl_options = properties_data_mesh.DATA_PT_texture_space.bl_options
119 draw = properties_data_mesh.DATA_PT_texture_space.draw
122 class DATA_PT_POV_vertex_groups(PovDataButtonsPanel, Panel):
123 bl_label = properties_data_mesh.DATA_PT_vertex_groups.bl_label
125 draw = properties_data_mesh.DATA_PT_vertex_groups.draw
128 class DATA_PT_POV_shape_keys(PovDataButtonsPanel, Panel):
129 bl_label = properties_data_mesh.DATA_PT_shape_keys.bl_label
131 draw = properties_data_mesh.DATA_PT_shape_keys.draw
134 class DATA_PT_POV_uv_texture(PovDataButtonsPanel, Panel):
135 bl_label = properties_data_mesh.DATA_PT_uv_texture.bl_label
137 draw = properties_data_mesh.DATA_PT_uv_texture.draw
140 class DATA_PT_POV_vertex_colors(PovDataButtonsPanel, Panel):
141 bl_label = properties_data_mesh.DATA_PT_vertex_colors.bl_label
143 draw = properties_data_mesh.DATA_PT_vertex_colors.draw
146 class DATA_PT_POV_customdata(PovDataButtonsPanel, Panel):
147 bl_label = properties_data_mesh.DATA_PT_customdata.bl_label
148 bl_options = properties_data_mesh.DATA_PT_customdata.bl_options
149 draw = properties_data_mesh.DATA_PT_customdata.draw
152 del properties_data_mesh
155 class MODIFIERS_PT_POV_modifiers(ModifierButtonsPanel, Panel):
156 """Use this class to define pov modifier buttons. (For booleans)"""
158 bl_label = "POV-Ray"
160 # def draw_header(self, context):
161 # scene = context.scene
162 # self.layout.prop(scene.pov, "boolean_mod", text="")
164 def draw(self, context):
165 # scene = context.scene
166 layout = self.layout
167 ob = context.object
168 col = layout.column()
169 # Find Boolean Modifiers for displaying CSG option
170 once_csg = 0
171 for mod in ob.modifiers:
172 if once_csg == 0 and mod:
173 if mod.type == "BOOLEAN":
174 col.prop(ob.pov, "boolean_mod")
175 once_csg = 1
177 if ob.pov.boolean_mod == "POV":
178 # split = layout.split() # better ?
179 col = layout.column()
180 # Inside Vector for CSG
181 col.prop(ob.pov, "inside_vector")
184 class OBJECT_PT_POV_obj_parameters(ObjectButtonsPanel, Panel):
185 """Use this class to define pov specific object level options buttons."""
187 bl_label = "POV"
189 @classmethod
190 def poll(cls, context):
192 engine = context.scene.render.engine
193 return engine in cls.COMPAT_ENGINES
195 def draw(self, context):
196 layout = self.layout
198 obj = context.object
200 split = layout.split()
202 col = split.column(align=True)
204 col.label(text="Radiosity:")
205 col.prop(obj.pov, "importance_value", text="Importance")
206 col.label(text="Photons:")
207 col.prop(obj.pov, "collect_photons", text="Receive Photon Caustics")
208 if obj.pov.collect_photons:
209 col.prop(obj.pov, "spacing_multiplier", text="Photons Spacing Multiplier")
211 split = layout.split()
213 col = split.column()
214 col.prop(obj.pov, "hollow")
215 col.prop(obj.pov, "double_illuminate")
217 if obj.type == "META" or obj.pov.curveshape == "lathe":
218 # if obj.pov.curveshape == 'sor'
219 col.prop(obj.pov, "sturm")
220 col.prop(obj.pov, "no_shadow")
221 col.prop(obj.pov, "no_image")
222 col.prop(obj.pov, "no_reflection")
223 col.prop(obj.pov, "no_radiosity")
224 col.prop(obj.pov, "inverse")
225 col.prop(obj.pov, "hierarchy")
226 # col.prop(obj.pov,"boundorclip",text="Bound / Clip")
227 # if obj.pov.boundorclip != "none":
228 # col.prop_search(obj.pov,"boundorclipob",context.blend_data,"objects",text="Object")
229 # text = "Clipped by"
230 # if obj.pov.boundorclip == "clipped_by":
231 # text = "Bounded by"
232 # col.prop(obj.pov,"addboundorclip",text=text)
235 class OBJECT_PT_POV_obj_sphere(PovDataButtonsPanel, Panel):
236 """Use this class to define pov sphere primitive parameters buttons."""
238 bl_label = "POV Sphere"
239 COMPAT_ENGINES = {"POVRAY_RENDER"}
240 # bl_options = {'HIDE_HEADER'}
242 @classmethod
243 def poll(cls, context):
244 engine = context.scene.render.engine
245 obj = context.object
246 return obj and obj.pov.object_as == "SPHERE" and (engine in cls.COMPAT_ENGINES)
248 def draw(self, context):
249 layout = self.layout
251 obj = context.object
253 col = layout.column()
255 if obj.pov.object_as == "SPHERE":
256 if not obj.pov.unlock_parameters:
257 col.prop(
258 obj.pov, "unlock_parameters", text="Exported parameters below", icon="LOCKED"
260 col.label(text="Sphere radius: " + str(obj.pov.sphere_radius))
262 else:
263 col.prop(
264 obj.pov, "unlock_parameters", text="Edit exported parameters", icon="UNLOCKED"
266 col.label(text="3D view proxy may get out of synch")
267 col.active = obj.pov.unlock_parameters
269 layout.operator("pov.sphere_update", text="Update", icon="SHADING_RENDERED")
271 # col.label(text="Parameters:")
272 col.prop(obj.pov, "sphere_radius", text="Radius of Sphere")
275 class OBJECT_PT_POV_obj_cylinder(PovDataButtonsPanel, Panel):
276 """Use this class to define pov cylinder primitive parameters buttons."""
278 bl_label = "POV Cylinder"
279 COMPAT_ENGINES = {"POVRAY_RENDER"}
280 # bl_options = {'HIDE_HEADER'}
282 @classmethod
283 def poll(cls, context):
284 engine = context.scene.render.engine
285 obj = context.object
286 return obj and obj.pov.object_as == "CYLINDER" and (engine in cls.COMPAT_ENGINES)
288 def draw(self, context):
289 layout = self.layout
291 obj = context.object
293 col = layout.column()
295 if obj.pov.object_as == "CYLINDER":
296 if not obj.pov.unlock_parameters:
297 col.prop(
298 obj.pov, "unlock_parameters", text="Exported parameters below", icon="LOCKED"
300 col.label(text="Cylinder radius: " + str(obj.pov.cylinder_radius))
301 col.label(text="Cylinder cap location: " + str(obj.pov.cylinder_location_cap))
303 else:
304 col.prop(
305 obj.pov, "unlock_parameters", text="Edit exported parameters", icon="UNLOCKED"
307 col.label(text="3D view proxy may get out of synch")
308 col.active = obj.pov.unlock_parameters
310 layout.operator("pov.cylinder_update", text="Update", icon="MESH_CYLINDER")
312 # col.label(text="Parameters:")
313 col.prop(obj.pov, "cylinder_radius")
314 col.prop(obj.pov, "cylinder_location_cap")
317 class OBJECT_PT_POV_obj_cone(PovDataButtonsPanel, Panel):
318 """Use this class to define pov cone primitive parameters buttons."""
320 bl_label = "POV Cone"
321 COMPAT_ENGINES = {"POVRAY_RENDER"}
322 # bl_options = {'HIDE_HEADER'}
324 @classmethod
325 def poll(cls, context):
326 engine = context.scene.render.engine
327 obj = context.object
328 return obj and obj.pov.object_as == "CONE" and (engine in cls.COMPAT_ENGINES)
330 def draw(self, context):
331 layout = self.layout
333 obj = context.object
335 col = layout.column()
337 if obj.pov.object_as == "CONE":
338 if not obj.pov.unlock_parameters:
339 col.prop(
340 obj.pov, "unlock_parameters", text="Exported parameters below", icon="LOCKED"
342 col.label(text="Cone base radius: " + str(obj.pov.cone_base_radius))
343 col.label(text="Cone cap radius: " + str(obj.pov.cone_cap_radius))
344 col.label(text="Cone proxy segments: " + str(obj.pov.cone_segments))
345 col.label(text="Cone height: " + str(obj.pov.cone_height))
346 else:
347 col.prop(
348 obj.pov, "unlock_parameters", text="Edit exported parameters", icon="UNLOCKED"
350 col.label(text="3D view proxy may get out of synch")
351 col.active = obj.pov.unlock_parameters
353 layout.operator("pov.cone_update", text="Update", icon="MESH_CONE")
355 # col.label(text="Parameters:")
356 col.prop(obj.pov, "cone_base_radius", text="Radius of Cone Base")
357 col.prop(obj.pov, "cone_cap_radius", text="Radius of Cone Cap")
358 col.prop(obj.pov, "cone_segments", text="Segmentation of Cone proxy")
359 col.prop(obj.pov, "cone_height", text="Height of the cone")
362 class OBJECT_PT_POV_obj_superellipsoid(PovDataButtonsPanel, Panel):
363 """Use this class to define pov superellipsoid primitive parameters buttons."""
365 bl_label = "POV Superquadric ellipsoid"
366 COMPAT_ENGINES = {"POVRAY_RENDER"}
367 # bl_options = {'HIDE_HEADER'}
369 @classmethod
370 def poll(cls, context):
371 engine = context.scene.render.engine
372 obj = context.object
373 return obj and obj.pov.object_as == "SUPERELLIPSOID" and (engine in cls.COMPAT_ENGINES)
375 def draw(self, context):
376 layout = self.layout
378 obj = context.object
380 col = layout.column()
382 if obj.pov.object_as == "SUPERELLIPSOID":
383 if not obj.pov.unlock_parameters:
384 col.prop(
385 obj.pov, "unlock_parameters", text="Exported parameters below", icon="LOCKED"
387 col.label(text="Radial segmentation: " + str(obj.pov.se_u))
388 col.label(text="Lateral segmentation: " + str(obj.pov.se_v))
389 col.label(text="Ring shape: " + str(obj.pov.se_n1))
390 col.label(text="Cross-section shape: " + str(obj.pov.se_n2))
391 col.label(text="Fill up and down: " + str(obj.pov.se_edit))
392 else:
393 col.prop(
394 obj.pov, "unlock_parameters", text="Edit exported parameters", icon="UNLOCKED"
396 col.label(text="3D view proxy may get out of synch")
397 col.active = obj.pov.unlock_parameters
399 layout.operator("pov.superellipsoid_update", text="Update", icon="MOD_SUBSURF")
401 # col.label(text="Parameters:")
402 col.prop(obj.pov, "se_u")
403 col.prop(obj.pov, "se_v")
404 col.prop(obj.pov, "se_n1")
405 col.prop(obj.pov, "se_n2")
406 col.prop(obj.pov, "se_edit")
409 class OBJECT_PT_POV_obj_torus(PovDataButtonsPanel, Panel):
410 """Use this class to define pov torus primitive parameters buttons."""
412 bl_label = "POV Torus"
413 COMPAT_ENGINES = {"POVRAY_RENDER"}
414 # bl_options = {'HIDE_HEADER'}
416 @classmethod
417 def poll(cls, context):
418 engine = context.scene.render.engine
419 obj = context.object
420 return obj and obj.pov.object_as == "TORUS" and (engine in cls.COMPAT_ENGINES)
422 def draw(self, context):
423 layout = self.layout
425 obj = context.object
427 col = layout.column()
429 if obj.pov.object_as == "TORUS":
430 if not obj.pov.unlock_parameters:
431 col.prop(
432 obj.pov, "unlock_parameters", text="Exported parameters below", icon="LOCKED"
434 col.label(text="Torus major radius: " + str(obj.pov.torus_major_radius))
435 col.label(text="Torus minor radius: " + str(obj.pov.torus_minor_radius))
436 col.label(text="Torus major segments: " + str(obj.pov.torus_major_segments))
437 col.label(text="Torus minor segments: " + str(obj.pov.torus_minor_segments))
438 else:
439 col.prop(
440 obj.pov, "unlock_parameters", text="Edit exported parameters", icon="UNLOCKED"
442 col.label(text="3D view proxy may get out of synch")
443 col.active = obj.pov.unlock_parameters
445 layout.operator("pov.torus_update", text="Update", icon="MESH_TORUS")
447 # col.label(text="Parameters:")
448 col.prop(obj.pov, "torus_major_radius")
449 col.prop(obj.pov, "torus_minor_radius")
450 col.prop(obj.pov, "torus_major_segments")
451 col.prop(obj.pov, "torus_minor_segments")
454 class OBJECT_PT_POV_obj_supertorus(PovDataButtonsPanel, Panel):
455 """Use this class to define pov supertorus primitive parameters buttons."""
457 bl_label = "POV SuperTorus"
458 COMPAT_ENGINES = {"POVRAY_RENDER"}
459 # bl_options = {'HIDE_HEADER'}
461 @classmethod
462 def poll(cls, context):
463 engine = context.scene.render.engine
464 obj = context.object
465 return obj and obj.pov.object_as == "SUPERTORUS" and (engine in cls.COMPAT_ENGINES)
467 def draw(self, context):
468 layout = self.layout
470 obj = context.object
472 col = layout.column()
474 if obj.pov.object_as == "SUPERTORUS":
475 if not obj.pov.unlock_parameters:
476 col.prop(
477 obj.pov, "unlock_parameters", text="Exported parameters below", icon="LOCKED"
479 col.label(text="SuperTorus major radius: " + str(obj.pov.st_major_radius))
480 col.label(text="SuperTorus minor radius: " + str(obj.pov.st_minor_radius))
481 col.label(text="SuperTorus major segments: " + str(obj.pov.st_u))
482 col.label(text="SuperTorus minor segments: " + str(obj.pov.st_v))
484 col.label(text="SuperTorus Ring Manipulator: " + str(obj.pov.st_ring))
485 col.label(text="SuperTorus Cross Manipulator: " + str(obj.pov.st_cross))
486 col.label(text="SuperTorus Internal And External radii: " + str(obj.pov.st_ie))
488 col.label(text="SuperTorus accuracy: " + str(obj.pov.st_accuracy))
489 col.label(text="SuperTorus max gradient: " + str(obj.pov.st_max_gradient))
491 else:
492 col.prop(
493 obj.pov, "unlock_parameters", text="Edit exported parameters", icon="UNLOCKED"
495 col.label(text="3D view proxy may get out of synch")
496 col.active = obj.pov.unlock_parameters
498 layout.operator("pov.supertorus_update", text="Update", icon="MESH_TORUS")
500 # col.label(text="Parameters:")
501 col.prop(obj.pov, "st_major_radius")
502 col.prop(obj.pov, "st_minor_radius")
503 col.prop(obj.pov, "st_u")
504 col.prop(obj.pov, "st_v")
505 col.prop(obj.pov, "st_ring")
506 col.prop(obj.pov, "st_cross")
507 col.prop(obj.pov, "st_ie")
508 # col.prop(obj.pov, "st_edit") #?
509 col.prop(obj.pov, "st_accuracy")
510 col.prop(obj.pov, "st_max_gradient")
513 class OBJECT_PT_POV_obj_isosurface(PovDataButtonsPanel, Panel):
514 """Use this class to define pov generic isosurface primitive function user field."""
516 bl_label = "POV Isosurface"
517 COMPAT_ENGINES = {"POVRAY_RENDER"}
518 # bl_options = {'HIDE_HEADER'}
520 @classmethod
521 def poll(cls, context):
522 engine = context.scene.render.engine
523 obj = context.object
524 return obj and obj.pov.object_as == "ISOSURFACE_VIEW" and (engine in cls.COMPAT_ENGINES)
526 def draw(self, context):
527 layout = self.layout
529 obj = context.object
531 col = layout.column()
533 if obj.pov.object_as == "ISOSURFACE_VIEW":
534 col.prop(obj.pov, "isosurface_eq")
537 class OBJECT_PT_POV_obj_parametric(PovDataButtonsPanel, Panel):
538 """Use this class to define pov parametric surface primitive parameters buttons."""
540 bl_label = "POV Parametric surface"
541 # bl_options = {'HIDE_HEADER'}
543 @classmethod
544 def poll(cls, context):
545 engine = context.scene.render.engine
546 obj = context.object
547 return obj and obj.pov.object_as == "PARAMETRIC" and (engine in cls.COMPAT_ENGINES)
549 def draw(self, context):
550 layout = self.layout
552 obj = context.object
554 col = layout.column()
556 if obj.pov.object_as == "PARAMETRIC":
557 if not obj.pov.unlock_parameters:
558 col.prop(
559 obj.pov, "unlock_parameters", text="Exported parameters below", icon="LOCKED"
561 col.label(text="Minimum U: " + str(obj.pov.u_min))
562 col.label(text="Minimum V: " + str(obj.pov.v_min))
563 col.label(text="Maximum U: " + str(obj.pov.u_max))
564 col.label(text="Minimum V: " + str(obj.pov.v_min))
565 col.label(text="X Function: " + str(obj.pov.x_eq))
566 col.label(text="Y Function: " + str(obj.pov.y_eq))
567 col.label(text="Z Function: " + str(obj.pov.x_eq))
569 else:
570 col.prop(
571 obj.pov, "unlock_parameters", text="Edit exported parameters", icon="UNLOCKED"
573 col.label(text="3D view proxy may get out of synch")
574 col.active = obj.pov.unlock_parameters
576 layout.operator("pov.parametric_update", text="Update", icon="SCRIPTPLUGINS")
578 col.prop(obj.pov, "u_min", text="Minimum U")
579 col.prop(obj.pov, "v_min", text="Minimum V")
580 col.prop(obj.pov, "u_max", text="Maximum U")
581 col.prop(obj.pov, "v_max", text="Minimum V")
582 col.prop(obj.pov, "x_eq", text="X Function")
583 col.prop(obj.pov, "y_eq", text="Y Function")
584 col.prop(obj.pov, "z_eq", text="Z Function")
587 class OBJECT_PT_povray_replacement_text(ObjectButtonsPanel, Panel):
588 """Use this class to define pov object replacement field."""
590 bl_label = "Custom POV Code"
591 COMPAT_ENGINES = {"POVRAY_RENDER"}
593 def draw(self, context):
594 layout = self.layout
596 obj = context.object
598 col = layout.column()
599 col.label(text="Replace properties with:")
600 col.prop(obj.pov, "replacement_text", text="")
603 # ---------------------------------------------------------------- #
604 # Add POV objects
605 # ---------------------------------------------------------------- #
606 def check_add_mesh_extra_objects():
607 """Test if Add mesh extra objects addon is activated
609 This addon is currently used to generate the proxy for POV parametric
610 surface which is almost the same principle as its Math xyz surface
612 return "add_mesh_extra_objects" in bpy.context.preferences.addons.keys()
615 def menu_func_add(self, context):
616 """Append the POV primitives submenu to blender add objects menu"""
617 engine = context.scene.render.engine
618 if engine == "POVRAY_RENDER":
619 self.layout.menu("VIEW_MT_POV_primitives_add", icon="PLUGIN")
622 class VIEW_MT_POV_primitives_add(Menu):
623 """Define the primitives menu with presets"""
625 bl_idname = "VIEW_MT_POV_primitives_add"
626 bl_label = "Povray"
627 COMPAT_ENGINES = {"POVRAY_RENDER"}
629 @classmethod
630 def poll(cls, context):
631 engine = context.scene.render.engine
632 return engine == "POVRAY_RENDER"
634 def draw(self, context):
635 layout = self.layout
636 layout.operator_context = "INVOKE_REGION_WIN"
637 layout.menu(VIEW_MT_POV_Basic_Shapes.bl_idname, text="Primitives", icon="GROUP")
638 layout.menu(VIEW_MT_POV_import.bl_idname, text="Import", icon="IMPORT")
641 class VIEW_MT_POV_Basic_Shapes(Menu):
642 """Use this class to sort simple primitives menu entries."""
644 bl_idname = "POVRAY_MT_basic_shape_tools"
645 bl_label = "Basic_shapes"
647 def draw(self, context):
648 layout = self.layout
649 layout.operator_context = "INVOKE_REGION_WIN"
650 layout.operator("pov.addplane", text="Infinite Plane", icon="MESH_PLANE")
651 layout.operator("pov.addbox", text="Box", icon="MESH_CUBE")
652 layout.operator("pov.addsphere", text="Sphere", icon="SHADING_RENDERED")
653 layout.operator("pov.addcylinder", text="Cylinder", icon="MESH_CYLINDER")
654 layout.operator("pov.addcone", text="Cone", icon="MESH_CONE")
655 layout.operator("pov.addtorus", text="Torus", icon="MESH_TORUS")
656 layout.separator()
657 layout.operator("pov.addrainbow", text="Rainbow", icon="COLOR")
658 layout.operator("pov.addlathe", text="Lathe", icon="MOD_SCREW")
659 layout.operator("pov.addprism", text="Prism", icon="MOD_SOLIDIFY")
660 layout.operator("pov.addsuperellipsoid", text="Superquadric Ellipsoid", icon="MOD_SUBSURF")
661 layout.operator("pov.addheightfield", text="Height Field", icon="RNDCURVE")
662 layout.operator("pov.addspheresweep", text="Sphere Sweep", icon="FORCE_CURVE")
663 layout.separator()
664 layout.operator("pov.addblobsphere", text="Blob Sphere", icon="META_DATA")
665 layout.separator()
666 layout.label(text="Isosurfaces")
667 layout.operator("pov.addisosurfacebox", text="Isosurface Box", icon="META_CUBE")
668 layout.operator("pov.addisosurfacesphere", text="Isosurface Sphere", icon="META_BALL")
669 layout.operator("pov.addsupertorus", text="Supertorus", icon="SURFACE_NTORUS")
670 layout.separator()
671 layout.label(text="Macro based")
672 layout.operator(
673 "pov.addpolygontocircle", text="Polygon To Circle Blending", icon="MOD_CAST"
675 layout.operator("pov.addloft", text="Loft", icon="SURFACE_NSURFACE")
676 layout.separator()
677 # Warning if the Add Advanced Objects addon containing
678 # Add mesh extra objects is not enabled
679 if not check_add_mesh_extra_objects():
680 # col = box.column()
681 layout.label(text="Please enable Add Mesh: Extra Objects addon", icon="INFO")
682 # layout.separator()
683 layout.operator(
684 "preferences.addon_show",
685 text="Go to Add Mesh: Extra Objects addon",
686 icon="PREFERENCES",
687 ).module = "add_mesh_extra_objects"
689 # layout.separator()
690 return
691 layout.operator("pov.addparametric", text="Parametric", icon="SCRIPTPLUGINS")
694 # ------------ Tool bar button------------ #
695 icon_path = os.path.join(os.path.dirname(__file__), "icons")
698 class VIEW_WT_POV_plane_add(WorkSpaceTool):
699 bl_space_type = "VIEW_3D"
700 bl_context_mode = "OBJECT"
702 # The prefix of the idname should be your add-on name.
703 bl_idname = "pov.addplane"
704 bl_label = "Add POV plane"
706 bl_description = "add a plane of infinite dimension for POV"
707 bl_icon = os.path.join(icon_path, "pov.add.infinite_plane")
708 bl_widget = None
709 bl_keymap = (("pov.addplane", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),)
712 class VIEW_WT_POV_box_add(WorkSpaceTool):
713 bl_space_type = "VIEW_3D"
714 bl_context_mode = "OBJECT"
716 # The prefix of the idname should be your add-on name.
717 bl_idname = "pov.addbox"
718 bl_label = "Add POV box"
720 bl_description = "add a POV box solid primitive"
721 bl_icon = os.path.join(icon_path, "pov.add.box")
722 bl_widget = None
723 bl_keymap = (("pov.addbox", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),)
726 class VIEW_WT_POV_sphere_add(WorkSpaceTool):
727 bl_space_type = "VIEW_3D"
728 bl_context_mode = "OBJECT"
730 # The prefix of the idname should be your add-on name.
731 bl_idname = "pov.addsphere"
732 bl_label = "Add POV sphere"
734 bl_description = "add an untesselated sphere for POV"
735 bl_icon = os.path.join(icon_path, "pov.add.sphere")
736 bl_widget = None
737 bl_keymap = (("pov.addsphere", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),)
740 class VIEW_WT_POV_cylinder_add(WorkSpaceTool):
741 bl_space_type = "VIEW_3D"
742 bl_context_mode = "OBJECT"
744 # The prefix of the idname should be your add-on name.
745 bl_idname = "pov.addcylinder"
746 bl_label = "Add POV cylinder"
748 bl_description = "add an untesselated cylinder for POV"
749 bl_icon = os.path.join(icon_path, "pov.add.cylinder")
750 bl_widget = None
751 bl_keymap = (
752 ("pov.addcylinder", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
756 class VIEW_WT_POV_cone_add(WorkSpaceTool):
757 bl_space_type = "VIEW_3D"
758 bl_context_mode = "OBJECT"
760 # The prefix of the idname should be your add-on name.
761 bl_idname = "pov.addcone"
762 bl_label = "Add POV cone"
764 bl_description = "add an untesselated cone for POV"
765 bl_icon = os.path.join(icon_path, "pov.add.cone")
766 bl_widget = None
767 bl_keymap = (("pov.addcone", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),)
770 class VIEW_WT_POV_torus_add(WorkSpaceTool):
771 bl_space_type = "VIEW_3D"
772 bl_context_mode = "OBJECT"
774 # The prefix of the idname should be your add-on name.
775 bl_idname = "pov.addtorus"
776 bl_label = "Add POV torus"
778 bl_description = "add an untesselated torus for POV"
779 bl_icon = os.path.join(icon_path, "pov.add.torus")
780 bl_widget = None
781 bl_keymap = (("pov.addtorus", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),)
784 class VIEW_WT_POV_rainbow_add(WorkSpaceTool):
785 bl_space_type = "VIEW_3D"
786 bl_context_mode = "OBJECT"
788 # The prefix of the idname should be your add-on name.
789 bl_idname = "pov.addrainbow"
790 bl_label = "Add POV rainbow"
792 bl_description = "add a POV rainbow primitive"
793 bl_icon = os.path.join(icon_path, "pov.add.rainbow")
794 bl_widget = None
795 bl_keymap = (("pov.addrainbow", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),)
798 class VIEW_WT_POV_lathe_add(WorkSpaceTool):
799 bl_space_type = "VIEW_3D"
800 bl_context_mode = "OBJECT"
802 # The prefix of the idname should be your add-on name.
803 bl_idname = "pov.addlathe"
804 bl_label = "Add POV lathe"
806 bl_description = "add a POV lathe primitive"
807 bl_icon = os.path.join(icon_path, "pov.add.lathe")
808 bl_widget = None
809 bl_keymap = (("pov.addlathe", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),)
812 class VIEW_WT_POV_prism_add(WorkSpaceTool):
813 bl_space_type = "VIEW_3D"
814 bl_context_mode = "OBJECT"
816 # The prefix of the idname should be your add-on name.
817 bl_idname = "pov.addprism"
818 bl_label = "Add POV prism"
820 bl_description = "add a POV prism primitive"
821 bl_icon = os.path.join(icon_path, "pov.add.prism")
822 bl_widget = None
823 bl_keymap = (("pov.addprism", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),)
826 class VIEW_WT_POV_heightfield_add(WorkSpaceTool):
827 bl_space_type = "VIEW_3D"
828 bl_context_mode = "OBJECT"
830 # The prefix of the idname should be your add-on name.
831 bl_idname = "pov.addheightfield"
832 bl_label = "Add POV heightfield"
834 bl_description = "add a POV heightfield primitive"
835 bl_icon = os.path.join(icon_path, "pov.add.heightfield")
836 bl_widget = None
837 bl_keymap = (
838 ("pov.addheightfield", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
842 class VIEW_WT_POV_superellipsoid_add(WorkSpaceTool):
843 bl_space_type = "VIEW_3D"
844 bl_context_mode = "OBJECT"
846 # The prefix of the idname should be your add-on name.
847 bl_idname = "pov.addsuperellipsoid"
848 bl_label = "Add POV superquadric ellipsoid"
850 bl_description = "add a POV superquadric ellipsoid primitive"
851 bl_icon = os.path.join(icon_path, "pov.add.superellipsoid")
852 bl_widget = None
853 bl_keymap = (
854 ("pov.addsuperellipsoid", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
858 class VIEW_WT_POV_spheresweep_add(WorkSpaceTool):
859 bl_space_type = "VIEW_3D"
860 bl_context_mode = "OBJECT"
862 # The prefix of the idname should be your add-on name.
863 bl_idname = "pov.addspheresweep"
864 bl_label = "Add POV spheresweep"
866 bl_description = "add a POV spheresweep primitive"
867 bl_icon = os.path.join(icon_path, "pov.add.spheresweep")
868 bl_widget = None
869 bl_keymap = (
870 ("pov.addspheresweep", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
874 class VIEW_WT_POV_loft_add(WorkSpaceTool):
875 bl_space_type = "VIEW_3D"
876 bl_context_mode = "OBJECT"
878 # The prefix of the idname should be your add-on name.
879 bl_idname = "pov.addloft"
880 bl_label = "Add POV loft macro"
882 bl_description = "add a POV loft macro between editable spline cross sections"
883 bl_icon = os.path.join(icon_path, "pov.add.loft")
884 bl_widget = None
885 bl_keymap = (("pov.addloft", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),)
888 class VIEW_WT_POV_polytocircle_add(WorkSpaceTool):
889 bl_space_type = "VIEW_3D"
890 bl_context_mode = "OBJECT"
892 # The prefix of the idname should be your add-on name.
893 bl_idname = "pov.addpolygontocircle"
894 bl_label = "Add POV poly to circle macro"
896 bl_description = "add a POV regular polygon to circle blending macro"
897 bl_icon = os.path.join(icon_path, "pov.add.polygontocircle")
898 bl_widget = None
899 bl_keymap = (
900 ("pov.addpolygontocircle", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
904 class VIEW_WT_POV_parametric_add(WorkSpaceTool):
905 bl_space_type = "VIEW_3D"
906 bl_context_mode = "OBJECT"
908 # The prefix of the idname should be your add-on name.
909 bl_idname = "pov.addparametric"
910 bl_label = "Add POV parametric surface"
912 bl_description = "add a POV parametric surface primitive shaped from three equations (for x, y, z directions)"
913 bl_icon = os.path.join(icon_path, "pov.add.parametric")
914 bl_widget = None
915 bl_keymap = (
916 ("pov.addparametric", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
920 class VIEW_WT_POV_isosurface_add(WorkSpaceTool):
921 bl_space_type = "VIEW_3D"
922 bl_context_mode = "OBJECT"
924 # The prefix of the idname should be your add-on name.
925 bl_idname = "pov.addisosurface"
926 bl_label = "Add POV generic isosurface"
928 bl_description = "add a POV generic shaped isosurface primitive"
929 bl_icon = os.path.join(icon_path, "pov.add.isosurface")
930 bl_widget = None
931 bl_keymap = (
932 ("pov.addisosurface", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
936 class VIEW_WT_POV_isosurfacebox_add(WorkSpaceTool):
937 bl_space_type = "VIEW_3D"
938 bl_context_mode = "OBJECT"
940 # The prefix of the idname should be your add-on name.
941 bl_idname = "pov.addisosurfacebox"
942 bl_label = "Add POV isosurface box"
944 bl_description = "add a POV box shaped isosurface primitive"
945 bl_icon = os.path.join(icon_path, "pov.add.isosurfacebox")
946 bl_widget = None
947 bl_keymap = (
948 ("pov.addisosurfacebox", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
952 class VIEW_WT_POV_isosurfacesphere_add(WorkSpaceTool):
953 bl_space_type = "VIEW_3D"
954 bl_context_mode = "OBJECT"
956 # The prefix of the idname should be your add-on name.
957 bl_idname = "pov.addisosurfacesphere"
958 bl_label = "Add POV isosurface sphere"
960 bl_description = "add a POV sphere shaped isosurface primitive"
961 bl_icon = os.path.join(icon_path, "pov.add.isosurfacesphere")
962 bl_widget = None
963 bl_keymap = (
964 ("pov.addisosurfacesphere", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
968 class VIEW_WT_POV_isosurfacesupertorus_add(WorkSpaceTool):
969 bl_space_type = "VIEW_3D"
970 bl_context_mode = "OBJECT"
972 # The prefix of the idname should be your add-on name.
973 bl_idname = "pov.addsupertorus"
974 bl_label = "Add POV isosurface supertorus"
976 bl_description = "add a POV torus shaped isosurface primitive"
977 bl_icon = os.path.join(icon_path, "pov.add.isosurfacesupertorus")
978 bl_widget = None
979 bl_keymap = (
980 ("pov.addsupertorus", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
984 class VIEW_WT_POV_blobsphere_add(WorkSpaceTool):
985 bl_space_type = "VIEW_3D"
986 bl_context_mode = "OBJECT"
988 # The prefix of the idname should be your add-on name.
989 bl_idname = "pov.addblobsphere"
990 bl_label = "Add POV blob sphere"
992 bl_description = "add a POV sphere shaped blob primitive"
993 bl_icon = os.path.join(icon_path, "pov.add.blobsphere")
994 bl_widget = None
995 bl_keymap = (
996 ("pov.addblobsphere", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
1000 class VIEW_WT_POV_blobcapsule_add(WorkSpaceTool):
1001 bl_space_type = "VIEW_3D"
1002 bl_context_mode = "OBJECT"
1004 # The prefix of the idname should be your add-on name.
1005 bl_idname = "pov.addblobcapsule"
1006 bl_label = "Add POV blob capsule"
1008 bl_description = "add a POV capsule shaped blob primitive"
1009 bl_icon = os.path.join(icon_path, "pov.add.blobcapsule")
1010 bl_widget = None
1011 bl_keymap = (
1012 ("pov.addblobcapsule", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
1016 class VIEW_WT_POV_blobplane_add(WorkSpaceTool):
1017 bl_space_type = "VIEW_3D"
1018 bl_context_mode = "OBJECT"
1020 # The prefix of the idname should be your add-on name.
1021 bl_idname = "pov.addblobplane"
1022 bl_label = "Add POV blob plane"
1024 bl_description = "add a POV plane shaped blob primitive"
1025 bl_icon = os.path.join(icon_path, "pov.add.blobplane")
1026 bl_widget = None
1027 bl_keymap = (
1028 ("pov.addblobplane", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
1032 class VIEW_WT_POV_blobellipsoid_add(WorkSpaceTool):
1033 bl_space_type = "VIEW_3D"
1034 bl_context_mode = "OBJECT"
1036 # The prefix of the idname should be your add-on name.
1037 bl_idname = "pov.addblobellipsoid"
1038 bl_label = "Add POV blob ellipsoid"
1040 bl_description = "add a POV ellipsoid shaped blob primitive"
1041 bl_icon = os.path.join(icon_path, "pov.add.blobellipsoid")
1042 bl_widget = None
1043 bl_keymap = (
1044 ("pov.addblobellipsoid", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
1048 class VIEW_WT_POV_blobcube_add(WorkSpaceTool):
1049 bl_space_type = "VIEW_3D"
1050 bl_context_mode = "OBJECT"
1052 # The prefix of the idname should be your add-on name.
1053 bl_idname = "pov.addsblobcube"
1054 bl_label = "Add POV blob cube"
1056 bl_description = "add a POV cube shaped blob primitive"
1057 bl_icon = os.path.join(icon_path, "pov.add.blobcube")
1058 bl_widget = None
1059 bl_keymap = (
1060 ("pov.addblobcube", {"type": "LEFTMOUSE", "value": "PRESS"}, {"properties": None}),
1064 classes = (
1065 # ObjectButtonsPanel,
1066 # PovDataButtonsPanel,
1067 DATA_PT_POV_normals,
1068 DATA_PT_POV_texture_space,
1069 DATA_PT_POV_vertex_groups,
1070 DATA_PT_POV_shape_keys,
1071 DATA_PT_POV_uv_texture,
1072 DATA_PT_POV_vertex_colors,
1073 DATA_PT_POV_customdata,
1074 MODIFIERS_PT_POV_modifiers,
1075 OBJECT_PT_POV_obj_parameters,
1076 OBJECT_PT_POV_obj_sphere,
1077 OBJECT_PT_POV_obj_cylinder,
1078 OBJECT_PT_POV_obj_cone,
1079 OBJECT_PT_POV_obj_superellipsoid,
1080 OBJECT_PT_POV_obj_torus,
1081 OBJECT_PT_POV_obj_supertorus,
1082 OBJECT_PT_POV_obj_isosurface,
1083 OBJECT_PT_POV_obj_parametric,
1084 OBJECT_PT_povray_replacement_text,
1085 VIEW_MT_POV_primitives_add,
1086 VIEW_MT_POV_Basic_Shapes,
1088 tool_classes = (
1089 VIEW_WT_POV_plane_add,
1090 VIEW_WT_POV_box_add,
1091 VIEW_WT_POV_sphere_add,
1092 VIEW_WT_POV_cylinder_add,
1093 VIEW_WT_POV_cone_add,
1094 VIEW_WT_POV_torus_add,
1095 VIEW_WT_POV_prism_add,
1096 VIEW_WT_POV_lathe_add,
1097 VIEW_WT_POV_spheresweep_add,
1098 VIEW_WT_POV_heightfield_add,
1099 VIEW_WT_POV_superellipsoid_add,
1100 VIEW_WT_POV_rainbow_add,
1101 VIEW_WT_POV_loft_add,
1102 VIEW_WT_POV_polytocircle_add,
1103 VIEW_WT_POV_parametric_add,
1104 VIEW_WT_POV_isosurface_add,
1105 VIEW_WT_POV_isosurfacebox_add,
1106 VIEW_WT_POV_isosurfacesphere_add,
1107 VIEW_WT_POV_isosurfacesupertorus_add,
1108 VIEW_WT_POV_blobsphere_add,
1109 VIEW_WT_POV_blobcapsule_add,
1110 VIEW_WT_POV_blobplane_add,
1111 VIEW_WT_POV_blobellipsoid_add,
1112 VIEW_WT_POV_blobcube_add,
1116 def register():
1117 for cls in classes:
1118 register_class(cls)
1120 # Register tools
1121 last_tool = {"builtin.measure"}
1122 for index, wtl in enumerate(tool_classes):
1123 # Only separate first and 12th tools and hide subtools only in 8th (isosurfaces)
1124 register_tool(
1125 wtl, after=last_tool, separator=index in {0, 7, 11, 12, 14, 19}, group=index == 15
1127 last_tool = {wtl.bl_idname}
1129 bpy.types.VIEW3D_MT_add.prepend(menu_func_add)
1130 # Below was used for parametric objects but made the other addon unreachable on
1131 # unregister for other tools to use. Created a user action call instead
1132 # addon_utils.enable("add_mesh_extra_objects", default_set=False, persistent=True)
1135 def unregister():
1136 # addon_utils.disable("add_mesh_extra_objects", default_set=False)
1137 bpy.types.VIEW3D_MT_add.remove(menu_func_add)
1139 for wtl in reversed(tool_classes):
1140 unregister_tool(wtl)
1142 for cls in reversed(classes):
1143 unregister_class(cls)