Logo Search packages:      
Sourcecode: blender version File versions

deform.c

/*  deform.c   June 2001
 *  
 *  support for deformation groups
 * 
 *    Reevan McKay
 *
 * $Id: deform.c,v 1.10 2004/11/10 15:55:07 ton Exp $
 *
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */

#include <string.h>
#include <math.h>

#include "MEM_guardedalloc.h"

#include "DNA_curve_types.h"
#include "DNA_effect_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"

#include "BKE_curve.h"
#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_lattice.h"
#include "BKE_object.h"
#include "BKE_softbody.h"
#include "BKE_utildefines.h"

#include "BLI_blenlib.h"
#include "BLI_arithb.h"

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

void color_temperature (float input, unsigned char *r, unsigned char *g, unsigned char *b)
{
      
      /* blue to red */
      
      float fr = (float)(*r);
      float fg = (float)(*g);
      float fb = (float)(*b);

      if (input < 0.0F)
            input = 0.0F;

      if (input > 1.0F)
            input = 1.0F;

      if (input<=0.25f){
            fr=0.0f;
            fg=255.0f * (input*4.0f);
            fb=255.0f;
      }
      else if (input<=0.50f){
            fr=0.0f;
            fg=255.0f;
            fb=255.0f * (1.0f-((input-0.25f)*4.0f)); 
      }
      else if (input<=0.75){
            fr=255.0f * ((input-0.50f)*4.0f);
            fg=255.0f;
            fb=0.0f;
      }
      else if (input<=1.0){
            fr=255.0f;
            fg=255.0f * (1.0f-((input-0.75f)*4.0f)); 
            fb=0.0f;
      }

      (*r) = (unsigned char)(fr * ((input/2.0f)+0.5f));
      (*g) = (unsigned char)(fg * ((input/2.0f)+0.5f));
      (*b) = (unsigned char)(fb * ((input/2.0f)+0.5f));


}

void copy_defgroups(ListBase *outbase, ListBase *inbase)
{
      bDeformGroup *defgroup, *defgroupn;

      outbase->first= outbase->last= 0;

      for (defgroup = inbase->first; defgroup; defgroup=defgroup->next){
            defgroupn= copy_defgroup(defgroup);
            BLI_addtail(outbase, defgroupn);
      }
}

bDeformGroup* copy_defgroup (bDeformGroup *ingroup)
{
      bDeformGroup *outgroup;

      if (!ingroup)
            return NULL;

      outgroup=MEM_callocN(sizeof(bDeformGroup), "deformGroup");
      
      /* For now, just copy everything over. */
      memcpy (outgroup, ingroup, sizeof(bDeformGroup));

      outgroup->next=outgroup->prev=NULL;

      return outgroup;
}

/* *************** HOOK ****************** */

/* vec==NULL: init
   vec is supposed to be local coord, deform happens in local space
*/

void hook_object_deform(Object *ob, int index, float *vec)
{
      float totforce;
      ObHook *hook;
      float vect[3], vectot[3];
      
      if(ob->hooks.first==NULL) return;
      
      /* reinitialize if... */
      if(vec==NULL) {
            totforce= 0.0;
            for(hook= ob->hooks.first; hook; hook= hook->next) {
                  if(hook->parent) {
                        hook->curindex= 0;
                        Mat4Invert(ob->imat, ob->obmat);
                        /* apparently this call goes from right to left... */
                        Mat4MulSerie(hook->mat, ob->imat, hook->parent->obmat, hook->parentinv, NULL, 
                                          NULL, NULL, NULL, NULL);
                  }
            }
            return;
      }

      totforce= 0.0;
      vectot[0]= vectot[1]= vectot[2]= 0.0;
      
      for(hook= ob->hooks.first; hook; hook= hook->next) {
            if(hook->parent) {
                  
                  /* is 'index' in hook array? */
                  while(hook->curindex < hook->totindex-1) {
                        if( hook->indexar[hook->curindex] < index ) hook->curindex++;
                        else break;
                  }
                  
                  if( hook->indexar[hook->curindex]==index ) {
                        float fac= hook->force, len;
                        
                        VecMat4MulVecfl(vect, hook->mat, vec);

                        if(hook->falloff!=0.0) {
                              /* hook->cent is in local coords */
                              len= VecLenf(vec, hook->cent);
                              if(len > hook->falloff) fac= 0.0;
                              else if(len>0.0) fac*= sqrt(1.0 - len/hook->falloff);
                        }
                        if(fac!=0.0) {
                              totforce+= fac;
                              vectot[0]+= fac*vect[0];
                              vectot[1]+= fac*vect[1];
                              vectot[2]+= fac*vect[2];
                        }
                  }
            }
      }

      /* if totforce < 1.0, we take old position also into account */
      if(totforce<1.0) {
            vectot[0]+= (1.0-totforce)*vec[0];
            vectot[1]+= (1.0-totforce)*vec[1];
            vectot[2]+= (1.0-totforce)*vec[2];
      }
      else VecMulf(vectot, 1.0/totforce);
      
      VECCOPY(vec, vectot);
}


/* modifiers: hooks, deform, softbody 
   mode=='s' is start, 'e' is end , 'a' is apply
*/

int mesh_modifier(Object *ob, char mode)
{
      static MVert *mvert=NULL;
      Mesh *me= ob->data;
      MVert *mv;
      int a, done=0;
      
      /* conditions if it's needed */
      if(ob->hooks.first);
      else if(ob->effect.first);    // weak... particles too
      else if(ob->parent && ob->parent->type==OB_LATTICE);
      else if(ob->parent && ob->partype==PARSKEL); 
      else if(ob->softflag);
      else return 0;
      
      if(me->totvert==0) return 0;
      
      if(mode=='s') { // "start"
            /* copy  */
            mvert= MEM_dupallocN(me->mvert);
            
            /* hooks */
            if(ob->hooks.first) {
                  done= 1;
                  
                  /* NULL signals initialize */
                  hook_object_deform(ob, 0, NULL);
                  
                  for(a=0, mv= me->mvert; a<me->totvert; a++, mv++) {
                        hook_object_deform(ob, a, mv->co);
                  }
            }
            
            if(ob->effect.first) done |= object_wave(ob);
            
            if(ob->softflag) {
                  float ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0);
                  done= 1;
                  object_softbody_step(ob, ctime);
            }
            
            /* deform: input mesh, output ob dl_verts. is used by subsurf (output should be in mesh ton!) */
            done |= object_deform(ob);    
            
            /* put deformed vertices in dl->verts, optional subsurf will replace that */
            if(done) {
                  DispList *dl= find_displist_create(&ob->disp, DL_VERTS);
                  float *fp;
                  
                  if(dl->verts) MEM_freeN(dl->verts);
                  if(dl->nors) MEM_freeN(dl->nors);
                  dl->nr= me->totvert;
                  if(dl->nr) {
                        
                        /* make disp array */
                        dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
                        mv= me->mvert;
                        for(a=0; a<me->totvert; a++, mv++, fp+=3) {
                              VECCOPY(fp, mv->co);
                        }
                  }
            }
            
      }
      else if(mode=='e') { // end
            if(mvert) {
                  if(me->mvert) MEM_freeN(me->mvert);
                  me->mvert= mvert;
                  mvert= NULL;
            }
      }
      else if(mode=='a') { // apply
            if(mvert) MEM_freeN(mvert);
            mvert= NULL;
      }
      
      return done;
}

int curve_modifier(Object *ob, char mode)
{
      static ListBase nurb={NULL, NULL};
      Curve *cu= ob->data;
      Nurb *nu, *newnu;
      BezTriple *bezt;
      BPoint *bp;
      int a, index, done= 0;
      
      /* conditions if it's needed */
      if(ob->hooks.first);
      else if(ob->parent && ob->partype==PARSKEL); 
      else if(ob->parent && ob->parent->type==OB_LATTICE);
      else return 0;
      
      if(mode=='s') { // "start"
            /* copy  */
            nurb.first= nurb.last= NULL;  
            nu= cu->nurb.first;
            while(nu) {
                  newnu= duplicateNurb(nu);
                  BLI_addtail(&nurb, newnu);
                  nu= nu->next;
            }
            
            /* hooks */
            if(ob->hooks.first) {
                  done= 1;
                  
                  /* NULL signals initialize */
                  hook_object_deform(ob, 0, NULL);
                  index= 0;
                  
                  nu= cu->nurb.first;
                  while(nu) {
                        if((nu->type & 7)==CU_BEZIER) {
                              bezt= nu->bezt;
                              a= nu->pntsu;
                              while(a--) {
                                    hook_object_deform(ob, index++, bezt->vec[0]);
                                    hook_object_deform(ob, index++, bezt->vec[1]);
                                    hook_object_deform(ob, index++, bezt->vec[2]);
                                    bezt++;
                              }
                        }
                        else {
                              bp= nu->bp;
                              a= nu->pntsu*nu->pntsv;
                              while(a--) {
                                    hook_object_deform(ob, index++, bp->vec);
                                    bp++;
                              }
                        }
                              
                        nu= nu->next;
                  }
            }
      }
      else if(mode=='e') {
            /* paste */
            freeNurblist(&cu->nurb);
            cu->nurb= nurb;
      }
      else if(mode=='a') {
            freeNurblist(&nurb);
      }
      
      return done;
}

int lattice_modifier(Object *ob, char mode)
{
      static BPoint *bpoint;
      Lattice *lt= ob->data;
      BPoint *bp;
      int a, index, done= 0;
      
      /* conditions if it's needed */
      if(ob->hooks.first);
      else if(ob->parent && ob->partype==PARSKEL); 
      else return 0;
      
      if(mode=='s') { // "start"
            /* copy  */
            bpoint= MEM_dupallocN(lt->def);
            
            /* hooks */
            if(ob->hooks.first) {
                  done= 1;
                  
                  /* NULL signals initialize */
                  hook_object_deform(ob, 0, NULL);
                  index= 0;
                  bp= lt->def;
                  a= lt->pntsu*lt->pntsv*lt->pntsw;
                  while(a--) {
                        hook_object_deform(ob, index++, bp->vec);
                        bp++;
                  }
            }
      }
      else { // end
            MEM_freeN(lt->def);
            lt->def= bpoint;
            bpoint= NULL;
      }
      
      return done;
}


Generated by  Doxygen 1.6.0   Back to index