Newer
Older
# SPDX-License-Identifier: GPL-2.0-or-later
""" Get POV-Ray specific objects In and Out of Blender """
import bpy
from bpy_extras.object_utils import object_data_add
Maurice Raybaud
committed
from bpy_extras.io_utils import ImportHelper
from bpy.utils import register_class, unregister_class
from bpy.types import Operator
Maurice Raybaud
committed
from bpy.props import (
StringProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
EnumProperty,
from mathutils import Vector, Matrix
# import collections
Maurice Raybaud
committed
Maurice Raybaud
committed
def write_object_modifiers(ob, File):
"""Translate some object level POV statements from Blender UI
to POV syntax and write to exported file """
# Maybe return that string to be added instead of directly written.
'''XXX WIP
Maurice Raybaud
committed
# import .object_mesh_topology.write_object_csg_inside_vector
write_object_csg_inside_vector(ob, file)
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'''
if ob.pov.hollow:
File.write("\thollow\n")
if ob.pov.double_illuminate:
File.write("\tdouble_illuminate\n")
if ob.pov.sturm:
File.write("\tsturm\n")
if ob.pov.no_shadow:
File.write("\tno_shadow\n")
if ob.pov.no_image:
File.write("\tno_image\n")
if ob.pov.no_reflection:
File.write("\tno_reflection\n")
if ob.pov.no_radiosity:
File.write("\tno_radiosity\n")
if ob.pov.inverse:
File.write("\tinverse\n")
if ob.pov.hierarchy:
File.write("\thierarchy\n")
# XXX, Commented definitions
'''
if scene.pov.photon_enable:
File.write("photons {\n")
if ob.pov.target:
File.write("target %.4g\n"%ob.pov.target_value)
if ob.pov.refraction:
File.write("refraction on\n")
if ob.pov.reflection:
File.write("reflection on\n")
if ob.pov.pass_through:
File.write("pass_through\n")
File.write("}\n")
if ob.pov.object_ior > 1:
File.write("interior {\n")
File.write("ior %.4g\n"%ob.pov.object_ior)
if scene.pov.photon_enable and ob.pov.target and ob.pov.refraction and ob.pov.dispersion:
File.write("ior %.4g\n"%ob.pov.dispersion_value)
File.write("ior %s\n"%ob.pov.dispersion_samples)
if scene.pov.photon_enable == False:
File.write("caustics %.4g\n"%ob.pov.fake_caustics_power)
'''
Maurice Raybaud
committed
def pov_define_mesh(mesh, verts, edges, faces, name, hide_geometry=True):
Maurice Raybaud
committed
if mesh is None:
mesh = bpy.data.meshes.new(name)
mesh.from_pydata(verts, edges, faces)
mesh.update()
mesh.validate(
verbose=False
) # Set it to True to see debug messages (helps ensure you generate valid geometry).
Maurice Raybaud
committed
if hide_geometry:
mesh.vertices.foreach_set("hide", [True] * len(mesh.vertices))
mesh.edges.foreach_set("hide", [True] * len(mesh.edges))
mesh.polygons.foreach_set("hide", [True] * len(mesh.polygons))
return mesh
class POVRAY_OT_lathe_add(Operator):
"""Add the representation of POV lathe using a screw modifier."""
Maurice Raybaud
committed
bl_idname = "pov.addlathe"
bl_label = "Lathe"
bl_description = "adds lathe"
Maurice Raybaud
committed
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
Maurice Raybaud
committed
def execute(self, context):
# ayers=[False]*20
# layers[0]=True
location=context.scene.cursor.location,
ob = context.view_layer.objects.active
ob_data = ob.data
ob.name = ob_data.name = "PovLathe"
ob_data.dimensions = '2D'
ob_data.transform(Matrix.Rotation(-pi / 2.0, 4, 'Z'))
ob.pov.object_as = 'LATHE'
self.report(
{'INFO'}, "This native POV-Ray primitive" "won't have any vertex to show in edit mode"
)
Maurice Raybaud
committed
ob.pov.curveshape = "lathe"
bpy.ops.object.modifier_add(type='SCREW')
mod = ob.modifiers[-1]
mod.axis = 'Y'
mod.show_render = False
Maurice Raybaud
committed
return {'FINISHED'}
def pov_superellipsoid_define(context, op, ob):
"""Create the proxy mesh of a POV superellipsoid using pov_superellipsoid_define()."""
Maurice Raybaud
committed
Maurice Raybaud
committed
u = op.se_u
v = op.se_v
n1 = op.se_n1
n2 = op.se_n2
edit = op.se_edit
se_param1 = n2 # op.se_param1
se_param2 = n1 # op.se_param2
Maurice Raybaud
committed
u = ob.pov.se_u
v = ob.pov.se_v
n1 = ob.pov.se_n1
n2 = ob.pov.se_n2
edit = ob.pov.se_edit
se_param1 = ob.pov.se_param1
se_param2 = ob.pov.se_param2
verts = []
stepSegment = 360 / v * pi / 180
stepRing = pi / u
angSegment = 0
angRing = -pi / 2
step = 0
for ring in range(0, u - 1):
for segment in range(0, v):
x = r * (abs(cos(angRing)) ** n1) * (abs(cos(angSegment)) ** n2)
Maurice Raybaud
committed
if (cos(angRing) < 0 < cos(angSegment)) or (
cos(angRing) > 0 > cos(angSegment)
y = r * (abs(cos(angRing)) ** n1) * (abs(sin(angSegment)) ** n2)
Maurice Raybaud
committed
if (cos(angRing) < 0 < sin(angSegment)) or (
cos(angRing) > 0 > sin(angSegment)
z = r * (abs(sin(angRing)) ** n1)
x = round(x, 4)
y = round(y, 4)
z = round(z, 4)
verts.append((x, y, z))
verts.append((0, 0, 1))
verts.append((0, 0, -1))
for i in range(0, u - 2):
m = i * v
for p in range(0, v):
if p < v - 1:
face = (m + p, 1 + m + p, v + 1 + m + p, v + m + p)
if p == v - 1:
face = (m + p, m, v + m, v + m + p)
Maurice Raybaud
committed
faces.append(face)
indexUp = len(verts) - 2
indexDown = len(verts) - 1
indexStartDown = len(verts) - 2 - v
for i in range(0, v):
if i < v - 1:
face = (indexDown, i, i + 1)
if i == v - 1:
face = (indexDown, i, 0)
for i in range(0, v):
if i < v - 1:
face = (indexUp, i + indexStartDown, i + indexStartDown + 1)
if i == v - 1:
face = (indexUp, i + indexStartDown, indexStartDown)
face = []
for i in range(0, v):
face = []
indexUp = len(verts) - 1
for i in range(0, v):
face.append(indexUp - i)
faces.append(face)
mesh = pov_define_mesh(mesh, verts, [], faces, "SuperEllipsoid")
Maurice Raybaud
committed
ob = object_data_add(context, mesh, operator=None)
# engine = context.scene.render.engine what for?
ob.name = ob.data.name = "PovSuperellipsoid"
ob.pov.object_as = 'SUPERELLIPSOID'
ob.pov.se_param1 = n2
ob.pov.se_param2 = n1
ob.pov.se_u = u
ob.pov.se_v = v
ob.pov.se_n1 = n1
ob.pov.se_n2 = n2
ob.pov.se_edit = edit
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
class POVRAY_OT_superellipsoid_add(Operator):
"""Add the representation of POV superellipsoid using the pov_superellipsoid_define()."""
Maurice Raybaud
committed
bl_idname = "pov.addsuperellipsoid"
bl_label = "Add SuperEllipsoid"
bl_description = "Create a SuperEllipsoid"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
# Keep in sync within object_properties.py section Superellipsoid
# as this allows interactive update
Maurice Raybaud
committed
# If someone knows how to define operators' props from a func, I'd be delighted to learn it!
Maurice Raybaud
committed
# XXX ARE the first two used for import ? could we hide or suppress them otherwise?
se_param1: FloatProperty(name="Parameter 1", description="", min=0.00, max=10.0, default=0.04)
Maurice Raybaud
committed
se_param2: FloatProperty(name="Parameter 2", description="", min=0.00, max=10.0, default=0.04)
se_u: IntProperty(
name="U-segments", description="radial segmentation", default=20, min=4, max=265
)
se_v: IntProperty(
name="V-segments", description="lateral segmentation", default=20, min=4, max=265
)
se_n1: FloatProperty(
name="Ring manipulator",
description="Manipulates the shape of the Ring",
default=1.0,
min=0.01,
max=100.0,
)
se_n2: FloatProperty(
name="Cross manipulator",
description="Manipulates the shape of the cross-section",
default=1.0,
min=0.01,
max=100.0,
)
se_edit: EnumProperty(
items=[("NOTHING", "Nothing", ""), ("NGONS", "N-Gons", ""), ("TRIANGLES", "Triangles", "")],
name="Fill up and down",
description="",
default='TRIANGLES',
)
Maurice Raybaud
committed
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
return engine in cls.COMPAT_ENGINES
def execute(self, context):
Maurice Raybaud
committed
pov_superellipsoid_define(context, self, None)
{'INFO'}, "This native POV-Ray primitive" "won't have any vertex to show in edit mode"
Maurice Raybaud
committed
return {'FINISHED'}
class POVRAY_OT_superellipsoid_update(Operator):
"""Update the superellipsoid.
Delete its previous proxy geometry and rerun pov_superellipsoid_define() function
with the new parameters"""
Maurice Raybaud
committed
bl_idname = "pov.superellipsoid_update"
bl_label = "Update"
bl_description = "Update Superellipsoid"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
ob = context.object
return ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES
Maurice Raybaud
committed
def execute(self, context):
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.reveal()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete(type='VERT')
bpy.ops.object.mode_set(mode="OBJECT")
pov_superellipsoid_define(context, None, context.object)
return {'FINISHED'}
def create_faces(vert_idx_1, vert_idx_2, closed=False, flipped=False):
"""Generate viewport proxy mesh data for some pov primitives"""
Maurice Raybaud
committed
faces = []
Maurice Raybaud
committed
return None
Maurice Raybaud
committed
return None
fan = False
if len(vert_idx_1) != len(vert_idx_2):
if len(vert_idx_1) == 1 and len(vert_idx_2) > 1:
Maurice Raybaud
committed
fan = True
else:
return None
Maurice Raybaud
committed
if closed:
if flipped:
face = [vert_idx_1[0], vert_idx_2[0], vert_idx_2[total - 1]]
Maurice Raybaud
committed
if not fan:
Maurice Raybaud
committed
faces.append(face)
else:
Maurice Raybaud
committed
if not fan:
face.append(vert_idx_1[total - 1])
face.append(vert_idx_2[total - 1])
Maurice Raybaud
committed
faces.append(face)
for num in range(total - 1):
if flipped:
if fan:
face = [vert_idx_2[num], vert_idx_1[0], vert_idx_2[num + 1]]
Maurice Raybaud
committed
else:
face = [vert_idx_2[num], vert_idx_1[num], vert_idx_1[num + 1], vert_idx_2[num + 1]]
Maurice Raybaud
committed
faces.append(face)
else:
if fan:
face = [vert_idx_1[0], vert_idx_2[num], vert_idx_2[num + 1]]
Maurice Raybaud
committed
else:
face = [vert_idx_1[num], vert_idx_2[num], vert_idx_2[num + 1], vert_idx_1[num + 1]]
Maurice Raybaud
committed
faces.append(face)
return faces
"""Workaround to negative a, where the math.pow() method would return a ValueError."""
Maurice Raybaud
committed
if a < 0:
return -((-a) ** b)
return a ** b
def supertoroid(R, r, u, v, n1, n2):
a = 2 * pi / u
b = 2 * pi / v
Maurice Raybaud
committed
verts = []
faces = []
for i in range(u):
s = power(sin(i * a), n1)
c = power(cos(i * a), n1)
Maurice Raybaud
committed
for j in range(v):
c2 = R + r * power(cos(j * b), n2)
s2 = r * power(sin(j * b), n2)
verts.append((c * c2, s * c2, s2)) # type as a (mathutils.Vector(c*c2,s*c2,s2))?
Maurice Raybaud
committed
if i > 0:
f = create_faces(range((i - 1) * v, i * v), range(i * v, (i + 1) * v), closed=True)
Maurice Raybaud
committed
faces.extend(f)
f = create_faces(range((u - 1) * v, u * v), range(v), closed=True)
Maurice Raybaud
committed
faces.extend(f)
return verts, faces
"""Get POV supertorus properties from operator (object creation/import) or data update."""
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
if op:
mesh = None
st_R = op.st_R
st_r = op.st_r
st_u = op.st_u
st_v = op.st_v
st_n1 = op.st_n1
st_n2 = op.st_n2
st_ie = op.st_ie
st_edit = op.st_edit
else:
assert ob
mesh = ob.data
st_R = ob.pov.st_major_radius
st_r = ob.pov.st_minor_radius
st_u = ob.pov.st_u
st_v = ob.pov.st_v
st_n1 = ob.pov.st_ring
st_n2 = ob.pov.st_cross
st_ie = ob.pov.st_ie
st_edit = ob.pov.st_edit
if st_ie:
rad1 = (st_R + st_r) / 2
rad2 = (st_R - st_r) / 2
if rad2 > rad1:
[rad1, rad2] = [rad2, rad1]
else:
rad1 = st_R
rad2 = st_r
if rad2 > rad1:
rad1 = rad2
verts, faces = supertoroid(rad1, rad2, st_u, st_v, st_n1, st_n2)
mesh = pov_define_mesh(mesh, verts, [], faces, "PovSuperTorus", True)
if not ob:
ob = object_data_add(context, mesh, operator=None)
ob.pov.object_as = 'SUPERTORUS'
ob.pov.st_major_radius = st_R
ob.pov.st_minor_radius = st_r
ob.pov.st_u = st_u
ob.pov.st_v = st_v
ob.pov.st_ring = st_n1
ob.pov.st_cross = st_n2
ob.pov.st_ie = st_ie
ob.pov.st_edit = st_edit
Maurice Raybaud
committed
class POVRAY_OT_supertorus_add(Operator):
"""Add the representation of POV supertorus using the pov_supertorus_define() function."""
Maurice Raybaud
committed
bl_idname = "pov.addsupertorus"
bl_label = "Add Supertorus"
bl_description = "Create a SuperTorus"
bl_options = {'REGISTER', 'UNDO'}
st_R: FloatProperty(
name="big radius",
description="The radius inside the tube",
default=1.0,
min=0.01,
max=100.0,
)
st_r: FloatProperty(
name="small radius", description="The radius of the tube", default=0.3, min=0.01, max=100.0
)
st_u: IntProperty(
name="U-segments", description="radial segmentation", default=16, min=3, max=265
)
st_v: IntProperty(
name="V-segments", description="lateral segmentation", default=8, min=3, max=265
)
st_n1: FloatProperty(
name="Ring manipulator",
description="Manipulates the shape of the Ring",
default=1.0,
min=0.01,
max=100.0,
)
st_n2: FloatProperty(
name="Cross manipulator",
description="Manipulates the shape of the cross-section",
default=1.0,
min=0.01,
max=100.0,
)
st_ie: BoolProperty(
name="Use Int.+Ext. radii", description="Use internal and external radii", default=False
st_edit: BoolProperty(name="", description="", default=False, options={'HIDDEN'})
Maurice Raybaud
committed
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
return engine in cls.COMPAT_ENGINES
Maurice Raybaud
committed
def execute(self, context):
pov_supertorus_define(context, self, None)
{'INFO'}, "This native POV-Ray primitive" "won't have any vertex to show in edit mode"
Maurice Raybaud
committed
class POVRAY_OT_supertorus_update(Operator):
"""Update the supertorus.
Delete its previous proxy geometry and rerun pov_supetorus_define() function
with the new parameters"""
Maurice Raybaud
committed
bl_idname = "pov.supertorus_update"
bl_label = "Update"
bl_description = "Update SuperTorus"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
ob = context.object
return ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES
Maurice Raybaud
committed
def execute(self, context):
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.reveal()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete(type='VERT')
bpy.ops.object.mode_set(mode="OBJECT")
pov_supertorus_define(context, None, context.object)
return {'FINISHED'}
# -----------------------------------------------------------------------------
class POVRAY_OT_loft_add(Operator):
"""Create the representation of POV loft using Blender curves."""
Maurice Raybaud
committed
bl_idname = "pov.addloft"
bl_label = "Add Loft Data"
bl_description = "Create a Curve data for Meshmaker"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
name="Segments", description="Vertical segments", default=16, min=3, max=720
)
loft_rings_bottom: IntProperty(
name="Bottom", description="Bottom rings", default=5, min=2, max=100
)
loft_rings_side: IntProperty(name="Side", description="Side rings", default=10, min=2, max=100)
loft_thick: FloatProperty(
name="Thickness",
description="Manipulates the shape of the Ring",
default=0.3,
min=0.01,
max=1.0,
)
loft_r: FloatProperty(name="Radius", description="Radius", default=1, min=0.01, max=10)
loft_height: FloatProperty(
name="Height",
description="Manipulates the shape of the Ring",
default=2,
min=0.01,
max=10.0,
)
def execute(self, context):
Maurice Raybaud
committed
props = self.properties
loft_data = bpy.data.curves.new('Loft', type='CURVE')
loft_data.dimensions = '3D'
loft_data.resolution_u = 2
# loft_data.show_normal_face = False # deprecated in 2.8
Maurice Raybaud
committed
thick = props.loft_thick
side = props.loft_rings_side
bottom = props.loft_rings_bottom
h = props.loft_height
r = props.loft_r
Maurice Raybaud
committed
r0 = 0.00001
Maurice Raybaud
committed
print("New")
for i in range(bottom + 1):
Maurice Raybaud
committed
coords = []
angle = 0
for p in range(n):
x = r0 * cos(angle)
y = r0 * sin(angle)
coords.append((x, y, z))
angle += pi * 2 / n
r0 += distB
nurbs.points.add(len(coords) - 1)
Maurice Raybaud
committed
nurbs.use_cyclic_u = True
for i in range(side):
Maurice Raybaud
committed
coords = []
angle = 0
for p in range(n):
x = r * cos(angle)
y = r * sin(angle)
coords.append((x, y, z))
angle += pi * 2 / n
nurbs.points.add(len(coords) - 1)
Maurice Raybaud
committed
nurbs.use_cyclic_u = True
Maurice Raybaud
committed
for i in range(side):
coords = []
angle = 0
for p in range(n):
x = r * cos(angle)
y = r * sin(angle)
coords.append((x, y, z))
angle += pi * 2 / n
nurbs.points.add(len(coords) - 1)
Maurice Raybaud
committed
nurbs.use_cyclic_u = True
z -= h / side
z = (-h / 2) + thick
distB = (r - 0.00001) / bottom
for i in range(bottom + 1):
Maurice Raybaud
committed
coords = []
angle = 0
for p in range(n):
x = r * cos(angle)
y = r * sin(angle)
coords.append((x, y, z))
angle += pi * 2 / n
r -= distB
nurbs.points.add(len(coords) - 1)
Maurice Raybaud
committed
nurbs.use_cyclic_u = True
ob = bpy.data.objects.new('Loft_shape', loft_data)
Maurice Raybaud
committed
scn = bpy.context.scene
Maurice Raybaud
committed
ob.pov.curveshape = "loft"
return {'FINISHED'}
class POVRAY_OT_plane_add(Operator):
"""Add the representation of POV infinite plane using just a very big Blender Plane.
Flag its primitive type with a specific pov.object_as attribute and lock edit mode
to keep proxy consistency by hiding edit geometry."""
Maurice Raybaud
committed
bl_idname = "pov.addplane"
bl_label = "Plane"
bl_description = "Add Plane"
bl_options = {'REGISTER', 'UNDO'}
Maurice Raybaud
committed
COMPAT_ENGINES = {'POVRAY_RENDER'}
Maurice Raybaud
committed
def execute(self, context):
# layers = 20*[False]
# layers[0] = True
Maurice Raybaud
committed
bpy.ops.mesh.primitive_plane_add(size=10000)
Maurice Raybaud
committed
ob = context.object
ob.name = ob.data.name = 'PovInfinitePlane'
bpy.ops.object.mode_set(mode="EDIT")
{'INFO'}, "This native POV-Ray primitive " "won't have any vertex to show in edit mode"
Maurice Raybaud
committed
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
bpy.ops.object.shade_smooth()
ob.pov.object_as = "PLANE"
return {'FINISHED'}
class POVRAY_OT_box_add(Operator):
"""Add the representation of POV box using a simple Blender mesh cube.
Flag its primitive type with a specific pov.object_as attribute and lock edit mode
to keep proxy consistency by hiding edit geometry."""
Maurice Raybaud
committed
bl_idname = "pov.addbox"
bl_label = "Box"
bl_description = "Add Box"
bl_options = {'REGISTER', 'UNDO'}
Maurice Raybaud
committed
COMPAT_ENGINES = {'POVRAY_RENDER'}
Maurice Raybaud
committed
def execute(self, context):
# layers = 20*[False]
# layers[0] = True
bpy.ops.mesh.primitive_cube_add()
Maurice Raybaud
committed
ob = context.object
ob.name = ob.data.name = 'PovBox'
bpy.ops.object.mode_set(mode="EDIT")
{'INFO'}, "This native POV-Ray primitive " "won't have any vertex to show in edit mode"
Maurice Raybaud
committed
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
ob.pov.object_as = "BOX"
return {'FINISHED'}
Maurice Raybaud
committed
def pov_cylinder_define(context, op, ob, radius, loc, loc_cap):
"""Pick POV cylinder properties either from creation operator, import, or data update """
Maurice Raybaud
committed
if op:
R = op.R
loc = bpy.context.scene.cursor.location
Maurice Raybaud
committed
loc_cap[0] = loc[0]
loc_cap[1] = loc[1]
loc_cap[2] = loc[2] + 2
Maurice Raybaud
committed
vec = Vector(loc_cap) - Vector(loc)
depth = vec.length
rot = Vector((0, 0, 1)).rotation_difference(vec) # Rotation from Z axis.
trans = rot @ Vector(
(0, 0, depth / 2)
) # Such that origin is at center of the base of the cylinder.
Maurice Raybaud
committed
roteuler = rot.to_euler()
if not ob:
bpy.ops.object.add(type='MESH', location=loc)
ob = context.object
ob.name = ob.data.name = "PovCylinder"
ob.pov.cylinder_radius = radius
ob.pov.cylinder_location_cap = vec
ob.pov.object_as = "CYLINDER"
else:
ob.location = loc
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.reveal()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete(type='VERT')
bpy.ops.mesh.primitive_cylinder_add(
radius=radius, depth=depth, location=loc, rotation=roteuler, end_fill_type='NGON'
Maurice Raybaud
committed
bpy.ops.transform.translate(value=trans)
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
bpy.ops.object.shade_smooth()
class POVRAY_OT_cylinder_add(Operator):
"""Add the representation of POV cylinder using pov_cylinder_define() function.
Use imported_cyl_loc when this operator is run by POV importer."""
Maurice Raybaud
committed
bl_idname = "pov.addcylinder"
bl_label = "Cylinder"
bl_description = "Add Cylinder"
bl_options = {'REGISTER', 'UNDO'}
Maurice Raybaud
committed
COMPAT_ENGINES = {'POVRAY_RENDER'}
Maurice Raybaud
committed
# Keep in sync within object_properties.py section Cylinder
# as this allows interactive update
R: FloatProperty(name="Cylinder radius", min=0.00, max=10.0, default=1.0)
Maurice Raybaud
committed
imported_cyl_loc: FloatVectorProperty(
name="Imported Pov base location", precision=6, default=(0.0, 0.0, 0.0)
)
Maurice Raybaud
committed
imported_cyl_loc_cap: FloatVectorProperty(
name="Imported Pov cap location", precision=6, default=(0.0, 0.0, 2.0)
)
Maurice Raybaud
committed
def execute(self, context):
Maurice Raybaud
committed
props = self.properties
R = props.R
# layers = 20*[False]
# layers[0] = True
Maurice Raybaud
committed
if ob:
if ob.pov.imported_cyl_loc:
LOC = ob.pov.imported_cyl_loc
if ob.pov.imported_cyl_loc_cap:
LOC_CAP = ob.pov.imported_cyl_loc_cap
Maurice Raybaud
committed
elif not props.imported_cyl_loc:
LOC_CAP = LOC = bpy.context.scene.cursor.location
LOC_CAP[2] += 2.0
Maurice Raybaud
committed
else:
Maurice Raybaud
committed
LOC = props.imported_cyl_loc
LOC_CAP = props.imported_cyl_loc_cap
self.report(
{'INFO'},
"This native POV-Ray primitive " "won't have any vertex to show in edit mode",
Maurice Raybaud
committed
pov_cylinder_define(context, self, None, self.R, LOC, LOC_CAP)
return {'FINISHED'}
class POVRAY_OT_cylinder_update(Operator):
"""Update the POV cylinder.
Delete its previous proxy geometry and rerun pov_cylinder_define() function
with the new parameters"""
Maurice Raybaud
committed
bl_idname = "pov.cylinder_update"
bl_label = "Update"
bl_description = "Update Cylinder"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
Maurice Raybaud
committed
ob = context.object
return (
ob
and ob.data
and ob.type == 'MESH'
and ob.pov.object_as == "CYLINDER"
and engine in cls.COMPAT_ENGINES
)
Maurice Raybaud
committed
def execute(self, context):
ob = context.object
radius = ob.pov.cylinder_radius
loc = ob.location
loc_cap = loc + ob.pov.cylinder_location_cap
pov_cylinder_define(context, None, ob, radius, loc, loc_cap)
Maurice Raybaud
committed
return {'FINISHED'}
Maurice Raybaud
committed
# ----------------------------------- SPHERE---------------------------------- #
Maurice Raybaud
committed
def pov_sphere_define(context, op, ob, loc):
"""create the representation of POV sphere using a Blender icosphere.
Maurice Raybaud
committed
Its nice platonic solid curvature better represents pov rendertime
tesselation than a UV sphere"""
if op:
R = op.R
loc = bpy.context.scene.cursor.location
else:
# keep object rotation and location for the add object operator
# obloc = ob.location
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.reveal()
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete(type='VERT')
bpy.ops.mesh.primitive_ico_sphere_add(
subdivisions=4, radius=ob.pov.sphere_radius, location=loc, rotation=obrot
)
# bpy.ops.transform.rotate(axis=obrot,orient_type='GLOBAL')
# bpy.ops.transform.rotate(axis=obrot, proportional_size=1)
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
bpy.ops.object.shade_smooth()
# bpy.ops.transform.rotate(axis=obrot,orient_type='GLOBAL')
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=R, location=loc)
ob.name = ob.data.name = "PovSphere"
ob.pov.object_as = "SPHERE"
ob.pov.sphere_radius = R
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
Maurice Raybaud
committed
class POVRAY_OT_sphere_add(Operator):
"""Add the representation of POV sphere using pov_sphere_define() function.
Use imported_loc when this operator is run by POV importer."""
Maurice Raybaud
committed
bl_idname = "pov.addsphere"
bl_label = "Sphere"
bl_description = "Add Sphere Shape"
bl_options = {'REGISTER', 'UNDO'}
Maurice Raybaud
committed
COMPAT_ENGINES = {'POVRAY_RENDER'}
Maurice Raybaud
committed
# Keep in sync within object_properties.py section Sphere
# as this allows interactive update
R: FloatProperty(name="Sphere radius", min=0.00, max=10.0, default=0.5)
imported_loc: FloatVectorProperty(
name="Imported Pov location", precision=6, default=(0.0, 0.0, 0.0)
)
def execute(self, context):
Maurice Raybaud
committed
props = self.properties
R = props.R
ob = context.object
Maurice Raybaud
committed
if ob:
if ob.pov.imported_loc:
LOC = ob.pov.imported_loc
Maurice Raybaud
committed
elif not props.imported_loc:
LOC = bpy.context.scene.cursor.location
Maurice Raybaud
committed
else:
LOC = props.imported_loc
self.report(
{'INFO'},
"This native POV-Ray primitive " "won't have any vertex to show in edit mode",
)
Maurice Raybaud
committed
pov_sphere_define(context, self, None, LOC)
Maurice Raybaud
committed
Maurice Raybaud
committed
return {'FINISHED'}
Maurice Raybaud
committed
# def execute(self,context):
# layers = 20*[False]
# layers[0] = True
# bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=ob.pov.sphere_radius)
# ob = context.object
# bpy.ops.object.mode_set(mode="EDIT")
# self.report({'INFO'}, "This native POV-Ray primitive "
# "won't have any vertex to show in edit mode")
# bpy.ops.mesh.hide(unselected=False)
# bpy.ops.object.mode_set(mode="OBJECT")
# bpy.ops.object.shade_smooth()
# ob.pov.object_as = "SPHERE"
# ob.name = ob.data.name = 'PovSphere'
# return {'FINISHED'}
class POVRAY_OT_sphere_update(Operator):
"""Update the POV sphere.
Delete its previous proxy geometry and rerun pov_sphere_define() function
with the new parameters"""
Maurice Raybaud
committed
bl_idname = "pov.sphere_update"
bl_label = "Update"
bl_description = "Update Sphere"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
ob = context.object
return ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES
Maurice Raybaud
committed
def execute(self, context):
pov_sphere_define(context, None, context.object, context.object.location)
Maurice Raybaud
committed
Maurice Raybaud
committed
# ----------------------------------- CONE ---------------------------------- #
Maurice Raybaud
committed
def pov_cone_define(context, op, ob):
"""Add the representation of POV cone using pov_define_mesh() function.
Blender cone does not offer the same features such as a second radius."""
Maurice Raybaud
committed
verts = []
faces = []
if op:
mesh = None
base = op.base
cap = op.cap
seg = op.seg
height = op.height
else:
Maurice Raybaud
committed
mesh = ob.data
base = ob.pov.cone_base_radius
cap = ob.pov.cone_cap_radius
seg = ob.pov.cone_segments