Blender
Python : animation
LOD-o-matic, 
level of details for animation 
(version française)
Beginning Index
previous Script Python
En chantier Nextt
Attention : 
sorry but this script does not work with Blender 2.40 .

In 3d animation, the computing times can be very long unless reducing the definition of the objects according to their distance from the camera. In Blender, the python scripting makes it possible to automate this operation. 
 
 

Surface subdivision
Automation for Motion
Bind the  script to the scene
Caméra state
To accelerate a little by using Bounding Box
Download the script and a blend file
EDITMODE Variable : to limit the effect to rendered animation

Surface Subdivision 

Blender offers an option of surface subdivision of the Catmull-Clarck type with 7 levels of smoothness (0->6) applicable to the objects of the meshes type.  Certain artists are using this tool to reduce the weight of the objects according to the distance. A value of 4 or 5 for the objects closest to the camera (beyond the number of faces would be  prohibitory) and 0 for most distant. 


[ Figure 1 ]. 

Automation for motion 

Only one trouble:  this operation  must be carried out by hand and is not very practical during an  animation because it is necessary to recalibrate division between each  image. It is the kind of work which a script can do while being connected to current animation to carry out computation in background task at each change of frame 


To bind a script to the scene.

The whole of the objects used in current animation is gathered in a "scene" :

In python, everything that is related to a scene (rendering information, lists of objects related to this scene, for example) is managed through a module of the same name. The first  thing to do is to obtain a variable representing the scene object thanks to the method: 
 

SCENE=Scene.getCurrent()

To facilitate comprehension, one writes all the variables in uppercase letter. 
The lamps objects, the cameras as well as the scenes have a method which makes it possible to automatically associate a script to them, which will be executed at each change of frame: 
 

SCENE.addScriptLink(NAME,EVENT) 

The bond should be established only once, which obliges us to recover and to test the list of already dependent scripts :
 

SCRIPTLINK=SCENE.getScriptLinks(EVENT) 


[Figure 3] 

SCENE.addScriptLink(NAME,EVENT) 

 
 

The state of the camera.

The scene gives access to the camera data :
 

CAMERA=Scene.getCurrent().getCurrentCamera()

which has two limits, ClipStart and ClipEnd [ Figure 4 ], before and back :


[Figure 4]


CAMclipEN=CAMERA.getData().getClipEnd()

All that is outwards will not be displayed. Thus, one sorts systematically all the objects, to treat only those which are inside and whose SubSurf option is activated.

To accelerate a little by using Bounding Box.

Each object of Blender contains the data of the bounding box in which it is locked up(Figure 4, pink lines).  Whatever the number of vertices the mesh contains, while passing by this bounding box one knows the position of the more extreme of them. Thus it remains only eight tests to carry out, to know if a part of this 
object is within the limits of vision of the camera. 

It only remains to do a simple division on the distance that separates the object from the camera , and to arrange the result in a list to nourish the function :
 

M.setSubDivLevels([LOD,LOD]) 

which will fix the value of the surface subdivision 


 

[Figures 5 et 6].









Improvements are possible while not taking into account the objects that would be completely below the ClipStart limit of the camera, or apart from the visual pyramid. 
 

The Script
Download  the script 
Download  the blend file 

#!BPY

"""
Name: 'A Cool Faked LOD'
Blender: 234
Group: 'Animation''
Tooltip: ' his script loads itself automatically to  manage the effects Level of Detail in  the current 
scene but only in Framechanged mode..'
"""
__author__ = "Jean-Michel Soler (jms)"
__url__ = (""" "Script's homepage, ",
"Communicate problems and errors, 
http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender""")
__version__ = "11/2004"
__bpydoc__ = """
 This script loads itself automatically to  manage the effects Level of Detail in  the current scene but
 only in Framechanged mode.
 Usage:

 One can launch the script from the animation scripts  menu or  load it in the text window and make 
 alt-p. 

""" 
# ====================================
# (c) jmsoler 01/11/2004, 
# ==================================== 

#========================================
# Load Main module 
#========================================
import Blender
#========================================
# Load sub-module
#========================================
from Blender import NMesh,Scene,Object,Text
from math import floor
#=========================================
# DATA DEFINITION 
#=========================================
#=========================================
# Display LOD effects in  EDIT mode
# if value =  zero the effect is  limited to render only 
#=========================================
EDITMODE=0
#=========================================
# Maximum zone limited to 4 numbers to avoid
# a too great number of surface
#=========================================
MAXZONE=4
#=========================================
# Link to current Scene
#=========================================
SCENE=Scene.getCurrent()
VERSION=Blender.Get('version')

#=========================================
# Collect information of camera
#=========================================
CAMERA=Scene.getCurrent().getCurrentCamera()
if CAMERA!=None:
    CAMPOS=CAMERA.mat[3][:]
    CAMclipST=CAMERA.getData().getClipStart()
    CAMclipEN=CAMERA.getData().getClipEnd()
    LIMITE= [abs(CAMPOS[n]+CAMclipEN) for n in [0,1,2]]
else:
    TEXT="Sorry but he scrit does not find an active camera  %%t|"
    TEXT+=" Add a camera or make at least a render to activate the one are currently using in your file ."
    Blender.Draw.PupMenu(TEXT)

FRAGMENT=4.0

#=========================================
# Automatic link of script to the scene. ...
#=========================================
DEVELOPPEMENT=0
EVENT='FrameChanged'
NAME='LOD.py'

def Charge(NAME):
   try:
     WINDOWTEXTES=Text.Get(NAME)
     print WINDOWTEXTES
   except:
       DIR = Blender.Get('homedir')
       SCRIPTDIR=DIR+Blender.sys.sep+'scripts'+Blender.sys.sep
       Text.Load(SCRIPTDIR+NAME)

#=========================================
# ... only if development is completed
#=========================================
if not DEVELOPPEMENT: 
    scriptlink=SCENE.getScriptLinks(EVENT)
    if scriptlink!=None and NAME not in scriptlink:
       if VERSION>=234:
             Charge(NAME)
       SCENE.addScriptLink(NAME,EVENT)
    elif  scriptlink==None :
       if VERSION>=234:
             Charge(NAME)
       SCENE.addScriptLink(NAME,EVENT)

#=========================================
# FUNCTIONS DEFINITIONS 
#=========================================
#=========================================
#
#========================================= 
def longueur_vect(p1,p2):
     p3=[]
     p3.append(p2[0]-p1[0])
     p3.append(p2[1]-p1[1])
     p3.append(p2[2]-p1[2])
     return [abs(p3[0]**2+p3[1]**2+p3[2]**2)**0.5,1.0,1.0]

def in_LIMIT(O,CAMPOS):
   OMTRX=O.getMatrix()[3][:]
   OBB=  [l for l in O.getBoundBox() 
           if (LIMITE[0]-longueur_vect(l,CAMPOS)[0])>0]
   for l in OBB:
      LOD=int(FRAGMENT-
          floor(longueur_vect(l,CAMPOS)[0]/(LIMITE[0]/FRAGMENT)))

      if EDITMODE:
              LOD0=LOD
      else :
             LOD0=0#

      M=O.getData()
      M.setSubDivLevels([LOD,LOD])
      M.update()
      #O.makeDisplayList()

#=========================================
# One recovers all the objects of the current scene
# but only if it has the activated option subsurf
#=========================================
OBJ=[O for O in Object.Get() 
        if O.getType()=='Mesh' and
            (O.getData().mode & 
            NMesh.Modes['SUBSURF'])]

for O in OBJ:
     in_LIMIT(O,CAMPOS) 

if VERSION==234: Blender.Window.RedrawAll()

Variable EDITMODE : limiter les effets au rendu de l'animation

This modification makes it possible to reduce display time in edit mode :
...
#=========================================
# Display LOD effects in  EDIT mode
# if value =  zero the effect is  limited to render only 
#=========================================
EDITMODE=0
...
...
     if EDITMODE:
        LOD0=LOD
     else :
       LOD0=0#O.getData().getSubDivLevels()[0]
...

 
previous Script Python
 En Chantier Suivant
Vers le  Haut de page

Les questions concernant cette page  peuvent être posées sur  :
 news://news.zoo-logique.org/3D.Blender


 

 

Livre en français
Blender : apprenez, pratiquez, Créez, livre, Ed. Campus Press, coll. Starter Kit
Blender Starter Kit

Forum
FAQ
Lexique
Didacticiels
Compilations
Blender2KT
Débuter
Modelage
Blender python
Materiaux
Lumière
Animation
API python (eng)
Archives nzn
Statistiques
Doc flash Sculptris
Galerie Sculptris

Les Fralibos sur youtube, soutien au personnel de Fralib de Gémenos