Merge branch 'master' into xr-controller-support

This commit is contained in:
Peter Kim 2021-06-11 20:51:51 +09:00
commit 161ee4a5c8
52 changed files with 884 additions and 864 deletions

View File

@ -80,8 +80,7 @@ def convert_old_presets(data_path, msg_data_path, old_preset_subdir,
import os
target_path = os.path.join("presets", old_preset_subdir)
target_path = bpy.utils.user_resource('SCRIPTS',
target_path)
target_path = bpy.utils.user_resource('SCRIPTS', path=target_path)
# created an anytype op to run against preset
op = type('', (), {})()
@ -93,9 +92,7 @@ def convert_old_presets(data_path, msg_data_path, old_preset_subdir,
return None
new_target_path = os.path.join("presets", new_preset_subdir)
new_target_path = bpy.utils.user_resource('SCRIPTS',
new_target_path,
create=True)
new_target_path = bpy.utils.user_resource('SCRIPTS', path=new_target_path, create=True)
for f in files:
file = open(os.path.join(target_path, f))
for line in file:

View File

@ -424,10 +424,11 @@ def menu_funcs(self, context):
layout = self.layout
if bpy.context.view_layer.objects.active.type == "CURVE":
layout.operator("curve.bevelcurve")
layout.operator("curve.tapercurve")
layout.separator()
if context.view_layer.objects.active:
if context.view_layer.objects.active.type == "CURVE":
layout.operator("curve.bevelcurve")
layout.operator("curve.tapercurve")
layout.separator()
# Register
classes = [

View File

@ -259,7 +259,7 @@ class Gl():
return self.get_render_location(context, coord)
region = context.region
rv3d = context.region_data
loc = view3d_utils.location_3d_to_region_2d(region, rv3d, coord, self.pos_2d)
loc = view3d_utils.location_3d_to_region_2d(region, rv3d, coord, default=self.pos_2d)
return Vector(loc)
def get_render_location(self, context, coord):

View File

@ -231,9 +231,7 @@ class MaterialSetManager():
def get_filename(self, object_type):
target_path = os.path.join("presets", "archipack_materials")
target_path = bpy.utils.user_resource('SCRIPTS',
target_path,
create=True)
target_path = bpy.utils.user_resource('SCRIPTS', path=target_path, create=True)
return os.path.join(target_path, object_type) + '.txt'
def cleanup(self):

View File

@ -34,8 +34,8 @@ from .archipack_gl import (
ThumbHandle, Screen, GlRect,
GlPolyline, GlPolygon, GlText, GlHandle
)
preset_paths = bpy.utils.script_paths("presets")
addons_paths = bpy.utils.script_paths("addons")
preset_paths = bpy.utils.script_paths(subdir="presets")
addons_paths = bpy.utils.script_paths(subdir="addons")
class CruxHandle(GlHandle):
@ -570,9 +570,7 @@ class ArchipackPreset(AddPresetBase):
filename = self.as_filename(name)
target_path = os.path.join("presets", self.preset_subdir)
target_path = bpy.utils.user_resource('SCRIPTS',
target_path,
create=True)
target_path = bpy.utils.user_resource('SCRIPTS', path=target_path, create=True)
preset = os.path.join(target_path, filename) + ".py"
cls = self.preset_subdir[10:]

View File

@ -99,9 +99,7 @@ class ARCHIPACK_OT_render_thumbs(Operator):
not f.startswith('.')])
target_path = path.join("presets", category)
presets_path = bpy.utils.user_resource('SCRIPTS',
target_path,
create=True)
presets_path = bpy.utils.user_resource('SCRIPTS', path=target_path, create=True)
# files from factory not found in user doesn't require a recompute
skipfiles = []
for f in file_list:
@ -130,7 +128,7 @@ class ARCHIPACK_OT_render_thumbs(Operator):
skipfiles = self.copy_to_user_path(category)
# load user def presets
preset_paths = bpy.utils.script_paths("presets")
preset_paths = bpy.utils.script_paths(subdir="presets")
for preset in preset_paths:
presets_path = path.join(preset, category)
if path.exists(presets_path):

View File

@ -98,7 +98,7 @@ class BmeshEdit():
private, end bmesh editing of active object
"""
bm.normal_update()
bmesh.update_edit_mesh(o.data, True)
bmesh.update_edit_mesh(o.data, loop_triangles=True)
bpy.ops.object.mode_set(mode='OBJECT')
bm.free()

View File

@ -94,7 +94,7 @@ class BlenderIdProfile(metaclass=_BIPMeta):
def register():
global profiles_path, profiles_file
profiles_path = bpy.utils.user_resource('CONFIG', 'blender_id', create=True)
profiles_path = bpy.utils.user_resource('CONFIG', path='blender_id', create=True)
profiles_file = os.path.join(profiles_path, 'profiles.json')

View File

@ -28,7 +28,7 @@ except Exception:
# global dxfColors
# if dxfColors is None:
# from dxfColorMap import color_map
# dxfColors = [(tuple(color),idx) for idx, color in color_map.iteritems()]
# dxfColors = [(tuple(color),idx) for idx, color in color_map.items()]
# dxfColors.sort()
# entry = (tuple(rgbcolor), -1)
# dxfColors.append(entry)

View File

@ -177,7 +177,7 @@ class UnfoldError(ValueError):
elem.select = False
for elem in chain(*elems.values()):
elem.select_set(True)
bmesh.update_edit_mesh(bpy.context.object.data, False, False)
bmesh.update_edit_mesh(bpy.context.object.data, loop_triangles=False, destructive=False)
class Unfolder:
@ -2269,7 +2269,7 @@ class SelectIsland(bpy.types.Operator):
edge.select = any(face.select for face in edge.link_faces)
for vert in verts:
vert.select = any(edge.select for edge in vert.link_edges)
bmesh.update_edit_mesh(me, False, False)
bmesh.update_edit_mesh(me, loop_triangles=False, destructive=False)
return {'FINISHED'}

View File

@ -1072,7 +1072,7 @@ def list_materials():
return sorted(list)
def get_material(name, link=False):
with bpy.data.libraries.load("{0}", link, False) as (data_from, data_to):
with bpy.data.libraries.load("{0}", link=link, relative=False) as (data_from, data_to):
data_to.materials = [name]
if link:
print(name + " linked.")

View File

@ -3433,8 +3433,7 @@ class Bridge(Operator):
if self.remove_faces and old_selected_faces:
bridge_remove_internal_faces(bm, old_selected_faces)
# make sure normals are facing outside
bmesh.update_edit_mesh(object.data, loop_triangles=False,
destructive=True)
bmesh.update_edit_mesh(object.data, loop_triangles=False, destructive=True)
bpy.ops.mesh.normals_make_consistent()
# cleaning up

View File

@ -65,7 +65,7 @@ def generate_bmesh_repr(p1, v1, axis, num_verts):
idx2 = (i + 1) % num_verts
bm.edges.new([v_refs[idx1], v_refs[idx2]])
bmesh.update_edit_mesh(me, True)
bmesh.update_edit_mesh(me, loop_triangles=True)
def generate_3PT(pts, obj, nv, mode=1):

View File

@ -79,7 +79,7 @@ def extend_vertex(self):
vertex_reference = v1_ref if (A_len < B_len) else v2_ref
bm.edges.new([vertex_reference, new_vertex])
bmesh.update_edit_mesh(me, True)
bmesh.update_edit_mesh(me, loop_triangles=True)
else:
failure_message_on_plane(self)

View File

@ -170,6 +170,6 @@ class TCAutoVTX(bpy.types.Operator):
bm.verts.index_update()
bm.edges.index_update()
bmesh.update_edit_mesh(me, True)
bmesh.update_edit_mesh(me, loop_triangles=True)
return {'FINISHED'}

View File

@ -23,7 +23,7 @@ def bmesh_release(bm, object):
mesh = object.data
bm.select_flush_mode()
if object.mode == 'EDIT':
bmesh.update_edit_mesh(mesh, True)
bmesh.update_edit_mesh(mesh, loop_triangles=True)
else:
bm.to_mesh(mesh)
bm.free()

View File

@ -1213,7 +1213,7 @@ class EdgeRoundifier(Operator):
verticesForDeletion.append(vi)
bmesh.ops.delete(bm, geom=verticesForDeletion, context = 'VERTS')
bmesh.update_edit_mesh(mesh, True)
bmesh.update_edit_mesh(mesh, loop_triangles=True)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')

View File

@ -283,7 +283,7 @@ class MESH_OT_edges_floor_plan(Operator):
if edge.is_boundary:
edge.select = True
bm = bmesh.update_edit_mesh(ob.data, 1, 1)
bm = bmesh.update_edit_mesh(ob.data, loop_triangles=True, destructive=True)
bpy.ops.object.mode_set(mode='OBJECT')
self.solidify_mod(context, ob, wid, offset, self.only_rim)
@ -366,7 +366,7 @@ class MESH_OT_edges_floor_plan(Operator):
if edge.is_boundary:
edge.select = True
bm = bmesh.update_edit_mesh(ob.data, 1, 1)
bm = bmesh.update_edit_mesh(ob.data, loop_triangles=True, destructive=True)
context.tool_settings.mesh_select_mode = store_selection_mode

View File

@ -310,7 +310,7 @@ class LengthSet(Operator):
'\n edge.verts[1].co' + str(verts[1]) +
'\n vector' + str(vector) + '\n v1 > v0:' + str((verts[1] >= verts[0]))
)
bmesh.update_edit_mesh(obj.data, True)
bmesh.update_edit_mesh(obj.data, loop_triangles=True)
return {'FINISHED'}

View File

@ -101,7 +101,7 @@ def solidify_split(self, list_0):
k.select = False
bpy.ops.mesh.normals_make_consistent(inside=False)
bmesh.update_edit_mesh(self.me, True)
bmesh.update_edit_mesh(self.me, loop_triangles=True)
class MESH_OT_split_solidify(Operator):

View File

@ -76,7 +76,7 @@ def bmesh_to_object(obj, bm):
me = obj.data
if obj.mode == 'EDIT':
bmesh.update_edit_mesh(me, True)
bmesh.update_edit_mesh(me, loop_triangles=True)
else:
bm.to_mesh(me)
me.update()

View File

@ -115,7 +115,7 @@ def extend_vertex(context):
vertex_reference = v1_ref if (a_len < b_len) else v2_ref
bm.edges.new([vertex_reference, new_vertex])
bmesh.update_edit_mesh(object_data, True)
bmesh.update_edit_mesh(object_data, loop_triangles=True)
else:
failure_message_on_plane(context)

View File

@ -94,7 +94,7 @@ scripting_gui.py :
Display properties from scripting_properties.py for user to add his custom POV code
scripting.py :
Insert POV native scene description elements to exported POV file
Insert POV native scene description elements into blender scene or to exported POV file
df3_library.py
Render smoke to *.df3 files
@ -214,20 +214,26 @@ else:
scripting_properties,
render,
object_primitives, # for import and export of POV specific primitives
update_files,
)
###############################################################################
# ---------------------------------------------------------------- #
# Auto update.
###############################################################################
# ---------------------------------------------------------------- #
class POV_OT_update_addon(bpy.types.Operator):
"""Update this addon to the latest version."""
bl_idname = "pov.update_addon"
bl_label = "Update POV addon"
def execute(self, context):
import os, tempfile, shutil, urllib.request, urllib.error, zipfile
def execute(self, context): # sourcery no-metrics
import os
import tempfile
import shutil
import urllib.request
import urllib.error
import zipfile
def recursive_overwrite(src, dest, ignore=None):
if os.path.isdir(src):
@ -250,7 +256,8 @@ class POV_OT_update_addon(bpy.types.Operator):
with tempfile.TemporaryDirectory() as temp_dir_path:
temp_zip_path = os.path.join(temp_dir_path, 'master.zip')
# Download zip archive of latest addons master branch commit (So we also get presets)
# Download zip archive of latest addons master branch commit
# More work needed so we also get files from the shared addons presets /pov folder
# switch this URL back to the BF hosted one as soon as gitweb snapshot gets fixed
url = 'https://github.com/blender/blender-addons/archive/refs/heads/master.zip'
try:
@ -303,7 +310,8 @@ class POV_OT_update_addon(bpy.types.Operator):
# TODO: Create backup
# Delete old POV addon files (only directories and *.py files, the user might have other stuff in there!)
# Delete old POV addon files
# (only directories and *.py files, user might have other stuff in there!)
print('Deleting old POV addon files')
# remove __init__.py
os.remove(os.path.join(render_povray_dir, '__init__.py'))
@ -328,9 +336,9 @@ class POV_OT_update_addon(bpy.types.Operator):
return {'FINISHED'}
###############################################################################
# ---------------------------------------------------------------- #
# Povray Preferences.
###############################################################################
# ---------------------------------------------------------------- #
class PovrayPreferences(bpy.types.AddonPreferences):
@ -397,7 +405,10 @@ class PovrayPreferences(bpy.types.AddonPreferences):
layout.operator("pov.update_addon", icon='FILE_REFRESH')
classes = (POV_OT_update_addon, PovrayPreferences)
classes = (
POV_OT_update_addon,
PovrayPreferences,
)
def register():
@ -410,19 +421,15 @@ def register():
texturing_properties.register()
object_properties.register()
scripting_properties.register()
scenography.register()
render.register()
base_ui.register()
scripting.register()
object_primitives.register()
def unregister():
object_primitives.unregister()
scripting.unregister()
base_ui.unregister()
render.unregister()
scenography.unregister()
scripting_properties.unregister()
object_properties.unregister()
texturing_properties.unregister()
@ -437,6 +444,6 @@ def unregister():
if __name__ == "__main__":
register()
# ------------8<---------[ BREAKPOINT ]--------------8<-----------# Move this snippet around
# __import__('code').interact(local=dict(globals(), **locals())) # < and uncomment this line
# ----------------------------------------------------------------# to inspect from Terminal
# ------------8<---------[ BREAKPOINT ]--------------8<----------- # Move this snippet around
# __import__('code').interact(local=dict(globals(), **locals())) # < and uncomment this line
# ---------------------------------------------------------------- # to inspect from Terminal

View File

@ -51,12 +51,13 @@ from . import (
texturing_gui,
shading_nodes, # for POV specific nodes
scripting_gui,
update_files,
)
############# POV-Centric WORKSPACE #############
# ------------ POV-Centric WORKSPACE ------------ #
@persistent
def povCentricWorkspace(dummy):
def pov_centric_moray_like_workspace(dummy):
"""Set up a POV centric Workspace if addon was activated and saved as default renderer.
This would bring a _RestrictData error because UI needs to be fully loaded before
@ -121,8 +122,8 @@ def povCentricWorkspace(dummy):
override['area'] = area
override['region'] = region
area_x = area.x + (area.width / 2)
area_y = area.y + area.height
# area_x = area.x + (area.width / 2)
# area_y = area.y + area.height
bpy.ops.screen.space_type_set_or_cycle(override, space_type='INFO')
try:
if area == pov_workspace[6] and bpy.ops.screen.area_move.poll(
@ -219,7 +220,7 @@ def povCentricWorkspace(dummy):
"\nThe factory 'Scripting' workspace is needed before POV centric "
"\nworkspace may activate when POV is set as your default renderer"
)
####################################UTF-8###################################
# -----------------------------------UTF-8---------------------------------- #
# Check and fix all strings in current .blend file to be valid UTF-8 Unicode
# sometimes needed for old, 2.4x / 2.6x area files
bpy.ops.wm.blend_strings_utf8_validate()
@ -237,10 +238,8 @@ def check_material(mat):
def simple_material(mat):
"""Test if a material uses nodes."""
if (mat is not None) and (not mat.use_nodes):
return True
return False
"""Test if a material is nodeless."""
return (mat is not None) and (not mat.use_nodes)
def pov_context_tex_datablock(context):
@ -282,6 +281,7 @@ def pov_context_tex_datablock(context):
def register():
update_files.register()
render_gui.register()
scenography_gui.register()
object_gui.register()
@ -290,13 +290,13 @@ def register():
shading_nodes.register()
scripting_gui.register()
if not povCentricWorkspace in bpy.app.handlers.load_post:
bpy.app.handlers.load_post.append(povCentricWorkspace)
if pov_centric_moray_like_workspace not in bpy.app.handlers.load_post:
bpy.app.handlers.load_post.append(pov_centric_moray_like_workspace)
def unregister():
if povCentricWorkspace in bpy.app.handlers.load_post:
bpy.app.handlers.load_post.remove(povCentricWorkspace)
if pov_centric_moray_like_workspace in bpy.app.handlers.load_post:
bpy.app.handlers.load_post.remove(pov_centric_moray_like_workspace)
scripting_gui.unregister()
shading_nodes.unregister()
@ -305,3 +305,4 @@ def unregister():
object_gui.unregister()
scenography_gui.unregister()
render_gui.unregister()
update_files.unregister()

View File

@ -19,7 +19,7 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
#
################################################################################
# -----------------------------------------------------------------------------
#
# Creation functions
# __init__(x=1, y=1, z=1) : default constructor
@ -42,13 +42,12 @@
# exportDF3():
# importDF3():
#
################################################################################
# -----------------------------------------------------------------------------
import struct
import os
import stat
import array
import sys
# -+-+-+- Start df3 Class -+-+-+-
@ -78,7 +77,7 @@ class df3:
self.voxel[i] = indf3.voxel[i]
return self
#### Info Functions
# --- Info Functions
def sizeX(self):
return self.maxX
@ -90,13 +89,12 @@ class df3:
return self.maxZ
def size(self):
tmp = []
tmp.append(self.sizeX())
tmp = [self.sizeX()]
tmp.append(self.sizeY())
tmp.append(self.sizeZ())
return tmp
#### Voxel Access Functions
# --- Voxel Access Functions
def get(self, x, y, z):
return self.voxel[self.__voxa__(x, y, z)]
@ -124,7 +122,7 @@ class df3:
self.voxel[self.__voxa__(x, y, z)] = val
#### Scalar Functions
# --- Scalar Functions
def mult(self, val):
for i in range(self.sizeX() * self.sizeY() * self.sizeZ()):
@ -156,7 +154,7 @@ class df3:
return tmp
#### Vector Functions
# --- Vector Functions
def compare(self, indf3):
if self.__samesize__(indf3) == 0:
@ -221,7 +219,7 @@ class df3:
return self
#### Import/Export Functions
# --- Import/Export Functions
def exportDF3(self, file, depth=8, rescale=1):
x = self.sizeX()
@ -230,7 +228,9 @@ class df3:
try:
f = open(file, 'wb')
except:
except BaseException as e:
print(e.__doc__)
print('An exception occurred: {}'.format(e))
print("Could not open " + file + " for write")
return
@ -253,7 +253,9 @@ class df3:
f = open(file, 'rb')
size = os.stat(file)[stat.ST_SIZE]
except:
except BaseException as e:
print(e.__doc__)
print('An exception occurred: {}'.format(e))
print("Could not open " + file + " for read")
return []
@ -272,19 +274,17 @@ class df3:
elif size == 4 * x * y * z:
format = 32
if format == 32:
for i in range(x * y * z):
for i in range(x * y * z):
if format == 32:
self.voxel[i] = float(struct.unpack(self.__struct4byte__, f.read(4))[0])
elif format == 16:
for i in range(x * y * z):
elif format == 16:
self.voxel[i] = float(struct.unpack(self.__struct2byte__, f.read(2))[0])
elif format == 8:
for i in range(x * y * z):
elif format == 8:
self.voxel[i] = float(struct.unpack(self.__struct1byte__, f.read(1))[0])
return self
#### Local classes not intended for user use
# --- Local classes not intended for user use
def __rip__(self, minX, maxX, minY, maxY, minZ, maxZ):
sizeX = maxX - minX + 1
@ -366,32 +366,32 @@ class df3:
# -=-=-=- End df3 Class -=-=-=-
##########DEFAULT EXAMPLES
# --------DEFAULT EXAMPLES
# if __name__ == '__main__':
# localX = 80
# localY = 90
# localZ = 100
## Generate an output
# -- Generate an output
# temp = df3(localX, localY, localZ)
# for i in range(localX):
# for j in range(localY):
# for k in range(localZ):
# if (i >= (localX/2)):
# temp.set(i, j, k, 1.0)
# for j in range(localY):
# for k in range(localZ):
# if (i >= (localX/2)):
# temp.set(i, j, k, 1.0)
# temp.exportDF3('temp.df3', 16)
###############################################################################
## Import
# -----------------------------------------------------------------------------
# -- Import
# temp2 = df3().importDF3('temp.df3')
# temp2.mult(1/temp2.max())
## Compare
# -- Compare
# print(temp2.size())
# if (temp.compare(temp2) == 0): print("DF3's Do Not Match")
###############################################################################
# -----------------------------------------------------------------------------
# ChangeLog
# ---------
# 08/09/05: 0.20 released
@ -400,4 +400,4 @@ class df3:
# + Convert from 3-d list structure to Array class for data storage
# + Add element access, scalar, and vector functions
# 07/13/05: 0.10 released
###############################################################################
# -----------------------------------------------------------------------------

View File

@ -25,20 +25,23 @@ meshes or curve based shapes.
import bpy
from .shading import write_object_material
from .shading import write_object_material_interior
################################ LOFT, ETC.
def export_curves(ob, string_strip_hyphen, global_matrix, tab_write):
# -------- LOFT, ETC.
def export_curves(file, ob, string_strip_hyphen, global_matrix, tab_write):
"""write all curves based POV primitives to exported file """
name_orig = "OB" + ob.name
# name_orig = "OB" + ob.name # XXX Unused, check instanciation
dataname_orig = "DATA" + ob.data.name
name = string_strip_hyphen(bpy.path.clean_name(name_orig))
# name = string_strip_hyphen(bpy.path.clean_name(name_orig)) # XXX Unused, check instanciation
dataname = string_strip_hyphen(bpy.path.clean_name(dataname_orig))
matrix = global_matrix @ ob.matrix_world
# matrix = global_matrix @ ob.matrix_world # XXX Unused, check instanciation
bezier_sweep = False
if ob.pov.curveshape == 'sphere_sweep':
# TODO: Check radius ; shorten lines, may use tab_write() ? > fstrings since py 2.9
# inlined spheresweep macro, which itself calls Shapes.inc:
file.write(' #include "shapes.inc"\n')
@ -959,12 +962,12 @@ def export_curves(ob, string_strip_hyphen, global_matrix, tab_write):
if ob.pov.curveshape in {'birail'}:
splines = '%s1,%s2,%s3,%s4' % (dataname, dataname, dataname, dataname)
tab_write('object {Coons(%s, %s, %s, "")\n' % (splines, ob.pov.res_u, ob.pov.res_v))
pov_mat_name = "Default_texture"
# pov_mat_name = "Default_texture" # XXX! Unused, check instanciation
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(ob.data)
# tab_write("texture {%s}\n"%pov_mat_name)

View File

@ -45,8 +45,8 @@ from bl_ui import properties_data_mesh
properties_data_mesh.DATA_PT_custom_props_mesh.COMPAT_ENGINES.add('POVRAY_RENDER')
properties_data_mesh.DATA_PT_context_mesh.COMPAT_ENGINES.add('POVRAY_RENDER')
## make some native panels contextual to some object variable
## by recreating custom panels inheriting their properties
# make some native panels contextual to some object variable
# by recreating custom panels inheriting their properties
from .scripting_gui import VIEW_MT_POV_import
@ -59,7 +59,7 @@ class ModifierButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "modifier"
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
COMPAT_ENGINES = {'POVRAY_RENDER'}
@classmethod
def poll(cls, context):
@ -75,7 +75,7 @@ class ObjectButtonsPanel:
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
COMPAT_ENGINES = {'POVRAY_RENDER'}
@classmethod
def poll(cls, context):
@ -107,7 +107,7 @@ class PovDataButtonsPanel(properties_data_mesh.MeshButtonsPanel):
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
# engine = context.scene.render.engine # XXX Unused
obj = context.object
# We use our parent class poll func too, avoids to re-define too much things...
return (
@ -185,17 +185,16 @@ class MODIFIERS_PT_POV_modifiers(ModifierButtonsPanel, Panel):
# Find Boolean Modifiers for displaying CSG option
onceCSG = 0
for mod in ob.modifiers:
if onceCSG == 0:
if mod:
if mod.type == 'BOOLEAN':
col.prop(ob.pov, "boolean_mod")
onceCSG = 1
if onceCSG == 0 and mod:
if mod.type == 'BOOLEAN':
col.prop(ob.pov, "boolean_mod")
onceCSG = 1
if ob.pov.boolean_mod == "POV":
split = layout.split()
col = layout.column()
# Inside Vector for CSG
col.prop(ob.pov, "inside_vector")
if ob.pov.boolean_mod == "POV":
# split = layout.split() # better ?
col = layout.column()
# Inside Vector for CSG
col.prop(ob.pov, "inside_vector")
class OBJECT_PT_POV_obj_parameters(ObjectButtonsPanel, Panel):
@ -256,6 +255,7 @@ class OBJECT_PT_POV_obj_sphere(PovDataButtonsPanel, Panel):
bl_label = "POV Sphere"
COMPAT_ENGINES = {'POVRAY_RENDER'}
# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
@ -295,6 +295,7 @@ class OBJECT_PT_POV_obj_cylinder(PovDataButtonsPanel, Panel):
bl_label = "POV Cylinder"
COMPAT_ENGINES = {'POVRAY_RENDER'}
# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
@ -311,14 +312,18 @@ class OBJECT_PT_POV_obj_cylinder(PovDataButtonsPanel, Panel):
if obj.pov.object_as == 'CYLINDER':
if not obj.pov.unlock_parameters:
col.prop(
obj.pov, "unlock_parameters", text="Exported parameters below", icon='LOCKED'
obj.pov, "unlock_parameters",
text="Exported parameters below",
icon='LOCKED'
)
col.label(text="Cylinder radius: " + str(obj.pov.cylinder_radius))
col.label(text="Cylinder cap location: " + str(obj.pov.cylinder_location_cap))
else:
col.prop(
obj.pov, "unlock_parameters", text="Edit exported parameters", icon='UNLOCKED'
obj.pov, "unlock_parameters",
text="Edit exported parameters",
icon='UNLOCKED'
)
col.label(text="3D view proxy may get out of synch")
col.active = obj.pov.unlock_parameters
@ -336,6 +341,7 @@ class OBJECT_PT_POV_obj_cone(PovDataButtonsPanel, Panel):
bl_label = "POV Cone"
COMPAT_ENGINES = {'POVRAY_RENDER'}
# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
@ -380,6 +386,7 @@ class OBJECT_PT_POV_obj_superellipsoid(PovDataButtonsPanel, Panel):
bl_label = "POV Superquadric ellipsoid"
COMPAT_ENGINES = {'POVRAY_RENDER'}
# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
@ -426,6 +433,7 @@ class OBJECT_PT_POV_obj_torus(PovDataButtonsPanel, Panel):
bl_label = "POV Torus"
COMPAT_ENGINES = {'POVRAY_RENDER'}
# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
@ -470,6 +478,7 @@ class OBJECT_PT_POV_obj_supertorus(PovDataButtonsPanel, Panel):
bl_label = "POV SuperTorus"
COMPAT_ENGINES = {'POVRAY_RENDER'}
# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
@ -528,6 +537,7 @@ class OBJECT_PT_POV_obj_parametric(PovDataButtonsPanel, Panel):
bl_label = "POV Parametric surface"
COMPAT_ENGINES = {'POVRAY_RENDER'}
# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
@ -588,9 +598,9 @@ class OBJECT_PT_povray_replacement_text(ObjectButtonsPanel, Panel):
col.prop(obj.pov, "replacement_text", text="")
###############################################################################
# Add Povray Objects
###############################################################################
# ---------------------------------------------------------------- #
# Add POV objects
# ---------------------------------------------------------------- #
def check_add_mesh_extra_objects():
"""Test if Add mesh extra objects addon is activated
@ -707,8 +717,6 @@ classes = (
def register():
# from bpy.utils import register_class
for cls in classes:
register_class(cls)
@ -721,7 +729,6 @@ def register():
def unregister():
# addon_utils.disable("add_mesh_extra_objects", default_set=False)
bpy.types.VIEW3D_MT_add.remove(menu_func_add)
for cls in reversed(classes):

View File

@ -22,12 +22,10 @@
meshes or curve based shapes."""
####################
## Faster mesh export
import numpy as np
####################
import random # used for hair
# --------
# -- Faster mesh export ...one day
# import numpy as np
# --------
import bpy
from . import texturing # for how textures influence shaders
from .scenography import export_smoke
@ -70,7 +68,7 @@ def export_meshes(
safety,
write_object_modifiers,
material_names_dictionary,
write_object_material,
write_object_material_interior,
exported_lights_count,
unpacked_images,
image_format,
@ -89,61 +87,62 @@ def export_meshes(
info_callback,
):
"""write all meshes as POV mesh2{} syntax to exported file """
# some numpy functions to speed up mesh export NOT IN USE YET
# # some numpy functions to speed up mesh export NOT IN USE YET
# # Current 2.93 beta numpy linking has troubles so definitions commented off for now
# TODO: also write a numpy function to read matrices at object level?
# feed below with mesh object.data, but only after doing data.calc_loop_triangles()
def read_verts_co(self, mesh):
#'float64' would be a slower 64-bit floating-point number numpy datatype
# using 'float32' vert coordinates for now until any issue is reported
mverts_co = np.zeros((len(mesh.vertices) * 3), dtype=np.float32)
mesh.vertices.foreach_get("co", mverts_co)
return np.reshape(mverts_co, (len(mesh.vertices), 3))
# # TODO: also write a numpy function to read matrices at object level?
# # feed below with mesh object.data, but only after doing data.calc_loop_triangles()
# def read_verts_co(self, mesh):
# #'float64' would be a slower 64-bit floating-point number numpy datatype
# # using 'float32' vert coordinates for now until any issue is reported
# mverts_co = np.zeros((len(mesh.vertices) * 3), dtype=np.float32)
# mesh.vertices.foreach_get("co", mverts_co)
# return np.reshape(mverts_co, (len(mesh.vertices), 3))
def read_verts_idx(self, mesh):
mverts_idx = np.zeros((len(mesh.vertices)), dtype=np.int64)
mesh.vertices.foreach_get("index", mverts_idx)
return np.reshape(mverts_idx, (len(mesh.vertices), 1))
# def read_verts_idx(self, mesh):
# mverts_idx = np.zeros((len(mesh.vertices)), dtype=np.int64)
# mesh.vertices.foreach_get("index", mverts_idx)
# return np.reshape(mverts_idx, (len(mesh.vertices), 1))
def read_verts_norms(self, mesh):
#'float64' would be a slower 64-bit floating-point number numpy datatype
# using less accurate 'float16' normals for now until any issue is reported
mverts_no = np.zeros((len(mesh.vertices) * 3), dtype=np.float16)
mesh.vertices.foreach_get("normal", mverts_no)
return np.reshape(mverts_no, (len(mesh.vertices), 3))
# def read_verts_norms(self, mesh):
# #'float64' would be a slower 64-bit floating-point number numpy datatype
# # using less accurate 'float16' normals for now until any issue is reported
# mverts_no = np.zeros((len(mesh.vertices) * 3), dtype=np.float16)
# mesh.vertices.foreach_get("normal", mverts_no)
# return np.reshape(mverts_no, (len(mesh.vertices), 3))
def read_faces_idx(self, mesh):
mfaces_idx = np.zeros((len(mesh.loop_triangles)), dtype=np.int64)
mesh.loop_triangles.foreach_get("index", mfaces_idx)
return np.reshape(mfaces_idx, (len(mesh.loop_triangles), 1))
# def read_faces_idx(self, mesh):
# mfaces_idx = np.zeros((len(mesh.loop_triangles)), dtype=np.int64)
# mesh.loop_triangles.foreach_get("index", mfaces_idx)
# return np.reshape(mfaces_idx, (len(mesh.loop_triangles), 1))
def read_faces_verts_indices(self, mesh):
mfaces_verts_idx = np.zeros((len(mesh.loop_triangles) * 3), dtype=np.int64)
mesh.loop_triangles.foreach_get("vertices", mfaces_verts_idx)
return np.reshape(mfaces_verts_idx, (len(mesh.loop_triangles), 3))
# def read_faces_verts_indices(self, mesh):
# mfaces_verts_idx = np.zeros((len(mesh.loop_triangles) * 3), dtype=np.int64)
# mesh.loop_triangles.foreach_get("vertices", mfaces_verts_idx)
# return np.reshape(mfaces_verts_idx, (len(mesh.loop_triangles), 3))
# Why is below different from vertex indices?
def read_faces_verts_loops(self, mesh):
mfaces_verts_loops = np.zeros((len(mesh.loop_triangles) * 3), dtype=np.int64)
mesh.loop_triangles.foreach_get("loops", mfaces_verts_loops)
return np.reshape(mfaces_verts_loops, (len(mesh.loop_triangles), 3))
# # Why is below different from vertex indices?
# def read_faces_verts_loops(self, mesh):
# mfaces_verts_loops = np.zeros((len(mesh.loop_triangles) * 3), dtype=np.int64)
# mesh.loop_triangles.foreach_get("loops", mfaces_verts_loops)
# return np.reshape(mfaces_verts_loops, (len(mesh.loop_triangles), 3))
def read_faces_norms(self, mesh):
#'float64' would be a slower 64-bit floating-point number numpy datatype
# using less accurate 'float16' normals for now until any issue is reported
mfaces_no = np.zeros((len(mesh.loop_triangles) * 3), dtype=np.float16)
mesh.loop_triangles.foreach_get("normal", mfaces_no)
return np.reshape(mfaces_no, (len(mesh.loop_triangles), 3))
# def read_faces_norms(self, mesh):
# #'float64' would be a slower 64-bit floating-point number numpy datatype
# # using less accurate 'float16' normals for now until any issue is reported
# mfaces_no = np.zeros((len(mesh.loop_triangles) * 3), dtype=np.float16)
# mesh.loop_triangles.foreach_get("normal", mfaces_no)
# return np.reshape(mfaces_no, (len(mesh.loop_triangles), 3))
def read_faces_smooth(self, mesh):
mfaces_smth = np.zeros((len(mesh.loop_triangles) * 1), dtype=np.bool)
mesh.loop_triangles.foreach_get("use_smooth", mfaces_smth)
return np.reshape(mfaces_smth, (len(mesh.loop_triangles), 1))
# def read_faces_smooth(self, mesh):
# mfaces_smth = np.zeros((len(mesh.loop_triangles) * 1), dtype=np.bool)
# mesh.loop_triangles.foreach_get("use_smooth", mfaces_smth)
# return np.reshape(mfaces_smth, (len(mesh.loop_triangles), 1))
def read_faces_material_indices(self, mesh):
mfaces_mats_idx = np.zeros((len(mesh.loop_triangles)), dtype=np.int16)
mesh.loop_triangles.foreach_get("material_index", mfaces_mats_idx)
return np.reshape(mfaces_mats_idx, (len(mesh.loop_triangles), 1))
# def read_faces_material_indices(self, mesh):
# mfaces_mats_idx = np.zeros((len(mesh.loop_triangles)), dtype=np.int16)
# mesh.loop_triangles.foreach_get("material_index", mfaces_mats_idx)
# return np.reshape(mfaces_mats_idx, (len(mesh.loop_triangles), 1))
# obmatslist = []
# def hasUniqueMaterial():
@ -166,7 +165,8 @@ def export_meshes(
# return True
# return False
# For objects using local material(s) only!
# This is a mapping between a tuple (dataname, material_names_dictionary, ...), and the POV dataname.
# This is a mapping between a tuple (dataname, material_names_dictionary, ...),
# and the POV dataname.
# As only objects using:
# * The same data.
# * EXACTLY the same materials, in EXACTLY the same sockets.
@ -222,11 +222,10 @@ def export_meshes(
data_ref[dataname] = [(name, matrix_as_pov_string(matrix))]
return dataname
# XXX TODO : Too many nested blocks in this object loop, split hair (+particles?) to their function in own file,
ob_num = 0
depsgraph = bpy.context.evaluated_depsgraph_get()
for ob in sel:
# Using depsgraph
depsgraph = bpy.context.evaluated_depsgraph_get()
ob = bpy.data.objects[ob.name].evaluated_get(depsgraph)
# subtract original from the count of their instances as were not counted before 2.8
@ -237,7 +236,7 @@ def export_meshes(
# for object we won't export here!
if ob.type in {
'LIGHT',
'CAMERA', #'EMPTY', #empties can bear dupligroups
'CAMERA', # 'EMPTY', #empties can bear dupligroups
'META',
'ARMATURE',
'LATTICE',
@ -277,32 +276,34 @@ def export_meshes(
and mod.show_render
and (p_sys.name == mod.particle_system.name)
):
export_hair(file, ob, p_sys, global_matrix, write_matrix)
export_hair(file, ob, mod, p_sys, global_matrix, write_matrix)
if not render_emitter:
continue # don't render mesh, skip to next object.
#############################################
# ------------------------------------------------
# Generating a name for object just like materials to be able to use it
# (baking for now or anything else).
# XXX I don't understand that if we are here, sel if a non-empty iterable,
# so this condition is always True, IMO -- mont29
if ob.data:
name_orig = "OB" + ob.name
dataname_orig = "DATA" + ob.data.name
elif ob.is_instancer:
# EMPTY type objects treated a little further below -- MR
# modified elif to if below as non EMPTY objects can also be instancers
if ob.is_instancer:
if ob.instance_type == 'COLLECTION':
name_orig = "OB" + ob.name
dataname_orig = "DATA" + ob.instance_collection.name
else:
# hoping only dupligroups have several source datablocks
# ob_dupli_list_create(scene) #deprecated in 2.8
depsgraph = bpy.context.evaluated_depsgraph_get()
for eachduplicate in depsgraph.object_instances:
# Real dupli instance filtered because
# original included in list since 2.8
if eachduplicate.is_instance:
dataname_orig = "DATA" + eachduplicate.object.name
# ob.dupli_list_clear() #just don't store any reference to instance since 2.8
elif ob.data: # not an EMPTY type object
name_orig = "OB" + ob.name
dataname_orig = "DATA" + ob.data.name
elif ob.type == 'EMPTY':
name_orig = "OB" + ob.name
dataname_orig = "DATA" + ob.name
@ -311,18 +312,16 @@ def export_meshes(
dataname_orig = DEF_OBJ_NAME
name = string_strip_hyphen(bpy.path.clean_name(name_orig))
dataname = string_strip_hyphen(bpy.path.clean_name(dataname_orig))
## for slot in ob.material_slots:
## if slot.material is not None and slot.link == 'OBJECT':
## obmaterial = slot.material
# for slot in ob.material_slots:
# if slot.material is not None and slot.link == 'OBJECT':
# obmaterial = slot.material
#############################################
# ------------------------------------------------
if info_callback:
info_callback("Object %2.d of %2.d (%s)" % (ob_num, len(sel), ob.name))
# if ob.type != 'MESH':
# continue
# me = ob.data
me = ob.data
matrix = global_matrix @ ob.matrix_world
povdataname = store(scene, ob, name, dataname, matrix)
@ -332,7 +331,7 @@ def export_meshes(
print("Writing Down First Occurrence of " + name)
############################################Povray Primitives
# ------------ Povray Primitives ------------ #
# special export_curves() function takes care of writing
# lathe, sphere_sweep, birail, and loft except with modifiers
# converted to mesh
@ -341,7 +340,7 @@ def export_meshes(
ob.pov.curveshape in {'lathe', 'sphere_sweep', 'loft'}
):
continue # Don't render proxy mesh, skip to next object
# pov_mat_name = "Default_texture" # Not used...remove?
if ob.pov.object_as == 'ISOSURFACE':
tab_write("#declare %s = isosurface{ \n" % povdataname)
tab_write("function{ \n")
@ -379,12 +378,11 @@ def export_meshes(
else:
if ob.pov.max_trace > 1:
tab_write("max_trace %.6g\n" % ob.pov.max_trace)
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -397,12 +395,11 @@ def export_meshes(
"#declare %s = superellipsoid{ <%.4f,%.4f>\n"
% (povdataname, ob.pov.se_n2, ob.pov.se_n1)
)
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -417,7 +414,7 @@ def export_meshes(
cross = ob.pov.st_cross
accuracy = ob.pov.st_accuracy
gradient = ob.pov.st_max_gradient
############Inline Supertorus macro
# --- Inline Supertorus macro
file.write(
"#macro Supertorus(RMj, RMn, MajorControl, MinorControl, Accuracy, MaxGradient)\n"
)
@ -439,17 +436,16 @@ def export_meshes(
file.write(" accuracy Accuracy\n")
file.write(" }\n")
file.write("#end\n")
############
# ---
tab_write(
"#declare %s = object{ Supertorus( %.4g,%.4g,%.4g,%.4g,%.4g,%.4g)\n"
% (povdataname, rad_maj, rad_min, ring, cross, accuracy, gradient)
)
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -460,12 +456,11 @@ def export_meshes(
if ob.pov.object_as == 'PLANE':
tab_write("#declare %s = plane{ <0,0,1>,1\n" % povdataname)
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -476,12 +471,11 @@ def export_meshes(
if ob.pov.object_as == 'BOX':
tab_write("#declare %s = box { -1,1\n" % povdataname)
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -499,12 +493,11 @@ def export_meshes(
"#declare %s = cone { <0,0,%.4f>,%.4f,<0,0,%.4f>,%.4f\n"
% (povdataname, bz, br, cz, cr)
)
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -522,12 +515,11 @@ def export_meshes(
"#declare %s = cylinder { <0,0,0>,<%6f,%6f,%6f>,%6f\n"
% (povdataname, x2, y2, z2, r)
)
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -551,12 +543,11 @@ def export_meshes(
data += ' water_level %.4f' % ob.pov.hf_water
# hierarchy = ob.pov.hf_hierarchy
tab_write('#declare %s = height_field { %s\n' % (povdataname, data))
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -572,12 +563,11 @@ def export_meshes(
tab_write(
"#declare %s = sphere { 0,%6f\n" % (povdataname, ob.pov.sphere_radius)
)
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -591,12 +581,11 @@ def export_meshes(
"#declare %s = torus { %.4f,%.4f\n"
% (povdataname, ob.pov.torus_major_radius, ob.pov.torus_minor_radius)
)
pov_mat_name = "Default_texture"
if ob.active_material:
# pov_mat_name = string_strip_hyphen(bpy.path.clean_name(ob.active_material.name))
try:
material = ob.active_material
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
# tab_write("texture {%s}\n"%pov_mat_name)
@ -726,10 +715,8 @@ def export_meshes(
tab_write("}\n")
continue # Don't render proxy mesh, skip to next object
## In remaining cases; keep at end so no "elif" is needed,
# (as not skipped by any previous "continue")
# and for originals not their instances,
# attempt to export mesh:
# Implicit else-if (as not skipped by previous "continue") Keep this last.
# For originals, but not their instances, attempt to export mesh:
if not ob.is_instancer:
# except duplis which should be instances groups for now but all duplis later
if ob.type == 'EMPTY':
@ -743,8 +730,7 @@ def export_meshes(
)
continue # Don't render empty object but this is later addition, watch it.
depsgraph = bpy.context.evaluated_depsgraph_get()
ob_eval = ob.evaluated_get(depsgraph)
ob_eval = ob # not sure this is needed in case to_mesh_clear could damage ob ?
try:
me = ob_eval.to_mesh()
@ -761,10 +747,10 @@ def export_meshes(
me.calc_loop_triangles()
me_materials = me.materials
me_faces = me.loop_triangles[:]
## numpytest
# --- numpytest
# me_looptris = me.loops
## otypes = ['int32'] is a 32-bit signed integer number numpy datatype
# Below otypes = ['int32'] is a 32-bit signed integer number numpy datatype
# get_v_index = np.vectorize(lambda l: l.vertex_index, otypes = ['int32'], cache = True)
# faces_verts_idx = get_v_index(me_looptris)
@ -853,7 +839,7 @@ def export_meshes(
uniqueUVs = {}
# n = 0
for f in me_faces: # me.faces in 2.7
uvs = [uv_layer[l].uv[:] for l in f.loops]
uvs = [uv_layer[loop_index].uv[:] for loop_index in f.loops]
for uv in uvs:
uniqueUVs[uv[:]] = [-1]
@ -903,7 +889,7 @@ def export_meshes(
material
): # and material.use_vertex_color_paint: #Always use vertex color when there is some for now
cols = [vcol_layer[l].color[:] for l in f.loops]
cols = [vcol_layer[loop_index].color[:] for loop_index in f.loops]
for col in cols:
key = (
@ -964,7 +950,7 @@ def export_meshes(
material_index = f.material_index
if vcol_layer:
cols = [vcol_layer[l].color[:] for l in f.loops]
cols = [vcol_layer[loop_index].color[:] for loop_index in f.loops]
if (
not me_materials or me_materials[material_index] is None
@ -1071,7 +1057,7 @@ def export_meshes(
tab_write("%d" % (len(me_faces))) # faces count
tab_str = tab * tab_level
for f in me_faces:
uvs = [uv_layer[l].uv[:] for l in f.loops]
uvs = [uv_layer[loop_index].uv[:] for loop_index in f.loops]
if linebreaksinlists:
file.write(",\n")
@ -1118,7 +1104,7 @@ def export_meshes(
if me.materials:
try:
material = me.materials[0] # dodgy
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
@ -1142,7 +1128,7 @@ def export_meshes(
for i, material in enumerate(me_materials):
if (
material and material.pov.material_use_nodes == False
material and material.pov.material_use_nodes is False
): # WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Multiply diffuse with SSS Color
if material.pov_subsurface_scattering.use:
@ -1171,15 +1157,12 @@ def export_meshes(
vertCols[key] = [-1]
idx = 0
local_material_names = []
local_material_names = [] #XXX track and revert
material_finish = None
for col, index in vertCols.items():
# if me_materials:
mater = me_materials[col[3]]
if me_materials is None: # XXX working?
material_finish = DEF_MAT_NAME # not working properly,
trans = 0.0
else:
if me_materials is not None:
texturing.write_texture_influence(
using_uberpov,
mater,
@ -1198,7 +1181,7 @@ def export_meshes(
preview_dir,
unpacked_images,
)
###################################################################
# ------------------------------------------------
index[0] = idx
idx += 1
@ -1223,7 +1206,7 @@ def export_meshes(
if (
material
and ob.active_material is not None
and material.pov.material_use_nodes == False
and not material.pov.material_use_nodes
):
if material.pov.replacement_text != "":
file.write("\n")
@ -1257,7 +1240,7 @@ def export_meshes(
material_index = f.material_index
if vcol_layer:
cols = [vcol_layer[l].color[:] for l in f.loops]
cols = [vcol_layer[loop_index].color[:] for loop_index in f.loops]
if (
not me_materials or me_materials[material_index] is None
@ -1366,7 +1349,7 @@ def export_meshes(
tab_write("%d" % (len(me_faces))) # faces count
tab_str = tab * tab_level
for f in me_faces:
uvs = [uv_layer[l].uv[:] for l in f.loops]
uvs = [uv_layer[loop_index].uv[:] for loop_index in f.loops]
if linebreaksinlists:
file.write(",\n")
@ -1413,7 +1396,7 @@ def export_meshes(
if me.materials:
try:
material = me.materials[0] # dodgy
write_object_material(material, ob, tab_write)
write_object_material_interior(material, ob, tab_write)
except IndexError:
print(me)
@ -1438,7 +1421,6 @@ def export_meshes(
if ob.is_instancer:
tab_write("\n//--DupliObjects in %s--\n\n" % ob.name)
# ob.dupli_list_create(scene) #deprecated in 2.8
depsgraph = bpy.context.evaluated_depsgraph_get()
dup = ""
if ob.is_modified(scene, 'RENDER'):
# modified object always unique so using object name rather than data name
@ -1456,7 +1438,7 @@ def export_meshes(
_dupname = eachduplicate.object.name
_dupobj = bpy.data.objects[_dupname]
# BEGIN introspection for troubleshooting purposes
if not "name" in dir(_dupobj.data):
if "name" not in dir(_dupobj.data):
if _dupname not in _dupnames_seen:
print(
"WARNING: bpy.data.objects[%s].data (of type %s) has no 'name' attribute"

View File

@ -20,9 +20,30 @@
"""Get some Blender particle objects translated to POV."""
import bpy
import random
def export_hair(file, ob, p_sys, global_matrix, write_matrix):
def pixel_relative_guess(ob):
"""Convert some object x dimension to a rough pixel relative order of magnitude"""
from bpy_extras import object_utils
scene = bpy.context.scene
cam = scene.camera
render = scene.render
# Get rendered image resolution
output_x_res = render.resolution_x
focal_length = cam.data.lens
# Get object bounding box size
object_location = ob.location
object_dimension_x = ob.dimensions[0]
world_to_camera = object_utils.world_to_camera_view(scene, cam, object_location)
apparent_size = (object_dimension_x * focal_length) / world_to_camera[2]
sensor_width = cam.data.sensor_width
pixel_pitch_x = sensor_width / output_x_res
return apparent_size / pixel_pitch_x
def export_hair(file, ob, mod, p_sys, global_matrix, write_matrix):
"""Get Blender path particles (hair strands) objects translated to POV sphere_sweep unions."""
# tstart = time.time()
textured_hair = 0
@ -33,18 +54,30 @@ def export_hair(file, ob, p_sys, global_matrix, write_matrix):
povtex = th.texture # slot.name
tex = bpy.data.textures[povtex]
if th and th.use:
if (tex.type == 'IMAGE' and tex.image) or tex.type != 'IMAGE':
if th.use_map_color_diffuse:
textured_hair = 1
if (
th
and th.use
and (
(tex.type == 'IMAGE' and tex.image) or tex.type != 'IMAGE'
)
and th.use_map_color_diffuse
):
textured_hair = 1
if pmaterial.strand.use_blender_units:
strand_start = pmaterial.strand.root_size
strand_end = pmaterial.strand.tip_size
strand_shape = pmaterial.strand.shape
else: # Blender unit conversion
strand_start = pmaterial.strand.root_size / 200.0
strand_end = pmaterial.strand.tip_size / 200.0
strand_shape = pmaterial.strand.shape
else:
try:
# inexact pixel size, just to make radius relative to screen and object size.
pixel_fac = pixel_relative_guess(ob)
except ZeroDivisionError:
# Fallback to hardwired constant value
pixel_fac = 4500
print("no pixel size found for stand radius, falling back to %i" % pixel_fac)
strand_start = pmaterial.strand.root_size / pixel_fac
strand_end = pmaterial.strand.tip_size / pixel_fac
strand_shape = pmaterial.strand.shape
else:
pmaterial = "default" # No material assigned in blender, use default one
strand_start = 0.01
@ -63,7 +96,7 @@ def export_hair(file, ob, p_sys, global_matrix, write_matrix):
total_number_of_strands = p_sys.settings.count + p_sys.settings.rendered_child_count
# hairCounter = 0
file.write('#declare HairArray = array[%i] {\n' % total_number_of_strands)
for pindex in range(0, total_number_of_strands):
for pindex in range(total_number_of_strands):
# if particle.is_exist and particle.is_visible:
# hairCounter += 1
@ -119,7 +152,7 @@ def export_hair(file, ob, p_sys, global_matrix, write_matrix):
else:
# only overwrite variable for each competing texture for now
init_color = tex.evaluate((init_coord[0], init_coord[1], init_coord[2]))
for step in range(0, steps):
for step in range(steps):
coord = ob.matrix_world.inverted() @ (p_sys.co_hair(ob, particle_no=pindex, step=step))
# for controlPoint in particle.hair_keys:
if p_sys.settings.clump_factor != 0:
@ -127,9 +160,16 @@ def export_hair(file, ob, p_sys, global_matrix, write_matrix):
elif step == 0:
hair_strand_diameter = strand_start
else:
hair_strand_diameter += (strand_end - strand_start) / (
if strand_shape != 0.0:
if strand_shape < 0.0:
fac = pow(step, (1.0 + strand_shape))
else:
fac = pow(step, (1.0 / (1.0 - strand_shape)))
else:
fac = step
hair_strand_diameter += fac * (strand_end - strand_start) / (
p_sys.settings.display_step + 1
) # XXX +1 or not? # XXX use strand_shape in formula
) # XXX +1 or -1 or nothing ?
if step == 0 and p_sys.settings.use_hair_bspline:
# Write three times the first point to compensate pov Bezier handling
file.write(
@ -162,9 +202,7 @@ def export_hair(file, ob, p_sys, global_matrix, write_matrix):
# All coordinates except the last need a following comma.
if step != steps - 1:
file.write(',\n')
else:
if step == steps - 1:
if textured_hair:
# Write pigment and alpha (between Pov and Blender,
# alpha 0 and 1 are reversed)
@ -175,6 +213,8 @@ def export_hair(file, ob, p_sys, global_matrix, write_matrix):
# End the sphere_sweep declaration for this hair
file.write('}\n')
else:
file.write(',\n')
# All but the final sphere_sweep (each array element) needs a terminating comma.
if pindex != total_number_of_strands:
file.write(',\n')
@ -212,10 +252,10 @@ def export_hair(file, ob, p_sys, global_matrix, write_matrix):
file.write(' #local I = 0;\n')
file.write(' #while (I < %i)\n' % total_number_of_strands)
file.write(' object {HairArray[I]')
if not textured_hair:
file.write(' texture{HairTexture}\n')
else:
if textured_hair:
file.write('\n')
else:
file.write(' texture{HairTexture}\n')
# Translucency of the hair:
file.write(' hollow\n')
file.write(' double_illuminate\n')
@ -243,8 +283,8 @@ def export_hair(file, ob, p_sys, global_matrix, write_matrix):
write_matrix(global_matrix @ ob.matrix_world)
file.write('}')
print('Totals hairstrands written: %i' % total_number_of_strands)
print('Number of tufts (particle systems)', len(ob.particle_systems))
print("Totals hairstrands written: %i" % total_number_of_strands)
print("Number of tufts (particle systems)", len(ob.particle_systems))
# Set back the displayed number of particles to preview count
# p_sys.set_resolution(scene, ob, 'PREVIEW') #DEPRECATED

View File

@ -155,7 +155,7 @@ class POVRAY_OT_lathe_add(Operator):
def pov_superellipsoid_define(context, op, ob):
"""Create the proxy mesh of a POV superellipsoid using the pov_superellipsoid_define() function."""
"""Create the proxy mesh of a POV superellipsoid using pov_superellipsoid_define()."""
if op:
mesh = None
@ -276,7 +276,7 @@ def pov_superellipsoid_define(context, op, ob):
class POVRAY_OT_superellipsoid_add(Operator):
"""Add the representation of POV superellipsoid using the pov_superellipsoid_define() function."""
"""Add the representation of POV superellipsoid using the pov_superellipsoid_define()."""
bl_idname = "pov.addsuperellipsoid"
bl_label = "Add SuperEllipsoid"
@ -435,7 +435,7 @@ def supertoroid(R, r, u, v, n1, n2):
def pov_supertorus_define(context, op, ob):
"""Pick POV supertorus properties either from operator (object creation/import) or data updating """
"""Get POV supertorus properties from operator (object creation/import) or data update."""
if op:
mesh = None
st_R = op.st_R
@ -572,7 +572,7 @@ class POVRAY_OT_supertorus_update(Operator):
return {'FINISHED'}
#########################################################################################################
# -----------------------------------------------------------------------------
class POVRAY_OT_loft_add(Operator):
"""Create the representation of POV loft using Blender curves."""
@ -780,7 +780,7 @@ def pov_cylinder_define(context, op, ob, radius, loc, loc_cap):
bpy.ops.mesh.delete(type='VERT')
bpy.ops.mesh.primitive_cylinder_add(
radius=radius, depth=depth, location=loc, rotation=roteuler, end_fill_type='NGON'
) #'NOTHING'
) # 'NOTHING'
bpy.ops.transform.translate(value=trans)
bpy.ops.mesh.hide(unselected=False)
@ -873,7 +873,7 @@ class POVRAY_OT_cylinder_update(Operator):
return {'FINISHED'}
################################SPHERE##########################################
# ----------------------------------- SPHERE---------------------------------- #
def pov_sphere_define(context, op, ob, loc):
"""create the representation of POV sphere using a Blender icosphere.
@ -960,8 +960,8 @@ class POVRAY_OT_sphere_add(Operator):
return {'FINISHED'}
# def execute(self,context):
## layers = 20*[False]
## layers[0] = True
# layers = 20*[False]
# layers[0] = True
# bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=ob.pov.sphere_radius)
# ob = context.object
@ -1001,7 +1001,7 @@ class POVRAY_OT_sphere_update(Operator):
return {'FINISHED'}
####################################CONE#######################################
# ----------------------------------- CONE ---------------------------------- #
def pov_cone_define(context, op, ob):
"""Add the representation of POV cone using pov_define_mesh() function.
@ -1144,7 +1144,7 @@ class POVRAY_OT_cone_update(Operator):
return {'FINISHED'}
########################################ISOSURFACES##################################
# ----------------------------------- ISOSURFACES ----------------------------------- #
class POVRAY_OT_isosurface_box_add(Operator):
@ -1350,7 +1350,7 @@ class POVRAY_OT_height_field_add(bpy.types.Operator, ImportHelper):
ob.name = ob.data.name = '%s' % im_name
ob.data.materials.append(mat)
bpy.ops.object.mode_set(mode="EDIT")
# bpy.ops.mesh.noise(factor=1) # TODO replace by a displace modifier as noise deprecated in 2.8
# bpy.ops.mesh.noise(factor=1) # TODO replace by displace modifier, noise deprecated in 2.8
bpy.ops.object.mode_set(mode="OBJECT")
# needs a loop to select by index?
@ -1368,7 +1368,7 @@ class POVRAY_OT_height_field_add(bpy.types.Operator, ImportHelper):
return {'FINISHED'}
############################TORUS############################################
# ----------------------------------- TORUS ----------------------------------- #
def pov_torus_define(context, op, ob):
"""Add the representation of POV torus using just a Blender torus.
@ -1477,7 +1477,7 @@ class POVRAY_OT_torus_update(Operator):
return {'FINISHED'}
###################################################################################
# -----------------------------------------------------------------------------
class POVRAY_OT_prism_add(Operator):
@ -1526,7 +1526,7 @@ class POVRAY_OT_prism_add(Operator):
return {'FINISHED'}
##############################PARAMETRIC######################################
# ----------------------------------- PARAMETRIC ----------------------------------- #
def pov_parametric_define(context, op, ob):
"""Add the representation of POV parametric surfaces by math surface from add mesh extra objects addon.
@ -1670,7 +1670,7 @@ class POVRAY_OT_parametric_update(Operator):
return {'FINISHED'}
#######################################################################
# -----------------------------------------------------------------------------
class POVRAY_OT_shape_polygon_to_circle_add(Operator):
@ -1769,5 +1769,5 @@ def register():
def unregister():
for cls in classes:
for cls in reversed(classes):
unregister_class(cls)

View File

@ -32,9 +32,9 @@ from bpy.props import (
)
###############################################################################
# ---------------------------------------------------------------- #
# Object POV properties.
###############################################################################
# ---------------------------------------------------------------- #
class RenderPovSettingsObject(PropertyGroup):
@ -84,7 +84,7 @@ class RenderPovSettingsObject(PropertyGroup):
default=1.00,
)
##################################CustomPOV Code############################
# ----------------------------------- CustomPOV Code ----------------------------------- #
# Only DUMMIES below for now:
replacement_text: StringProperty(
name="Declared name:",
@ -93,7 +93,7 @@ class RenderPovSettingsObject(PropertyGroup):
default="",
)
#############POV specific object properties.############################
# -------- POV specific object properties. -------- #
object_as: StringProperty(maxlen=1024)
imported_loc: FloatVectorProperty(
@ -200,9 +200,9 @@ class RenderPovSettingsObject(PropertyGroup):
max_trace: IntProperty(name="Max Trace", min=1, max=100, default=1)
###########Cylinder
# -------- Cylinder
def prop_update_cylinder(self, context):
"""Update POV cylinder primitive parameters not only at creation but anytime they are changed in UI."""
"""Update POV cylinder primitive parameters at creation and anytime they change in UI."""
if bpy.ops.pov.cylinder_update.poll():
bpy.ops.pov.cylinder_update()
@ -213,7 +213,7 @@ class RenderPovSettingsObject(PropertyGroup):
cylinder_location_cap: FloatVectorProperty(
name="Cylinder Cap Location",
subtype="TRANSLATION",
description="The position of the 'other' end of the cylinder (relative to object location)",
description="Position of the 'other' end of the cylinder (relative to object location)",
default=(0.0, 0.0, 2.0),
update=prop_update_cylinder,
)
@ -226,10 +226,10 @@ class RenderPovSettingsObject(PropertyGroup):
name="Imported Pov location", precision=6, default=(0.0, 0.0, 2.0)
)
###########Sphere
# -------- Sphere
def prop_update_sphere(self, context):
"""Update POV sphere primitive parameters not only at creation but anytime they are changed in UI."""
"""Update POV sphere primitive parameters at creation and anytime they change in UI."""
bpy.ops.pov.sphere_update()
@ -237,10 +237,10 @@ class RenderPovSettingsObject(PropertyGroup):
name="Sphere radius", min=0.00, max=10.0, default=0.5, update=prop_update_sphere
)
###########Cone
# -------- Cone
def prop_update_cone(self, context):
"""Update POV cone primitive parameters not only at creation but anytime they are changed in UI."""
"""Update POV cone primitive parameters at creation and anytime they change in UI."""
bpy.ops.pov.cone_update()
@ -284,10 +284,10 @@ class RenderPovSettingsObject(PropertyGroup):
cone_cap_z: FloatProperty()
###########Parametric
# -------- Parametric
def prop_update_parametric(self, context):
"""Update POV parametric surface primitive parameters not only at creation but anytime they are changed in UI."""
"""Update POV parametric surface primitive settings at creation and on any UI change."""
bpy.ops.pov.parametric_update()
@ -311,11 +311,11 @@ class RenderPovSettingsObject(PropertyGroup):
maxlen=1024, default="sin(v)*(1+cos(u))*sin(v/8)", update=prop_update_parametric
)
###########Torus
# -------- Torus
def prop_update_torus(self, context):
"""Update POV torus primitive parameters not only at creation but anytime they are changed in UI."""
"""Update POV torus primitive parameters at creation and anytime they change in UI."""
bpy.ops.pov.torus_update()
@ -355,7 +355,7 @@ class RenderPovSettingsObject(PropertyGroup):
update=prop_update_torus,
)
###########Rainbow
# -------- Rainbow
arc_angle: FloatProperty(
name="Arc angle",
description="The angle of the raynbow arc in degrees",
@ -372,7 +372,7 @@ class RenderPovSettingsObject(PropertyGroup):
max=360,
)
###########HeightFields
# -------- HeightFields
quality: IntProperty(name="Quality", description="", default=100, min=1, max=100)
@ -390,10 +390,10 @@ class RenderPovSettingsObject(PropertyGroup):
hf_hierarchy: BoolProperty(name="Hierarchy", description="Height field hierarchy", default=True)
##############Superellipsoid
# -------- Superellipsoid
def prop_update_superellipsoid(self, context):
"""Update POV superellipsoid primitive parameters not only at creation but anytime they are changed in UI."""
"""Update POV superellipsoid primitive settings at creation and on any UI change."""
bpy.ops.pov.superellipsoid_update()
@ -445,7 +445,7 @@ class RenderPovSettingsObject(PropertyGroup):
update=prop_update_superellipsoid,
)
#############Used for loft but also Superellipsoid, etc.
# -------- Used for loft but also Superellipsoid, etc.
curveshape: EnumProperty(
name="Povray Shape Type",
items=(
@ -460,10 +460,10 @@ class RenderPovSettingsObject(PropertyGroup):
default="sphere_sweep",
)
#############Supertorus
# -------- Supertorus
def prop_update_supertorus(self, context):
"""Update POV supertorus primitive parameters not only at creation but anytime they are changed in UI."""
"""Update POV supertorus primitive parameters not only at creation and on any UI change."""
bpy.ops.pov.supertorus_update()
@ -581,7 +581,7 @@ class RenderPovSettingsObject(PropertyGroup):
name="", description="", default=False, options={"HIDDEN"}, update=prop_update_supertorus
)
########################Loft
# -------- Loft
loft_n: IntProperty(
name="Segments", description="Vertical segments", default=16, min=3, max=720
)
@ -610,17 +610,17 @@ class RenderPovSettingsObject(PropertyGroup):
max=10.0,
)
###################Prism
# -------- Prism
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)
##################Isosurface
# -------- Isosurface
iso_function_text: StringProperty(
name="Function Text", maxlen=1024
) # ,update=iso_props_update_callback)
##################PolygonToCircle
# -------- PolygonToCircle
polytocircle_resolution: IntProperty(
name="Resolution", description="", default=3, min=0, max=256
)
@ -631,9 +631,9 @@ class RenderPovSettingsObject(PropertyGroup):
polytocircle_circleR: FloatProperty(name="Circle Radius", description="", default=1.0)
###############################################################################
# ---------------------------------------------------------------- #
# Modifiers POV properties.
###############################################################################
# ---------------------------------------------------------------- #
# class RenderPovSettingsModifier(PropertyGroup):
boolean_mod: EnumProperty(
name="Operation",
@ -646,7 +646,7 @@ class RenderPovSettingsObject(PropertyGroup):
default="BMESH",
)
#################Avogadro
# -------- Avogadro
# filename_ext = ".png"
# filter_glob = StringProperty(

View File

@ -17,7 +17,9 @@
# #**** END GPL LICENSE BLOCK #****
# <pep8 compliant>
"""Wirte the POV file using this file's functions and some from other modules then render it."""
import bpy
import subprocess
import os
@ -45,7 +47,7 @@ from . import object_curve_topology # for curves based geometry
from .scenography import image_format, img_map, img_map_transforms, path_image
from .shading import write_object_material
from .shading import write_object_material_interior
from .object_primitives import write_object_modifiers
@ -79,7 +81,7 @@ def safety(name, ref_level_bound):
# prefix = "shader"
# except BaseException as e:
# print(e.__doc__)
# print('An exXXXception occurred: {}'.format(e))
# print('An exception occurred: {}'.format(e))
# prefix = "" # rewritten below...
prefix = "shader_"
name = string_strip_hyphen(name)
@ -93,8 +95,8 @@ def safety(name, ref_level_bound):
return prefix + name + "1" # used for 1 of specular map
##############end safety string name material
##############################EndSF###########################
# -------- end safety string name material
csg_list = []
@ -120,7 +122,7 @@ unpacked_images = []
user_dir = bpy.utils.resource_path('USER')
preview_dir = os.path.join(user_dir, "preview")
## Make sure Preview directory exists and is empty
# Make sure Preview directory exists and is empty
smoke_path = os.path.join(preview_dir, "smoke.df3")
'''
@ -306,7 +308,7 @@ def write_pov(filename, scene=None, info_callback=None):
material_names_dictionary = {}
DEF_MAT_NAME = "" # or "Default"?
#################################################################
# -----------------------------------------------------------------------------
def export_meta(metas):
"""write all POV blob primitives and Blender Metas to exported file """
@ -319,7 +321,7 @@ def write_pov(filename, scene=None, info_callback=None):
meta_elems = {}
for ob in metas:
prefix = ob.name.split(".")[0]
if not prefix in meta_group:
if prefix not in meta_group:
meta_group[prefix] = ob # .data.threshold
elems = [
(elem, ob)
@ -335,7 +337,9 @@ def write_pov(filename, scene=None, info_callback=None):
if len(elems) == 0:
tab_write("\n//dummy sphere to represent empty meta location\n")
tab_write(
"sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} no_image no_reflection no_radiosity photons{pass_through collect off} hollow}\n\n"
"sphere {<%.6g, %.6g, %.6g>,0 pigment{rgbt 1} "
"no_image no_reflection no_radiosity "
"photons{pass_through collect off} hollow}\n\n"
% (ob.location.x, ob.location.y, ob.location.z)
) # ob.name > povdataname)
# other metaballs
@ -504,13 +508,15 @@ def write_pov(filename, scene=None, info_callback=None):
)
tab_write("finish{%s} " % safety(material_finish, ref_level_bound=2))
else:
material_finish = DEF_MAT_NAME
trans = 0.0
tab_write(
"pigment{srgb 1} finish{%s} "
% (safety(DEF_MAT_NAME, ref_level_bound=2))
"pigment{srgbt<1,1,1,%.3g} finish{%s} "
% (trans, safety(material_finish, ref_level_bound=2))
)
write_object_material(material, mob, tab_write)
# write_object_material(material, elems[1])
write_object_material_interior(material, mob, tab_write)
# write_object_material_interior(material, elems[1])
tab_write("radiosity{importance %3g}\n" % mob.pov.importance_value)
tab_write("}\n\n") # End of Metaball block
@ -577,7 +583,7 @@ def write_pov(filename, scene=None, info_callback=None):
# Write the finish last.
tab_write("finish {%s}\n" % (safety(DEF_MAT_NAME, ref_level_bound=2)))
write_object_material(material, elems[1])
write_object_material_interior(material, elems[1])
write_matrix(global_matrix @ ob.matrix_world)
# Importance for radiosity sampling added here
@ -732,12 +738,12 @@ def write_pov(filename, scene=None, info_callback=None):
for ob in bpy.data.objects:
if ob.type == 'MESH':
for mod in ob.modifiers:
if mod.type == 'BOOLEAN':
if mod.object not in csg_list:
if mod.type == 'BOOLEAN' and mod.object not in csg_list:
csg_list.append(mod.object)
if csg_list != []:
csg = False
sel = no_renderable_objects()
#export non rendered boolean objects operands
object_mesh_topology.export_meshes(
preview_dir,
file,
@ -748,7 +754,7 @@ def write_pov(filename, scene=None, info_callback=None):
safety,
write_object_modifiers,
material_names_dictionary,
write_object_material,
write_object_material_interior,
scenography.exported_lights_count,
unpacked_images,
image_format,
@ -797,7 +803,7 @@ def write_pov(filename, scene=None, info_callback=None):
continue # don't export as pov curves objects with modifiers, but as mesh
# Implicit else-if (as not skipped by previous "continue")
if c.type == 'CURVE' and (c.pov.curveshape in {'lathe', 'sphere_sweep', 'loft', 'birail'}):
object_curve_topology.export_curves(c, string_strip_hyphen, global_matrix, tab_write)
object_curve_topology.export_curves(file, c, string_strip_hyphen, global_matrix, tab_write)
if comments:
file.write("\n//--Material Definitions--\n\n")
@ -875,7 +881,7 @@ def write_pov(filename, scene=None, info_callback=None):
safety,
write_object_modifiers,
material_names_dictionary,
write_object_material,
write_object_material_interior,
scenography.exported_lights_count,
unpacked_images,
image_format,
@ -1024,16 +1030,6 @@ class PovrayRender(bpy.types.RenderEngine):
if os.path.exists(pov_binary):
return pov_binary
# Then try 32bits UberPOV
pov_binary = os.path.join(win_home, "bin", "uberpov32.exe")
if os.path.exists(pov_binary):
return pov_binary
# Then try 32bits POV
pov_binary = os.path.join(win_home, "bin", "pvengine.exe")
if os.path.exists(pov_binary):
return pov_binary
# search the path all os's
pov_binary_default = "povray"
@ -1331,14 +1327,14 @@ class PovrayRender(bpy.types.RenderEngine):
self._cleanup()
else:
##WIP output format
## if r.image_settings.file_format == 'OPENEXR':
## fformat = 'EXR'
## render.image_settings.color_mode = 'RGBA'
## else:
## fformat = 'TGA'
## r.image_settings.file_format = 'TARGA'
## r.image_settings.color_mode = 'RGBA'
# WIP output format
# if r.image_settings.file_format == 'OPENEXR':
# fformat = 'EXR'
# render.image_settings.color_mode = 'RGBA'
# else:
# fformat = 'TGA'
# r.image_settings.file_format = 'TARGA'
# r.image_settings.color_mode = 'RGBA'
blend_scene_name = bpy.data.filepath.split(os.path.sep)[-1].split(".")[0]
pov_scene_name = ""
@ -1424,13 +1420,8 @@ class PovrayRender(bpy.types.RenderEngine):
pov_path = os.path.join(pov_path, pov_scene_name)
pov_path = os.path.realpath(pov_path)
# for now this has to be the same like the pov output. Bug in POV-Ray RC3.
# image_render_path = image_render_path + "\\" + pov_scene_name
image_render_path = pov_path # Bugfix for POV-Ray RC3 bug
# image_render_path = os.path.realpath(image_render_path) # Bugfix for POV-Ray RC3 bug
# print("Export path: %s" % pov_path)
# print("Render Image path: %s" % image_render_path)
image_render_path = pov_path
# print("Render Image path: " + image_render_path)
# start export
self.update_stats("", "POV-Ray 3.7: Exporting data from Blender")
@ -1594,22 +1585,28 @@ class PovrayRender(bpy.types.RenderEngine):
scr = win.screen
for area in scr.areas:
if area.type == 'CONSOLE':
# pass # XXX temp override
# context override
# ctx = {'window': win, 'screen': scr, 'area':area}#bpy.context.copy()
ctx = {}
ctx['area'] = area
ctx['region'] = area.regions[-1]
ctx['space_data'] = area.spaces.active
ctx['screen'] = scr # C.screen
ctx['window'] = win
try:
ctx = {}
ctx['area'] = area
ctx['region'] = area.regions[-1]
ctx['space_data'] = area.spaces.active
ctx['screen'] = scr # C.screen
ctx['window'] = win
# bpy.ops.console.banner(ctx, text = "Hello world")
bpy.ops.console.clear_line(ctx)
stdmsg = msg.split('\n') # XXX todo , test and see
for i in stdmsg:
# Crashes if no Terminal displayed on Windows
bpy.ops.console.scrollback_append(ctx, text=i, type='INFO')
# bpy.ops.console.insert(ctx, text=(i + "\n"))
# bpy.ops.console.banner(ctx, text = "Hello world")
bpy.ops.console.clear_line(ctx)
stdmsg = msg.split('\n') # XXX todo , test and see segfault crash?
for i in stdmsg:
# Crashes if no Terminal displayed on Windows
bpy.ops.console.scrollback_append(ctx, text=i, type='INFO')
# bpy.ops.console.insert(ctx, text=(i + "\n"))
except BaseException as e:
print(e.__doc__)
print('An exception occurred: {}'.format(e))
pass
self.update_stats("", "")
@ -1679,9 +1676,9 @@ class PovrayRender(bpy.types.RenderEngine):
os.system("echo %s | espeak &" % (finished_render_message))
##################################################################################
#################################Operators########################################
##################################################################################
# --------------------------------------------------------------------------------- #
# ----------------------------------- Operators ----------------------------------- #
# --------------------------------------------------------------------------------- #
class RenderPovTexturePreview(Operator):
"""Export only files necessary to texture preview and render image"""
@ -1692,14 +1689,14 @@ class RenderPovTexturePreview(Operator):
tex = bpy.context.object.active_material.active_texture # context.texture
tex_prev_name = string_strip_hyphen(bpy.path.clean_name(tex.name)) + "_prev"
## Make sure Preview directory exists and is empty
# Make sure Preview directory exists and is empty
if not os.path.isdir(preview_dir):
os.mkdir(preview_dir)
ini_prev_file = os.path.join(preview_dir, "Preview.ini")
input_prev_file = os.path.join(preview_dir, "Preview.pov")
output_prev_file = os.path.join(preview_dir, tex_prev_name)
##################### ini ##########################################
# ---------------------------------- ini ---------------------------------- #
file_ini = open("%s" % ini_prev_file, "w")
file_ini.write('Version=3.8\n')
file_ini.write('Input_File_Name="%s"\n' % input_prev_file)
@ -1715,7 +1712,7 @@ class RenderPovTexturePreview(Operator):
file_ini.write('Antialias_Depth=3\n')
file_ini.write('-d\n')
file_ini.close()
##################### pov ##########################################
# ---------------------------------- pov ---------------------------------- #
file_pov = open("%s" % input_prev_file, "w")
pat_name = "PAT_" + string_strip_hyphen(bpy.path.clean_name(tex.name))
file_pov.write("#declare %s = \n" % pat_name)
@ -1748,7 +1745,7 @@ class RenderPovTexturePreview(Operator):
file_pov.write(" translate <0.000000, 0.000000, 0.000000>\n")
file_pov.write("}\n")
file_pov.close()
##################### end write ##########################################
# ------------------------------- end write ------------------------------- #
pov_binary = PovrayRender._locate_binary()
@ -1807,14 +1804,20 @@ class RunPovTextRender(Operator):
return {'FINISHED'}
classes = (PovrayRender, RenderPovTexturePreview, RunPovTextRender)
classes = (
PovrayRender,
RenderPovTexturePreview,
RunPovTextRender,
)
def register():
for cls in classes:
register_class(cls)
scripting.register()
def unregister():
scripting.unregister()
for cls in reversed(classes):
unregister_class(cls)

View File

@ -20,6 +20,7 @@
"""User interface for rendering parameters"""
import bpy
from sys import platform # really import here, as in render.py?
@ -27,7 +28,6 @@ from sys import platform # really import here, as in render.py?
# from os.path import isfile
from bl_operators.presets import AddPresetBase
from bpy.utils import register_class, unregister_class
from bpy.props import EnumProperty
from bpy.types import Operator, Menu, Panel
@ -44,10 +44,12 @@ from bl_ui import properties_freestyle
for member in dir(properties_freestyle):
subclass = getattr(properties_freestyle, member)
if hasattr(subclass, "COMPAT_ENGINES"):
if not (subclass.bl_space_type == 'PROPERTIES' and subclass.bl_context == "render"):
subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
# subclass.bl_parent_id = "RENDER_PT_POV_filter"
if hasattr(subclass, "COMPAT_ENGINES") and (
subclass.bl_space_type != 'PROPERTIES'
or subclass.bl_context != "render"
):
subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
# subclass.bl_parent_id = "RENDER_PT_POV_filter"
del properties_freestyle
from bl_ui import properties_view_layer
@ -75,9 +77,7 @@ def check_render_freestyle_svg():
This addon is currently used to generate the SVG lines file
when Freestyle is enabled alongside POV
"""
if "render_freestyle_svg" in bpy.context.preferences.addons.keys():
return True
return False
return "render_freestyle_svg" in bpy.context.preferences.addons.keys()
class RenderButtonsPanel:
@ -258,6 +258,27 @@ class RENDER_PT_POV_antialias(RenderButtonsPanel, Panel):
else:
self.layout.prop(scene.pov, "antialias_enable", text="", icon='ALIASED')
def uberpov_only_qmc_til_pov38release(self, layout):
col = layout.column()
col.alignment = 'CENTER'
col.label(text="Stochastic Anti Aliasing is")
col.label(text="Only Available with UberPOV")
col.label(text="Feature Set in User Preferences.")
col.label(text="Using Type 2 (recursive) instead")
def no_qmc_fallbacks(self, row, scene, layout):
row.prop(scene.pov, "jitter_enable", text="Jitter")
split = layout.split()
col = split.column()
col.prop(scene.pov, "antialias_depth", text="AA Depth")
sub = split.column()
sub.prop(scene.pov, "jitter_amount", text="Jitter Amount")
sub.enabled = bool(scene.pov.jitter_enable)
row = layout.row()
row.prop(scene.pov, "antialias_threshold", text="AA Threshold")
row.prop(scene.pov, "antialias_gamma", text="AA Gamma")
def draw(self, context):
prefs = bpy.context.preferences.addons[__package__].preferences
layout = self.layout
@ -269,37 +290,13 @@ class RENDER_PT_POV_antialias(RenderButtonsPanel, Panel):
row.prop(scene.pov, "antialias_method", text="")
if prefs.branch_feature_set_povray != 'uberpov' and scene.pov.antialias_method == '2':
col = layout.column()
col.alignment = 'CENTER'
col.label(text="Stochastic Anti Aliasing is")
col.label(text="Only Available with UberPOV")
col.label(text="Feature Set in User Preferences.")
col.label(text="Using Type 2 (recursive) instead")
self.uberpov_only_qmc_til_pov38release(layout)
else:
row.prop(scene.pov, "jitter_enable", text="Jitter")
split = layout.split()
col = split.column()
col.prop(scene.pov, "antialias_depth", text="AA Depth")
sub = split.column()
sub.prop(scene.pov, "jitter_amount", text="Jitter Amount")
if scene.pov.jitter_enable:
sub.enabled = True
else:
sub.enabled = False
self.no_qmc_fallbacks(row, scene, layout)
if prefs.branch_feature_set_povray == 'uberpov':
row = layout.row()
row.prop(scene.pov, "antialias_threshold", text="AA Threshold")
row.prop(scene.pov, "antialias_gamma", text="AA Gamma")
if prefs.branch_feature_set_povray == 'uberpov':
row = layout.row()
row.prop(scene.pov, "antialias_confidence", text="AA Confidence")
if scene.pov.antialias_method == '2':
row.enabled = True
else:
row.enabled = False
row.prop(scene.pov, "antialias_confidence", text="AA Confidence")
row.enabled = scene.pov.antialias_method == '2'
class RENDER_PT_POV_radiosity(RenderButtonsPanel, Panel):
"""Use this class to define pov radiosity buttons."""
@ -414,20 +411,20 @@ def rad_panel_func(self, context):
).remove_active = True
###############################################################################
# ---------------------------------------------------------------- #
# Freestyle
###############################################################################
# ---------------------------------------------------------------- #
# import addon_utils
# addon_utils.paths()[0]
# addon_utils.modules()
# mod.bl_info['name'] == 'Freestyle SVG Exporter':
bpy.utils.script_paths("addons")
# render_freestyle_svg = os.path.join(bpy.utils.script_paths("addons"), "render_freestyle_svg.py")
bpy.utils.script_paths(subdir="addons")
# render_freestyle_svg = os.path.join(bpy.utils.script_paths(subdir="addons"), "render_freestyle_svg.py")
render_freestyle_svg = bpy.context.preferences.addons.get('render_freestyle_svg')
# mpath=addon_utils.paths()[0].render_freestyle_svg
# import mpath
# from mpath import render_freestyle_svg #= addon_utils.modules(['Freestyle SVG Exporter'])
# from mpath import render_freestyle_svg #= addon_utils.modules(module_cache=['Freestyle SVG Exporter'])
# from scripts\\addons import render_freestyle_svg
if check_render_freestyle_svg():
'''
@ -537,10 +534,10 @@ classes = (
def register():
for cls in classes:
register_class(cls)
bpy.types.RENDER_PT_POV_radiosity.prepend(rad_panel_func)
RENDER_PT_POV_radiosity.prepend(rad_panel_func)
def unregister():
bpy.types.RENDER_PT_POV_radiosity.remove(rad_panel_func)
RENDER_PT_POV_radiosity.remove(rad_panel_func)
for cls in reversed(classes):
unregister_class(cls)

View File

@ -32,9 +32,9 @@ from bpy.props import (
PointerProperty,
)
###############################################################################
# ---------------------------------------------------------------- #
# Scene POV properties.
###############################################################################
# ---------------------------------------------------------------- #
class RenderPovSettingsScene(PropertyGroup):
"""Declare scene level properties controllable in UI and translated to POV"""
@ -445,7 +445,7 @@ class RenderPovSettingsScene(PropertyGroup):
default=2,
)
########################### PHOTONS #######################################
# -------- PHOTONS -------- #
photon_enable: BoolProperty(name="Photons", description="Enable global photons", default=False)
photon_enable_count: BoolProperty(
@ -519,7 +519,7 @@ class RenderPovSettingsScene(PropertyGroup):
photon_map_file: StringProperty(name="File", description="", maxlen=1024, subtype="FILE_PATH")
#########RADIOSITY########
# -------- RADIOSITY -------- #
radio_adc_bailout: FloatProperty(
name="ADC Bailout",
description="The adc_bailout for radiosity rays. Use "
@ -672,7 +672,9 @@ class RenderPovSettingsScene(PropertyGroup):
)
classes = (RenderPovSettingsScene,)
classes = (
RenderPovSettingsScene,
)
def register():

View File

@ -23,14 +23,17 @@
with world, sky, atmospheric effects such as rainbows or smoke """
import bpy
from bpy.utils import register_class, unregister_class
import os
from imghdr import what # imghdr is a python lib to identify image file types
from math import atan, pi, sqrt, degrees
from . import df3_library # for smoke rendering
from .object_primitives import write_object_modifiers
##############find image texture # used for export_world
# -------- find image texture # used for export_world -------- #
def image_format(imgF):
"""Identify input image filetypes to transmit to POV."""
# First use the below explicit extensions to identify image file prospects
@ -68,8 +71,8 @@ def img_map(ts):
elif ts.mapping == 'TUBE':
image_map = "map_type 2 "
## map_type 3 and 4 in development (?) (ENV in pov 3.8)
## for POV-Ray, currently they just seem to default back to Flat (type 0)
# map_type 3 and 4 in development (?) (ENV in pov 3.8)
# for POV-Ray, currently they just seem to default back to Flat (type 0)
# elif ts.mapping=="?":
# image_map = " map_type 3 "
# elif ts.mapping=="?":
@ -133,7 +136,7 @@ def img_map_bg(wts):
tex = bpy.data.textures[wts.texture]
image_mapBG = ""
# texture_coords refers to the mapping of world textures:
if wts.texture_coords == 'VIEW' or wts.texture_coords == 'GLOBAL':
if wts.texture_coords in ['VIEW', 'GLOBAL']:
image_mapBG = " map_type 0 "
elif wts.texture_coords == 'ANGMAP':
image_mapBG = " map_type 1 "
@ -192,7 +195,7 @@ def export_camera(scene, global_matrix, render, tab_write):
else:
if camera.data.type == 'ORTHO':
# todo: track when SensorHeightRatio was added to see if needed (not used)
# XXX todo: track when SensorHeightRatio was added to see if needed (not used)
sensor_height_ratio = (
render.resolution_x * camera.data.ortho_scale / render.resolution_y
)
@ -392,16 +395,16 @@ def export_world(world, scene, global_matrix, tab_write):
"""write world as POV backgrounbd and sky_sphere to exported file """
render = scene.pov
camera = scene.camera
matrix = global_matrix @ camera.matrix_world # view dependant for later use
# matrix = global_matrix @ camera.matrix_world # view dependant for later use NOT USED
if not world:
return
#############Maurice####################################
# These lines added to get sky gradient (visible with PNG output)
if world:
# For simple flat background:
if not world.pov.use_sky_blend:
# Non fully transparent background could premultiply alpha and avoid anti-aliasing
# display issue:
# Non fully transparent background could premultiply alpha and avoid
# anti-aliasing display issue:
if render.alpha_mode == 'TRANSPARENT':
tab_write(
"background {rgbt<%.3g, %.3g, %.3g, 0.75>}\n" % (world.pov.horizon_color[:])
@ -526,7 +529,7 @@ def export_world(world, scene, global_matrix, tab_write):
# scene.pov.radio_enable = world.pov.light_settings.use_indirect_light
# and other such translations but maybe this would not be allowed either?
###############################################################
# -----------------------------------------------------------------------------
mist = world.mist_settings
@ -570,9 +573,10 @@ def export_world(world, scene, global_matrix, tab_write):
tab_write("}\n")
####################################################################################################
# -----------------------------------------------------------------------------
def export_rainbows(rainbows, file, scene, global_matrix, write_matrix, tab_write):
"""write all POV rainbows primitives to exported file """
pov_mat_name = "Default_texture"
for ob in rainbows:
povdataname = ob.data.name # enough? XXX not used nor matrix fn?
angle = degrees(ob.data.spot_size / 2.5) # radians in blender (2
@ -631,7 +635,6 @@ def export_rainbows(rainbows, file, scene, global_matrix, write_matrix, tab_writ
tab_write("[1.000 color srgbt<1.0, 0.2, 0.2, 1.0>]\n")
tab_write("}\n")
pov_mat_name = "Default_texture"
# tab_write("texture {%s}\n"%pov_mat_name)
write_object_modifiers(scene, ob, file)
# tab_write("rotate x*90\n")
@ -652,20 +655,17 @@ def export_smoke(file, smoke_obj_name, smoke_path, comments, global_matrix, writ
# Search smoke domain target for smoke modifiers
for mod in smoke_obj.modifiers:
if mod.type == 'FLUID':
if mod.fluid_type == 'FLOW':
if mod.flow_settings.flow_type == 'BOTH':
flowtype = 2
else:
if mod.flow_settings.smoke_flow_type == 'SMOKE':
flowtype = 0
else:
if mod.flow_settings.smoke_flow_type == 'FIRE':
flowtype = 1
if mod.fluid_type == 'DOMAIN':
domain = smoke_obj
smoke_modifier = mod
elif mod.fluid_type == 'FLOW':
if mod.flow_settings.flow_type == 'BOTH':
flowtype = 2
elif mod.flow_settings.flow_type == 'FIRE':
flowtype = 1
elif mod.flow_settings.flow_type == 'SMOKE':
flowtype = 0
eps = 0.000001 # XXX not used currently. restore from corner case ... zero div?
if domain is not None:
mod_set = smoke_modifier.domain_settings
@ -673,7 +673,7 @@ def export_smoke(file, smoke_obj_name, smoke_path, comments, global_matrix, writ
for v in mod_set.density_grid:
channeldata.append(v.real)
print(v.real)
## Usage en voxel texture:
# -------- Usage in voxel texture:
# channeldata = []
# if channel == 'density':
# for v in mod_set.density_grid:
@ -695,7 +695,7 @@ def export_smoke(file, smoke_obj_name, smoke_path, comments, global_matrix, writ
big_res[2] = big_res[2] * (mod_set.noise_scale + 1)
# else:
# p = []
##gather smoke domain settings
# -------- gather smoke domain settings
# BBox = domain.bound_box
# p.append([BBox[0][0], BBox[0][1], BBox[0][2]])
# p.append([BBox[6][0], BBox[6][1], BBox[6][2]])
@ -710,7 +710,7 @@ def export_smoke(file, smoke_obj_name, smoke_path, comments, global_matrix, writ
# fire = ret[4]
# if res_x * res_y * res_z > 0:
##new cache format
# -------- new cache format
# big_res = []
# big_res.append(res_x)
# big_res.append(res_y)
@ -771,15 +771,17 @@ def export_smoke(file, smoke_obj_name, smoke_path, comments, global_matrix, writ
for y in range(sim_sizeY):
for z in range(sim_sizeZ):
mydf3.set(x, y, z, channeldata[((z * sim_sizeY + y) * sim_sizeX + x)])
mydf3.exportDF3(smoke_path)
try:
mydf3.exportDF3(smoke_path)
except ZeroDivisionError:
print("Show smoke simulation in 3D view before export")
print('Binary smoke.df3 file written in preview directory')
if comments:
file.write("\n//--Smoke--\n\n")
# Note: We start with a default unit cube.
# This is mandatory to read correctly df3 data - otherwise we could just directly use bbox
# coordinates from the start, and avoid scale/translate operations at the end...
# This is mandatory to read correctly df3 data - otherwise we could just directly use
# bbox coordinates from the start, and avoid scale/translate operations at the end...
file.write("box{<0,0,0>, <1,1,1>\n")
file.write(" pigment{ rgbt 1 }\n")
file.write(" hollow\n")
@ -832,16 +834,3 @@ def export_smoke(file, smoke_obj_name, smoke_path, comments, global_matrix, writ
# file.write(" frequency 0\n")
# file.write(" }\n")
# file.write("}\n")
classes = ()
def register():
for cls in classes:
register_class(cls)
def unregister():
for cls in classes:
unregister_class(cls)

View File

@ -35,8 +35,7 @@ for member in dir(properties_data_camera):
subclass.COMPAT_ENGINES.add('POVRAY_RENDER')
del properties_data_camera
# ##################################
# # Use only a subset of the world panels
# -------- Use only a subset of the world panels
# from bl_ui import properties_world
# # TORECREATE##DEPRECATED#properties_world.WORLD_PT_preview.COMPAT_ENGINES.add('POVRAY_RENDER')
@ -44,7 +43,7 @@ del properties_data_camera
# # TORECREATE##DEPRECATED#properties_world.WORLD_PT_world.COMPAT_ENGINES.add('POVRAY_RENDER')
# del properties_world
##################################
# -------- #
# Physics Main wrapping every class 'as is'
from bl_ui import properties_physics_common
@ -158,9 +157,9 @@ class WorldButtonsPanel:
return wld and (rd.engine in cls.COMPAT_ENGINES)
###############################################################################
# ---------------------------------------------------------------- #
# Camera Settings
###############################################################################
# ---------------------------------------------------------------- #
class CAMERA_PT_POV_cam_dof(CameraDataButtonsPanel, Panel):
"""Use this class for camera depth of field focal blur buttons."""
@ -236,9 +235,9 @@ class CAMERA_PT_POV_replacement_text(CameraDataButtonsPanel, Panel):
col.prop(cam.pov, "replacement_text", text="")
###############################################################################
# ---------------------------------------------------------------- #
# World background and sky sphere Settings
###############################################################################
# ---------------------------------------------------------------- #
class WORLD_PT_POV_world(WorldButtonsPanel, Panel):
@ -386,11 +385,11 @@ class RENDER_PT_POV_media(WorldButtonsPanel, Panel):
col.prop(scene.pov, "media_eccentricity", text="Eccentricity")
###############################################################################
# ---------------------------------------------------------------- #
# Lights settings
###############################################################################
# ---------------------------------------------------------------- #
################################################################################
# ----------------------------------------------------------------
# from bl_ui import properties_data_light
# for member in dir(properties_data_light):
# subclass = getattr(properties_data_light, member)
@ -401,16 +400,18 @@ class RENDER_PT_POV_media(WorldButtonsPanel, Panel):
# print('An exception occurred: {}'.format(e))
# pass
# del properties_data_light
#########################LIGHTS################################
# -------- LIGHTS -------- #
from bl_ui import properties_data_light
# # These panels are kept
# -------- These panels are kept
# properties_data_light.DATA_PT_custom_props_light.COMPAT_ENGINES.add('POVRAY_RENDER')
# properties_data_light.DATA_PT_context_light.COMPAT_ENGINES.add('POVRAY_RENDER')
## make some native panels contextual to some object variable
## by recreating custom panels inheriting their properties
# make some native panels contextual to some object variable
# by recreating custom panels inheriting their properties
class PovLightButtonsPanel(properties_data_light.DataButtonsPanel):
"""Use this class to define buttons from the light data tab of
properties window."""
@ -682,6 +683,7 @@ class OBJECT_PT_POV_rainbow(PovLightButtonsPanel, Panel):
bl_label = "POV-Ray Rainbow"
COMPAT_ENGINES = {'POVRAY_RENDER'}
# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
@ -750,12 +752,10 @@ def register():
for cls in classes:
register_class(cls)
bpy.types.LIGHT_PT_POV_light.prepend(light_panel_func)
LIGHT_PT_POV_light.prepend(light_panel_func)
def unregister():
bpy.types.LIGHT_PT_POV_light.remove(light_panel_func)
LIGHT_PT_POV_light.remove(light_panel_func)
for cls in reversed(classes):
unregister_class(cls)

View File

@ -29,18 +29,17 @@ from bpy.props import (
FloatProperty,
EnumProperty,
PointerProperty,
CollectionProperty,
)
from .shading_properties import (
active_texture_name_from_uilist,
active_texture_name_from_search,
brush_texture_update,
)
###############################################################################
# ---------------------------------------------------------------- #
# Camera POV properties.
###############################################################################
# ---------------------------------------------------------------- #
class RenderPovSettingsCamera(PropertyGroup):
"""Declare camera properties controllable in UI and translated to POV."""
@ -138,7 +137,7 @@ class RenderPovSettingsCamera(PropertyGroup):
scale: FloatProperty(name="Scale", min=0.0, default=1.0)
##################################CustomPOV Code############################
# ----------------------------------- CustomPOV Code ----------------------------------- #
# Only DUMMIES below for now:
replacement_text: StringProperty(
name="Texts in blend file",
@ -148,9 +147,9 @@ class RenderPovSettingsCamera(PropertyGroup):
)
###############################################################################
# ---------------------------------------------------------------- #
# Light POV properties.
###############################################################################
# ---------------------------------------------------------------- #
class RenderPovSettingsLight(PropertyGroup):
"""Declare light properties controllable in UI and translated to POV."""
@ -251,9 +250,9 @@ class RenderPovSettingsLight(PropertyGroup):
)
###############################################################################
# ---------------------------------------------------------------- #
# World POV properties.
###############################################################################
# ---------------------------------------------------------------- #
class RenderPovSettingsWorld(PropertyGroup):
"""Declare world properties controllable in UI and translated to POV."""
@ -353,20 +352,6 @@ class RenderPovSettingsWorld(PropertyGroup):
)
"""
# class WORLD_TEXTURE_SLOTS_UL_layerlist(bpy.types.UIList):
# texture_slots:
class WorldTextureSlots(bpy.props.PropertyGroup):
index = bpy.prop.PropertyInt(name='index')
# foo = random prop
bpy.types.World.texture_slots = bpy.props.CollectionProperty(type=PropertyGroup)
for i in range(18): # length of world texture slots
world.texture_slots.add()
"""
classes = (
RenderPovSettingsCamera,
RenderPovSettingsLight,

View File

@ -25,9 +25,10 @@ load, create or edit"""
import bpy
from bpy.props import StringProperty, BoolProperty, CollectionProperty
from bpy_extras.io_utils import ImportHelper
from bpy.utils import register_class, unregister_class
from mathutils import Vector
from math import pi
from math import pi, sqrt
def export_custom_code(file):
@ -44,7 +45,7 @@ def export_custom_code(file):
file.write("\n")
#############################IMPORT
# ----------------------------------- IMPORT
class ImportPOV(bpy.types.Operator, ImportHelper):
@ -75,8 +76,8 @@ class ImportPOV(bpy.types.Operator, ImportHelper):
verts = []
faces = []
materials = []
blend_mats = [] ##############
pov_mats = [] ##############
blend_mats = [] # XXX
pov_mats = [] # XXX
colors = []
mat_names = []
lenverts = None
@ -91,32 +92,28 @@ class ImportPOV(bpy.types.Operator, ImportHelper):
cylinder_search = False
sphere_search = False
cone_search = False
tex_search = False ##################
tex_search = False # XXX
cache = []
matrixes = {}
write_matrix = False
index = None
value = None
# file_pov = bpy.path.abspath(self.filepath) #was used for single files
# file_pov = bpy.path.abspath(self.filepath) # was used for single files
def mat_search(cache):
r = g = b = 0.5
f = t = 0
color = None
for item, value in enumerate(cache):
if value == 'texture':
pass
# if value == 'texture': # add more later
if value == 'pigment':
# Todo: create function for all color models.
# instead of current pass statements
# distinguish srgb from rgb into blend option
if cache[item + 2] in {'rgb', 'srgb'}:
pass
elif cache[item + 2] in {'rgbf', 'srgbf'}:
pass
elif cache[item + 2] in {'rgbt', 'srgbt'}:
try:
r, g, b, t = (
@ -197,8 +194,8 @@ class ImportPOV(bpy.types.Operator, ImportHelper):
S = S.replace(";", " ; ")
S = S.split()
# lenS = len(S) # Not used... why written?
for i, word in enumerate(S):
##################Primitives Import##################
for word in enumerate(S):
# -------- Primitives Import -------- #
if word == 'cone':
cone_search = True
name_search = False
@ -340,7 +337,7 @@ class ImportPOV(bpy.types.Operator, ImportHelper):
mat_search(cache)
cache = []
sphere_search = False
##################End Primitives Import##################
# -------- End Primitives Import -------- #
if word == '#declare':
name_search = True
if name_search:
@ -374,16 +371,16 @@ class ImportPOV(bpy.types.Operator, ImportHelper):
cache = []
# if word == 'face_indices':
# faces_search = True
if word == 'texture_list': ########
tex_search = True #######
if tex_search: #########
if word == 'texture_list': # XXX
tex_search = True # XXX
if tex_search: # XXX
if (
word not in {'texture_list', 'texture', '{', '}', 'face_indices'}
and not word.isdigit()
): ##############
pov_mats.append(word) #################
): # XXX
pov_mats.append(word) # XXX
if word == 'face_indices':
tex_search = False ################
tex_search = False # XXX
faces_search = True
if faces_search:
cache.append(word)
@ -423,34 +420,34 @@ class ImportPOV(bpy.types.Operator, ImportHelper):
# mesh = pov_define_mesh(None, verts, [], faces, name, hide_geometry=False)
# ob = object_utils.object_data_add(context, mesh, operator=None)
me = bpy.data.meshes.new(name) ########
ob = bpy.data.objects.new(name, me) ##########
bpy.context.collection.objects.link(ob) #########
me.from_pydata(verts, [], faces) ############
me = bpy.data.meshes.new(name) # XXX
ob = bpy.data.objects.new(name, me) # XXX
bpy.context.collection.objects.link(ob) # XXX
me.from_pydata(verts, [], faces) # XXX
for mat in bpy.data.materials: ##############
blend_mats.append(mat.name) #############
for m_name in pov_mats: #####################
if m_name not in blend_mats: ###########
povMat = bpy.data.materials.new(m_name) #################
for mat in bpy.data.materials: # XXX
blend_mats.append(mat.name) # XXX
for m_name in pov_mats: # XXX
if m_name not in blend_mats: # XXX
bpy.data.materials.new(m_name) # XXX
mat_search(cache)
ob.data.materials.append(
bpy.data.materials[m_name]
) ###################
if materials: ##################
for l, val in enumerate(materials): ####################
try: ###################
) # XXX
if materials: # XXX
for idx, val in enumerate(materials): # XXX
try: # XXX
ob.data.polygons[
l
].material_index = val ####################
except TypeError: ###################
ob.data.polygons[l].material_index = int(
idx
].material_index = val # XXX
except TypeError: # XXX
ob.data.polygons[idx].material_index = int(
val[0]
) ##################
) # XXX
blend_mats = [] #########################
pov_mats = [] #########################
materials = [] #########################
blend_mats = [] # XXX
pov_mats = [] # XXX
materials = [] # XXX
cache = []
name_search = True
if name in matrixes and not self.import_at_cur:
@ -510,7 +507,7 @@ class ImportPOV(bpy.types.Operator, ImportHelper):
# if color == colors[m]:
# ob.data.materials.append(bpy.data.materials[mat_names[m]])
##To keep Avogadro Camera angle:
# To keep Avogadro Camera angle:
# for obj in bpy.context.view_layer.objects:
# if obj.type == "CAMERA":
# track = obj.constraints.new(type = "TRACK_TO")
@ -521,9 +518,16 @@ class ImportPOV(bpy.types.Operator, ImportHelper):
return {'FINISHED'}
classes = (
ImportPOV,
)
def register():
bpy.utils.register_class(ImportPOV)
for cls in classes:
register_class(cls)
def unregister():
bpy.utils.unregister_class(ImportPOV)
for cls in reversed(classes):
unregister_class(cls)

View File

@ -72,7 +72,9 @@ def locate_docpath():
return ""
################################################################################
# ---------------------------------------------------------------- #
class TextButtonsPanel:
"""Use this class to define buttons from the side tab of
text window."""
@ -89,13 +91,13 @@ class TextButtonsPanel:
return text and (rd.engine in cls.COMPAT_ENGINES)
###############################################################################
# ---------------------------------------------------------------- #
# Text Povray Settings
###############################################################################
# ---------------------------------------------------------------- #
class TEXT_OT_POV_insert(Operator):
"""Use this class to create blender text editor operator to insert pov snippets like other pov IDEs"""
"""Create blender text editor operator to insert pov snippets like other pov IDEs"""
bl_idname = "text.povray_insert"
bl_label = "Insert"
@ -125,7 +127,7 @@ def validinsert(ext):
class TEXT_MT_POV_insert(Menu):
"""Use this class to create a menu launcher in text editor for the TEXT_OT_POV_insert operator ."""
"""Create a menu launcher in text editor for the TEXT_OT_POV_insert operator ."""
bl_label = "Insert"
bl_idname = "TEXT_MT_POV_insert"
@ -197,7 +199,7 @@ class TEXT_PT_POV_custom_code(TextButtonsPanel, Panel):
layout.label(text="replacement fields")
###############################################
# ---------------------------------------------------------------- #
# Text editor templates from header menu
@ -220,8 +222,10 @@ def menu_func_templates(self, context):
self.layout.menu("TEXT_MT_POV_templates")
###############################################
# ---------------------------------------------------------------- #
# POV Import menu
class VIEW_MT_POV_import(Menu):
"""Use this class for the import menu."""
@ -251,7 +255,6 @@ classes = (
def register():
for cls in classes:
register_class(cls)
@ -260,7 +263,6 @@ def register():
def unregister():
bpy.types.TEXT_MT_templates.remove(menu_func_templates)
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)

View File

@ -17,17 +17,17 @@
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
import bpy
"""Declare pov native file syntax properties controllable in UI hooks and text blocks"""
import bpy
from bpy.utils import register_class, unregister_class
from bpy.types import PropertyGroup
from bpy.props import EnumProperty, PointerProperty
###############################################################################
# ---------------------------------------------------------------- #
# Text POV properties.
###############################################################################
# ---------------------------------------------------------------- #
class RenderPovSettingsText(PropertyGroup):
@ -42,7 +42,9 @@ class RenderPovSettingsText(PropertyGroup):
)
classes = (RenderPovSettingsText,)
classes = (
RenderPovSettingsText,
)
def register():

View File

@ -23,10 +23,11 @@
import bpy
def write_object_material(material, ob, tab_write):
def write_object_material_interior(material, ob, tab_write):
"""Translate some object level material from Blender UI (VS data level)
to POV interior{} syntax and write it to exported file.
This is called in object_mesh_topology.export_meshes
"""
# DH - modified some variables to be function local, avoiding RNA write
# this should be checked to see if it is functionally correct
@ -107,23 +108,28 @@ def write_object_material(material, ob, tab_write):
def write_material(
using_uberpov, DEF_MAT_NAME, tab_write, safety, comments, unique_name, material_names, material
using_uberpov,
DEF_MAT_NAME,
tab_write,
safety,
comments,
unique_name,
material_names_dictionary,
material
):
"""Translate Blender material POV texture{} block and write to exported file."""
"""Translate Blender material to POV texture{} block and write in exported file."""
# Assumes only called once on each material
if material:
name_orig = material.name
name = material_names[name_orig] = unique_name(
bpy.path.clean_name(name_orig), material_names
name = material_names_dictionary[name_orig] = unique_name(
bpy.path.clean_name(name_orig), material_names_dictionary
)
else:
name = name_orig = DEF_MAT_NAME
if material:
# If saturation(.s) is not zero, then color is not grey, and has a tint
colored_specular_found = (material.pov.specular_color.s > 0.0) and (
material.pov.diffuse_shader != "MINNAERT"
)
else:
name = name_orig = DEF_MAT_NAME
##################
# Several versions of the finish: ref_level_bound conditions are variations for specular/Mirror
@ -185,7 +191,7 @@ def write_material(
# add a small value because 0.0 is invalid.
roughness += 1.0 / 511.0
################################Diffuse Shader######################################
# ------------------------------ Diffuse Shader ------------------------------ #
# Not used for Full spec (ref_level_bound=3) of the shader.
if material.pov.diffuse_shader == "OREN_NAYAR" and ref_level_bound != 3:
# Blender roughness is what is generally called oren nayar Sigma,
@ -209,7 +215,7 @@ def write_material(
tab_write("brilliance 1\n")
if ref_level_bound == 2:
###########################Specular Shader######################################
# ------------------------------ Specular Shader ------------------------------ #
# No difference between phong and cook torrence in blender HaHa!
if (
material.pov.specular_shader == "COOKTORR"
@ -247,7 +253,7 @@ def write_material(
# specular for some values.
tab_write("brilliance %.4g\n" % (1.8 - material.pov.specular_slope * 1.8))
####################################################################################
# -------------------------------------------------------------------------------- #
elif ref_level_bound == 1:
if (
material.pov.specular_shader == "COOKTORR"
@ -472,7 +478,7 @@ def export_pattern(texture):
# pov noise_generator 3 means perlin noise
if tex.type not in {"NONE", "IMAGE"} and pat.tex_pattern_type == "emulator":
text_strg += "pigment {\n"
####################### EMULATE BLENDER VORONOI TEXTURE ####################
# ------------------------- EMULATE BLENDER VORONOI TEXTURE ------------------------- #
if tex.type == "VORONOI":
text_strg += "crackle\n"
text_strg += " offset %.4g\n" % tex.nabla
@ -504,7 +510,7 @@ def export_pattern(texture):
text_strg += "[1 color rgbt<1,1,1,0>]\n"
text_strg += "}\n"
####################### EMULATE BLENDER CLOUDS TEXTURE ####################
# ------------------------- EMULATE BLENDER CLOUDS TEXTURE ------------------------- #
if tex.type == "CLOUDS":
if tex.noise_type == "SOFT_NOISE":
text_strg += "wrinkles\n"
@ -519,7 +525,7 @@ def export_pattern(texture):
text_strg += "[1 color rgbt<1,1,1,0>]\n"
text_strg += "}\n"
####################### EMULATE BLENDER WOOD TEXTURE ####################
# ------------------------- EMULATE BLENDER WOOD TEXTURE ------------------------- #
if tex.type == "WOOD":
if tex.wood_type == "RINGS":
text_strg += "wood\n"
@ -552,7 +558,7 @@ def export_pattern(texture):
text_strg += "[1 color rgbt<1,1,1,0>]\n"
text_strg += "}\n"
####################### EMULATE BLENDER STUCCI TEXTURE ####################
# ------------------------- EMULATE BLENDER STUCCI TEXTURE ------------------------- #
if tex.type == "STUCCI":
text_strg += "bozo\n"
text_strg += "scale 0.25\n"
@ -574,7 +580,7 @@ def export_pattern(texture):
text_strg += "[1 color rgbt<1,1,1,0>]\n"
text_strg += "}\n"
####################### EMULATE BLENDER MAGIC TEXTURE ####################
# ------------------------- EMULATE BLENDER MAGIC TEXTURE ------------------------- #
if tex.type == "MAGIC":
text_strg += "leopard\n"
if tex.use_color_ramp:
@ -589,7 +595,7 @@ def export_pattern(texture):
text_strg += "}\n"
text_strg += "scale 0.1\n"
####################### EMULATE BLENDER MARBLE TEXTURE ####################
# ------------------------- EMULATE BLENDER MARBLE TEXTURE ------------------------- #
if tex.type == "MARBLE":
text_strg += "marble\n"
text_strg += "turbulence 0.5\n"
@ -622,7 +628,7 @@ def export_pattern(texture):
if tex.noise_basis_2 == "SAW":
text_strg += "ramp_wave\n"
####################### EMULATE BLENDER BLEND TEXTURE ####################
# ------------------------- EMULATE BLENDER BLEND TEXTURE ------------------------- #
if tex.type == "BLEND":
if tex.progression == "RADIAL":
text_strg += "radial\n"
@ -665,7 +671,7 @@ def export_pattern(texture):
if tex.progression == "EASING":
text_strg += " poly_wave 1.5\n"
####################### EMULATE BLENDER MUSGRAVE TEXTURE ####################
# ------------------------- EMULATE BLENDER MUSGRAVE TEXTURE ------------------------- #
# if tex.type == 'MUSGRAVE':
# text_strg+="function{ f_ridged_mf( x, y, 0, 1, 2, 9, -0.5, 3,3 )*0.5}\n"
# text_strg+="color_map {\n"
@ -683,7 +689,7 @@ def export_pattern(texture):
"color_map {[0.5 color rgbf<0,0,0,1>][1 color rgbt<1,1,1,0>]}ramp_wave \n"
)
####################### EMULATE BLENDER DISTORTED NOISE TEXTURE ####################
# ------------------------- EMULATE BLENDER DISTORTED NOISE TEXTURE ------------------------- #
if tex.type == "DISTORTED_NOISE":
text_strg += "average\n"
text_strg += " pigment_map {\n"
@ -747,7 +753,7 @@ def export_pattern(texture):
text_strg += "]\n"
text_strg += " }\n"
####################### EMULATE BLENDER NOISE TEXTURE ####################
# ------------------------- EMULATE BLENDER NOISE TEXTURE ------------------------- #
if tex.type == "NOISE":
text_strg += "cells\n"
text_strg += "turbulence 3\n"
@ -760,7 +766,7 @@ def export_pattern(texture):
text_strg += "[1 color rgb<1,1,1,>]\n"
text_strg += "}\n"
####################### IGNORE OTHER BLENDER TEXTURE ####################
# ------------------------- IGNORE OTHER BLENDER TEXTURE ------------------------- #
else: # non translated textures
pass
text_strg += "}\n\n"
@ -839,7 +845,7 @@ def export_pattern(texture):
num_pattern,
pat.pave_form,
)
################ functions ##########################################################
# ------------------------- functions ------------------------- #
if pat.tex_pattern_type == "function":
text_strg += "{ %s" % pat.func_list
text_strg += "(x"
@ -973,7 +979,7 @@ def export_pattern(texture):
text_strg += ",%.4g" % pat.func_P8
text_strg += ",%.4g" % pat.func_P9
text_strg += ")}\n"
############## end functions ###############################################################
# ------------------------- end functions ------------------------- #
if pat.tex_pattern_type not in {"checker", "hexagon", "square", "triangular", "brick"}:
text_strg += "color_map {\n"
num_color = 0
@ -1041,7 +1047,7 @@ def string_strip_hyphen(name):
return name.replace("-", "")
# WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# WARNING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
def write_nodes(scene, pov_mat_name, ntree, file):
"""Translate Blender node trees to pov and write them to file."""
# such function local inlined import are official guidelines
@ -1490,7 +1496,7 @@ def write_nodes(scene, pov_mat_name, ntree, file):
link.to_node == node
and link.from_node.bl_idname == "ShaderPatternNode"
):
########### advanced ###############################################
# ------------ advanced ------------------------- #
lfn = link.from_node
pattern = lfn.pattern
if pattern == "agate":

View File

@ -38,14 +38,11 @@ from .shading_properties import check_material
def simple_material(mat):
"""Test if a material uses nodes"""
if (mat is not None) and (not mat.use_nodes):
return True
return False
return (mat is not None) and (not mat.use_nodes)
class MaterialButtonsPanel:
"""Use this class to define buttons from the material tab of
properties window."""
"""Use this class to define buttons from the material tab of properties window."""
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
@ -163,8 +160,9 @@ class MATERIAL_PT_POV_activate_node(MaterialButtonsPanel, Panel):
return (
mat
and mat.pov.type == "SURFACE"
and (engine in cls.COMPAT_ENGINES)
and not (mat.pov.material_use_nodes or mat.use_nodes)
and engine in cls.COMPAT_ENGINES
and not mat.pov.material_use_nodes
and not mat.use_nodes
)
def draw(self, context):
@ -196,50 +194,31 @@ class MATERIAL_PT_POV_active_node(MaterialButtonsPanel, Panel):
)
def draw(self, context):
layout = self.layout
mat = context.material
node_tree = mat.node_tree
if node_tree:
if node_tree and mat.use_nodes:
layout = self.layout
node = node_tree.nodes.active
if mat.use_nodes:
if node:
layout.prop(mat.pov, "material_active_node")
if node.bl_idname == "PovrayMaterialNode":
layout.context_pointer_set("node", node)
if hasattr(node, "draw_buttons_ext"):
node.draw_buttons_ext(context, layout)
elif hasattr(node, "draw_buttons"):
node.draw_buttons(context, layout)
value_inputs = [
socket
for socket in node.inputs
if socket.enabled and not socket.is_linked
]
if value_inputs:
layout.separator()
layout.label(text="Inputs:")
for socket in value_inputs:
row = layout.row()
socket.draw(context, row, node, socket.name)
else:
layout.context_pointer_set("node", node)
if hasattr(node, "draw_buttons_ext"):
node.draw_buttons_ext(context, layout)
elif hasattr(node, "draw_buttons"):
node.draw_buttons(context, layout)
value_inputs = [
socket
for socket in node.inputs
if socket.enabled and not socket.is_linked
]
if value_inputs:
layout.separator()
layout.label(text="Inputs:")
for socket in value_inputs:
row = layout.row()
socket.draw(context, row, node, socket.name)
else:
layout.label(text="No active nodes!")
if node:
layout.prop(mat.pov, "material_active_node")
layout.context_pointer_set("node", node)
if hasattr(node, "draw_buttons_ext"):
node.draw_buttons_ext(context, layout)
elif hasattr(node, "draw_buttons"):
node.draw_buttons(context, layout)
value_inputs = [
socket
for socket in node.inputs
if socket.enabled and not socket.is_linked
]
if value_inputs:
layout.separator()
layout.label(text="Inputs:")
for socket in value_inputs:
row = layout.row()
socket.draw(context, row, node, socket.name)
else:
layout.label(text="No active nodes!")
class MATERIAL_PT_POV_specular(MaterialButtonsPanel, Panel):
@ -452,8 +431,9 @@ class MATERIAL_PT_POV_reflection(MaterialButtonsPanel, Panel):
return (
mat
and mat.pov.type == "SURFACE"
and (engine in cls.COMPAT_ENGINES)
and not (mat.pov.material_use_nodes or mat.use_nodes)
and engine in cls.COMPAT_ENGINES
and not mat.pov.material_use_nodes
and not mat.use_nodes
)
def draw(self, context):
@ -491,7 +471,9 @@ class MATERIAL_PT_POV_interior(MaterialButtonsPanel, Panel):
def poll(cls, context):
engine = context.scene.render.engine
mat=context.material
return mat and mat.pov.type == "SURFACE" and (engine in cls.COMPAT_ENGINES) and not (mat.pov.material_use_nodes or mat.use_nodes)
return mat and mat.pov.type == "SURFACE"
and (engine in cls.COMPAT_ENGINES)
and not (mat.pov.material_use_nodes or mat.use_nodes)
def draw_header(self, context):
@ -513,8 +495,9 @@ class MATERIAL_PT_POV_fade_color(MaterialButtonsPanel, Panel):
return (
mat
and mat.pov.type == "SURFACE"
and (engine in cls.COMPAT_ENGINES)
and not (mat.pov.material_use_nodes or mat.use_nodes)
and engine in cls.COMPAT_ENGINES
and not mat.pov.material_use_nodes
and not mat.use_nodes
)
def draw_header(self, context):
@ -523,10 +506,10 @@ class MATERIAL_PT_POV_fade_color(MaterialButtonsPanel, Panel):
self.layout.prop(mat.pov, "interior_fade_color", text="")
def draw(self, context):
layout = self.layout
mat = context.material
# layout.active = mat.pov.interior_fade_color
if mat.pov.interior_fade_color != (0.0, 0.0, 0.0):
layout = self.layout
# layout.active = mat.pov.interior_fade_color
layout.label(text="Raytrace transparency")
layout.label(text="depth max Limit needs")
layout.label(text="to be non zero to fade")
@ -545,8 +528,9 @@ class MATERIAL_PT_POV_caustics(MaterialButtonsPanel, Panel):
return (
mat
and mat.pov.type == "SURFACE"
and (engine in cls.COMPAT_ENGINES)
and not (mat.pov.material_use_nodes or mat.use_nodes)
and engine in cls.COMPAT_ENGINES
and not mat.pov.material_use_nodes
and not mat.use_nodes
)
def draw_header(self, context):
@ -661,7 +645,7 @@ classes = (
MATERIAL_PT_POV_mirror,
MATERIAL_PT_POV_transp,
MATERIAL_PT_POV_reflection,
## MATERIAL_PT_POV_interior,
# MATERIAL_PT_POV_interior,
MATERIAL_PT_POV_fade_color,
MATERIAL_PT_POV_caustics,
MATERIAL_PT_POV_replacement_text,
@ -669,12 +653,10 @@ classes = (
def register():
for cls in classes:
register_class(cls)
def unregister():
for cls in reversed(classes):
unregister_class(cls)

View File

@ -34,9 +34,9 @@ import nodeitems_utils
from nodeitems_utils import NodeCategory, NodeItem
###############################################################################
# ---------------------------------------------------------------- #
# Pov Nodes init
###############################################################################
# ---------------------------------------------------------------- #
class PovraySocketUniversal(NodeSocket):
@ -550,9 +550,9 @@ node_categories = [
PovraySceneNodeCategory("ISOSURFACE", "Isosurface", items=[NodeItem("IsoPropsNode")]),
PovraySceneNodeCategory("FOG", "Fog", items=[NodeItem("PovrayFogNode")]),
]
############### end nodes init
############### nodes ui
##############Nodes
# -------- end nodes init
# -------- nodes ui
# -------- Nodes
# def find_node_input(node, name):
# for input in node.inputs:
@ -604,7 +604,7 @@ def menu_func_nodes(self, context):
self.layout.prop(tex.pov, "texture_use_nodes")
############### object
# -------- object
class ObjectNodeTree(bpy.types.NodeTree):
@ -633,7 +633,7 @@ class ObjectNodeTree(bpy.types.NodeTree):
self.refresh = True
################### output #############################################################################################
# -------- output # ---------------------------------------------------------------- #
class PovrayOutputNode(Node, ObjectNodeTree):
@ -661,7 +661,7 @@ class PovrayOutputNode(Node, ObjectNodeTree):
return "Output"
################### material ###########################################################################################
# -------- material # ---------------------------------------------------------------- #
class PovrayTextureNode(Node, ObjectNodeTree):
'''Texture'''
@ -867,7 +867,7 @@ class PovraySubsurfaceNode(Node, ObjectNodeTree):
return "Subsurface"
#####################################################################################################
# ---------------------------------------------------------------- #
class PovrayMappingNode(Node, ObjectNodeTree):
@ -1612,7 +1612,7 @@ class PovraySlopeNode(Node, TextureNodeTree):
return "Slope Map"
######################################## Texture nodes ###############################
# -------- Texture nodes # ---------------------------------------------------------------- #
class TextureOutputNode(Node, TextureNodeTree):
'''Output'''
@ -1634,9 +1634,9 @@ class TextureOutputNode(Node, TextureNodeTree):
return "Color Map"
##################################################################################
#################################Operators########################################
##################################################################################
# ------------------------------------------------------------------------------ #
# --------------------------------- Operators ---------------------------------- #
# ------------------------------------------------------------------------------ #
class NODE_OT_iso_add(Operator):
@ -1995,7 +1995,6 @@ classes = (
def register():
# from bpy.utils import register_class
bpy.types.NODE_HT_header.append(menu_func_nodes)
nodeitems_utils.register_node_categories("POVRAYNODES", node_categories)
for cls in classes:
@ -2003,8 +2002,6 @@ def register():
def unregister():
# from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
nodeitems_utils.unregister_node_categories("POVRAYNODES")

View File

@ -127,7 +127,7 @@ def brush_texture_update(self, context):
class RenderPovSettingsMaterial(PropertyGroup):
"""Declare material level properties controllable in UI and translated to POV."""
######################Begin Old Blender Internal Props#########################
# --------------------------- Begin Old Blender Internal Props --------------------------- #
# former Space properties from removed Blender Internal
use_limited_texture_context: BoolProperty(
name="",
@ -854,7 +854,7 @@ class RenderPovSettingsMaterial(PropertyGroup):
default="1",
)
##################################CustomPOV Code############################
# ------------------------------ CustomPOV Code ------------------------------ #
replacement_text: StringProperty(
name="Declared name:",
description="Type the variable name as declared either directly inlined "
@ -936,12 +936,9 @@ class RenderPovSettingsMaterial(PropertyGroup):
return node
def node_enum_callback(self, context):
items = []
mat = context.material
nodes = mat.node_tree.nodes
for node in nodes:
items.append(("%s" % node.name, "%s" % node.name, ""))
return items
return [("%s" % node.name, "%s" % node.name, "") for node in nodes]
def pigment_normal_callback(self, context):
render = context.scene.pov.render # XXX comment out > remove?
@ -2252,7 +2249,7 @@ class MaterialStrandSettings(PropertyGroup):
"""
#######################End Old Blender Internal Props##########################
# ------------------------------ End Old Blender Internal Props ------------------------------ #
classes = (

View File

@ -59,7 +59,6 @@ def write_texture_influence(
else:
pov_filter = 0.0
##############SF
texture_dif = ""
texture_spec = ""
texture_norm = ""
@ -166,7 +165,7 @@ def write_texture_influence(
# was the above used? --MR
t_alpha = t
####################################################################################
# -----------------------------------------------------------------------------
tab_write("\n")
# THIS AREA NEEDS TO LEAVE THE TEXTURE OPEN UNTIL ALL MAPS ARE WRITTEN DOWN.
@ -174,11 +173,11 @@ def write_texture_influence(
current_material_name = string_strip_hyphen(material_names_dictionary[mater.name])
local_material_names.append(current_material_name)
tab_write("\n#declare MAT_%s = \ntexture{\n" % current_material_name)
################################################################################
# -----------------------------------------------------------------------------
if mater.pov.replacement_text != "":
tab_write("%s\n" % mater.pov.replacement_text)
#################################################################################
# -----------------------------------------------------------------------------
# XXX TODO: replace by new POV MINNAERT rather than aoi
if mater.pov.diffuse_shader == "MINNAERT":
tab_write("\n")
@ -221,14 +220,13 @@ def write_texture_influence(
mapping_spec = img_map_transforms(t_spec)
if texture_spec and texture_spec.startswith("PAT_"):
tab_write("function{f%s(x,y,z).grey}\n" % texture_spec)
tab_write("%s\n" % mapping_spec)
else:
tab_write(
'uv_mapping image_map{%s "%s" %s}\n'
% (image_format(texture_spec), texture_spec, img_map(t_spec))
)
tab_write("%s\n" % mapping_spec)
tab_write("%s\n" % mapping_spec)
tab_write("}\n")
tab_write("texture_map {\n")
tab_write("[0 \n")
@ -270,14 +268,6 @@ def write_texture_influence(
% (col[0], col[1], col[2], pov_filter, trans)
)
if texture_spec != "":
# ref_level_bound 1 is no specular
tab_write("finish {%s}\n" % (safety(material_finish, ref_level_bound=1)))
else:
# ref_level_bound 2 is translated spec
tab_write("finish {%s}\n" % (safety(material_finish, ref_level_bound=2)))
else:
mapping_dif = img_map_transforms(t_dif)
@ -333,25 +323,25 @@ def write_texture_influence(
)
)
if texture_spec != "":
# ref_level_bound 1 is no specular
tab_write("finish {%s}\n" % (safety(material_finish, ref_level_bound=1)))
# scale 1 rotate y*0
# imageMap = ("{image_map {%s \"%s\" %s }\n" % \
# (image_format(textures),textures,img_map(t_dif)))
# tab_write("uv_mapping pigment %s} %s finish {%s}\n" % \
# (imageMap,mapping,safety(material_finish)))
# tab_write("pigment {uv_mapping image_map {%s \"%s\" %s}%s} " \
# "finish {%s}\n" % \
# (image_format(texture_dif), texture_dif, img_map(t_dif),
# mapping_dif, safety(material_finish)))
if texture_spec != "":
# ref_level_bound 1 is no specular
tab_write("finish {%s}\n" % (safety(material_finish, ref_level_bound=1)))
else:
# ref_level_bound 2 is translated specular
tab_write("finish {%s}\n" % (safety(material_finish, ref_level_bound=2)))
else:
# ref_level_bound 2 is translated spec
tab_write("finish {%s}\n" % (safety(material_finish, ref_level_bound=2)))
## scale 1 rotate y*0
# imageMap = ("{image_map {%s \"%s\" %s }\n" % \
# (image_format(textures),textures,img_map(t_dif)))
# tab_write("uv_mapping pigment %s} %s finish {%s}\n" % \
# (imageMap,mapping,safety(material_finish)))
# tab_write("pigment {uv_mapping image_map {%s \"%s\" %s}%s} " \
# "finish {%s}\n" % \
# (image_format(texture_dif), texture_dif, img_map(t_dif),
# mapping_dif, safety(material_finish)))
if texture_norm != "":
## scale 1 rotate y*0
# scale 1 rotate y*0
mapping_normal = img_map_transforms(t_nor)
@ -362,7 +352,8 @@ def write_texture_influence(
)
else:
tab_write("normal {\n")
# XXX TODO: fix and propagate the micro normals reflection blur below to non textured materials
# XXX TODO: fix and propagate the micro normals reflection blur below
# to non textured materials
if (
mater.pov_raytrace_mirror.use
and mater.pov_raytrace_mirror.gloss_factor < 1.0
@ -464,10 +455,10 @@ def write_texture_influence(
tab_write("]}}\n")
else:
tab_write("]}\n")
if texture_spec != "":
tab_write("]\n")
##################Second index for mapping specular max value###############
tab_write("[1 \n")
if texture_spec != "":
tab_write("]\n")
# -------- Second index for mapping specular max value -------- #
tab_write("[1 \n")
if texture_dif == "" and mater.pov.replacement_text == "":
if texture_alpha != "":
@ -673,7 +664,7 @@ def write_texture_influence(
# ref_level_bound 2 is translated specular
tab_write("finish {%s}\n" % (safety(material_finish, ref_level_bound=2)))
## scale 1 rotate y*0
# scale 1 rotate y*0
# imageMap = ("{image_map {%s \"%s\" %s }" % \
# (image_format(textures), textures,img_map(t_dif)))
# tab_write("\n\t\t\tuv_mapping pigment %s} %s finish {%s}" % \
@ -693,7 +684,8 @@ def write_texture_influence(
)
else:
tab_write("normal {\n")
# XXX TODO: fix and propagate the micro normals reflection blur below to non textured materials
# XXX TODO: fix and propagate the micro normals reflection blur below
# to non textured materials
if (
mater.pov_raytrace_mirror.use
and mater.pov_raytrace_mirror.gloss_factor < 1.0

View File

@ -83,13 +83,14 @@ class TEXTURE_MT_POV_specials(Menu):
class WORLD_TEXTURE_SLOTS_UL_POV_layerlist(UIList):
"""Use this class to show pov texture slots list.""" # XXX Not used yet
"""Use this class to show pov texture slots list."""
index: bpy.props.IntProperty(name='index')
# should active_propname be index or..?
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
world = context.scene.world # .pov
active_data = world.pov
# world = context.scene.world # .pov # NOT USED
# active_data = world.pov # NOT USED
# tex = context.texture #may be needed later?
# We could write some code to decide which icon to use here...
@ -120,6 +121,7 @@ class MATERIAL_TEXTURE_SLOTS_UL_POV_layerlist(UIList):
# texture_slots:
index: bpy.props.IntProperty(name='index')
# foo = random prop
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
# ob = data
slot = item
@ -149,6 +151,7 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel):
COMPAT_ENGINES = {'POVRAY_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
# register but not unregistered because
# the modified parts concern only POVRAY_RENDER
@classmethod
def poll(cls, context):
return (
@ -247,14 +250,16 @@ class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel):
if mat.pov_texture_slots:
index = mat.pov.active_texture_index
slot = mat.pov_texture_slots[index]
povtex = slot.texture # slot.name
tex = bpy.data.textures[povtex]
col.prop(tex, 'use_fake_user', text='')
# layout.label(text='Linked Texture data browser:')
# propname = slot.texture_search
# if slot.texture was a pointer to texture data rather than just a name string:
# layout.template_ID(povtex, "texture", new="texture.new")
try:
povtex = slot.texture # slot.name
tex = bpy.data.textures[povtex]
col.prop(tex, 'use_fake_user', text='')
# layout.label(text='Linked Texture data browser:')
# propname = slot.texture_search
# if slot.texture was a pointer to texture data rather than just a name string:
# layout.template_ID(povtex, "texture", new="texture.new")
except KeyError:
tex = None
layout.prop_search(
slot, 'texture_search', bpy.data, 'textures', text='', icon='TEXTURE'
)
@ -308,7 +313,7 @@ class TEXTURE_PT_POV_context_texture(TextureButtonsPanel, Panel):
tex = bpy.data.textures[povtex]
col.prop(tex, 'use_fake_user', text='')
# layout.label(text='Linked Texture data browser:')
propname = slot.texture_search
# propname = slot.texture_search # NOT USED
# if slot.texture was a pointer to texture data rather than just a name string:
# layout.template_ID(povtex, "texture", new="texture.new")
@ -614,10 +619,9 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel):
def draw(self, context):
# mat = bpy.context.active_object.active_material # Unused
layout = self.layout
tex = context.texture
align = True
if tex is not None and tex.pov.tex_pattern_type != 'emulator':
layout = self.layout
if tex.pov.tex_pattern_type == 'agate':
layout.prop(tex.pov, "modifier_turbulence", text="Agate Turbulence")
if tex.pov.tex_pattern_type in {'spiral1', 'spiral2'}:
@ -626,6 +630,7 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel):
layout.prop(tex.pov, "modifier_numbers", text="Pattern number")
if tex.pov.tex_pattern_type == 'magnet':
layout.prop(tex.pov, "magnet_style", text="Magnet style")
align = True
if tex.pov.tex_pattern_type == 'quilted':
row = layout.row(align=align)
row.prop(tex.pov, "modifier_control0", text="Control0")
@ -825,7 +830,7 @@ class TEXTURE_PT_POV_parameters(TextureButtonsPanel, Panel):
row = layout.row(align=align)
row.prop(tex.pov, "func_P8", text="P8")
row.prop(tex.pov, "func_P9", text="P9")
###################################################End Patterns############################
# ------------------------- End Patterns ------------------------- #
layout.prop(tex.pov, "warp_types", text="Warp types") # warp
if tex.pov.warp_types == "TOROIDAL":
@ -987,6 +992,7 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
# bl_context = 'texture'
@classmethod
def poll(cls, context):
idblock = pov_context_tex_datablock(context)
@ -1015,8 +1021,11 @@ class TEXTURE_PT_POV_influence(TextureSlotPanel, Panel):
texslot = idblock.pov_texture_slots[
idblock.pov.active_texture_index
] # bpy.data.textures[mat.active_texture_index]
# below tex is unused
tex = bpy.data.textures[idblock.pov_texture_slots[idblock.pov.active_texture_index].texture]
# below tex unused yet ...maybe for particles?
try:
tex = bpy.data.textures[idblock.pov_texture_slots[idblock.pov.active_texture_index].texture] # NOT USED
except KeyError:
tex = None # NOT USED
def factor_but(layout, toggle, factor, name):
row = layout.row(align=True)
@ -1224,6 +1233,7 @@ class TEXTURE_PT_POV_tex_gamma(TextureButtonsPanel, Panel):
classes = (
WORLD_TEXTURE_SLOTS_UL_POV_layerlist,
TEXTURE_MT_POV_specials,
# TEXTURE_PT_context # todo: solve UI design for painting
TEXTURE_PT_POV_context_texture,
TEXTURE_PT_colors,
TEXTURE_PT_POV_type,
@ -1239,13 +1249,11 @@ classes = (
def register():
for cls in classes:
register_class(cls)
def unregister():
for cls in reversed(classes):
if cls != TEXTURE_PT_context:
unregister_class(cls)
# if cls != TEXTURE_PT_context:
unregister_class(cls)

View File

@ -17,6 +17,7 @@
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
"""Declare texturing properties controllable in UI."""
import bpy
@ -35,9 +36,11 @@ from bpy.props import (
from .shading_properties import active_texture_name_from_uilist, active_texture_name_from_search
###############################################################################
# ---------------------------------------------------------------- #
# Texture slots (Material context) exported as POV texture properties.
###############################################################################
# ---------------------------------------------------------------- #
class MaterialTextureSlot(PropertyGroup):
"""Declare material texture slot level properties for UI and translated to POV."""
@ -381,7 +384,7 @@ class MaterialTextureSlot(PropertyGroup):
default=0.0,
)
#######################################
# ---------------------------------------------------------------- #
blend_factor: FloatProperty(
name="Blend",
@ -461,9 +464,9 @@ class MaterialTextureSlot(PropertyGroup):
)
###############################################################################
# ---------------------------------------------------------------- #
# Texture slots (World context) exported as POV texture properties.
###############################################################################
# ---------------------------------------------------------------- #
class WorldTextureSlot(PropertyGroup):
"""Declare world texture slot level properties for UI and translated to POV."""
@ -583,9 +586,9 @@ class WorldTextureSlot(PropertyGroup):
)
###############################################################################
# ---------------------------------------------------------------- #
# Space properties from removed former Blender Internal
###############################################################################
# ---------------------------------------------------------------- #
# added below at superclass level so as to be available in World, Material,
# and Light, for texture slots use
@ -614,9 +617,9 @@ bpy.types.ID.texture_context = EnumProperty(
# )
###############################################################################
# ---------------------------------------------------------------- #
# Texture POV properties.
###############################################################################
# ---------------------------------------------------------------- #
class RenderPovSettingsTexture(PropertyGroup):
@ -682,7 +685,7 @@ class RenderPovSettingsTexture(PropertyGroup):
default=1.00,
)
##################################CustomPOV Code############################
# ----------------------------------- CustomPOV Code ----------------------------------- #
# commented out below if we wanted custom pov code in texture only, inside exported material:
# replacement_text = StringProperty(
# name="Declared name:",
@ -953,8 +956,7 @@ class RenderPovSettingsTexture(PropertyGroup):
pave_form: IntProperty(name="Pavement form", description="", min=0, max=4, default=0)
#########FUNCTIONS#############################################################################
#########FUNCTIONS#############################################################################
# -------- FUNCTIONS# ---------------------------------------------------------------- #
func_list: EnumProperty(
name="Functions",
@ -1090,7 +1092,7 @@ class RenderPovSettingsTexture(PropertyGroup):
func_P9: FloatProperty(name="P9", description="", min=0.0, max=25.0, default=1.0)
#########################################
# ----------------------------------- #
tex_rot_x: FloatProperty(name="Rotate X", description="", min=-180.0, max=180.0, default=0.0)
tex_rot_y: FloatProperty(name="Rotate Y", description="", min=-180.0, max=180.0, default=0.0)
@ -1116,7 +1118,11 @@ class RenderPovSettingsTexture(PropertyGroup):
tex_scale_z: FloatProperty(name="Scale Z", description="", min=0.0, max=10000.0, default=1.0)
classes = (MaterialTextureSlot, WorldTextureSlot, RenderPovSettingsTexture)
classes = (
MaterialTextureSlot,
WorldTextureSlot,
RenderPovSettingsTexture,
)
def register():

View File

@ -55,105 +55,119 @@ def update2_0_0_9():
# Mapping old names -> old default values
# XXX We could also store the new name, but as it is just the same without leading pov_ ...
# Get default values of pov scene props.
old_sce_props = {}
for k in [
"pov_tempfiles_enable",
"pov_deletefiles_enable",
"pov_scene_name",
"pov_scene_path",
"pov_renderimage_path",
"pov_list_lf_enable",
"pov_radio_enable",
"pov_radio_display_advanced",
"pov_media_enable",
"pov_media_samples",
"pov_media_color",
"pov_baking_enable",
"pov_indentation_character",
"pov_indentation_spaces",
"pov_comments_enable",
"pov_command_line_switches",
"pov_antialias_enable",
"pov_antialias_method",
"pov_antialias_depth",
"pov_antialias_threshold",
"pov_jitter_enable",
"pov_jitter_amount",
"pov_antialias_gamma",
"pov_max_trace_level",
"pov_photon_spacing",
"pov_photon_max_trace_level",
"pov_photon_adc_bailout",
"pov_photon_gather_min",
"pov_photon_gather_max",
"pov_radio_adc_bailout",
"pov_radio_always_sample",
"pov_radio_brightness",
"pov_radio_count",
"pov_radio_error_bound",
"pov_radio_gray_threshold",
"pov_radio_low_error_factor",
"pov_radio_media",
"pov_radio_minimum_reuse",
"pov_radio_nearest_count",
"pov_radio_normal",
"pov_radio_recursion_limit",
"pov_radio_pretrace_start",
"pov_radio_pretrace_end",
]:
old_sce_props[k] = getattr(bpy.types.Scene, k)[1].get('default', None)
old_sce_props = {
k: getattr(bpy.types.Scene, k)[1].get('default', None)
for k in [
"pov_tempfiles_enable",
"pov_deletefiles_enable",
"pov_scene_name",
"pov_scene_path",
"pov_renderimage_path",
"pov_list_lf_enable",
"pov_radio_enable",
"pov_radio_display_advanced",
"pov_media_enable",
"pov_media_samples",
"pov_media_color",
"pov_baking_enable",
"pov_indentation_character",
"pov_indentation_spaces",
"pov_comments_enable",
"pov_command_line_switches",
"pov_antialias_enable",
"pov_antialias_method",
"pov_antialias_depth",
"pov_antialias_threshold",
"pov_jitter_enable",
"pov_jitter_amount",
"pov_antialias_gamma",
"pov_max_trace_level",
"pov_photon_spacing",
"pov_photon_max_trace_level",
"pov_photon_adc_bailout",
"pov_photon_gather_min",
"pov_photon_gather_max",
"pov_radio_adc_bailout",
"pov_radio_always_sample",
"pov_radio_brightness",
"pov_radio_count",
"pov_radio_error_bound",
"pov_radio_gray_threshold",
"pov_radio_low_error_factor",
"pov_radio_media",
"pov_radio_minimum_reuse",
"pov_radio_nearest_count",
"pov_radio_normal",
"pov_radio_recursion_limit",
"pov_radio_pretrace_start",
"pov_radio_pretrace_end",
]
}
# Get default values of pov material props.
old_mat_props = {}
for k in [
"pov_irid_enable",
"pov_mirror_use_IOR",
"pov_mirror_metallic",
"pov_conserve_energy",
"pov_irid_amount",
"pov_irid_thickness",
"pov_irid_turbulence",
"pov_interior_fade_color",
"pov_caustics_enable",
"pov_fake_caustics",
"pov_fake_caustics_power",
"pov_photons_refraction",
"pov_photons_dispersion",
"pov_photons_reflection",
"pov_refraction_type",
"pov_replacement_text",
]:
old_mat_props[k] = getattr(bpy.types.Material, k)[1].get('default', None)
old_mat_props = {
k: getattr(bpy.types.Material, k)[1].get('default', None)
for k in [
"pov_irid_enable",
"pov_mirror_use_IOR",
"pov_mirror_metallic",
"pov_conserve_energy",
"pov_irid_amount",
"pov_irid_thickness",
"pov_irid_turbulence",
"pov_interior_fade_color",
"pov_caustics_enable",
"pov_fake_caustics",
"pov_fake_caustics_power",
"pov_photons_refraction",
"pov_photons_dispersion",
"pov_photons_reflection",
"pov_refraction_type",
"pov_replacement_text",
]
}
# Get default values of pov texture props.
old_tex_props = {}
for k in ["pov_tex_gamma_enable", "pov_tex_gamma_value", "pov_replacement_text"]:
old_tex_props[k] = getattr(bpy.types.Texture, k)[1].get('default', None)
old_tex_props = {
k: getattr(bpy.types.Texture, k)[1].get('default', None)
for k in [
"pov_tex_gamma_enable",
"pov_tex_gamma_value",
"pov_replacement_text",
]
}
# Get default values of pov object props.
old_obj_props = {}
for k in ["pov_importance_value", "pov_collect_photons", "pov_replacement_text"]:
old_obj_props[k] = getattr(bpy.types.Object, k)[1].get('default', None)
old_obj_props = {
k: getattr(bpy.types.Object, k)[1].get('default', None)
for k in [
"pov_importance_value",
"pov_collect_photons",
"pov_replacement_text",
]
}
# Get default values of pov camera props.
old_cam_props = {}
for k in [
"pov_dof_enable",
"pov_dof_aperture",
"pov_dof_samples_min",
"pov_dof_samples_max",
"pov_dof_variance",
"pov_dof_confidence",
"pov_replacement_text",
]:
old_cam_props[k] = getattr(bpy.types.Camera, k)[1].get('default', None)
old_cam_props = {
k: getattr(bpy.types.Camera, k)[1].get('default', None)
for k in [
"pov_dof_enable",
"pov_dof_aperture",
"pov_dof_samples_min",
"pov_dof_samples_max",
"pov_dof_variance",
"pov_dof_confidence",
"pov_replacement_text",
]
}
# Get default values of pov text props.
old_txt_props = {}
for k in ["pov_custom_code"]:
old_txt_props[k] = getattr(bpy.types.Text, k)[1].get('default', None)
old_txt_props = {
k: getattr(bpy.types.Text, k)[1].get('default', None)
for k in ["pov_custom_code"]
}
################################################################################################
# -----------------------------------------------------------------------------
# Now, update !
# For each old pov property of each scene, if its value is not equal to the default one,
# copy it to relevant new prop...
@ -215,7 +229,7 @@ def register():
Obj = bpy.types.Object
Cam = bpy.types.Camera
Text = bpy.types.Text
###########################SCENE##################################
# -------------------------------------- SCENE --------------------------------------#
# File Options
Scene.pov_tempfiles_enable = BoolProperty(
@ -549,7 +563,7 @@ def register():
precision=3,
)
#############################MATERIAL######################################
# -------------------------------------- MATERIAL -------------------------------------- #
Mat.pov_irid_enable = BoolProperty(
name="Enable Iridescence",
@ -668,7 +682,7 @@ def register():
description="use fake caustics (fast) or true photons for refractive Caustics",
default="1",
)
##################################CustomPOV Code############################
# -------------------------------------- CustomPOV Code -------------------------------------- #
Mat.pov_replacement_text = StringProperty(
name="Declared name:",
description="Type the declared name in custom POV code or an external .inc it points at. texture {} expected",
@ -693,7 +707,7 @@ def register():
description="Type the declared name in custom POV code or an external .inc it points at. camera {} expected",
default="",
)
##############################TEXTURE######################################
# -------------------------------------- TEXTURE -------------------------------------- #
# Custom texture gamma
Tex.pov_tex_gamma_enable = BoolProperty(
@ -712,7 +726,7 @@ def register():
default=1.00,
)
#################################OBJECT####################################
# -------------------------------------- OBJECT -------------------------------------- #
# Importance sampling
Obj.pov_importance_value = FloatProperty(
@ -730,7 +744,7 @@ def register():
default=True,
)
##################################CAMERA###################################
# -------------------------------------- CAMERA -------------------------------------- #
# DOF Toggle
Cam.pov_dof_enable = BoolProperty(
@ -780,7 +794,7 @@ def register():
default=0.90,
)
###################################TEXT####################################
# -------------------------------------- TEXT -------------------------------------- #
Text.pov_custom_code = BoolProperty(
name="Custom Code",

View File

@ -401,7 +401,7 @@ def deactivate_custom_properties(obj, *, reset=True):
for key, value in obj.items():
valtype = type(value)
if valtype in {int, float}:
info = rna_idprop_ui_prop_get(obj, key, False) or {}
info = rna_idprop_ui_prop_get(obj, key, create=False) or {}
obj[key] = valtype(info.get("default", 0))
@ -435,7 +435,7 @@ def copy_custom_properties(src, dest, *, prefix='', dest_prefix='', link_driver=
dest[new_key] = value
if info:
info2 = rna_idprop_ui_prop_get(dest, new_key, True)
info2 = rna_idprop_ui_prop_get(dest, new_key, create=True)
for ki, vi in info.items():
info2[ki] = vi

View File

@ -136,7 +136,7 @@ brush_icons = {}
def create_icons():
global brush_icons
icons_directory = bpy.utils.system_resource('DATAFILES', "icons")
icons_directory = bpy.utils.system_resource('DATAFILES', path="icons")
brushes = ["crease", "blob", "smooth", "draw", "clay", "clay_strips", "inflate", "grab",
"nudge", "thumb", "snake_hook", "rotate", "flatten", "scrape", "fill", "pinch",
"layer", "mask"]

View File

@ -73,14 +73,17 @@ class UI_OT_i18n_edittranslation_update_mo(Operator):
def execute(self, context):
if self.clean_mo:
root = bpy.utils.user_resource('DATAFILES', settings.settings.MO_PATH_ROOT_RELATIVE)
root = bpy.utils.user_resource('DATAFILES', path=settings.settings.MO_PATH_ROOT_RELATIVE)
if root:
shutil.rmtree(root)
elif not (self.lang and self.po_file):
return {'CANCELLED'}
else:
mo_dir = bpy.utils.user_resource('DATAFILES', settings.settings.MO_PATH_TEMPLATE_RELATIVE.format(self.lang),
create=True)
mo_dir = bpy.utils.user_resource(
'DATAFILES',
path=settings.settings.MO_PATH_TEMPLATE_RELATIVE.format(self.lang),
create=True,
)
mo_file = os.path.join(mo_dir, settings.settings.MO_FILE_NAME)
_get_messages(self.lang, self.po_file).write(kind='MO', dest=mo_file)

View File

@ -71,7 +71,7 @@ def enum_addons(self, context):
global _cached_enum_addons
setts = getattr(self, "settings", settings.settings)
if not _cached_enum_addons:
for mod in addon_utils.modules(addon_utils.addons_fake_modules):
for mod in addon_utils.modules(module_cache=addon_utils.addons_fake_modules):
mod_info = addon_utils.module_bl_info(mod)
# Skip OFFICIAL addons, they are already translated in main i18n system (together with Blender itself).
if mod_info["support"] in {'OFFICIAL'}: