Newer
Older
Maurice Raybaud
committed
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
zc = height / 2
zb = -zc
angle = 2 * pi / seg
t = 0
for i in range(seg):
xb = base * cos(t)
yb = base * sin(t)
xc = cap * cos(t)
yc = cap * sin(t)
verts.append((xb, yb, zb))
verts.append((xc, yc, zc))
t += angle
for i in range(seg):
f = i * 2
if i == seg - 1:
faces.append([0, 1, f + 1, f])
else:
faces.append([f + 2, f + 3, f + 1, f])
if base != 0:
base_face = []
for i in range(seg - 1, -1, -1):
p = i * 2
base_face.append(p)
faces.append(base_face)
if cap != 0:
cap_face = []
for i in range(seg):
p = i * 2 + 1
cap_face.append(p)
faces.append(cap_face)
mesh = pov_define_mesh(mesh, verts, [], faces, "PovCone", True)
if not ob:
ob = object_data_add(context, mesh, operator=None)
Maurice Raybaud
committed
ob.pov.object_as = "CONE"
ob.pov.cone_base_radius = base
ob.pov.cone_cap_radius = cap
ob.pov.cone_height = height
ob.pov.cone_base_z = zb
ob.pov.cone_cap_z = zc
class POVRAY_OT_cone_add(Operator):
"""Add the representation of POV cone using pov_cone_define() function."""
Maurice Raybaud
committed
bl_idname = "pov.addcone"
Maurice Raybaud
committed
bl_label = "Cone"
bl_description = "Add Cone"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
# Keep in sync within object_properties.py section Cone
Maurice Raybaud
committed
# If someone knows how to define operators' props from a func, I'd be delighted to learn it!
name="Base radius",
description="The first radius of the cone",
default=1.0,
min=0.01,
max=100.0,
)
name="Cap radius",
description="The second radius of the cone",
default=0.3,
min=0.0,
max=100.0,
)
name="Segments",
description="Radial segmentation of the proxy mesh",
default=16,
min=3,
max=265,
)
name="Height", description="Height of the cone", default=2.0, min=0.01, max=100.0
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_cone_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_cone_update(Operator):
"""Update the POV cone.
Delete its previous proxy geometry and rerun pov_cone_define() function
with the new parameters"""
Maurice Raybaud
committed
bl_idname = "pov.cone_update"
bl_label = "Update"
bl_description = "Update Cone"
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_cone_define(context, None, context.object)
return {'FINISHED'}
# ----------------------------------- ISOSURFACES ----------------------------------- #
Maurice Raybaud
committed
Maurice Raybaud
committed
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
def pov_isosurface_view_define(context, op, ob, loc):
"""create the representation of POV isosurface using a Blender empty."""
if op:
eq = op.isosurface_eq
loc = bpy.context.scene.cursor.location
else:
assert ob
eq = ob.pov.isosurface_eq
# keep object rotation and location for the add object operator
obrot = ob.rotation_euler
# obloc = ob.location
obscale = ob.scale
#bpy.ops.object.empty_add(type='CUBE', location=loc, rotation=obrot)
bpy.ops.mesh.primitive_emptyvert_add()
# bpy.ops.transform.rotate(axis=obrot,orient_type='GLOBAL')
bpy.ops.transform.resize(value=obscale)
# bpy.ops.transform.rotate(axis=obrot, proportional_size=1)
bpy.ops.object.mode_set(mode="OBJECT")
if not ob:
#bpy.ops.object.empty_add(type='CUBE', location=loc)
bpy.ops.mesh.primitive_emptyvert_add()
ob = context.object
ob.name = ob.data.name = "PovIsosurface"
ob.pov.object_as = "ISOSURFACE_VIEW"
ob.pov.isosurface_eq = eq
ob.pov.contained_by = 'box'
bpy.ops.object.mode_set(mode="OBJECT")
class POVRAY_OT_isosurface_add(Operator):
"""Add the representation of POV isosurface sphere by a Blender mesh icosphere.
Flag its primitive type with a specific pov.object_as attribute and lock edit mode
to keep proxy consistency by hiding edit geometry."""
bl_idname = "pov.addisosurface"
bl_label = "Generic Isosurface"
bl_description = "Add Isosurface"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
# Keep in sync within object_properties.py section Sphere
# as this allows interactive update
isosurface_eq: StringProperty(
name="f(x,y,z)=",
description="Type the POV Isosurface function syntax for equation, "
"pattern,etc. ruling an implicit surface to be rendered",
default="sqrt(pow(x,2) + pow(y,2) + pow(z,2)) - 1.5",
)
imported_loc: FloatVectorProperty(
name="Imported Pov location", precision=6, default=(0.0, 0.0, 0.0)
)
def execute(self, context):
# layers = 20*[False]
# layers[0] = True
props = self.properties
ob = context.object
if ob:
if ob.pov.imported_loc:
LOC = ob.pov.imported_loc
elif not props.imported_loc:
LOC = bpy.context.scene.cursor.location
else:
LOC = props.imported_loc
pov_isosurface_view_define(context, self, None, LOC)
self.report(
{'INFO'}, "This native POV-Ray primitive " "is only an abstract proxy in Blender"
)
return {'FINISHED'}
class POVRAY_OT_isosurface_update(Operator):
"""Update the POV isosurface.
Rerun pov_isosurface_view_define() function
with the new parameters"""
bl_idname = "pov.isosurface_update"
bl_label = "Update"
bl_description = "Update Isosurface"
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 == 'ISOSURFACE_VIEW' and engine in cls.COMPAT_ENGINES
def execute(self, context):
pov_isosurface_view_define(context, None, context.object, context.object.location)
return {'FINISHED'}
class POVRAY_OT_isosurface_box_add(Operator):
"""Add the representation of POV isosurface box using also just a 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.addisosurfacebox"
bl_label = "Isosurface Box"
bl_description = "Add Isosurface contained by 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
Maurice Raybaud
committed
ob = context.object
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")
Maurice Raybaud
committed
ob.pov.object_as = "ISOSURFACE_NODE"
Maurice Raybaud
committed
ob.pov.contained_by = 'box'
ob.name = 'PovIsosurfaceBox'
Maurice Raybaud
committed
return {'FINISHED'}
class POVRAY_OT_isosurface_sphere_add(Operator):
"""Add the representation of POV isosurface sphere by a Blender mesh icosphere.
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.addisosurfacesphere"
bl_label = "Isosurface Sphere"
bl_description = "Add Isosurface contained by Sphere"
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_ico_sphere_add(subdivisions=4)
Maurice Raybaud
committed
ob = context.object
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()
Maurice Raybaud
committed
ob.pov.object_as = "ISOSURFACE_NODE"
Maurice Raybaud
committed
ob.pov.contained_by = 'sphere'
ob.name = 'PovIsosurfaceSphere'
Maurice Raybaud
committed
return {'FINISHED'}
class POVRAY_OT_sphere_sweep_add(Operator):
"""Add the representation of POV sphere_sweep using a Blender NURBS curve.
Flag its primitive type with a specific ob.pov.curveshape attribute and
leave access to edit mode to keep user editable handles."""
Maurice Raybaud
committed
bl_idname = "pov.addspheresweep"
bl_label = "Sphere Sweep"
bl_description = "Create Sphere Sweep along curve"
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
ob = context.object
ob.name = ob.data.name = "PovSphereSweep"
ob.pov.curveshape = "sphere_sweep"
ob.data.bevel_depth = 0.02
ob.data.bevel_resolution = 4
ob.data.fill_mode = 'FULL'
# ob.data.splines[0].order_u = 4
Maurice Raybaud
committed
return {'FINISHED'}
Maurice Raybaud
committed
class POVRAY_OT_blobsphere_add(Operator):
"""Add the representation of POV blob using a Blender meta ball.
No need to flag its primitive type as meta are exported to blobs
and leave access to edit mode to keep user editable thresholds."""
Maurice Raybaud
committed
bl_idname = "pov.addblobsphere"
bl_label = "Blob Sphere"
bl_description = "Add Blob Sphere"
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.object.metaball_add(type='BALL')
Maurice Raybaud
committed
ob = context.object
ob.name = "PovBlob"
Maurice Raybaud
committed
return {'FINISHED'}
Maurice Raybaud
committed
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
class POVRAY_OT_blobcapsule_add(Operator):
"""Add the representation of POV blob using a Blender meta ball.
No need to flag its primitive type as meta are exported to blobs
and leave access to edit mode to keep user editable thresholds."""
bl_idname = "pov.addblobcapsule"
bl_label = "Blob Capsule"
bl_description = "Add Blob Capsule"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
def execute(self, context):
# layers = 20*[False]
# layers[0] = True
bpy.ops.object.metaball_add(type='CAPSULE')
ob = context.object
ob.name = "PovBlob"
return {'FINISHED'}
class POVRAY_OT_blobplane_add(Operator):
"""Add the representation of POV blob using a Blender meta ball.
No need to flag its primitive type as meta are exported to blobs
and leave access to edit mode to keep user editable thresholds."""
bl_idname = "pov.addblobplane"
bl_label = "Blob Plane"
bl_description = "Add Blob Plane"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
def execute(self, context):
# layers = 20*[False]
# layers[0] = True
bpy.ops.object.metaball_add(type='PLANE')
ob = context.object
ob.name = "PovBlob"
return {'FINISHED'}
class POVRAY_OT_blobellipsoid_add(Operator):
"""Add the representation of POV blob using a Blender meta ball.
No need to flag its primitive type as meta are exported to blobs
and leave access to edit mode to keep user editable thresholds."""
bl_idname = "pov.addblobellipsoid"
bl_label = "Blob Ellipsoid"
bl_description = "Add Blob Ellipsoid"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
# layers = 20*[False]
# layers[0] = True
bpy.ops.object.metaball_add(type='ELLIPSOID')
ob = context.object
ob.name = "PovBlob"
return {'FINISHED'}
class POVRAY_OT_blobcube_add(Operator):
"""Add the representation of POV blob using a Blender meta ball.
No need to flag its primitive type as meta are exported to blobs
and leave access to edit mode to keep user editable thresholds."""
bl_idname = "pov.addblobcube"
bl_label = "Blob Cube"
bl_description = "Add Blob Cube"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
def execute(self, context):
# layers = 20*[False]
# layers[0] = True
bpy.ops.object.metaball_add(type='CUBE')
ob = context.object
ob.name = "PovBlob"
return {'FINISHED'}
class POVRAY_OT_rainbow_add(Operator):
"""Add the representation of POV rainbow using a Blender spot light.
Rainbows indeed propagate along a visibility cone.
Flag its primitive type with a specific ob.pov.object_as attribute
and leave access to edit mode to keep user editable handles.
Add a constraint to orient it towards camera because POV Rainbows
are view dependant and having it always initially visible is less
confusing """
Maurice Raybaud
committed
bl_idname = "pov.addrainbow"
bl_label = "Rainbow"
bl_description = "Add Rainbow"
bl_options = {'REGISTER', 'UNDO'}
Maurice Raybaud
committed
COMPAT_ENGINES = {'POVRAY_RENDER'}
def execute(self, context):
Maurice Raybaud
committed
cam = context.scene.camera
bpy.ops.object.light_add(type='SPOT', radius=1)
Maurice Raybaud
committed
ob = context.object
ob.data.show_cone = False
ob.data.spot_blend = 0.5
# ob.data.shadow_buffer_clip_end = 0 # deprecated in 2.8
ob.data.shadow_buffer_clip_start = 4 * cam.location.length
Maurice Raybaud
committed
ob.data.distance = cam.location.length
Maurice Raybaud
committed
ob.name = ob.data.name = "PovRainbow"
ob.pov.object_as = "RAINBOW"
# obj = context.object
Maurice Raybaud
committed
bpy.ops.object.constraint_add(type='DAMPED_TRACK')
ob.constraints["Damped Track"].target = cam
ob.constraints["Damped Track"].track_axis = 'TRACK_NEGATIVE_Z'
ob.location = -cam.location
# refocus on the actual rainbow
bpy.context.view_layer.objects.active = ob
Maurice Raybaud
committed
return {'FINISHED'}
Maurice Raybaud
committed
class POVRAY_OT_height_field_add(bpy.types.Operator, ImportHelper):
"""Add the representation of POV height_field using a displaced grid.
texture slot fix and displace modifier will be needed because noise
displace operator was deprecated in 2.8"""
Maurice Raybaud
committed
bl_idname = "pov.addheightfield"
bl_label = "Height Field"
bl_description = "Add Height Field"
Maurice Raybaud
committed
bl_options = {'REGISTER', 'UNDO'}
Maurice Raybaud
committed
COMPAT_ENGINES = {'POVRAY_RENDER'}
# Keep in sync within object_properties.py section HeightFields
# as this allows interactive update
Maurice Raybaud
committed
# filename_ext = ".png"
Maurice Raybaud
committed
# filter_glob = StringProperty(
# default="*.exr;*.gif;*.hdr;*.iff;*.jpeg;*.jpg;*.pgm;*.png;*.pot;*.ppm;*.sys;*.tga;*.tiff;*.EXR;*.GIF;*.HDR;*.IFF;*.JPEG;*.JPG;*.PGM;*.PNG;*.POT;*.PPM;*.SYS;*.TGA;*.TIFF",
# options={'HIDDEN'},
# )
quality: IntProperty(name="Quality", description="", default=100, min=1, max=100)
hf_filename: StringProperty(maxlen=1024)
hf_gamma: FloatProperty(name="Gamma", description="Gamma", min=0.0001, max=20.0, default=1.0)
Maurice Raybaud
committed
hf_premultiplied: BoolProperty(name="Premultiplied", description="Premultiplied", default=True)
Maurice Raybaud
committed
hf_smooth: BoolProperty(name="Smooth", description="Smooth", default=False)
Maurice Raybaud
committed
name="Water Level", description="Wather Level", min=0.00, max=1.00, default=0.0
Maurice Raybaud
committed
hf_hierarchy: BoolProperty(name="Hierarchy", description="Height field hierarchy", default=True)
def execute(self, context):
Maurice Raybaud
committed
props = self.properties
impath = bpy.path.abspath(self.filepath)
img = bpy.data.images.load(impath)
im_name = img.name
im_name, file_extension = os.path.splitext(im_name)
hf_tex = bpy.data.textures.new('%s_hf_image' % im_name, type='IMAGE')
Maurice Raybaud
committed
hf_tex.image = img
mat = bpy.data.materials.new('Tex_%s_hf' % im_name)
hf_slot = mat.pov_texture_slots.add()
hf_slot.texture = hf_tex.name
# layers = 20*[False]
# layers[0] = True
Maurice Raybaud
committed
quality = props.quality
res = 100 / quality
w, h = hf_tex.image.size[:]
w = int(w / res)
h = int(h / res)
bpy.ops.mesh.primitive_grid_add(x_subdivisions=w, y_subdivisions=h, size=0.5)
Maurice Raybaud
committed
ob = context.object
ob.name = ob.data.name = '%s' % im_name
Maurice Raybaud
committed
ob.data.materials.append(mat)
bpy.ops.object.mode_set(mode="EDIT")
# bpy.ops.mesh.noise(factor=1) # TODO replace by displace modifier, noise deprecated in 2.8
Maurice Raybaud
committed
bpy.ops.object.mode_set(mode="OBJECT")
# needs a loop to select by index?
# bpy.ops.object.material_slot_remove()
# material just left there for now
Maurice Raybaud
committed
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
ob.pov.object_as = 'HEIGHT_FIELD'
# POV-Ray will soon use only forwards slashes on every OS and already can
forward_impath = impath.replace(os.sep, '/')
ob.pov.hf_filename = forward_impath
Maurice Raybaud
committed
return {'FINISHED'}
# ----------------------------------- TORUS ----------------------------------- #
Maurice Raybaud
committed
def pov_torus_define(context, op, ob):
"""Add the representation of POV torus using just a Blender torus.
Picking properties either from creation operator, import, or data update.
But flag its primitive type with a specific pov.object_as attribute and lock edit mode
to keep proxy consistency by hiding edit geometry."""
if op:
mas = op.mas
mis = op.mis
mar = op.mar
mir = op.mir
else:
mas = ob.pov.torus_major_segments
mis = ob.pov.torus_minor_segments
mar = ob.pov.torus_major_radius
mir = ob.pov.torus_minor_radius
# keep object rotation and location for the add object operator
obrot = ob.rotation_euler
obloc = ob.location
Maurice Raybaud
committed
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_torus_add(
rotation=obrot,
location=obloc,
major_segments=mas,
minor_segments=mis,
major_radius=mar,
minor_radius=mir,
)
Maurice Raybaud
committed
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
if not ob:
bpy.ops.mesh.primitive_torus_add(
major_segments=mas, minor_segments=mis, major_radius=mar, minor_radius=mir
ob.name = ob.data.name = "PovTorus"
ob.pov.object_as = "TORUS"
ob.pov.torus_major_segments = mas
ob.pov.torus_minor_segments = mis
ob.pov.torus_major_radius = mar
ob.pov.torus_minor_radius = mir
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
class POVRAY_OT_torus_add(Operator):
"""Add the representation of POV torus using using pov_torus_define() function."""
Maurice Raybaud
committed
bl_idname = "pov.addtorus"
bl_label = "Torus"
bl_description = "Add Torus"
bl_options = {'REGISTER', 'UNDO'}
Maurice Raybaud
committed
COMPAT_ENGINES = {'POVRAY_RENDER'}
# Keep in sync within object_properties.py section Torus
# as this allows interactive update
mas: IntProperty(name="Major Segments", description="", default=48, min=3, max=720)
mis: IntProperty(name="Minor Segments", description="", default=12, min=3, max=720)
mar: FloatProperty(name="Major Radius", description="", default=1.0)
mir: FloatProperty(name="Minor Radius", description="", default=0.25)
def execute(self, context):
Maurice Raybaud
committed
props = self.properties
mar = props.mar
mir = props.mir
mas = props.mas
mis = props.mis
pov_torus_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_torus_update(Operator):
"""Update the POV torus.
Delete its previous proxy geometry and rerun pov_torus_define() function
with the new parameters"""
Maurice Raybaud
committed
bl_idname = "pov.torus_update"
bl_label = "Update"
bl_description = "Update Torus"
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_torus_define(context, None, context.object)
# -----------------------------------------------------------------------------
Maurice Raybaud
committed
class POVRAY_OT_prism_add(Operator):
"""Add the representation of POV prism using using an extruded curve."""
Maurice Raybaud
committed
bl_idname = "pov.addprism"
bl_label = "Prism"
bl_description = "Create Prism"
bl_options = {'REGISTER', 'UNDO'}
Maurice Raybaud
committed
COMPAT_ENGINES = {'POVRAY_RENDER'}
prism_n: IntProperty(name="Sides", description="Number of sides", default=5, min=3, max=720)
prism_r: FloatProperty(name="Radius", description="Radius", default=1.0)
def execute(self, context):
Maurice Raybaud
committed
props = self.properties
loft_data = bpy.data.curves.new('Prism', type='CURVE')
loft_data.dimensions = '2D'
loft_data.resolution_u = 2
# loft_data.show_normal_face = False
loft_data.extrude = 2
n = props.prism_n
r = props.prism_r
Maurice Raybaud
committed
coords = []
z = 0
angle = 0
for p in range(n):
x = r * cos(angle)
y = r * sin(angle)
coords.append((x, y, z))
angle += pi * 2 / n
poly.points.add(len(coords) - 1)
Maurice Raybaud
committed
for i, coord in enumerate(coords):
Maurice Raybaud
committed
poly.points[i].co = (x, y, z, 1)
poly.use_cyclic_u = True
ob = bpy.data.objects.new('Prism_shape', loft_data)
Maurice Raybaud
committed
scn = bpy.context.scene
context.view_layer.objects.active = ob
Maurice Raybaud
committed
ob.pov.curveshape = "prism"
ob.name = ob.data.name = "Prism"
return {'FINISHED'}
# ----------------------------------- PARAMETRIC ----------------------------------- #
"""Add the representation of POV parametric surfaces by math surface from add mesh extra objects addon.
Maurice Raybaud
committed
Picking properties either from creation operator, import, or data update.
But flag its primitive type with a specific pov.object_as attribute and lock edit mode
to keep proxy consistency by hiding edit geometry."""
if op:
u_min = op.u_min
u_max = op.u_max
v_min = op.v_min
v_max = op.v_max
x_eq = op.x_eq
y_eq = op.y_eq
z_eq = op.z_eq
Maurice Raybaud
committed
u_min = ob.pov.u_min
u_max = ob.pov.u_max
v_min = ob.pov.v_min
v_max = ob.pov.v_max
x_eq = ob.pov.x_eq
y_eq = ob.pov.y_eq
z_eq = ob.pov.z_eq
# keep object rotation and location for the updated object
obrot = ob.rotation_euler # In radians
# Parametric addon has no loc rot, some extra work is needed
# in case cursor has moved
Maurice Raybaud
committed
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_xyz_function_surface(
x_eq=x_eq,
y_eq=y_eq,
z_eq=z_eq,
range_u_min=u_min,
range_u_max=u_max,
range_v_min=v_min,
range_v_max=v_max,
)
# extra work:
bpy.ops.transform.translate(value=(obloc - curloc), proportional_size=1)
# XXX TODO : https://devtalk.blender.org/t/bpy-ops-transform-rotate-option-axis/6235/7
# to complete necessary extra work rotation, after updating from blender version > 2.92
# update and uncomment below, but simple axis deprecated since 2.8
# bpy.ops.transform.rotate(axis=obrot, proportional_size=1)
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
if not ob:
bpy.ops.mesh.primitive_xyz_function_surface(
x_eq=x_eq,
y_eq=y_eq,
z_eq=z_eq,
range_u_min=u_min,
range_u_max=u_max,
range_v_min=v_min,
range_v_max=v_max,
)
ob.name = ob.data.name = "PovParametric"
ob.pov.object_as = "PARAMETRIC"
ob.pov.u_min = u_min
ob.pov.u_max = u_max
ob.pov.v_min = v_min
ob.pov.v_max = v_max
ob.pov.x_eq = x_eq
ob.pov.y_eq = y_eq
ob.pov.z_eq = z_eq
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
class POVRAY_OT_parametric_add(Operator):
"""Add the representation of POV parametric surfaces using pov_parametric_define() function."""
Maurice Raybaud
committed
bl_idname = "pov.addparametric"
bl_label = "Parametric"
bl_description = "Add Paramertic"
bl_options = {'REGISTER', 'UNDO'}
Maurice Raybaud
committed
COMPAT_ENGINES = {'POVRAY_RENDER'}
Maurice Raybaud
committed
# Keep in sync within object_properties.py section Parametric primitive
# as this allows interactive update
u_min: FloatProperty(name="U Min", description="", default=0.0)
v_min: FloatProperty(name="V Min", description="", default=0.0)
u_max: FloatProperty(name="U Max", description="", default=6.28)
v_max: FloatProperty(name="V Max", description="", default=12.57)
x_eq: StringProperty(maxlen=1024, default="cos(v)*(1+cos(u))*sin(v/8)")
y_eq: StringProperty(maxlen=1024, default="sin(u)*sin(v/8)+cos(v/8)*1.5")
z_eq: StringProperty(maxlen=1024, default="sin(v)*(1+cos(u))*sin(v/8)")
def execute(self, context):
Maurice Raybaud
committed
props = self.properties
u_min = props.u_min
v_min = props.v_min
u_max = props.u_max
v_max = props.v_max
x_eq = props.x_eq
y_eq = props.y_eq
z_eq = props.z_eq
Maurice Raybaud
committed
try:
pov_parametric_define(context, self, None)
self.report(
{'INFO'}, "This native POV-Ray primitive " "won't have any vertex to show in edit mode"
)
except AttributeError:
self.report(
{'INFO'}, "Please enable Add Mesh: Extra Objects addon"
)
Maurice Raybaud
committed
return {'FINISHED'}
class POVRAY_OT_parametric_update(Operator):
"""Update the representation of POV parametric surfaces.
Delete its previous proxy geometry and rerun pov_parametric_define() function
with the new parameters"""
Maurice Raybaud
committed
bl_idname = "pov.parametric_update"
bl_label = "Update"
bl_description = "Update parametric object"
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_parametric_define(context, None, context.object)
return {'FINISHED'}
# -----------------------------------------------------------------------------
class POVRAY_OT_shape_polygon_to_circle_add(Operator):
"""Add the proxy mesh for POV Polygon to circle lofting macro"""
Maurice Raybaud
committed
bl_idname = "pov.addpolygontocircle"
bl_label = "Polygon To Circle Blending"
bl_description = "Add Polygon To Circle Blending Surface"
bl_options = {'REGISTER', 'UNDO'}
COMPAT_ENGINES = {'POVRAY_RENDER'}
# Keep in sync within object_properties.py section PolygonToCircle properties
# as this allows interactive update
polytocircle_resolution: IntProperty(
name="Resolution", description="", default=3, min=0, max=256
)
polytocircle_ngon: IntProperty(name="NGon", description="", min=3, max=64, default=5)
polytocircle_ngonR: FloatProperty(name="NGon Radius", description="", default=0.3)
polytocircle_circleR: FloatProperty(name="Circle Radius", description="", default=1.0)
def execute(self, context):
Maurice Raybaud
committed
props = self.properties
ngon = props.polytocircle_ngon
ngonR = props.polytocircle_ngonR
circleR = props.polytocircle_circleR
resolution = props.polytocircle_resolution
# layers = 20*[False]
# layers[0] = True
bpy.ops.mesh.primitive_circle_add(
vertices=ngon, radius=ngonR, fill_type='NGON', enter_editmode=True
)
Maurice Raybaud
committed
bpy.ops.transform.translate(value=(0, 0, 1))
bpy.ops.mesh.subdivide(number_cuts=resolution)
numCircleVerts = ngon + (ngon * resolution)
Maurice Raybaud
committed
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.mesh.primitive_circle_add(
vertices=numCircleVerts, radius=circleR, fill_type='NGON', enter_editmode=True
Maurice Raybaud
committed
bpy.ops.transform.translate(value=(0, 0, -1))
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.bridge_edge_loops()
if ngon < 5:
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.mesh.primitive_circle_add(
vertices=ngon, radius=ngonR, fill_type='TRIFAN', enter_editmode=True
Maurice Raybaud
committed
bpy.ops.transform.translate(value=(0, 0, 1))
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.remove_doubles()
bpy.ops.object.mode_set(mode='OBJECT')
ob = context.object
ob.name = "Polygon_To_Circle"
ob.pov.object_as = 'POLYCIRCLE'
ob.pov.ngon = ngon
ob.pov.ngonR = ngonR
ob.pov.circleR = circleR
bpy.ops.object.mode_set(mode="EDIT")
bpy.ops.mesh.hide(unselected=False)
bpy.ops.object.mode_set(mode="OBJECT")
return {'FINISHED'}
classes = (
POVRAY_OT_lathe_add,
POVRAY_OT_superellipsoid_add,
POVRAY_OT_superellipsoid_update,
POVRAY_OT_supertorus_add,
POVRAY_OT_supertorus_update,
POVRAY_OT_loft_add,
POVRAY_OT_plane_add,
POVRAY_OT_box_add,
POVRAY_OT_cylinder_add,
POVRAY_OT_cylinder_update,
POVRAY_OT_sphere_add,
POVRAY_OT_sphere_update,
POVRAY_OT_cone_add,
POVRAY_OT_cone_update,
Maurice Raybaud
committed
POVRAY_OT_isosurface_add,
POVRAY_OT_isosurface_update,
POVRAY_OT_isosurface_box_add,
POVRAY_OT_isosurface_sphere_add,
POVRAY_OT_sphere_sweep_add,
Maurice Raybaud
committed
POVRAY_OT_blobsphere_add,
POVRAY_OT_blobcapsule_add,
POVRAY_OT_blobplane_add,
POVRAY_OT_blobellipsoid_add,
POVRAY_OT_blobcube_add,
POVRAY_OT_rainbow_add,
POVRAY_OT_height_field_add,
POVRAY_OT_torus_add,
POVRAY_OT_torus_update,
POVRAY_OT_prism_add,
POVRAY_OT_parametric_add,
POVRAY_OT_parametric_update,
POVRAY_OT_shape_polygon_to_circle_add,
)
def register():
for cls in classes:
register_class(cls)
def unregister():