svn merge ^/trunk/blender -r43092:43092
authorCampbell Barton <ideasman42@gmail.com>
Wed, 4 Jan 2012 06:20:10 +0000 (06:20 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 4 Jan 2012 06:20:10 +0000 (06:20 +0000)
15 files changed:
1  2 
doc/python_api/rst/info_best_practice.rst
doc/python_api/rst/info_quickstart.rst
doc/python_api/rst/info_tips_and_tricks.rst
release/scripts/startup/bl_ui/properties_object_constraint.py
source/blender/blenfont/intern/blf.c
source/blender/blenfont/intern/blf_glyph.c
source/blender/blenkernel/intern/object.c
source/blender/gpu/intern/gpu_material.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesrna/intern/rna_modifier.c
source/blender/modifiers/intern/MOD_util.c
source/blender/modifiers/intern/MOD_uvproject.c
source/blender/modifiers/intern/MOD_wave.c
source/blender/python/mathutils/mathutils_Vector.c
source/blender/render/intern/source/render_texture.c

@@@ -2,9 -2,9 +2,9 @@@
  Best Practice
  *************
  
--When writing you're own scripts python is great for new developers to pick up and become productive, but you can also pick up odd habits or at least write scripts that are not easy for others to understand.
++When writing your own scripts python is great for new developers to pick up and become productive, but you can also pick up odd habits or at least write scripts that are not easy for others to understand.
  
--For you're own work this is of course fine, but if you want to collaborate with others or have you're work included with blender there are practices we encourage.
++For your own work this is of course fine, but if you want to collaborate with others or have your work included with blender there are practices we encourage.
  
  
  Style Conventions
@@@ -244,7 -244,7 +244,7 @@@ Use ``float(string)`` rather than ``eva
  Checking String Start/End
  ^^^^^^^^^^^^^^^^^^^^^^^^^
  
--If your checking the start of a string for a keyword, rather than...
++If you're checking the start of a string for a keyword, rather than...
  
  >>> if line[0:5] == "vert ": ...
  
@@@ -279,8 -279,8 +279,8 @@@ Python has two ways to compare values `
  In cases where you know you are checking for the same value which is referenced from multiple places, ``is`` is faster.
  
  
--Time You're Code
------------------
++Time Your Code
++--------------
  
  While developing a script its good to time it to be aware of any changes in performance, this can be done simply.
  
@@@ -262,8 -262,8 +262,7 @@@ To run the script
  
  #. Click on the button **Run Script**.
  
--#. Move you're mouse into the 3D view, press spacebar for the operator search
--   menu, and type "Simple".
++#. Move your mouse into the 3D view, press spacebar for the operator search menu, and type "Simple".
  
  #. Click on the "Simple Operator" item found in search.
  
@@@ -16,7 -16,7 +16,7 @@@ When writing python scripts, it's usefu
  
  There are 3 main uses for the terminal, these are:
  
--* You can see the output of ``print()`` as you're script runs, which is useful to view debug info.
++* You can see the output of ``print()`` as your script runs, which is useful to view debug info.
  
  * The error trace-back is printed in full to the terminal which won't always generate an error popup in blender's user interface (depending on how the script is executed).
  
@@@ -135,15 -135,15 +135,15 @@@ Once the script is running properly in 
  * if the results can be displayed as text - print them or write them to a file.
  
  
--This can take a little time to setup, but it can be well worth the effort to reduce the time it takes to test changes - you can even have blender running the script ever few seconds with a viewer updating the results, so no need to leave you're text editor to see changes.
++This can take a little time to setup, but it can be well worth the effort to reduce the time it takes to test changes - you can even have blender running the script ever few seconds with a viewer updating the results, so no need to leave your text editor to see changes.
  
  
  Use External Tools
  ==================
  
--When there are no readily available python modules to perform specific tasks it's worth keeping in mind you may be able to have python execute an external command on you're data and read the result back in.
++When there are no readily available python modules to perform specific tasks it's worth keeping in mind you may be able to have python execute an external command on your data and read the result back in.
  
--Using external programs adds an extra dependency and may limit who can use the script but to quickly setup you're own custom pipeline or writing one-off scripts this can be handy.
++Using external programs adds an extra dependency and may limit who can use the script but to quickly setup your own custom pipeline or writing one-off scripts this can be handy.
  
  Examples include:
  
  Bundled Python & Extensions
  ===========================
  
--The Blender releases distributed from blender.org include a complete python installation on all platforms, this has the disadvantage that any extensions you have installed in you're systems python wont be found by blender.
++The Blender releases distributed from blender.org include a complete python installation on all platforms, this has the disadvantage that any extensions you have installed in your systems python wont be found by blender.
  
  There are 2 ways around this:
  
  * copy the extensions into blender's python sub-directory so blender can access them, you could also copy the entire python installation into blenders sub-directory, replacing the one blender comes with. This works as long as the python versions match and the paths are created in the same relative locations. Doing this has the advantage that you can redistribute this bundle to others with blender and/or the game player, including any extensions you rely on.
  
  
--Drop Into a Python Interpreter in You're Script
--===============================================
++Drop Into a Python Interpreter in Your Script
++=============================================
  
  In the middle of a script you may want to inspect some variables, run some function and generally dig about to see whats going on.
  
@@@ -187,7 -187,7 +187,7 @@@ If you want to access both global and l
     code.interact(local=namespace)
  
  
--The next example is an equivalent single line version of the script above which is easier to paste into you're code:
++The next example is an equivalent single line version of the script above which is easier to paste into your code:
  
  .. code-block:: python
  
@@@ -774,7 -774,7 +774,7 @@@ class ConstraintButtonsPanel()
  
          if clip:
              layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
--            layout.prop_search(con, "track", clip.tracking, "tracks", icon='ANIMATION_DATA')
++            layout.prop_search(con, "track", clip.tracking, "tracks", icon='ANIM_DATA')
  
          layout.prop(con, "camera")
  
@@@ -479,7 -479,7 +479,7 @@@ void BLF_rotation_default(float angle
        }
  }
  
--static void blf_draw__start(FontBLF *font)
++static void blf_draw__start(FontBLF *font, GLint *mode)
  {
        /*
         * The pixmap alignment hack is handle
        glEnable(GL_TEXTURE_2D);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
++      /* Save the current matrix mode. */
++      glGetIntegerv(GL_MATRIX_MODE, mode);
++
++      glMatrixMode(GL_TEXTURE);
++      glPushMatrix();
++      glLoadIdentity();
++
++      glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
  
        if (font->flags & BLF_MATRIX)
  
        /* always bind the texture for the first glyph */
        font->tex_bind_state= -1;
--
  }
  
--static void blf_draw__end(void)
++static void blf_draw__end(GLint mode)
  {
++      glMatrixMode(GL_TEXTURE);
        glPopMatrix();
++
++      glMatrixMode(GL_MODELVIEW);
++      glPopMatrix();
++
++      if (mode != GL_MODELVIEW)
++              glMatrixMode(mode);
++
        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);
  }
  void BLF_draw(int fontid, const char *str, size_t len)
  {
        FontBLF *font= BLF_get(fontid);
++      GLint mode;
  
        if (font && font->glyph_cache) {
--              blf_draw__start(font);
++              blf_draw__start(font, &mode);
                blf_font_draw(font, str, len);
--              blf_draw__end();
++              blf_draw__end(mode);
        }
  }
  
  void BLF_draw_ascii(int fontid, const char *str, size_t len)
  {
        FontBLF *font= BLF_get(fontid);
++      GLint mode;
  
        if (font && font->glyph_cache) {
--              blf_draw__start(font);
++              blf_draw__start(font, &mode);
                blf_font_draw_ascii(font, str, len);
--              blf_draw__end();
++              blf_draw__end(mode);
        }
  }
  
@@@ -368,6 -368,6 +368,7 @@@ int blf_glyph_render(FontBLF *font, Gly
        float dx, dx1;
        float y1, y2;
        float xo, yo;
++      GLint param;
  
        if ((!g->width) || (!g->height))
                return 1;
                glBindTexture(GL_TEXTURE_2D, (font->tex_bind_state= g->tex));
        }
  
++      /* Save the current parameter to restore it later. */
++      glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &param);
++      if (param != GL_MODULATE)
++              glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
++
        if (font->flags & BLF_SHADOW) {
  
                switch(font->shadow) {
                        break;
        }
  
++      /* and restore the original value. */
++      if (param != GL_MODULATE)
++              glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param);
++
        return 1;
  }
@@@ -431,7 -430,7 +431,8 @@@ void unlink_object(Object *ob
                                if(pchan->custom==ob)
                                        pchan->custom= NULL;
                        }
--              } else if(ELEM(OB_MBALL, ob->type, obt->type)) {
++              } 
++              else if(ELEM(OB_MBALL, ob->type, obt->type)) {
                        if(is_mball_basis_for(obt, ob))
                                obt->recalc|= OB_RECALC_DATA;
                }
                sce= sce->id.next;
        }
        
--#if 0 // XXX old animation system
--      /* ipos */
--      ipo= bmain->ipo.first;
--      while(ipo) {
--              if(ipo->id.lib==NULL) {
--                      IpoCurve *icu;
--                      for(icu= ipo->curve.first; icu; icu= icu->next) {
--                              if(icu->driver && icu->driver->ob==ob)
--                                      icu->driver->ob= NULL;
--                      }
--              }
--              ipo= ipo->id.next;
--      }
--#endif // XXX old animation system
--      
        /* screens */
        sc= bmain->screen.first;
        while(sc) {
@@@ -991,7 -990,7 +977,7 @@@ void copy_object_particlesystems(Objec
                        }
                        else if (md->type==eModifierType_Smoke) {
                                SmokeModifierData *smd = (SmokeModifierData*) md;
--
++                              
                                if(smd->type==MOD_SMOKE_TYPE_FLOW) {
                                        if (smd->flow) {
                                                if (smd->flow->psys == psys)
@@@ -1027,22 -1026,22 +1013,6 @@@ static void copy_object_pose(Object *ob
                        ListBase targets = {NULL, NULL};
                        bConstraintTarget *ct;
                        
--#if 0 // XXX old animation system
--                      /* note that we can't change lib linked ipo blocks. for making
--                       * proxies this still works correct however because the object
--                       * is changed to object->proxy_from when evaluating the driver. */
--                      if(con->ipo && !con->ipo->id.lib) {
--                              IpoCurve *icu;
--                              
--                              con->ipo= copy_ipo(con->ipo);
--                              
--                              for(icu= con->ipo->curve.first; icu; icu= icu->next) {
--                                      if(icu->driver && icu->driver->ob==ob)
--                                              icu->driver->ob= obn;
--                              }
--                      }
--#endif // XXX old animation system
--                      
                        if (cti && cti->get_constraint_targets) {
                                cti->get_constraint_targets(con, &targets);
                                
@@@ -1072,8 -1071,8 +1042,7 @@@ static int object_pose_context(Object *
        }
  }
  
--//Object *object_pose_armature_get(Object *ob)
--Object *object_pose_armature_get(struct Object *ob)
++Object *object_pose_armature_get(Object *ob)
  {
        if(ob==NULL)
                return NULL;
@@@ -1179,13 -1178,13 +1148,8 @@@ Object *copy_object(Object *ob
  
  static void extern_local_object(Object *ob)
  {
--      //bActionStrip *strip;
        ParticleSystem *psys;
  
--#if 0 // XXX old animation system
--      id_lib_extern((ID *)ob->action);
--      id_lib_extern((ID *)ob->ipo);
--#endif // XXX old animation system
        id_lib_extern((ID *)ob->data);
        id_lib_extern((ID *)ob->dup_group);
        id_lib_extern((ID *)ob->poselib);
  
        extern_local_matarar(ob->mat, ob->totcol);
  
--#if 0 // XXX old animation system
--      for (strip=ob->nlastrips.first; strip; strip=strip->next) {
--              id_lib_extern((ID *)strip->act);
--      }
--#endif // XXX old animation system
        for(psys=ob->particlesystem.first; psys; psys=psys->next)
                id_lib_extern((ID *)psys->part);
  }
@@@ -1120,7 -1120,7 +1120,11 @@@ static void do_material_tex(GPUShadeInp
                                                // to inverting the bump map. Should this ever change
                                                // this negate must be removed.
                                                norfac = -hScale * mtex->norfac;
--                                              if(found_deriv_map) norfac /= sqrtf(ima_x*ima_y);
++                                              if(found_deriv_map)
++                                              {
++                                                      float fVirtDim = sqrtf(fabsf(ima_x*mtex->size[0]*ima_y*mtex->size[1]));
++                                                      norfac /= MAX2(fVirtDim, FLT_EPSILON);
++                                              }
  
                                                tnorfac = GPU_uniform(&norfac);
  
@@@ -316,13 -313,13 +316,13 @@@ typedef struct DisplaceModifierData 
        char uvlayer_name[32];
        int uvlayer_tmp;
        int texmapping;
--      int pad10;
        /* end MappingInfoModifierData */
  
        float strength;
        int direction;
        char defgrp_name[32];
        float midlevel;
++      int pad;
  } DisplaceModifierData;
  
  /* DisplaceModifierData->direction */
@@@ -339,7 -336,7 +339,7 @@@ enum 
        MOD_DISP_MAP_LOCAL,
        MOD_DISP_MAP_GLOBAL,
        MOD_DISP_MAP_OBJECT,
--      MOD_DISP_MAP_UV,
++      MOD_DISP_MAP_UV
  };
  
  typedef struct UVProjectModifierData {
@@@ -404,13 -401,13 +404,6 @@@ typedef struct CastModifierData 
        short flag, type;
  } CastModifierData;
  
--enum {
--      MOD_WAV_MAP_LOCAL,
--      MOD_WAV_MAP_GLOBAL,
--      MOD_WAV_MAP_OBJECT,
--      MOD_WAV_MAP_UV,
--};
--
  /* WaveModifierData.flag */
  #define MOD_WAVE_X      (1<<1)
  #define MOD_WAVE_Y      (1<<2)
  typedef struct WaveModifierData {
        ModifierData modifier;
  
--      struct Object *objectcenter;
--      char defgrp_name[32];
++      /* keep in sync with MappingInfoModifierData */
        struct Tex *texture;
        struct Object *map_object;
++      char uvlayer_name[32];
++      int uvlayer_tmp;
++      int texmapping;
++      /* end MappingInfoModifierData */
++
++      struct Object *objectcenter;
++      char defgrp_name[32];
  
        short flag, pad;
  
        float startx, starty, height, width;
        float narrow, speed, damp, falloff;
  
--      int texmapping, uvlayer_tmp;
--
--      char uvlayer_name[32];
--
        float timeoffs, lifetime;
        float pad1;
  } WaveModifierData;
@@@ -831,19 -822,19 +826,17 @@@ typedef struct WarpModifierData 
        char uvlayer_name[32];
        int uvlayer_tmp;
        int texmapping;
--      int pad10;
        /* end MappingInfoModifierData */
  
--      float strength;
--
        struct Object *object_from;
        struct Object *object_to;
        struct CurveMapping *curfalloff;
        char defgrp_name[32];                   /* optional vertexgroup name */
++      float strength;
        float falloff_radius;
        char flag; /* not used yet */
        char falloff_type;
--      char pad[2];
++      char pad[6];
  } WarpModifierData;
  
  #define MOD_WARP_VOLUME_PRESERVE 1
@@@ -455,12 -452,12 +455,6 @@@ static void RNA_WarpModifier_vgroup_set
        rna_object_vgroup_name_set(ptr, value, tmd->defgrp_name, sizeof(tmd->defgrp_name));
  }
  
--static void rna_WaveModifier_uvlayer_set(PointerRNA *ptr, const char *value)
--{
--      WaveModifierData *wmd= (WaveModifierData*)ptr->data;
--      rna_object_uvlayer_name_set(ptr, value, wmd->uvlayer_name, sizeof(wmd->uvlayer_name));
--}
--
  static void rna_WeightVGModifier_mask_uvlayer_set(PointerRNA *ptr, const char *value)
  {
        ModifierData *md = (ModifierData*)ptr->data;
@@@ -1128,13 -1125,13 +1122,6 @@@ static void rna_def_modifier_wave(Blend
        StructRNA *srna;
        PropertyRNA *prop;
  
--      static EnumPropertyItem prop_texture_coordinates_items[] = {
--              {MOD_WAV_MAP_LOCAL, "LOCAL", 0, "Local", ""},
--              {MOD_WAV_MAP_GLOBAL, "GLOBAL", 0, "Global", ""},
--              {MOD_WAV_MAP_OBJECT, "OBJECT", 0, "Object", ""},
--              {MOD_WAV_MAP_UV, "MAP_UV", 0, "UV", ""},
--              {0, NULL, 0, NULL, NULL}};
--
        srna= RNA_def_struct(brna, "WaveModifier", "Modifier");
        RNA_def_struct_ui_text(srna, "Wave Modifier", "Wave effect modifier");
        RNA_def_struct_sdna(srna, "WaveModifierData");
        RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_vgroup_set");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
  
--      prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
--      RNA_def_property_ui_text(prop, "Texture", "Texture for modulating the wave");
--      RNA_def_property_flag(prop, PROP_EDITABLE);
--      RNA_def_property_update(prop, 0, "rna_Modifier_update");
--
--      prop= RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE);
--      RNA_def_property_enum_sdna(prop, NULL, "texmapping");
--      RNA_def_property_enum_items(prop, prop_texture_coordinates_items);
--      RNA_def_property_ui_text(prop, "Texture Coordinates", "Texture coordinates used for modulating input");
--      RNA_def_property_update(prop, 0, "rna_Modifier_update");
--
--      prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
--      RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
--      RNA_def_property_ui_text(prop, "UV Map", "UV map name");
--      RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_uvlayer_set");
--      RNA_def_property_update(prop, 0, "rna_Modifier_update");
--
--      prop= RNA_def_property(srna, "texture_coords_object", PROP_POINTER, PROP_NONE);
--      RNA_def_property_pointer_sdna(prop, NULL, "map_object");
--      RNA_def_property_ui_text(prop, "Texture Coordinates Object", "");
--      RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
--      RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
--
        prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
        RNA_def_property_ui_range(prop, -1, 1, 10, 2);
        RNA_def_property_ui_range(prop, 0, 10, 10, 2);
        RNA_def_property_ui_text(prop, "Narrowness", "Distance between the top and the base of a wave, the higher the value, the more narrow the wave");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
++
++      rna_def_modifier_generic_map_info(srna);
  }
  
  static void rna_def_modifier_armature(BlenderRNA *brna)
@@@ -107,36 -107,36 +107,19 @@@ void get_texture_coords(MappingInfoModi
  
                        /* verts are given the UV from the first face that uses them */
                        for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
--                              if(!done[mf->v1]) {
--                                      texco[mf->v1][0] = tf->uv[0][0];
--                                      texco[mf->v1][1] = tf->uv[0][1];
--                                      texco[mf->v1][2] = 0;
--                                      done[mf->v1] = 1;
--                              }
--                              if(!done[mf->v2]) {
--                                      texco[mf->v2][0] = tf->uv[1][0];
--                                      texco[mf->v2][1] = tf->uv[1][1];
--                                      texco[mf->v2][2] = 0;
--                                      done[mf->v2] = 1;
--                              }
--                              if(!done[mf->v3]) {
--                                      texco[mf->v3][0] = tf->uv[2][0];
--                                      texco[mf->v3][1] = tf->uv[2][1];
--                                      texco[mf->v3][2] = 0;
--                                      done[mf->v3] = 1;
--                              }
--                              if(!done[mf->v4]) {
--                                      texco[mf->v4][0] = tf->uv[3][0];
--                                      texco[mf->v4][1] = tf->uv[3][1];
--                                      texco[mf->v4][2] = 0;
--                                      done[mf->v4] = 1;
--                              }
--                      }
++                              unsigned int fidx= mf->v4 ? 3:2;
++
++                              do {
++                                      unsigned int vidx = *(&mf->v1 + fidx);
++
++                                      if (done[vidx] == 0) {
++                                              /* remap UVs from [0, 1] to [-1, 1] */
++                                              texco[vidx][0] = (tf->uv[fidx][0] * 2.0f) - 1.0f;
++                                              texco[vidx][1] = (tf->uv[fidx][1] * 2.0f) - 1.0f;
++                                              done[vidx] = 1;
++                                      }
  
--                      /* remap UVs from [0, 1] to [-1, 1] */
--                      for(i = 0; i < numVerts; ++i) {
--                              texco[i][0] = texco[i][0] * 2 - 1;
--                              texco[i][1] = texco[i][1] * 2 - 1;
++                              } while (fidx--);
                        }
  
                        MEM_freeN(done);
@@@ -288,41 -287,41 +288,34 @@@ static DerivedMesh *uvprojectModifier_d
                if(override_image || !image || tface->tpage == image) {
                        if(num_projectors == 1) {
                                if(projectors[0].uci) {
--                                      project_from_camera(tface->uv[0], coords[mf->v1], projectors[0].uci);
--                                      project_from_camera(tface->uv[1], coords[mf->v2], projectors[0].uci);
--                                      project_from_camera(tface->uv[2], coords[mf->v3], projectors[0].uci);
--                                      if(mf->v4)
--                                              project_from_camera(tface->uv[3], coords[mf->v4], projectors[0].uci);
++                                      unsigned int fidx= mf->v4 ? 3:2;
++                                      do {
++                                              unsigned int vidx= *(&mf->v1 + fidx);
++                                              project_from_camera(tface->uv[fidx], coords[vidx], projectors[0].uci);
++                                      } while (fidx--);
                                }
                                else {
                                        /* apply transformed coords as UVs */
--                                      copy_v2_v2(tface->uv[0], coords[mf->v1]);
--                                      copy_v2_v2(tface->uv[1], coords[mf->v2]);
--                                      copy_v2_v2(tface->uv[2], coords[mf->v3]);
--                                      if (mf->v4) {
--                                              copy_v2_v2(tface->uv[3], coords[mf->v4]);
--                                      }
++                                      unsigned int fidx= mf->v4 ? 3:2;
++                                      do {
++                                              unsigned int vidx= *(&mf->v1 + fidx);
++                                              copy_v2_v2(tface->uv[fidx], coords[vidx]);
++                                      } while (fidx--);
                                }
                        } else {
                                /* multiple projectors, select the closest to face normal
                                * direction
                                */
--                              float co1[3], co2[3], co3[3], co4[3];
                                float face_no[3];
                                int j;
                                Projector *best_projector;
                                float best_dot;
  
--                              copy_v3_v3(co1, coords[mf->v1]);
--                              copy_v3_v3(co2, coords[mf->v2]);
--                              copy_v3_v3(co3, coords[mf->v3]);
--
                                /* get the untransformed face normal */
                                if(mf->v4) {
--                                      copy_v3_v3(co4, coords[mf->v4]);
--                                      normal_quad_v3(face_no, co1, co2, co3, co4);
++                                      normal_quad_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3], coords[mf->v4]);
                                } else { 
--                                      normal_tri_v3(face_no, co1, co2, co3);
++                                      normal_tri_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3]);
                                }
  
                                /* find the projector which the face points at most directly
                                }
  
                                if(best_projector->uci) {
--                                      project_from_camera(tface->uv[0], coords[mf->v1], best_projector->uci);
--                                      project_from_camera(tface->uv[1], coords[mf->v2], best_projector->uci);
--                                      project_from_camera(tface->uv[2], coords[mf->v3], best_projector->uci);
--                                      if(mf->v4)
--                                              project_from_camera(tface->uv[3], coords[mf->v4], best_projector->uci);
++                                      unsigned int fidx= mf->v4 ? 3:2;
++                                      do {
++                                              unsigned int vidx= *(&mf->v1 + fidx);
++                                              project_from_camera(tface->uv[fidx], coords[vidx], best_projector->uci);
++                                      } while (fidx--);
                                }
                                else {
--                                      mul_project_m4_v3(best_projector->projmat, co1);
--                                      mul_project_m4_v3(best_projector->projmat, co2);
--                                      mul_project_m4_v3(best_projector->projmat, co3);
--                                      if(mf->v4)
--                                              mul_project_m4_v3(best_projector->projmat, co4);
++                                      unsigned int fidx= mf->v4 ? 3:2;
++                                      do {
++                                              unsigned int vidx= *(&mf->v1 + fidx);
++                                              float tco[3];
  
--                                      /* apply transformed coords as UVs */
--                                      copy_v2_v2(tface->uv[0], co1);
--                                      copy_v2_v2(tface->uv[1], co2);
--                                      copy_v2_v2(tface->uv[2], co3);
--                                      if (mf->v4) {
--                                              copy_v2_v2(tface->uv[3], co4);
--                                      }
++                                              copy_v3_v3(tco, coords[vidx]);
++                                              mul_project_m4_v3(best_projector->projmat, tco);
++                                              copy_v2_v2(tface->uv[fidx], tco);
++
++                                      } while (fidx--);
                                }
                        }
                }
@@@ -73,7 -73,7 +73,7 @@@ static void initData(ModifierData *md
        wmd->lifetime= 0.0f;
        wmd->damp= 10.0f;
        wmd->falloff= 0.0f;
--      wmd->texmapping = MOD_WAV_MAP_LOCAL;
++      wmd->texmapping = MOD_DISP_MAP_LOCAL;
        wmd->defgrp_name[0] = 0;
  }
  
@@@ -160,7 -160,7 +160,7 @@@ static CustomDataMask requiredDataMask(
  
  
        /* ask for UV coordinates if we need them */
--      if(wmd->texture && wmd->texmapping == MOD_WAV_MAP_UV)
++      if(wmd->texture && wmd->texmapping == MOD_DISP_MAP_UV)
                dataMask |= CD_MASK_MTFACE;
  
        /* ask for vertexgroups if we need them */
        return dataMask;
  }
  
--static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
--                                         DerivedMesh *dm,
--         float (*co)[3], float (*texco)[3],
--                 int numVerts)
--{
--      int i;
--      int texmapping = wmd->texmapping;
--
--      if(texmapping == MOD_WAV_MAP_OBJECT) {
--              if(wmd->map_object)
--                      invert_m4_m4(wmd->map_object->imat, wmd->map_object->obmat);
--              else /* if there is no map object, default to local */
--                      texmapping = MOD_WAV_MAP_LOCAL;
--      }
--
--      /* UVs need special handling, since they come from faces */
--      if(texmapping == MOD_WAV_MAP_UV) {
--              if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
-                       MFace *mface = dm->getTessFaceArray(dm);
 -                      MFace *mface = dm->getFaceArray(dm);
--                      MFace *mf;
--                      char *done = MEM_callocN(sizeof(*done) * numVerts,
--                                      "get_texture_coords done");
-                       int numFaces = dm->getNumTessFaces(dm);
 -                      int numFaces = dm->getNumFaces(dm);
--                      char uvname[32];
--                      MTFace *tf;
--
--                      CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname);
--                      tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
--
--                      /* verts are given the UV from the first face that uses them */
--                      for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
--                              if(!done[mf->v1]) {
--                                      texco[mf->v1][0] = tf->uv[0][0];
--                                      texco[mf->v1][1] = tf->uv[0][1];
--                                      texco[mf->v1][2] = 0;
--                                      done[mf->v1] = 1;
--                              }
--                              if(!done[mf->v2]) {
--                                      texco[mf->v2][0] = tf->uv[1][0];
--                                      texco[mf->v2][1] = tf->uv[1][1];
--                                      texco[mf->v2][2] = 0;
--                                      done[mf->v2] = 1;
--                              }
--                              if(!done[mf->v3]) {
--                                      texco[mf->v3][0] = tf->uv[2][0];
--                                      texco[mf->v3][1] = tf->uv[2][1];
--                                      texco[mf->v3][2] = 0;
--                                      done[mf->v3] = 1;
--                              }
--                              if(!done[mf->v4]) {
--                                      texco[mf->v4][0] = tf->uv[3][0];
--                                      texco[mf->v4][1] = tf->uv[3][1];
--                                      texco[mf->v4][2] = 0;
--                                      done[mf->v4] = 1;
--                              }
--                      }
--
--                      /* remap UVs from [0, 1] to [-1, 1] */
--                      for(i = 0; i < numVerts; ++i) {
--                              texco[i][0] = texco[i][0] * 2 - 1;
--                              texco[i][1] = texco[i][1] * 2 - 1;
--                      }
--
--                      MEM_freeN(done);
--                      return;
--              } else /* if there are no UVs, default to local */
--                      texmapping = MOD_WAV_MAP_LOCAL;
--      }
--
--      for(i = 0; i < numVerts; ++i, ++co, ++texco) {
--              switch(texmapping) {
--                      case MOD_WAV_MAP_LOCAL:
--                              copy_v3_v3(*texco, *co);
--                              break;
--                      case MOD_WAV_MAP_GLOBAL:
--                              mul_v3_m4v3(*texco, ob->obmat, *co);
--                              break;
--                      case MOD_WAV_MAP_OBJECT:
--                              mul_v3_m4v3(*texco, ob->obmat, *co);
--                              mul_m4_v3(wmd->map_object->imat, *texco);
--                              break;
--              }
--      }
--}
--
  static void waveModifier_do(WaveModifierData *md, 
                Scene *scene, Object *ob, DerivedMesh *dm,
           float (*vertexCos)[3], int numVerts)
        if(wmd->texture) {
                tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts,
                                         "waveModifier_do tex_co");
--              wavemod_get_texture_coords(wmd, ob, dm, vertexCos, tex_co, numVerts);
++              get_texture_coords((MappingInfoModifierData *)wmd, ob, dm, vertexCos, tex_co, numVerts);
        }
  
        if(lifefac != 0.0f) {
@@@ -334,18 -334,18 +334,18 @@@ PyDoc_STRVAR(Vector_normalize_doc
  "\n"
  "   Normalize the vector, making the length of the vector always 1.0.\n"
  "\n"
--"   .. warning:: Normalizing a vector where all values are zero results\n"
--"      in all axis having a nan value (not a number).\n"
++"   .. warning:: Normalizing a vector where all values are zero has no effect.\n"
  "\n"
  "   .. note:: Normalize works for vectors of all sizes,\n"
  "      however 4D Vectors w axis is left untouched.\n"
  );
  static PyObject *Vector_normalize(VectorObject *self)
  {
++      int size = (self->size == 4 ? 3 : self->size);
        if (BaseMath_ReadCallback(self) == -1)
                return NULL;
  
--      normalize_vn(self->vec, self->size);
++      normalize_vn(self->vec, size);
  
        (void)BaseMath_WriteCallback(self);
        Py_RETURN_NONE;
@@@ -1480,10 -1480,10 +1480,10 @@@ static PyObject *Vector_isub(PyObject *
    mulplication*/
  
  
--/* COLUMN VECTOR Multiplication (Vector X Matrix)
-- * [a] * [1][4][7]
-- * [b] * [2][5][8]
-- * [c] * [3][6][9]
++/* COLUMN VECTOR Multiplication (Matrix X Vector)
++ * [1][4][7]   [a]
++ * [2][5][8] * [b]
++ * [3][6][9]   [c]
   *
   * note: vector/matrix multiplication IS NOT COMMUTATIVE!!!!
   * note: assume read callbacks have been done first.
@@@ -1500,8 -1500,8 +1500,8 @@@ int column_vector_multiplication(float 
                else {
                        PyErr_SetString(PyExc_TypeError,
                                        "matrix * vector: "
--                                      "matrix.row_size and len(vector) must be the same, "
--                                      "except for 3D vector * 4x4 matrix.");
++                                                      "len(matrix.col) and len(vector) must be the same, "
++                                      "except for 4x4 matrix * 3D vector.");
                        return -1;
                }
        }
@@@ -1969,7 -1969,7 +1969,10 @@@ static int ntap_bump_compute(NTapBump *
                {
                        auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale;
                }
--              auto_bump /= sqrtf((float) (dimx*dimy));
++              {
++                      float fVirtDim = sqrtf(fabsf((float) (dimx*dimy)*mtex->size[0]*mtex->size[1]));
++                      auto_bump /= MAX2(fVirtDim, FLT_EPSILON);
++              }
                
                // this variant using a derivative map is described here
                // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html