[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2002] trunk/py/scripts/addons/ render_povray/render.py: Render POVRay addon: Now using instances for objects?\226?\128?\153 data, to avoid having exported hundred times the same mesh/materi
Daniel Salazar - 3Developer.com
zanqdo at gmail.com
Sun Jun 5 11:29:35 CEST 2011
Haven't tried it but a after a quick read trough the commit log i
think this is an incorrect implementation of instances. Only duplis
should be treated as instances since objects with shared data have a
different derived mesh, meaning different modifiers. This is the same
reason why blender internal sees *only* duplis as instances for the
renderer
Daniel Salazar
3Developer.com
On Sun, Jun 5, 2011 at 1:56 AM, Bastien Montagne <montagne29 at wanadoo.fr> wrote:
> Revision: 2002
> http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2002
> Author: mont29
> Date: 2011-06-05 07:56:28 +0000 (Sun, 05 Jun 2011)
> Log Message:
> -----------
> Render POVRay addon: Now using instances for objects?\226?\128?\153 data, to avoid having exported hundred times the same mesh/material?\226?\128?\166
> Coded in collaboration with MauriciusRay.
>
> Modified Paths:
> --------------
> trunk/py/scripts/addons/render_povray/render.py
>
> Modified: trunk/py/scripts/addons/render_povray/render.py
> ===================================================================
> --- trunk/py/scripts/addons/render_povray/render.py 2011-06-04 06:37:05 UTC (rev 2001)
> +++ trunk/py/scripts/addons/render_povray/render.py 2011-06-05 07:56:28 UTC (rev 2002)
> @@ -30,7 +30,6 @@
> ##############find image texture
>
>
> -# XXX A simple dict would be much simpler for this… --mont29
> def imageFormat(imgF):
> ext = {
> 'JPG': "jpeg",
> @@ -233,6 +232,13 @@
> matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0],
> matrix[3][1], matrix[3][2]))
>
> + def MatrixAsPovString(matrix):
> + sMatrix=("matrix <%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, " \
> + "%.6f>\n" % (matrix[0][0], matrix[0][1], matrix[0][2], matrix[1][0], matrix[1][1],
> + matrix[1][2], matrix[2][0], matrix[2][1], matrix[2][2], matrix[3][0],
> + matrix[3][1], matrix[3][2]))
> + return sMatrix
> +
> def writeObjectMaterial(material, ob):
>
> # DH - modified some variables to be function local, avoiding RNA write
> @@ -740,24 +746,92 @@
> if not scene.pov.tempfiles_enable and scene.pov.comments_enable and len(metas) >= 1:
> file.write("\n")
>
> - objectNames = {}
> +# objectNames = {}
> DEF_OBJ_NAME = "Default"
>
> - def exportMeshs(scene, sel):
> + def exportMeshes(scene, sel):
> +# obmatslist = []
> +# def hasUniqueMaterial():
> +# # Grab materials attached to object instances ...
> +# if hasattr(ob, 'material_slots'):
> +# for ms in ob.material_slots:
> +# if ms.material != None and ms.link == 'OBJECT':
> +# if ms.material in obmatslist:
> +# return False
> +# else:
> +# obmatslist.append(ms.material)
> +# return True
> +# def hasObjectMaterial(ob):
> +# # Grab materials attached to object instances ...
> +# if hasattr(ob, 'material_slots'):
> +# for ms in ob.material_slots:
> +# if ms.material != None and ms.link == 'OBJECT':
> +# # If there is at least one material slot linked to the object
> +# # and not the data (mesh), always create a new, “private” data instance.
> +# return True
> +# return False
> + # For objects using local material(s) only!
> + # This is a mapping between a tuple (dataname, materialnames, …), and the POV dataname.
> + # As only objects using:
> + # * The same data.
> + # * EXACTLY the same materials, in EXACTLY the same sockets.
> + # … can share a same instance in POV export.
> + obmats2data = {}
> + def checkObjectMaterials(ob, name, dataname):
> + if hasattr(ob, 'material_slots'):
> + has_local_mats = False
> + key = [dataname]
> + for ms in ob.material_slots:
> + if ms.material != None:
> + key.append(ms.material.name)
> + if ms.link == 'OBJECT' and not has_local_mats:
> + has_local_mats = True
> + else:
> + # Even if the slot is empty, it is important to grab it…
> + key.append("")
> + if has_local_mats:
> + # If this object uses local material(s), lets find if another object
> + # using the same data and exactly the same list of materials
> + # (in the same slots) has already been processed…
> + # Note that here also, we use object name as new, unique dataname for Pov.
> + key = tuple(key) # Lists are not hashable…
> + if key not in obmats2data:
> + obmats2data[key] = name
> + return obmats2data[key]
> + return None
>
> + data_ref = {}
> + def store(scene, ob, name, dataname, matrix):
> + # The Object needs to be written at least once but if its data is
> + # already in data_ref this has already been done.
> + # This func returns the “povray” name of the data, or None
> + # if no writing is needed.
> + if ob.is_modified(scene, 'RENDER'):
> + # Data modified.
> + # Create unique entry in data_ref by using object name
> + # (always unique in Blender) as data name.
> + data_ref[name] = [(name, MatrixAsPovString(matrix))]
> + return name
> + # Here, we replace dataname by the value returned by checkObjectMaterials, only if
> + # it is not evaluated to False (i.e. only if the object uses some local material(s)).
> + dataname = checkObjectMaterials(ob, name, dataname) or dataname
> + if dataname in data_ref:
> + # Data already known, just add the object instance.
> + data_ref[dataname].append((name, MatrixAsPovString(matrix)))
> + # No need to write data
> + return None
> + else:
> + # Data not yet processed, create a new entry in data_ref.
> + data_ref[dataname] = [(name, MatrixAsPovString(matrix))]
> + return dataname
> +
> +
> ob_num = 0
> -
> for ob in sel:
> ob_num += 1
> -#############################################
> - #Generating a name for object just like materials to be able to use it
> - # (baking for now or anything else).
> - if sel:
> - name_orig = ob.name
> - else:
> - name_orig = DEF_OBJ_NAME
> - name = objectNames[name_orig] = uniqueName(bpy.path.clean_name(name_orig), objectNames)
> -#############################################
> +
> + # XXX I moved all those checks here, as there is no need to compute names
> + # for object we won’t export here!
> if ob.type in ('LAMP', 'CAMERA', 'EMPTY', 'META', 'ARMATURE', 'LATTICE'):
> continue
>
> @@ -774,6 +848,25 @@
> if not me or not me_faces:
> continue
>
> +#############################################
> + # 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 sel:
> + name_orig = "OB" + ob.name
> + dataname_orig = "DATA" + ob.data.name
> + else:
> + name_orig = DEF_OBJ_NAME
> + dataname_orig = DEF_OBJ_NAME
> + name = splitHyphen(bpy.path.clean_name(name_orig))
> + dataname = splitHyphen(bpy.path.clean_name(dataname_orig))
> +## for slot in ob.material_slots:
> +## if slot.material != 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))
>
> @@ -782,6 +875,13 @@
> # me = ob.data
>
> matrix = global_matrix * ob.matrix_world
> + povdataname = store(scene, ob, name, dataname, matrix)
> + if povdataname is None:
> + print("This is an instance")
> + continue
> +
> + print("Writing Down First Occurence")
> +
> try:
> uv_layer = me.uv_textures.active.data
> except AttributeError:
> @@ -801,7 +901,7 @@
>
> # Use named declaration to allow reference e.g. for baking. MR
> file.write("\n")
> - tabWrite("#declare %s =\n" % name)
> + tabWrite("#declare %s =\n" % povdataname)
> tabWrite("mesh2 {\n")
> tabWrite("vertex_vectors {\n")
> tabWrite("%d" % len(me.vertices)) # vert count
> @@ -1427,7 +1527,6 @@
> except IndexError:
> print(me)
>
> - writeMatrix(matrix)
>
> #Importance for radiosity sampling added here:
> tabWrite("radiosity { \n")
> @@ -1435,10 +1534,17 @@
> tabWrite("}\n")
>
> tabWrite("}\n") # End of mesh block
> - tabWrite("%s\n" % name) # Use named declaration to allow reference e.g. for baking. MR
>
> bpy.data.meshes.remove(me)
>
> + for data_name, inst in data_ref.items():
> + for ob_name, matrix_str in inst:
> + tabWrite("//----Blender Object Name:%s----\n" % ob_name)
> + tabWrite("object { \n")
> + tabWrite("%s\n" % data_name)
> + tabWrite("%s\n" % matrix_str)
> + tabWrite("}\n")
> +
> def exportWorld(world):
> render = scene.render
> camera = scene.camera
> @@ -1477,6 +1583,7 @@
> texturesBlend = image_filename
> #colvalue = t.default_value
> t_blend = t
> +
> # Commented below was an idea to make the Background image oriented as camera
> # taken here:
> #http://news.povray.org/povray.newusers/thread/%3Cweb.4a5cddf4e9c9822ba2f93e20@news.povray.org%3E/
> @@ -1598,7 +1705,9 @@
> tabWrite("pretrace_end %.3g\n" % scene.pov.radio_pretrace_end)
> tabWrite("recursion_limit %d\n" % scene.pov.radio_recursion_limit)
> tabWrite("}\n")
> - once = 1
> + onceSss = 1
> + onceAmbient = 1
> + oncePhotons = 1
> for material in bpy.data.materials:
> if material.subsurface_scattering.use and once:
> # In pov, the scale has reversed influence compared to blender. these number
> @@ -1606,18 +1715,20 @@
> tabWrite("mm_per_unit %.6f\n" % \
> (material.subsurface_scattering.scale * (-100.0) + 15.0))
> # In POV-Ray, the scale factor for all subsurface shaders needs to be the same
> - once = 0
> + onceSss = 0
>
> - if world:
> + if world and onceAmbient:
>
> @@ Diff output truncated at 10240 characters. @@
> _______________________________________________
> Bf-extensions-cvs mailing list
> Bf-extensions-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-extensions-cvs
>
More information about the Bf-extensions-cvs
mailing list