svn merge ^/trunk/blender -r46559:HEAD
authorOve Murberg Henriksen <sorayasilvermoon@hotmail.com>
Tue, 15 May 2012 01:28:12 +0000 (01:28 +0000)
committerOve Murberg Henriksen <sorayasilvermoon@hotmail.com>
Tue, 15 May 2012 01:28:12 +0000 (01:28 +0000)
1  2 
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/editors/object/object_vgroup.c

@@@ -376,353 -376,6 +376,360 @@@ int ED_vgroup_copy_array(Object *ob, Ob
        return 1;
  }
  
 +/*Copy a single vertex group from source to destination with weights by identical meshes*/
 +int ED_vgroup_copy_single(Object *ob_dst, const Object *ob_src)
 +{
 +      MDeformVert **dv_array_src;
 +      MDeformVert **dv_array_dst;
 +      MDeformWeight *dw_dst, *dw_src;
 +      int dv_tot_src, dv_tot_dst;
 +      int i, index_src, index_dst;
 +      bDeformGroup *dg_src, *dg_dst;
 +
 +      /*get source deform group*/
 +      dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1));
 +
 +      /*create new and overwrite vertex group on destination without data*/
 +      ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name));
 +      ED_vgroup_add_name(ob_dst, dg_src->name);
 +
 +      /*get destination deformgroup*/
 +      dg_dst= defgroup_find_name(ob_dst, dg_src->name);
 +
 +      /*get vertex group arrays*/
 +      ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE);
 +      ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE);
 +
 +      /*get indexes of vertex groups*/
 +      index_src= BLI_findindex(&ob_src->defbase, dg_src);
 +      index_dst= BLI_findindex(&ob_dst->defbase, dg_dst);
 +
 +      /*check if indices are matching, delete and return if not*/
 +      if (ob_dst == ob_src || dv_tot_dst == 0 || (dv_tot_dst != dv_tot_src) || dv_array_src == NULL || dv_array_dst == NULL) {
 +              ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name));
 +              return 0;
 +      }
 +
 +      /* loop through the vertices and copy weight*/
 +      for(i=0; i<dv_tot_dst; i++, dv_array_src++, dv_array_dst++) {
 +              dw_src= defvert_verify_index(*dv_array_src, index_src);
 +              dw_dst= defvert_verify_index(*dv_array_dst, index_dst);
 +              dw_dst->weight= dw_src->weight;
 +      }
 +
 +      return 1;
 +}
 +
 +/*Copy a single vertex group from source to destination with weights by nearest weight*/
 +int ED_vgroup_copy_by_nearest_vertex_single(Object *ob_dst, Object *ob_src)
 +{
 +      bDeformGroup *dg_src, *dg_dst;
 +      MDeformVert **dv_array_src, **dv_array_dst;
 +      MDeformWeight *dw_dst, *dw_src;
 +      MVert *mv_dst;
 +      Mesh *me_dst;
 +      BVHTreeFromMesh tree_mesh_src;
 +      BVHTreeNearest nearest;
 +      DerivedMesh *dmesh_src;
 +      int dv_tot_src, dv_tot_dst, i, index_dst, index_src;
 +      float tmp_co[3], tmp_mat[4][4];
 +
 +      /*get source deform group*/
 +      dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1));
 +
 +      /*create new and overwrite vertex group on destination without data*/
 +      ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name));
 +      ED_vgroup_add_name(ob_dst, dg_src->name);
 +
 +      /*get destination deformgroup*/
 +      dg_dst= defgroup_find_name(ob_dst, dg_src->name);
 +
 +      /*get meshes*/
 +      me_dst= ob_dst->data;
 +      dmesh_src= ob_src->derivedDeform;
 +
 +      /*make node tree*/
 +      bvhtree_from_mesh_verts(&tree_mesh_src, dmesh_src, 0.0, 2, 6);
 +
 +      /*get vertex group arrays*/
 +      ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE);
 +      ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE);
 +
 +      /*get indexes of vertex groups*/
 +      index_src= BLI_findindex(&ob_src->defbase, dg_src);
 +      index_dst= BLI_findindex(&ob_dst->defbase, dg_dst);
 +
 +      /*get vertices*/
 +      mv_dst= me_dst->mvert;
 +
 +      /*prepare transformation matrix*/
 +      /*this can be excluded to make a lazy feature that works better when object centers relative to mesh is the same*/
 +      invert_m4_m4(ob_src->imat, ob_src->obmat);
 +      mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat);
 +
 +      /* loop through the vertices and copy weight from nearest weight*/
 +      for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){
 +
 +              /*reset nearest*/
 +              nearest.index= -1;
 +              nearest.dist= FLT_MAX;
 +
 +              /*transform into target space*/
 +              mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
 +
 +              /*node tree accelerated search for closest vetex*/
 +              BLI_bvhtree_find_nearest(tree_mesh_src.tree, tmp_co, &nearest, tree_mesh_src.nearest_callback, &tree_mesh_src);
 +
 +              /*copy weight*/
 +              dw_src= defvert_verify_index(dv_array_src[nearest.index], index_src);
 +              dw_dst= defvert_verify_index(*dv_array_dst, index_dst);
 +              dw_dst->weight= dw_src->weight;
 +      }
 +
 +      /*free memory and return*/
 +      free_bvhtree_from_mesh(&tree_mesh_src);
 +      return 1;
 +}
 +
 +/*Copy a single vertex group from source to destination with weights by nearest weight in face*/
 +int ED_vgroup_copy_by_nearest_vertex_in_face_single(Object *ob_dst, Object *ob_src)
 +{
 +      bDeformGroup *dg_src, *dg_dst;
 +      Mesh *me_dst;
 +      DerivedMesh *dmesh_src;
 +      BVHTreeFromMesh tree_mesh_faces_src = {NULL};
 +      MDeformVert **dv_array_src, **dv_array_dst;
 +      MVert *mv_dst, *mv_src;
 +      MFace *mface_src;
 +      BVHTreeNearest nearest;
 +      MDeformWeight *dw_dst, *dw_src;
 +      int dv_tot_src, dv_tot_dst, i, index_dst, index_src;
 +      float dist_v1, dist_v2, dist_v3, dist_v4, tmp_co[3], tmp_mat[4][4];
 +
 +      /*get source deform group*/
 +      dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1));
 +
 +      /*create new and overwrite vertex group on destination without data*/
 +      ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name));
 +      ED_vgroup_add_name(ob_dst, dg_src->name);
 +
 +      /*get destination deformgroup*/
 +      dg_dst= defgroup_find_name(ob_dst, dg_src->name);
 +
 +      /*get meshes*/
 +      me_dst= ob_dst->data;
 +      dmesh_src= ob_src->derivedDeform;
 +
 +      /*make node tree*/
 +      DM_ensure_tessface(dmesh_src);
 +      bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6);
 +
 +      /*get vertex group arrays*/
 +      ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE);
 +      ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE);
 +
 +      /*get indexes of vertex groups*/
 +      index_src= BLI_findindex(&ob_src->defbase, dg_src);
 +      index_dst= BLI_findindex(&ob_dst->defbase, dg_dst);
 +
 +      /*get vertices*/
 +      mv_dst= me_dst->mvert;
 +      mv_src= dmesh_src->getVertArray(dmesh_src);
 +
 +      /*get faces*/
 +      mface_src= dmesh_src->getTessFaceArray(dmesh_src);
 +
 +      /*prepare transformation matrix*/
 +      invert_m4_m4(ob_src->imat, ob_src->obmat);
 +      mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat);
 +
 +      /* loop through the vertices and copy weight from nearest weight*/
 +      for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){
 +
 +              /*reset nearest*/
 +              nearest.index= -1;
 +              nearest.dist= FLT_MAX;
 +
 +              /*transform into target space*/
 +              mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
 +
 +              /*node tree accelerated search for closest face*/
 +              BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
 +
 +              /*get distances*/
 +              dist_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co);
 +              dist_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co);
 +              dist_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co);
 +
 +              /*get weight from triangle*/
 +              if(dist_v1<dist_v2 && dist_v1<dist_v3){
 +                      dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src);
 +              }
 +              else if(dist_v2<dist_v3){
 +                      dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src);
 +              }
 +              else{
 +                      dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src);
 +              }
 +              /*check for and get weight from quad*/
 +              if(mface_src[nearest.index].v4){
 +                      dist_v4= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v4].co);
 +                      if(dist_v4<dist_v1 && dist_v4<dist_v2 && dist_v4<dist_v3){
 +                              dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src);
 +                      }
 +              }
 +
 +              /*copy weight*/
 +              dw_dst= defvert_verify_index(*dv_array_dst, index_dst);
 +              dw_dst->weight= dw_src->weight;
 +      }
 +
 +      /*free memory and return*/
 +      free_bvhtree_from_mesh(&tree_mesh_faces_src);
 +      return 1;
 +}
 +
 +/*Copy a single vertex group from source to destination with weights interpolated over nearest face*/
 +/*TODO: transform into target space as in by_vertex function. postphoned due to easier testing during development*/
 +int ED_vgroup_copy_by_nearest_face_single(Object *ob_dst, Object *ob_src)
 +{
 +      bDeformGroup *dg_src, *dg_dst;
 +      Mesh *me_dst;
 +      DerivedMesh *dmesh_src;
 +      BVHTreeFromMesh tree_mesh_faces_src = {NULL};
 +      MDeformVert **dv_array_src, **dv_array_dst;
 +      MVert *mv_dst, *mv_src;
 +      MFace *mface_src;
 +      BVHTreeNearest nearest;
 +      MDeformWeight *dw_dst, *dw_src;
 +      int dv_tot_src, dv_tot_dst, i, index_dst, index_src;
 +      float weight, tot_distribution, distribution_v1, distribution_v2, distribution_v3, distribution_v4, tmp_co[3], tmp_co_v4[3], normal[3];
 +
 +      /*get source deform group*/
 +      dg_src= BLI_findlink(&ob_src->defbase, (ob_src->actdef-1));
 +
 +      /*create new and overwrite vertex group on destination without data*/
 +      ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name));
 +      ED_vgroup_add_name(ob_dst, dg_src->name);
 +
 +      /*get destination deformgroup*/
 +      dg_dst= defgroup_find_name(ob_dst, dg_src->name);
 +
 +      /*get meshes*/
 +      me_dst= ob_dst->data;
 +      dmesh_src= ob_src->derivedDeform;
 +
 +      /*make node tree*/
 +      DM_ensure_tessface(dmesh_src);
 +      bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, 0.0, 2, 6);
 +
 +      /*get vertex group arrays*/
 +      ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE);
 +      ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE);
 +
 +      /*get indexes of vertex groups*/
 +      index_src= BLI_findindex(&ob_src->defbase, dg_src);
 +      index_dst= BLI_findindex(&ob_dst->defbase, dg_dst);
 +
 +      /*get vertices*/
 +      mv_dst= me_dst->mvert;
 +      mv_src= dmesh_src->getVertArray(dmesh_src);
 +
 +      /*get faces*/
 +      mface_src= dmesh_src->getTessFaceArray(dmesh_src);
 +
 +      /* loop through the vertices and copy weight from nearest weight*/
 +      for(i=0; i < me_dst->totvert; i++, mv_dst++, dv_array_dst++){
 +
 +              /*reset nearest*/
 +              nearest.index= -1;
 +              nearest.dist= FLT_MAX;
 +
 +              /*set destination coordinate*/
 +              copy_v3_v3(tmp_co, mv_dst->co);
 +
 +              /*node tree accelerated search for closest face*/
 +              BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
 +
 +              /*project destination coordinate onto face*/
 +              normal_tri_v3(normal, mv_src[mface_src[nearest.index].v1].co, mv_src[mface_src[nearest.index].v2].co, mv_src[mface_src[nearest.index].v3].co);
 +              project_v3_plane(tmp_co, normal, mv_src[mface_src[nearest.index].v1].co);
 +
 +              /*get distances*/
 +              distribution_v1= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v1].co);
 +              distribution_v2= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v2].co);
 +              distribution_v3= len_squared_v3v3(tmp_co, mv_src[mface_src[nearest.index].v3].co);
 +
 +              /*get weight from overlapping vert if any*/
 +              if(distribution_v1 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src)->weight;
 +              if(distribution_v2 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src)->weight;
 +              if(distribution_v3 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src)->weight;
 +              else{
 +                      /*invert distribution*/
 +                      distribution_v1= 1/distribution_v1;
 +                      distribution_v2= 1/distribution_v2;
 +                      distribution_v3= 1/distribution_v3;
 +
 +                      /*set total distribution*/
 +                      tot_distribution= distribution_v1 + distribution_v2 + distribution_v3;
 +
 +                      /*check for quad*/
 +                      if(mface_src[nearest.index].v4){
 +                              /*project vertex nr4 coordinate onto face and distribute*/
 +                              copy_v3_v3(tmp_co_v4, mv_src[mface_src[nearest.index].v4].co);
 +                              project_v3_plane(tmp_co_v4, normal, mv_src[mface_src[nearest.index].v1].co);
 +                              distribution_v4= len_squared_v3v3(tmp_co, tmp_co_v4);
 +                              if(distribution_v4 == 0) weight= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src)->weight;
 +                              else{
 +                                      distribution_v4= 1/distribution_v4;
 +                                      tot_distribution+= distribution_v4;
 +
 +                                      /*get weight from quad*/
 +                                      dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src);
 +                                      weight= dw_src->weight * distribution_v1 / tot_distribution;
 +                                      dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src);
 +                                      weight+= dw_src->weight * distribution_v2 / tot_distribution;
 +                                      dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src);
 +                                      weight+= dw_src->weight * distribution_v3 / tot_distribution;
 +                                      dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v4], index_src);
 +                                      weight+= dw_src->weight * distribution_v4 / tot_distribution;
 +                              }
 +                      }
 +                      else{
 +                              /*get weight from triangle*/
 +                              dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v1], index_src);
 +                              weight= dw_src->weight * distribution_v1 / tot_distribution;
 +                              dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v2], index_src);
 +                              weight+= dw_src->weight * distribution_v2 / tot_distribution;
 +                              dw_src= defvert_verify_index(dv_array_src[mface_src[nearest.index].v3], index_src);
 +                              weight+= dw_src->weight * distribution_v3 / tot_distribution;
 +                      }
 +              }
 +
++              /*dist_to_line_segment_v3()*/
++              /*There is probably something fundamentaly wrong about the interpolation.
++              When a vertex is on an edge, it should get no weight from the vertex not connected to the edge...
++              Projected onto edge it should get linar interpolation from two vertices.
++              so it should get the interpolated weight from the third vertex based on the inverted distance from edge along normal to edge!
++              if I got this right! :P
++              */
 +              /*snap to valid number, for testing. This should not be nessecary if interpolation works as its supposed to! or is my logick wrong???*//*
 +              weight*= 1000;
 +              weight+= 0.5;
 +              weight= (int)weight;
 +              weight/=1000;
 +              if(weight>1)weight= 1;*/
 +
 +              /*copy weight*/
 +              dw_dst= defvert_verify_index(*dv_array_dst, index_dst);
 +              dw_dst->weight= weight;
 +      }
 +
 +      /*free memory and return*/
 +      free_bvhtree_from_mesh(&tree_mesh_faces_src);
 +      return 1;
 +}
 +
  
  /* for Mesh in Object mode */
  /* allows editmode for Lattice */