Blender V2.61 - r43446

mball.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * Contributor(s): Jiri Hnidek <jiri.hnidek@vslib.cz>.
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  *
00025  * MetaBalls are created from a single Object (with a name without number in it),
00026  * here the DispList and BoundBox also is located.
00027  * All objects with the same name (but with a number in it) are added to this.
00028  *
00029  * texture coordinates are patched within the displist
00030  */
00031 
00036 #include <stdio.h>
00037 #include <string.h>
00038 #include <math.h>
00039 #include <stdlib.h>
00040 #include <ctype.h>
00041 #include <float.h>
00042 #include "MEM_guardedalloc.h"
00043 
00044 #include "DNA_material_types.h"
00045 #include "DNA_object_types.h"
00046 #include "DNA_meta_types.h"
00047 #include "DNA_scene_types.h"
00048 
00049 
00050 #include "BLI_blenlib.h"
00051 #include "BLI_math.h"
00052 #include "BLI_utildefines.h"
00053 #include "BLI_bpath.h"
00054 
00055 
00056 #include "BKE_global.h"
00057 #include "BKE_main.h"
00058 
00059 /*  #include "BKE_object.h" */
00060 #include "BKE_animsys.h"
00061 #include "BKE_scene.h"
00062 #include "BKE_library.h"
00063 #include "BKE_displist.h"
00064 #include "BKE_mball.h"
00065 #include "BKE_object.h"
00066 #include "BKE_material.h"
00067 
00068 /* Global variables */
00069 
00070 static float thresh= 0.6f;
00071 static int totelem=0;
00072 static MetaElem **mainb;
00073 static octal_tree *metaball_tree = NULL;
00074 /* Functions */
00075 
00076 void unlink_mball(MetaBall *mb)
00077 {
00078     int a;
00079     
00080     for(a=0; a<mb->totcol; a++) {
00081         if(mb->mat[a]) mb->mat[a]->id.us--;
00082         mb->mat[a]= NULL;
00083     }
00084 }
00085 
00086 
00087 /* do not free mball itself */
00088 void free_mball(MetaBall *mb)
00089 {
00090     unlink_mball(mb);   
00091     
00092     if(mb->adt) {
00093         BKE_free_animdata((ID *)mb);
00094         mb->adt = NULL;
00095     }
00096     if(mb->mat) MEM_freeN(mb->mat);
00097     if(mb->bb) MEM_freeN(mb->bb);
00098     BLI_freelistN(&mb->elems);
00099     if(mb->disp.first) freedisplist(&mb->disp);
00100 }
00101 
00102 MetaBall *add_mball(const char *name)
00103 {
00104     MetaBall *mb;
00105     
00106     mb= alloc_libblock(&G.main->mball, ID_MB, name);
00107     
00108     mb->size[0]= mb->size[1]= mb->size[2]= 1.0;
00109     mb->texflag= MB_AUTOSPACE;
00110     
00111     mb->wiresize= 0.4f;
00112     mb->rendersize= 0.2f;
00113     mb->thresh= 0.6f;
00114     
00115     return mb;
00116 }
00117 
00118 MetaBall *copy_mball(MetaBall *mb)
00119 {
00120     MetaBall *mbn;
00121     int a;
00122     
00123     mbn= copy_libblock(&mb->id);
00124 
00125     BLI_duplicatelist(&mbn->elems, &mb->elems);
00126     
00127     mbn->mat= MEM_dupallocN(mb->mat);
00128     for(a=0; a<mbn->totcol; a++) {
00129         id_us_plus((ID *)mbn->mat[a]);
00130     }
00131     mbn->bb= MEM_dupallocN(mb->bb);
00132 
00133     mbn->editelems= NULL;
00134     mbn->lastelem= NULL;
00135     
00136     return mbn;
00137 }
00138 
00139 static void extern_local_mball(MetaBall *mb)
00140 {
00141     if(mb->mat) {
00142         extern_local_matarar(mb->mat, mb->totcol);
00143     }
00144 }
00145 
00146 void make_local_mball(MetaBall *mb)
00147 {
00148     Main *bmain= G.main;
00149     Object *ob;
00150     int is_local= FALSE, is_lib= FALSE;
00151 
00152     /* - only lib users: do nothing
00153      * - only local users: set flag
00154      * - mixed: make copy
00155      */
00156     
00157     if(mb->id.lib==NULL) return;
00158     if(mb->id.us==1) {
00159         id_clear_lib_data(bmain, &mb->id);
00160         extern_local_mball(mb);
00161         
00162         return;
00163     }
00164 
00165     for(ob= G.main->object.first; ob && ELEM(0, is_lib, is_local); ob= ob->id.next) {
00166         if(ob->data == mb) {
00167             if(ob->id.lib) is_lib= TRUE;
00168             else is_local= TRUE;
00169         }
00170     }
00171     
00172     if(is_local && is_lib == FALSE) {
00173         id_clear_lib_data(bmain, &mb->id);
00174         extern_local_mball(mb);
00175     }
00176     else if(is_local && is_lib) {
00177         MetaBall *mb_new= copy_mball(mb);
00178         mb_new->id.us= 0;
00179 
00180         /* Remap paths of new ID using old library as base. */
00181         BKE_id_lib_local_paths(bmain, mb->id.lib, &mb_new->id);
00182 
00183         for(ob= G.main->object.first; ob; ob= ob->id.next) {
00184             if(ob->data == mb) {
00185                 if(ob->id.lib==NULL) {
00186                     ob->data= mb_new;
00187                     mb_new->id.us++;
00188                     mb->id.us--;
00189                 }
00190             }
00191         }
00192     }
00193 }
00194 
00195 /* most simple meta-element adding function
00196  * don't do context manipulation here (rna uses) */
00197 MetaElem *add_metaball_element(MetaBall *mb, const int type)
00198 {
00199     MetaElem *ml= MEM_callocN(sizeof(MetaElem), "metaelem");
00200 
00201     unit_qt(ml->quat);
00202 
00203     ml->rad= 2.0;
00204     ml->s= 2.0;
00205     ml->flag= MB_SCALE_RAD;
00206 
00207     switch(type) {
00208     case MB_BALL:
00209         ml->type = MB_BALL;
00210         ml->expx= ml->expy= ml->expz= 1.0;
00211 
00212         break;
00213     case MB_TUBE:
00214         ml->type = MB_TUBE;
00215         ml->expx= ml->expy= ml->expz= 1.0;
00216 
00217         break;
00218     case MB_PLANE:
00219         ml->type = MB_PLANE;
00220         ml->expx= ml->expy= ml->expz= 1.0;
00221 
00222         break;
00223     case MB_ELIPSOID:
00224         ml->type = MB_ELIPSOID;
00225         ml->expx= 1.2f;
00226         ml->expy= 0.8f;
00227         ml->expz= 1.0;
00228         
00229         break;
00230     case MB_CUBE:
00231         ml->type = MB_CUBE;
00232         ml->expx= ml->expy= ml->expz= 1.0;
00233 
00234         break;
00235     default:
00236         break;
00237     }
00238 
00239     BLI_addtail(&mb->elems, ml);
00240 
00241     return ml;
00242 }
00249 void tex_space_mball(Object *ob)
00250 {
00251     DispList *dl;
00252     BoundBox *bb;
00253     float *data, min[3], max[3] /*, loc[3], size[3] */;
00254     int tot, doit=0;
00255 
00256     if(ob->bb==NULL) ob->bb= MEM_callocN(sizeof(BoundBox), "mb boundbox");
00257     bb= ob->bb;
00258     
00259     /* Weird one, this. */
00260 /*      INIT_MINMAX(min, max); */
00261     (min)[0]= (min)[1]= (min)[2]= 1.0e30f;
00262     (max)[0]= (max)[1]= (max)[2]= -1.0e30f;
00263 
00264     dl= ob->disp.first;
00265     while(dl) {
00266         tot= dl->nr;
00267         if(tot) doit= 1;
00268         data= dl->verts;
00269         while(tot--) {
00270             /* Also weird... but longer. From utildefines. */
00271             DO_MINMAX(data, min, max);
00272             data+= 3;
00273         }
00274         dl= dl->next;
00275     }
00276 
00277     if(!doit) {
00278         min[0] = min[1] = min[2] = -1.0f;
00279         max[0] = max[1] = max[2] = 1.0f;
00280     }
00281     /*
00282     loc[0]= (min[0]+max[0])/2.0f;
00283     loc[1]= (min[1]+max[1])/2.0f;
00284     loc[2]= (min[2]+max[2])/2.0f;
00285     
00286     size[0]= (max[0]-min[0])/2.0f;
00287     size[1]= (max[1]-min[1])/2.0f;
00288     size[2]= (max[2]-min[2])/2.0f;
00289     */
00290     boundbox_set_from_min_max(bb, min, max);
00291 }
00292 
00293 float *make_orco_mball(Object *ob, ListBase *dispbase)
00294 {
00295     BoundBox *bb;
00296     DispList *dl;
00297     float *data, *orco, *orcodata;
00298     float loc[3], size[3];
00299     int a;
00300 
00301     /* restore size and loc */
00302     bb= ob->bb;
00303     loc[0]= (bb->vec[0][0]+bb->vec[4][0])/2.0f;
00304     size[0]= bb->vec[4][0]-loc[0];
00305     loc[1]= (bb->vec[0][1]+bb->vec[2][1])/2.0f;
00306     size[1]= bb->vec[2][1]-loc[1];
00307     loc[2]= (bb->vec[0][2]+bb->vec[1][2])/2.0f;
00308     size[2]= bb->vec[1][2]-loc[2];
00309 
00310     dl= dispbase->first;
00311     orcodata= MEM_mallocN(sizeof(float)*3*dl->nr, "MballOrco");
00312 
00313     data= dl->verts;
00314     orco= orcodata;
00315     a= dl->nr;
00316     while(a--) {
00317         orco[0]= (data[0]-loc[0])/size[0];
00318         orco[1]= (data[1]-loc[1])/size[1];
00319         orco[2]= (data[2]-loc[2])/size[2];
00320 
00321         data+= 3;
00322         orco+= 3;
00323     }
00324 
00325     return orcodata;
00326 }
00327 
00328 /* Note on mball basis stuff 2.5x (this is a can of worms)
00329  * This really needs a rewrite/refactor its totally broken in anything other then basic cases
00330  * Multiple Scenes + Set Scenes & mixing mball basis SHOULD work but fails to update the depsgraph on rename
00331  * and linking into scenes or removal of basis mball. so take care when changing this code.
00332  * 
00333  * Main idiot thing here is that the system returns find_basis_mball() objects which fail a is_basis_mball() test.
00334  *
00335  * Not only that but the depsgraph and their areas depend on this behavior!, so making small fixes here isn't worth it.
00336  * - Campbell
00337  */
00338 
00339 
00345 int is_basis_mball(Object *ob)
00346 {
00347     int len;
00348     
00349     /* just a quick test */
00350     len= strlen(ob->id.name);
00351     if( isdigit(ob->id.name[len-1]) ) return 0;
00352     return 1;
00353 }
00354 
00355 /* return nonzero if ob1 is a basis mball for ob */
00356 int is_mball_basis_for(Object *ob1, Object *ob2)
00357 {
00358     int basis1nr, basis2nr;
00359     char basis1name[MAX_ID_NAME], basis2name[MAX_ID_NAME];
00360 
00361     BLI_split_name_num(basis1name, &basis1nr, ob1->id.name+2, '.');
00362     BLI_split_name_num(basis2name, &basis2nr, ob2->id.name+2, '.');
00363 
00364     if(!strcmp(basis1name, basis2name)) return is_basis_mball(ob1);
00365     else return 0;
00366 }
00367 
00368 /* \brief copy some properties from object to other metaball object with same base name
00369  *
00370  * When some properties (wiresize, threshold, update flags) of metaball are changed, then this properties
00371  * are copied to all metaballs in same "group" (metaballs with same base name: MBall,
00372  * MBall.001, MBall.002, etc). The most important is to copy properties to the base metaball,
00373  * because this metaball influence polygonisation of metaballs. */
00374 void copy_mball_properties(Scene *scene, Object *active_object)
00375 {
00376     Scene *sce_iter= scene;
00377     Base *base;
00378     Object *ob;
00379     MetaBall *active_mball = (MetaBall*)active_object->data;
00380     int basisnr, obnr;
00381     char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
00382     
00383     BLI_split_name_num(basisname, &basisnr, active_object->id.name+2, '.');
00384 
00385     /* XXX recursion check, see scene.c, just too simple code this next_object() */
00386     if(F_ERROR==next_object(&sce_iter, 0, NULL, NULL))
00387         return;
00388     
00389     while(next_object(&sce_iter, 1, &base, &ob)) {
00390         if (ob->type==OB_MBALL) {
00391             if(ob!=active_object){
00392                 BLI_split_name_num(obname, &obnr, ob->id.name+2, '.');
00393 
00394                 /* Object ob has to be in same "group" ... it means, that it has to have
00395                  * same base of its name */
00396                 if(strcmp(obname, basisname)==0){
00397                     MetaBall *mb= ob->data;
00398 
00399                     /* Copy properties from selected/edited metaball */
00400                     mb->wiresize= active_mball->wiresize;
00401                     mb->rendersize= active_mball->rendersize;
00402                     mb->thresh= active_mball->thresh;
00403                     mb->flag= active_mball->flag;
00404                 }
00405             }
00406         }
00407     }
00408 }
00409 
00419 Object *find_basis_mball(Scene *scene, Object *basis)
00420 {
00421     Scene *sce_iter= scene;
00422     Base *base;
00423     Object *ob,*bob= basis;
00424     MetaElem *ml=NULL;
00425     int basisnr, obnr;
00426     char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
00427 
00428     BLI_split_name_num(basisname, &basisnr, basis->id.name+2, '.');
00429     totelem= 0;
00430 
00431     /* XXX recursion check, see scene.c, just too simple code this next_object() */
00432     if(F_ERROR==next_object(&sce_iter, 0, NULL, NULL))
00433         return NULL;
00434     
00435     while(next_object(&sce_iter, 1, &base, &ob)) {
00436         
00437         if (ob->type==OB_MBALL) {
00438             if(ob==bob){
00439                 MetaBall *mb= ob->data;
00440                 
00441                 /* if bob object is in edit mode, then dynamic list of all MetaElems
00442                  * is stored in editelems */
00443                 if(mb->editelems) ml= mb->editelems->first;
00444                 /* if bob object is in object mode */
00445                 else ml= mb->elems.first;
00446             }
00447             else{
00448                 BLI_split_name_num(obname, &obnr, ob->id.name+2, '.');
00449 
00450                 /* object ob has to be in same "group" ... it means, that it has to have
00451                  * same base of its name */
00452                 if(strcmp(obname, basisname)==0){
00453                     MetaBall *mb= ob->data;
00454                     
00455                     /* if object is in edit mode, then dynamic list of all MetaElems
00456                      * is stored in editelems */
00457                     if(mb->editelems) ml= mb->editelems->first;
00458                     /* if bob object is in object mode */
00459                     else ml= mb->elems.first;
00460                     
00461                     if(obnr<basisnr){
00462                         if(!(ob->flag & OB_FROMDUPLI)){
00463                             basis= ob;
00464                             basisnr= obnr;
00465                         }
00466                     }   
00467                 }
00468             }
00469             
00470             while(ml){
00471                 if(!(ml->flag & MB_HIDE)) totelem++;
00472                 ml= ml->next;
00473             }
00474         }
00475     }
00476 
00477     return basis;
00478 }
00479 
00480 
00481 /* ******************** ARITH ************************* */
00482 
00483 /* BASED AT CODE (but mostly rewritten) :
00484  * C code from the article
00485  * "An Implicit Surface Polygonizer"
00486  * by Jules Bloomenthal, jbloom@beauty.gmu.edu
00487  * in "Graphics Gems IV", Academic Press, 1994
00488 
00489  * Authored by Jules Bloomenthal, Xerox PARC.
00490  * Copyright (c) Xerox Corporation, 1991.  All rights reserved.
00491  * Permission is granted to reproduce, use and distribute this code for
00492  * any and all purposes, provided that this notice appears in all copies. */
00493 
00494 #define RES 12 /* # converge iterations    */
00495 
00496 #define L   0  /* left direction:   -x, -i */
00497 #define R   1  /* right direction:  +x, +i */
00498 #define B   2  /* bottom direction: -y, -j */
00499 #define T   3  /* top direction:    +y, +j */
00500 #define N   4  /* near direction:   -z, -k */
00501 #define F   5  /* far direction:    +z, +k */
00502 #define LBN 0  /* left bottom near corner  */
00503 #define LBF 1  /* left bottom far corner   */
00504 #define LTN 2  /* left top near corner     */
00505 #define LTF 3  /* left top far corner      */
00506 #define RBN 4  /* right bottom near corner */
00507 #define RBF 5  /* right bottom far corner  */
00508 #define RTN 6  /* right top near corner    */
00509 #define RTF 7  /* right top far corner     */
00510 
00511 /* the LBN corner of cube (i, j, k), corresponds with location
00512  * (i-0.5)*size, (j-0.5)*size, (k-0.5)*size) */
00513 
00514 #define HASHBIT     (5)
00515 #define HASHSIZE    (size_t)(1<<(3*HASHBIT))   
00517 #define HASH(i,j,k) ((((( (i) & 31)<<5) | ( (j) & 31))<<5 ) | ( (k) & 31) )
00518 
00519 #define MB_BIT(i, bit) (((i)>>(bit))&1)
00520 #define FLIP(i,bit) ((i)^1<<(bit)) /* flip the given bit of i */
00521 
00522 
00523 /* **************** POLYGONIZATION ************************ */
00524 
00525 void calc_mballco(MetaElem *ml, float *vec)
00526 {
00527     if(ml->mat) {
00528         mul_m4_v3((float ( * )[4])ml->mat, vec);
00529     }
00530 }
00531 
00532 float densfunc(MetaElem *ball, float x, float y, float z)
00533 {
00534     float dist2 = 0.0, dx, dy, dz;
00535     float vec[3];
00536 
00537     vec[0]= x;
00538     vec[1]= y;
00539     vec[2]= z;
00540     mul_m4_v3((float ( * )[4])ball->imat, vec);
00541     dx= vec[0];
00542     dy= vec[1];
00543     dz= vec[2];
00544     
00545     if(ball->type==MB_BALL) {
00546     }
00547     else if(ball->type==MB_TUBEX) {
00548         if( dx > ball->len) dx-= ball->len;
00549         else if(dx< -ball->len) dx+= ball->len;
00550         else dx= 0.0;
00551     }
00552     else if(ball->type==MB_TUBEY) {
00553         if( dy > ball->len) dy-= ball->len;
00554         else if(dy< -ball->len) dy+= ball->len;
00555         else dy= 0.0;
00556     }
00557     else if(ball->type==MB_TUBEZ) {
00558         if( dz > ball->len) dz-= ball->len;
00559         else if(dz< -ball->len) dz+= ball->len;
00560         else dz= 0.0;
00561     }
00562     else if(ball->type==MB_TUBE) {
00563         if( dx > ball->expx) dx-= ball->expx;
00564         else if(dx< -ball->expx) dx+= ball->expx;
00565         else dx= 0.0;
00566     }
00567     else if(ball->type==MB_PLANE) {
00568         if( dx > ball->expx) dx-= ball->expx;
00569         else if(dx< -ball->expx) dx+= ball->expx;
00570         else dx= 0.0;
00571         if( dy > ball->expy) dy-= ball->expy;
00572         else if(dy< -ball->expy) dy+= ball->expy;
00573         else dy= 0.0;
00574     }
00575     else if(ball->type==MB_ELIPSOID) {
00576         dx *= 1/ball->expx;
00577         dy *= 1/ball->expy;
00578         dz *= 1/ball->expz;
00579     }
00580     else if(ball->type==MB_CUBE) {
00581         if( dx > ball->expx) dx-= ball->expx;
00582         else if(dx< -ball->expx) dx+= ball->expx;
00583         else dx= 0.0;
00584         if( dy > ball->expy) dy-= ball->expy;
00585         else if(dy< -ball->expy) dy+= ball->expy;
00586         else dy= 0.0;
00587         if( dz > ball->expz) dz-= ball->expz;
00588         else if(dz< -ball->expz) dz+= ball->expz;
00589         else dz= 0.0;
00590     }
00591 
00592     dist2= (dx*dx + dy*dy + dz*dz);
00593 
00594     if(ball->flag & MB_NEGATIVE) {
00595         dist2= 1.0f-(dist2/ball->rad2);
00596         if(dist2 < 0.0f) return 0.5f;
00597 
00598         return 0.5f-ball->s*dist2*dist2*dist2;
00599     }
00600     else {
00601         dist2= 1.0f-(dist2/ball->rad2);
00602         if(dist2 < 0.0f) return -0.5f;
00603 
00604         return ball->s*dist2*dist2*dist2 -0.5f;
00605     }
00606 }
00607 
00608 octal_node* find_metaball_octal_node(octal_node *node, float x, float y, float z, short depth)
00609 {
00610     if(!depth) return node;
00611     
00612     if(z < node->z){
00613         if(y < node->y){
00614             if(x < node->x){
00615                 if(node->nodes[0])
00616                     return find_metaball_octal_node(node->nodes[0],x,y,z,depth--);
00617                 else
00618                     return node;
00619             }
00620             else{
00621                 if(node->nodes[1])
00622                     return find_metaball_octal_node(node->nodes[1],x,y,z,depth--);
00623                 else
00624                     return node;
00625             }
00626         }
00627         else{
00628             if(x < node->x){
00629                 if(node->nodes[3])
00630                     return find_metaball_octal_node(node->nodes[3],x,y,z,depth--);
00631                 else
00632                     return node;
00633             }
00634             else{
00635                 if(node->nodes[2])
00636                     return find_metaball_octal_node(node->nodes[2],x,y,z,depth--);
00637                 else
00638                     return node;
00639             }       
00640         }
00641     }
00642     else{
00643         if(y < node->y){
00644             if(x < node->x){
00645                 if(node->nodes[4])
00646                     return find_metaball_octal_node(node->nodes[4],x,y,z,depth--);
00647                 else
00648                     return node;
00649             }
00650             else{
00651                 if(node->nodes[5])
00652                     return find_metaball_octal_node(node->nodes[5],x,y,z,depth--);
00653                 else
00654                     return node;
00655             }
00656         }
00657         else{
00658             if(x < node->x){
00659                 if(node->nodes[7])
00660                     return find_metaball_octal_node(node->nodes[7],x,y,z,depth--);
00661                 else
00662                     return node;
00663             }
00664             else{
00665                 if(node->nodes[6])
00666                     return find_metaball_octal_node(node->nodes[6],x,y,z,depth--);
00667                 else
00668                     return node;
00669             }       
00670         }
00671     }
00672     
00673     return node;
00674 }
00675 
00676 float metaball(float x, float y, float z)
00677 /*  float x, y, z; */
00678 {
00679     struct octal_node *node;
00680     struct ml_pointer *ml_p;
00681     float dens=0;
00682     int a;
00683     
00684     if(totelem > 1){
00685         node= find_metaball_octal_node(metaball_tree->first, x, y, z, metaball_tree->depth);
00686         if(node){
00687             ml_p= node->elems.first;
00688 
00689             while(ml_p){
00690                 dens+=densfunc(ml_p->ml, x, y, z);
00691                 ml_p= ml_p->next;
00692             }
00693 
00694             dens+= -0.5f*(metaball_tree->pos - node->pos);
00695             dens+= 0.5f*(metaball_tree->neg - node->neg);
00696         }
00697         else{
00698             for(a=0; a<totelem; a++) {
00699                 dens+= densfunc( mainb[a], x, y, z);
00700             }
00701         }
00702     }
00703     else{
00704         dens+= densfunc( mainb[0], x, y, z);
00705     }
00706 
00707     return thresh - dens;
00708 }
00709 
00710 /* ******************************************** */
00711 
00712 static int *indices=NULL;
00713 static int totindex, curindex;
00714 
00715 
00716 void accum_mballfaces(int i1, int i2, int i3, int i4)
00717 {
00718     int *newi, *cur;
00719     /* static int i=0; I would like to delete altogether, but I don't dare to, yet */
00720 
00721     if(totindex==curindex) {
00722         totindex+= 256;
00723         newi= MEM_mallocN(4*sizeof(int)*totindex, "vertindex");
00724         
00725         if(indices) {
00726             memcpy(newi, indices, 4*sizeof(int)*(totindex-256));
00727             MEM_freeN(indices);
00728         }
00729         indices= newi;
00730     }
00731     
00732     cur= indices+4*curindex;
00733 
00734     /* displists now support array drawing, we treat tri's as fake quad */
00735     
00736     cur[0]= i1;
00737     cur[1]= i2;
00738     cur[2]= i3;
00739     if(i4==0)
00740         cur[3]= i3;
00741     else 
00742         cur[3]= i4;
00743     
00744     curindex++;
00745 
00746 }
00747 
00748 /* ******************* MEMORY MANAGEMENT *********************** */
00749 void *new_pgn_element(int size)
00750 {
00751     /* during polygonize 1000s of elements are allocated
00752      * and never freed in between. Freeing only done at the end.
00753      */
00754     int blocksize= 16384;
00755     static int offs= 0;     /* the current free address */
00756     static struct pgn_elements *cur= NULL;
00757     static ListBase lb= {NULL, NULL};
00758     void *adr;
00759     
00760     if(size>10000 || size==0) {
00761         printf("incorrect use of new_pgn_element\n");
00762     }
00763     else if(size== -1) {
00764         cur= lb.first;
00765         while(cur) {
00766             MEM_freeN(cur->data);
00767             cur= cur->next;
00768         }
00769         BLI_freelistN(&lb);
00770         
00771         return NULL;    
00772     }
00773     
00774     size= 4*( (size+3)/4 );
00775     
00776     if(cur) {
00777         if(size+offs < blocksize) {
00778             adr= (void *) (cur->data+offs);
00779             offs+= size;
00780             return adr;
00781         }
00782     }
00783     
00784     cur= MEM_callocN( sizeof(struct pgn_elements), "newpgn");
00785     cur->data= MEM_callocN(blocksize, "newpgn");
00786     BLI_addtail(&lb, cur);
00787     
00788     offs= size;
00789     return cur->data;
00790 }
00791 
00792 void freepolygonize(PROCESS *p)
00793 {
00794     MEM_freeN(p->corners);
00795     MEM_freeN(p->edges);
00796     MEM_freeN(p->centers);
00797 
00798     new_pgn_element(-1);
00799     
00800     if(p->vertices.ptr) MEM_freeN(p->vertices.ptr);
00801 }
00802 
00803 /**** Cubical Polygonization (optional) ****/
00804 
00805 #define LB  0  /* left bottom edge  */
00806 #define LT  1  /* left top edge */
00807 #define LN  2  /* left near edge    */
00808 #define LF  3  /* left far edge */
00809 #define RB  4  /* right bottom edge */
00810 #define RT  5  /* right top edge    */
00811 #define RN  6  /* right near edge   */
00812 #define RF  7  /* right far edge    */
00813 #define BN  8  /* bottom near edge  */
00814 #define BF  9  /* bottom far edge   */
00815 #define TN  10 /* top near edge */
00816 #define TF  11 /* top far edge  */
00817 
00818 static INTLISTS *cubetable[256];
00819 
00820 /* edge: LB, LT, LN, LF, RB, RT, RN, RF, BN, BF, TN, TF */
00821 static int corner1[12]     = {
00822     LBN,LTN,LBN,LBF,RBN,RTN,RBN,RBF,LBN,LBF,LTN,LTF};
00823 static int corner2[12]     = {
00824     LBF,LTF,LTN,LTF,RBF,RTF,RTN,RTF,RBN,RBF,RTN,RTF};
00825 static int leftface[12]    = {
00826     B,  L,  L,  F,  R,  T,  N,  R,  N,  B,  T,  F};
00827 /* face on left when going corner1 to corner2 */
00828 static int rightface[12]   = {
00829     L,  T,  N,  L,  B,  R,  R,  F,  B,  F,  N,  T};
00830 /* face on right when going corner1 to corner2 */
00831 
00832 
00833 /* docube: triangulate the cube directly, without decomposition */
00834 
00835 void docube(CUBE *cube, PROCESS *p, MetaBall *mb)
00836 {
00837     INTLISTS *polys;
00838     CORNER *c1, *c2;
00839     int i, index = 0, count, indexar[8];
00840     
00841     for (i = 0; i < 8; i++) if (cube->corners[i]->value > 0.0f) index += (1<<i);
00842     
00843     for (polys = cubetable[index]; polys; polys = polys->next) {
00844         INTLIST *edges;
00845         
00846         count = 0;
00847         
00848         for (edges = polys->list; edges; edges = edges->next) {
00849             c1 = cube->corners[corner1[edges->i]];
00850             c2 = cube->corners[corner2[edges->i]];
00851             
00852             indexar[count] = vertid(c1, c2, p, mb);
00853             count++;
00854         }
00855         if(count>2) {
00856             switch(count) {
00857             case 3:
00858                 accum_mballfaces(indexar[2], indexar[1], indexar[0], 0);
00859                 break;
00860             case 4:
00861                 if(indexar[0]==0) accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
00862                 else accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
00863                 break;
00864             case 5:
00865                 if(indexar[0]==0) accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
00866                 else accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
00867 
00868                 accum_mballfaces(indexar[4], indexar[3], indexar[0], 0);
00869                 break;
00870             case 6:
00871                 if(indexar[0]==0) {
00872                     accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
00873                     accum_mballfaces(indexar[0], indexar[5], indexar[4], indexar[3]);
00874                 }
00875                 else {
00876                     accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
00877                     accum_mballfaces(indexar[5], indexar[4], indexar[3], indexar[0]);
00878                 }
00879                 break;
00880             case 7:
00881                 if(indexar[0]==0) {
00882                     accum_mballfaces(indexar[0], indexar[3], indexar[2], indexar[1]);
00883                     accum_mballfaces(indexar[0], indexar[5], indexar[4], indexar[3]);
00884                 }
00885                 else {
00886                     accum_mballfaces(indexar[3], indexar[2], indexar[1], indexar[0]);
00887                     accum_mballfaces(indexar[5], indexar[4], indexar[3], indexar[0]);
00888                 }
00889                 
00890                 accum_mballfaces(indexar[6], indexar[5], indexar[0], 0);
00891                 
00892                 break;
00893             }
00894         }
00895     }
00896 }
00897 
00898 
00899 /* testface: given cube at lattice (i, j, k), and four corners of face,
00900  * if surface crosses face, compute other four corners of adjacent cube
00901  * and add new cube to cube stack */
00902 
00903 void testface(int i, int j, int k, CUBE* old, int bit, int c1, int c2, int c3, int c4, PROCESS *p)
00904 {
00905     CUBE newc;
00906     CUBES *oldcubes = p->cubes;
00907     CORNER *corn1, *corn2, *corn3, *corn4;
00908     int n, pos;
00909 
00910     corn1= old->corners[c1];
00911     corn2= old->corners[c2];
00912     corn3= old->corners[c3];
00913     corn4= old->corners[c4];
00914     
00915     pos = corn1->value > 0.0f ? 1 : 0;
00916 
00917     /* test if no surface crossing */
00918     if( (corn2->value > 0) == pos && (corn3->value > 0) == pos && (corn4->value > 0) == pos) return;
00919     /* test if cube out of bounds */
00920     /*if ( abs(i) > p->bounds || abs(j) > p->bounds || abs(k) > p->bounds) return;*/
00921     /* test if already visited (always as last) */
00922     if (setcenter(p->centers, i, j, k)) return;
00923 
00924 
00925     /* create new cube and add cube to top of stack: */
00926     p->cubes = (CUBES *) new_pgn_element(sizeof(CUBES));
00927     p->cubes->next = oldcubes;
00928     
00929     newc.i = i;
00930     newc.j = j;
00931     newc.k = k;
00932     for (n = 0; n < 8; n++) newc.corners[n] = NULL;
00933     
00934     newc.corners[FLIP(c1, bit)] = corn1;
00935     newc.corners[FLIP(c2, bit)] = corn2;
00936     newc.corners[FLIP(c3, bit)] = corn3;
00937     newc.corners[FLIP(c4, bit)] = corn4;
00938 
00939     if(newc.corners[0]==NULL) newc.corners[0] = setcorner(p, i, j, k);
00940     if(newc.corners[1]==NULL) newc.corners[1] = setcorner(p, i, j, k+1);
00941     if(newc.corners[2]==NULL) newc.corners[2] = setcorner(p, i, j+1, k);
00942     if(newc.corners[3]==NULL) newc.corners[3] = setcorner(p, i, j+1, k+1);
00943     if(newc.corners[4]==NULL) newc.corners[4] = setcorner(p, i+1, j, k);
00944     if(newc.corners[5]==NULL) newc.corners[5] = setcorner(p, i+1, j, k+1);
00945     if(newc.corners[6]==NULL) newc.corners[6] = setcorner(p, i+1, j+1, k);
00946     if(newc.corners[7]==NULL) newc.corners[7] = setcorner(p, i+1, j+1, k+1);
00947 
00948     p->cubes->cube= newc;   
00949 }
00950 
00951 /* setcorner: return corner with the given lattice location
00952    set (and cache) its function value */
00953 
00954 CORNER *setcorner (PROCESS* p, int i, int j, int k)
00955 {
00956     /* for speed, do corner value caching here */
00957     CORNER *c;
00958     int index;
00959 
00960     /* does corner exist? */
00961     index = HASH(i, j, k);
00962     c = p->corners[index];
00963     
00964     for (; c != NULL; c = c->next) {
00965         if (c->i == i && c->j == j && c->k == k) {
00966             return c;
00967         }
00968     }
00969 
00970     c = (CORNER *) new_pgn_element(sizeof(CORNER));
00971 
00972     c->i = i; 
00973     c->x = ((float)i-0.5f)*p->size;
00974     c->j = j; 
00975     c->y = ((float)j-0.5f)*p->size;
00976     c->k = k; 
00977     c->z = ((float)k-0.5f)*p->size;
00978     c->value = p->function(c->x, c->y, c->z);
00979     
00980     c->next = p->corners[index];
00981     p->corners[index] = c;
00982     
00983     return c;
00984 }
00985 
00986 
00987 /* nextcwedge: return next clockwise edge from given edge around given face */
00988 
00989 int nextcwedge (int edge, int face)
00990 {
00991     switch (edge) {
00992     case LB: 
00993         return (face == L)? LF : BN;
00994     case LT: 
00995         return (face == L)? LN : TF;
00996     case LN: 
00997         return (face == L)? LB : TN;
00998     case LF: 
00999         return (face == L)? LT : BF;
01000     case RB: 
01001         return (face == R)? RN : BF;
01002     case RT: 
01003         return (face == R)? RF : TN;
01004     case RN: 
01005         return (face == R)? RT : BN;
01006     case RF: 
01007         return (face == R)? RB : TF;
01008     case BN: 
01009         return (face == B)? RB : LN;
01010     case BF: 
01011         return (face == B)? LB : RF;
01012     case TN: 
01013         return (face == T)? LT : RN;
01014     case TF: 
01015         return (face == T)? RT : LF;
01016     }
01017     return 0;
01018 }
01019 
01020 
01021 /* otherface: return face adjoining edge that is not the given face */
01022 
01023 int otherface (int edge, int face)
01024 {
01025     int other = leftface[edge];
01026     return face == other? rightface[edge] : other;
01027 }
01028 
01029 
01030 /* makecubetable: create the 256 entry table for cubical polygonization */
01031 
01032 void makecubetable (void)
01033 {
01034     static int isdone= 0;
01035     int i, e, c, done[12], pos[8];
01036 
01037     if(isdone) return;
01038     isdone= 1;
01039 
01040     for (i = 0; i < 256; i++) {
01041         for (e = 0; e < 12; e++) done[e] = 0;
01042         for (c = 0; c < 8; c++) pos[c] = MB_BIT(i, c);
01043         for (e = 0; e < 12; e++)
01044             if (!done[e] && (pos[corner1[e]] != pos[corner2[e]])) {
01045                 INTLIST *ints = NULL;
01046                 INTLISTS *lists = (INTLISTS *) MEM_callocN(sizeof(INTLISTS), "mball_intlist");
01047                 int start = e, edge = e;
01048                 
01049                 /* get face that is to right of edge from pos to neg corner: */
01050                 int face = pos[corner1[e]]? rightface[e] : leftface[e];
01051                 
01052                 while (1) {
01053                     edge = nextcwedge(edge, face);
01054                     done[edge] = 1;
01055                     if (pos[corner1[edge]] != pos[corner2[edge]]) {
01056                         INTLIST *tmp = ints;
01057                         
01058                         ints = (INTLIST *) MEM_callocN(sizeof(INTLIST), "mball_intlist");
01059                         ints->i = edge;
01060                         ints->next = tmp; /* add edge to head of list */
01061                         
01062                         if (edge == start) break;
01063                         face = otherface(edge, face);
01064                     }
01065                 }
01066                 lists->list = ints; /* add ints to head of table entry */
01067                 lists->next = cubetable[i];
01068                 cubetable[i] = lists;
01069             }
01070     }
01071 }
01072 
01073 void BKE_freecubetable(void)
01074 {
01075     int i;
01076     INTLISTS *lists, *nlists;
01077     INTLIST *ints, *nints;
01078 
01079     for (i = 0; i < 256; i++) {
01080         lists= cubetable[i];
01081         while(lists) {
01082             nlists= lists->next;
01083             
01084             ints= lists->list;
01085             while(ints) {
01086                 nints= ints->next;
01087                 MEM_freeN(ints);
01088                 ints= nints;
01089             }
01090             
01091             MEM_freeN(lists);
01092             lists= nlists;
01093         }
01094         cubetable[i]= NULL;
01095     }
01096 }
01097 
01098 /**** Storage ****/
01099 
01100 /* setcenter: set (i,j,k) entry of table[]
01101  * return 1 if already set; otherwise, set and return 0 */
01102 
01103 int setcenter(CENTERLIST *table[], int i, int j, int k)
01104 {
01105     int index;
01106     CENTERLIST *newc, *l, *q;
01107 
01108     index= HASH(i, j, k);
01109     q= table[index];
01110 
01111     for (l = q; l != NULL; l = l->next) {
01112         if (l->i == i && l->j == j && l->k == k) return 1;
01113     }
01114     
01115     newc = (CENTERLIST *) new_pgn_element(sizeof(CENTERLIST));
01116     newc->i = i; 
01117     newc->j = j; 
01118     newc->k = k; 
01119     newc->next = q;
01120     table[index] = newc;
01121     
01122     return 0;
01123 }
01124 
01125 
01126 /* setedge: set vertex id for edge */
01127 
01128 void setedge (EDGELIST *table[],
01129               int i1, int j1,
01130               int k1, int i2,
01131               int j2, int k2,
01132               int vid)
01133 {
01134     unsigned int index;
01135     EDGELIST *newe;
01136     
01137     if (i1>i2 || (i1==i2 && (j1>j2 || (j1==j2 && k1>k2)))) {
01138         int t=i1; 
01139         i1=i2; 
01140         i2=t; 
01141         t=j1; 
01142         j1=j2; 
01143         j2=t; 
01144         t=k1; 
01145         k1=k2; 
01146         k2=t;
01147     }
01148     index = HASH(i1, j1, k1) + HASH(i2, j2, k2);
01149     newe = (EDGELIST *) new_pgn_element(sizeof(EDGELIST));
01150     newe->i1 = i1; 
01151     newe->j1 = j1; 
01152     newe->k1 = k1;
01153     newe->i2 = i2; 
01154     newe->j2 = j2; 
01155     newe->k2 = k2;
01156     newe->vid = vid;
01157     newe->next = table[index];
01158     table[index] = newe;
01159 }
01160 
01161 
01162 /* getedge: return vertex id for edge; return -1 if not set */
01163 
01164 int getedge (EDGELIST *table[],
01165              int i1, int j1, int k1,
01166              int i2, int j2, int k2)
01167 {
01168     EDGELIST *q;
01169     
01170     if (i1>i2 || (i1==i2 && (j1>j2 || (j1==j2 && k1>k2)))) {
01171         int t=i1; 
01172         i1=i2; 
01173         i2=t; 
01174         t=j1; 
01175         j1=j2; 
01176         j2=t; 
01177         t=k1; 
01178         k1=k2; 
01179         k2=t;
01180     }
01181     q = table[HASH(i1, j1, k1)+HASH(i2, j2, k2)];
01182     for (; q != NULL; q = q->next)
01183         if (q->i1 == i1 && q->j1 == j1 && q->k1 == k1 &&
01184             q->i2 == i2 && q->j2 == j2 && q->k2 == k2)
01185             return q->vid;
01186     return -1;
01187 }
01188 
01189 
01190 /**** Vertices ****/
01191 
01192 #undef R
01193 
01194 
01195 
01196 /* vertid: return index for vertex on edge:
01197  * c1->value and c2->value are presumed of different sign
01198  * return saved index if any; else compute vertex and save */
01199 
01200 /* addtovertices: add v to sequence of vertices */
01201 
01202 void addtovertices (VERTICES *vertices, VERTEX v)
01203 {
01204     if (vertices->count == vertices->max) {
01205         int i;
01206         VERTEX *newv;
01207         vertices->max = vertices->count == 0 ? 10 : 2*vertices->count;
01208         newv = (VERTEX *) MEM_callocN(vertices->max * sizeof(VERTEX), "addtovertices");
01209         
01210         for (i = 0; i < vertices->count; i++) newv[i] = vertices->ptr[i];
01211         
01212         if (vertices->ptr != NULL) MEM_freeN(vertices->ptr);
01213         vertices->ptr = newv;
01214     }
01215     vertices->ptr[vertices->count++] = v;
01216 }
01217 
01218 /* vnormal: compute unit length surface normal at point */
01219 
01220 void vnormal (MB_POINT *point, PROCESS *p, MB_POINT *v)
01221 {
01222     float delta= 0.2f*p->delta;
01223     float f = p->function(point->x, point->y, point->z);
01224 
01225     v->x = p->function(point->x+delta, point->y, point->z)-f;
01226     v->y = p->function(point->x, point->y+delta, point->z)-f;
01227     v->z = p->function(point->x, point->y, point->z+delta)-f;
01228     f = sqrtf(v->x*v->x + v->y*v->y + v->z*v->z);
01229 
01230     if (f != 0.0f) {
01231         v->x /= f; 
01232         v->y /= f; 
01233         v->z /= f;
01234     }
01235     
01236     if(FALSE) {
01237         MB_POINT temp;
01238         
01239         delta *= 2.0f;
01240         
01241         f = p->function(point->x, point->y, point->z);
01242     
01243         temp.x = p->function(point->x+delta, point->y, point->z)-f;
01244         temp.y = p->function(point->x, point->y+delta, point->z)-f;
01245         temp.z = p->function(point->x, point->y, point->z+delta)-f;
01246         f = sqrtf(temp.x*temp.x + temp.y*temp.y + temp.z*temp.z);
01247     
01248         if (f != 0.0f) {
01249             temp.x /= f; 
01250             temp.y /= f; 
01251             temp.z /= f;
01252             
01253             v->x+= temp.x;
01254             v->y+= temp.y;
01255             v->z+= temp.z;
01256             
01257             f = sqrtf(v->x*v->x + v->y*v->y + v->z*v->z);
01258         
01259             if (f != 0.0f) {
01260                 v->x /= f; 
01261                 v->y /= f; 
01262                 v->z /= f;
01263             }
01264         }
01265     }
01266     
01267 }
01268 
01269 
01270 int vertid (CORNER *c1, CORNER *c2, PROCESS *p, MetaBall *mb)
01271 {
01272     VERTEX v;
01273     MB_POINT a, b;
01274     int vid = getedge(p->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
01275 
01276     if (vid != -1) return vid;               /* previously computed */
01277     a.x = c1->x; 
01278     a.y = c1->y; 
01279     a.z = c1->z;
01280     b.x = c2->x; 
01281     b.y = c2->y; 
01282     b.z = c2->z;
01283 
01284     converge(&a, &b, c1->value, c2->value, p->function, &v.position, mb, 1); /* position */
01285     vnormal(&v.position, p, &v.normal);
01286 
01287     addtovertices(&p->vertices, v);            /* save vertex */
01288     vid = p->vertices.count-1;
01289     setedge(p->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
01290     
01291     return vid;
01292 }
01293 
01294 
01295 
01296 
01297 /* converge: from two points of differing sign, converge to zero crossing */
01298 /* watch it: p1 and p2 are used to calculate */
01299 void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2,
01300                float (*function)(float, float, float), MB_POINT *p, MetaBall *mb, int f)
01301 {
01302     int i = 0;
01303     MB_POINT pos, neg;
01304     float positive = 0.0f, negative = 0.0f;
01305     float dx = 0.0f ,dy = 0.0f ,dz = 0.0f;
01306     
01307     if (v1 < 0) {
01308         pos= *p2;
01309         neg= *p1;
01310         positive = v2;
01311         negative = v1;
01312     }
01313     else {
01314         pos= *p1;
01315         neg= *p2;
01316         positive = v1;
01317         negative = v2;
01318     }
01319 
01320     dx = pos.x - neg.x;
01321     dy = pos.y - neg.y;
01322     dz = pos.z - neg.z;
01323 
01324 /* Approximation by linear interpolation is faster then binary subdivision,
01325  * but it results sometimes (mb->thresh < 0.2) into the strange results */
01326     if((mb->thresh > 0.2f) && (f==1)){
01327     if((dy == 0.0f) && (dz == 0.0f)){
01328         p->x = neg.x - negative*dx/(positive-negative);
01329         p->y = neg.y;
01330         p->z = neg.z;
01331         return;
01332     }
01333       if((dx == 0.0f) && (dz == 0.0f)){
01334         p->x = neg.x;
01335         p->y = neg.y - negative*dy/(positive-negative);
01336         p->z = neg.z;
01337         return;
01338     }
01339     if((dx == 0.0f) && (dy == 0.0f)){
01340         p->x = neg.x;
01341         p->y = neg.y;
01342         p->z = neg.z - negative*dz/(positive-negative);
01343         return;
01344     }
01345     }
01346 
01347     if((dy == 0.0f) && (dz == 0.0f)){
01348         p->y = neg.y;
01349         p->z = neg.z;
01350         while (1) {
01351             if (i++ == RES) return;
01352             p->x = 0.5f*(pos.x + neg.x);
01353             if ((function(p->x,p->y,p->z)) > 0.0f)  pos.x = p->x; else neg.x = p->x;
01354         }
01355     }
01356 
01357     if((dx == 0.0f) && (dz == 0.0f)){
01358         p->x = neg.x;
01359         p->z = neg.z;
01360         while (1) {
01361             if (i++ == RES) return;
01362             p->y = 0.5f*(pos.y + neg.y);
01363             if ((function(p->x,p->y,p->z)) > 0.0f)  pos.y = p->y; else neg.y = p->y;
01364         }
01365       }
01366    
01367     if((dx == 0.0f) && (dy == 0.0f)){
01368         p->x = neg.x;
01369         p->y = neg.y;
01370         while (1) {
01371             if (i++ == RES) return;
01372             p->z = 0.5f*(pos.z + neg.z);
01373             if ((function(p->x,p->y,p->z)) > 0.0f)  pos.z = p->z; else neg.z = p->z;
01374         }
01375     }
01376 
01377     /* This is necessary to find start point */
01378     while (1) {
01379         p->x = 0.5f*(pos.x + neg.x);
01380         p->y = 0.5f*(pos.y + neg.y);
01381         p->z = 0.5f*(pos.z + neg.z);
01382 
01383         if (i++ == RES) return;
01384    
01385         if ((function(p->x, p->y, p->z)) > 0.0f){
01386             pos.x = p->x;
01387             pos.y = p->y;
01388             pos.z = p->z;
01389         }
01390         else{
01391             neg.x = p->x;
01392             neg.y = p->y;
01393             neg.z = p->z;
01394         }
01395     }
01396 }
01397 
01398 /* ************************************** */
01399 void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
01400 {
01401     CUBES *ncube;
01402     int n;
01403     int a, b, c;
01404 
01405     /* hmmm, not only one, but eight cube will be added on the stack 
01406      * ... */
01407     for(a=i-1; a<i+count; a++)
01408         for(b=j-1; b<j+count; b++)
01409             for(c=k-1; c<k+count; c++) {
01410                 /* test if cube has been found before */
01411                 if( setcenter(mbproc->centers, a, b, c)==0 ) {
01412                     /* push cube on stack: */
01413                     ncube= (CUBES *) new_pgn_element(sizeof(CUBES));
01414                     ncube->next= mbproc->cubes;
01415                     mbproc->cubes= ncube;
01416 
01417                     ncube->cube.i= a;
01418                     ncube->cube.j= b;
01419                     ncube->cube.k= c;
01420 
01421                     /* set corners of initial cube: */
01422                     for (n = 0; n < 8; n++)
01423                     ncube->cube.corners[n] = setcorner(mbproc, a+MB_BIT(n,2), b+MB_BIT(n,1), c+MB_BIT(n,0));
01424                 }
01425             }
01426 }
01427 
01428 
01429 void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
01430 {
01431     MB_POINT IN, in, OUT, out; /*point;*/
01432     MetaElem *ml;
01433     int i, j, k, c_i, c_j, c_k;
01434     int index[3]={1,0,-1};
01435     float f =0.0f;
01436     float in_v /*, out_v*/;
01437     MB_POINT workp;
01438     float tmp_v, workp_v, max_len, len, dx, dy, dz, nx, ny, nz, MAXN;
01439 
01440     ml = mainb[a];
01441 
01442     f = 1-(mb->thresh/ml->s);
01443 
01444     /* Skip, when Stiffness of MetaElement is too small ... MetaElement can't be
01445      * visible alone ... but still can influence others MetaElements :-) */
01446     if(f > 0.0f) {
01447         OUT.x = IN.x = in.x= 0.0;
01448         OUT.y = IN.y = in.y= 0.0;
01449         OUT.z = IN.z = in.z= 0.0;
01450 
01451         calc_mballco(ml, (float *)&in);
01452         in_v = mbproc->function(in.x, in.y, in.z);
01453 
01454         for(i=0;i<3;i++){
01455             switch (ml->type) {
01456                 case MB_BALL:
01457                     OUT.x = out.x= IN.x + index[i]*ml->rad;
01458                     break;
01459                 case MB_TUBE:
01460                 case MB_PLANE:
01461                 case MB_ELIPSOID:
01462                 case MB_CUBE:
01463                     OUT.x = out.x= IN.x + index[i]*(ml->expx + ml->rad);
01464                     break;
01465             }
01466 
01467             for(j=0;j<3;j++) {
01468                 switch (ml->type) {
01469                     case MB_BALL:
01470                         OUT.y = out.y= IN.y + index[j]*ml->rad;
01471                         break;
01472                     case MB_TUBE:
01473                     case MB_PLANE:
01474                     case MB_ELIPSOID:
01475                     case MB_CUBE:
01476                         OUT.y = out.y= IN.y + index[j]*(ml->expy + ml->rad);
01477                         break;
01478                 }
01479             
01480                 for(k=0;k<3;k++) {
01481                     out.x = OUT.x;
01482                     out.y = OUT.y;
01483                     switch (ml->type) {
01484                         case MB_BALL:
01485                         case MB_TUBE:
01486                         case MB_PLANE:
01487                             out.z= IN.z + index[k]*ml->rad;
01488                             break;
01489                         case MB_ELIPSOID:
01490                         case MB_CUBE:
01491                             out.z= IN.z + index[k]*(ml->expz + ml->rad);
01492                             break;
01493                     }
01494 
01495                     calc_mballco(ml, (float *)&out);
01496 
01497                     /*out_v = mbproc->function(out.x, out.y, out.z);*/ /*UNUSED*/
01498 
01499                     /* find "first points" on Implicit Surface of MetaElemnt ml */
01500                     workp.x = in.x;
01501                     workp.y = in.y;
01502                     workp.z = in.z;
01503                     workp_v = in_v;
01504                     max_len = sqrtf((out.x-in.x)*(out.x-in.x) + (out.y-in.y)*(out.y-in.y) + (out.z-in.z)*(out.z-in.z));
01505 
01506                     nx = abs((out.x - in.x)/mbproc->size);
01507                     ny = abs((out.y - in.y)/mbproc->size);
01508                     nz = abs((out.z - in.z)/mbproc->size);
01509                     
01510                     MAXN = MAX3(nx,ny,nz);
01511                     if(MAXN!=0.0f) {
01512                         dx = (out.x - in.x)/MAXN;
01513                         dy = (out.y - in.y)/MAXN;
01514                         dz = (out.z - in.z)/MAXN;
01515 
01516                         len = 0.0;
01517                         while(len<=max_len) {
01518                             workp.x += dx;
01519                             workp.y += dy;
01520                             workp.z += dz;
01521                             /* compute value of implicite function */
01522                             tmp_v = mbproc->function(workp.x, workp.y, workp.z);
01523                             /* add cube to the stack, when value of implicite function crosses zero value */
01524                             if((tmp_v<0.0f && workp_v>=0.0f)||(tmp_v>0.0f && workp_v<=0.0f)) {
01525 
01526                                 /* indexes of CUBE, which includes "first point" */
01527                                 c_i= (int)floor(workp.x/mbproc->size);
01528                                 c_j= (int)floor(workp.y/mbproc->size);
01529                                 c_k= (int)floor(workp.z/mbproc->size);
01530                                 
01531                                 /* add CUBE (with indexes c_i, c_j, c_k) to the stack,
01532                                  * this cube includes found point of Implicit Surface */
01533                                 if (ml->flag & MB_NEGATIVE)
01534                                     add_cube(mbproc, c_i, c_j, c_k, 2);
01535                                 else
01536                                     add_cube(mbproc, c_i, c_j, c_k, 1);
01537                             }
01538                             len = sqrtf((workp.x-in.x)*(workp.x-in.x) + (workp.y-in.y)*(workp.y-in.y) + (workp.z-in.z)*(workp.z-in.z));
01539                             workp_v = tmp_v;
01540 
01541                         }
01542                     }
01543                 }
01544             }
01545         }
01546     }
01547 }
01548 
01549 void polygonize(PROCESS *mbproc, MetaBall *mb)
01550 {
01551     CUBE c;
01552     int a;
01553 
01554     mbproc->vertices.count = mbproc->vertices.max = 0;
01555     mbproc->vertices.ptr = NULL;
01556 
01557     /* allocate hash tables and build cube polygon table: */
01558     mbproc->centers = MEM_callocN(HASHSIZE * sizeof(CENTERLIST *), "mbproc->centers");
01559     mbproc->corners = MEM_callocN(HASHSIZE * sizeof(CORNER *), "mbproc->corners");
01560     mbproc->edges = MEM_callocN(2*HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
01561     makecubetable();
01562 
01563     for(a=0; a<totelem; a++) {
01564 
01565         /* try to find 8 points on the surface for each MetaElem */
01566         find_first_points(mbproc, mb, a);   
01567     }
01568 
01569     /* polygonize all MetaElems of current MetaBall */
01570     while (mbproc->cubes != NULL) { /* process active cubes till none left */
01571         c = mbproc->cubes->cube;
01572 
01573         /* polygonize the cube directly: */
01574         docube(&c, mbproc, mb);
01575         
01576         /* pop current cube from stack */
01577         mbproc->cubes = mbproc->cubes->next;
01578         
01579         /* test six face directions, maybe add to stack: */
01580         testface(c.i-1, c.j, c.k, &c, 2, LBN, LBF, LTN, LTF, mbproc);
01581         testface(c.i+1, c.j, c.k, &c, 2, RBN, RBF, RTN, RTF, mbproc);
01582         testface(c.i, c.j-1, c.k, &c, 1, LBN, LBF, RBN, RBF, mbproc);
01583         testface(c.i, c.j+1, c.k, &c, 1, LTN, LTF, RTN, RTF, mbproc);
01584         testface(c.i, c.j, c.k-1, &c, 0, LBN, LTN, RBN, RTN, mbproc);
01585         testface(c.i, c.j, c.k+1, &c, 0, LBF, LTF, RBF, RTF, mbproc);
01586     }
01587 }
01588 
01589 float init_meta(Scene *scene, Object *ob)   /* return totsize */
01590 {
01591     Scene *sce_iter= scene;
01592     Base *base;
01593     Object *bob;
01594     MetaBall *mb;
01595     MetaElem *ml;
01596     float size, totsize, obinv[4][4], obmat[4][4], vec[3];
01597     //float max=0.0;
01598     int a, obnr, zero_size=0;
01599     char obname[MAX_ID_NAME];
01600     
01601     copy_m4_m4(obmat, ob->obmat);   /* to cope with duplicators from next_object */
01602     invert_m4_m4(obinv, ob->obmat);
01603     a= 0;
01604     
01605     BLI_split_name_num(obname, &obnr, ob->id.name+2, '.');
01606     
01607     /* make main array */
01608     next_object(&sce_iter, 0, NULL, NULL);
01609     while(next_object(&sce_iter, 1, &base, &bob)) {
01610 
01611         if(bob->type==OB_MBALL) {
01612             zero_size= 0;
01613             ml= NULL;
01614 
01615             if(bob==ob && (base->flag & OB_FROMDUPLI)==0) {
01616                 mb= ob->data;
01617     
01618                 if(mb->editelems) ml= mb->editelems->first;
01619                 else ml= mb->elems.first;
01620             }
01621             else {
01622                 char name[MAX_ID_NAME];
01623                 int nr;
01624                 
01625                 BLI_split_name_num(name, &nr, bob->id.name+2, '.');
01626                 if( strcmp(obname, name)==0 ) {
01627                     mb= bob->data;
01628                     
01629                     if(mb->editelems) ml= mb->editelems->first;
01630                     else ml= mb->elems.first;
01631                 }
01632             }
01633 
01634             /* when metaball object has zero scale, then MetaElem to this MetaBall
01635              * will not be put to mainb array */
01636             if(bob->size[0]==0.0f || bob->size[1]==0.0f || bob->size[2]==0.0f) {
01637                 zero_size= 1;
01638             }
01639             else if(bob->parent) {
01640                 struct Object *pob=bob->parent;
01641                 while(pob) {
01642                     if(pob->size[0]==0.0f || pob->size[1]==0.0f || pob->size[2]==0.0f) {
01643                         zero_size= 1;
01644                         break;
01645                     }
01646                     pob= pob->parent;
01647                 }
01648             }
01649 
01650             if (zero_size) {
01651                 unsigned int ml_count=0;
01652                 while(ml) {
01653                     ml_count++;
01654                     ml= ml->next;
01655                 }
01656                 totelem -= ml_count;
01657             }
01658             else {
01659             while(ml) {
01660                 if(!(ml->flag & MB_HIDE)) {
01661                     int i;
01662                     float temp1[4][4], temp2[4][4], temp3[4][4];
01663                     float (*mat)[4] = NULL, (*imat)[4] = NULL;
01664                     float max_x, max_y, max_z, min_x, min_y, min_z;
01665 
01666                     max_x = max_y = max_z = -3.4e38;
01667                     min_x = min_y = min_z =  3.4e38;
01668 
01669                     /* too big stiffness seems only ugly due to linear interpolation
01670                      * no need to have possibility for too big stiffness */
01671                     if(ml->s > 10.0f) ml->s = 10.0f;
01672                     
01673                     /* Rotation of MetaElem is stored in quat */
01674                      quat_to_mat4( temp3,ml->quat);
01675 
01676                     /* Translation of MetaElem */
01677                     unit_m4(temp2);
01678                     temp2[3][0]= ml->x;
01679                     temp2[3][1]= ml->y;
01680                     temp2[3][2]= ml->z;
01681 
01682                     mult_m4_m4m4(temp1, temp2, temp3);
01683                 
01684                     /* make a copy because of duplicates */
01685                     mainb[a]= new_pgn_element(sizeof(MetaElem));
01686                     *(mainb[a])= *ml;
01687                     mainb[a]->bb = new_pgn_element(sizeof(BoundBox));
01688                 
01689                     mat= new_pgn_element(4*4*sizeof(float));
01690                     imat= new_pgn_element(4*4*sizeof(float));
01691                     
01692                     /* mat is the matrix to transform from mball into the basis-mball */
01693                     invert_m4_m4(obinv, obmat);
01694                     mult_m4_m4m4(temp2, obinv, bob->obmat);
01695                     /* MetaBall transformation */
01696                     mult_m4_m4m4(mat, temp2, temp1);
01697 
01698                     invert_m4_m4(imat,mat);             
01699 
01700                     mainb[a]->rad2= ml->rad*ml->rad;
01701 
01702                     mainb[a]->mat= (float*) mat;
01703                     mainb[a]->imat= (float*) imat;
01704 
01705                     /* untransformed Bounding Box of MetaElem */
01706                     /* 0 */
01707                     mainb[a]->bb->vec[0][0]= -ml->expx;
01708                     mainb[a]->bb->vec[0][1]= -ml->expy;
01709                     mainb[a]->bb->vec[0][2]= -ml->expz;
01710                     /* 1 */
01711                     mainb[a]->bb->vec[1][0]=  ml->expx;
01712                     mainb[a]->bb->vec[1][1]= -ml->expy;
01713                     mainb[a]->bb->vec[1][2]= -ml->expz;
01714                     /* 2 */
01715                     mainb[a]->bb->vec[2][0]=  ml->expx;
01716                     mainb[a]->bb->vec[2][1]=  ml->expy;
01717                     mainb[a]->bb->vec[2][2]= -ml->expz;
01718                     /* 3 */
01719                     mainb[a]->bb->vec[3][0]= -ml->expx;
01720                     mainb[a]->bb->vec[3][1]=  ml->expy;
01721                     mainb[a]->bb->vec[3][2]= -ml->expz;
01722                     /* 4 */
01723                     mainb[a]->bb->vec[4][0]= -ml->expx;
01724                     mainb[a]->bb->vec[4][1]= -ml->expy;
01725                     mainb[a]->bb->vec[4][2]=  ml->expz;
01726                     /* 5 */
01727                     mainb[a]->bb->vec[5][0]=  ml->expx;
01728                     mainb[a]->bb->vec[5][1]= -ml->expy;
01729                     mainb[a]->bb->vec[5][2]=  ml->expz;
01730                     /* 6 */
01731                     mainb[a]->bb->vec[6][0]=  ml->expx;
01732                     mainb[a]->bb->vec[6][1]=  ml->expy;
01733                     mainb[a]->bb->vec[6][2]=  ml->expz;
01734                     /* 7 */
01735                     mainb[a]->bb->vec[7][0]= -ml->expx;
01736                     mainb[a]->bb->vec[7][1]=  ml->expy;
01737                     mainb[a]->bb->vec[7][2]=  ml->expz;
01738 
01739                     /* transformation of Metalem bb */
01740                     for(i=0; i<8; i++)
01741                         mul_m4_v3((float ( * )[4])mat, mainb[a]->bb->vec[i]);
01742 
01743                     /* find max and min of transformed bb */
01744                     for(i=0; i<8; i++){
01745                         /* find maximums */
01746                         if(mainb[a]->bb->vec[i][0] > max_x) max_x = mainb[a]->bb->vec[i][0];
01747                         if(mainb[a]->bb->vec[i][1] > max_y) max_y = mainb[a]->bb->vec[i][1];
01748                         if(mainb[a]->bb->vec[i][2] > max_z) max_z = mainb[a]->bb->vec[i][2];
01749                         /* find  minimums */
01750                         if(mainb[a]->bb->vec[i][0] < min_x) min_x = mainb[a]->bb->vec[i][0];
01751                         if(mainb[a]->bb->vec[i][1] < min_y) min_y = mainb[a]->bb->vec[i][1];
01752                         if(mainb[a]->bb->vec[i][2] < min_z) min_z = mainb[a]->bb->vec[i][2];
01753                     }
01754 
01755                     /* create "new" bb, only point 0 and 6, which are
01756                      * neccesary for octal tree filling */
01757                     mainb[a]->bb->vec[0][0] = min_x - ml->rad;
01758                     mainb[a]->bb->vec[0][1] = min_y - ml->rad;
01759                     mainb[a]->bb->vec[0][2] = min_z - ml->rad;
01760 
01761                     mainb[a]->bb->vec[6][0] = max_x + ml->rad;
01762                     mainb[a]->bb->vec[6][1] = max_y + ml->rad;
01763                     mainb[a]->bb->vec[6][2] = max_z + ml->rad;
01764                     
01765                     a++;
01766                 }
01767                 ml= ml->next;
01768             }
01769             }
01770         }
01771     }
01772 
01773     
01774     /* totsize (= 'manhattan' radius) */
01775     totsize= 0.0;
01776     for(a=0; a<totelem; a++) {
01777         
01778         vec[0]= mainb[a]->x + mainb[a]->rad + mainb[a]->expx;
01779         vec[1]= mainb[a]->y + mainb[a]->rad + mainb[a]->expy;
01780         vec[2]= mainb[a]->z + mainb[a]->rad + mainb[a]->expz;
01781 
01782         calc_mballco(mainb[a], vec);
01783     
01784         size= fabsf( vec[0] );
01785         if( size > totsize ) totsize= size;
01786         size= fabsf( vec[1] );
01787         if( size > totsize ) totsize= size;
01788         size= fabsf( vec[2] );
01789         if( size > totsize ) totsize= size;
01790 
01791         vec[0]= mainb[a]->x - mainb[a]->rad;
01792         vec[1]= mainb[a]->y - mainb[a]->rad;
01793         vec[2]= mainb[a]->z - mainb[a]->rad;
01794                 
01795         calc_mballco(mainb[a], vec);
01796     
01797         size= fabsf( vec[0] );
01798         if( size > totsize ) totsize= size;
01799         size= fabsf( vec[1] );
01800         if( size > totsize ) totsize= size;
01801         size= fabsf( vec[2] );
01802         if( size > totsize ) totsize= size;
01803     }
01804 
01805     for(a=0; a<totelem; a++) {
01806         thresh+= densfunc( mainb[a], 2.0f*totsize, 2.0f*totsize, 2.0f*totsize);
01807     }
01808 
01809     return totsize;
01810 }
01811 
01812 /* if MetaElem lies in node, then node includes MetaElem pointer (ml_p)
01813  * pointing at MetaElem (ml)
01814  */
01815 void fill_metaball_octal_node(octal_node *node, MetaElem *ml, short i)
01816 {
01817     ml_pointer *ml_p;
01818 
01819     ml_p= MEM_mallocN(sizeof(ml_pointer), "ml_pointer");
01820     ml_p->ml= ml;
01821     BLI_addtail(&(node->nodes[i]->elems), ml_p);
01822     node->count++;
01823     
01824     if(ml->flag & MB_NEGATIVE) {
01825         node->nodes[i]->neg++;
01826     }
01827     else{
01828         node->nodes[i]->pos++;
01829     }
01830 }
01831 
01832 /* Node is subdivided as is ilustrated on the following figure:
01833  * 
01834  *      +------+------+
01835  *     /      /      /|
01836  *    +------+------+ |
01837  *   /      /      /| +
01838  *  +------+------+ |/|
01839  *  |      |      | + |
01840  *  |      |      |/| +
01841  *  +------+------+ |/
01842  *  |      |      | +
01843  *  |      |      |/
01844  *  +------+------+
01845  *  
01846  */
01847 void subdivide_metaball_octal_node(octal_node *node, float size_x, float size_y, float size_z, short depth)
01848 {
01849     MetaElem *ml;
01850     ml_pointer *ml_p;
01851     float x,y,z;
01852     int a,i;
01853 
01854     /* create new nodes */
01855     for(a=0;a<8;a++){
01856         node->nodes[a]= MEM_mallocN(sizeof(octal_node),"octal_node");
01857         for(i=0;i<8;i++)
01858             node->nodes[a]->nodes[i]= NULL;
01859         node->nodes[a]->parent= node;
01860         node->nodes[a]->elems.first= NULL;
01861         node->nodes[a]->elems.last= NULL;
01862         node->nodes[a]->count= 0;
01863         node->nodes[a]->neg= 0;
01864         node->nodes[a]->pos= 0;
01865     }
01866 
01867     size_x /= 2;
01868     size_y /= 2;
01869     size_z /= 2;
01870     
01871     /* center of node */
01872     node->x = x = node->x_min + size_x;
01873     node->y = y = node->y_min + size_y;
01874     node->z = z = node->z_min + size_z;
01875 
01876     /* setting up of border points of new nodes */
01877     node->nodes[0]->x_min = node->x_min;
01878     node->nodes[0]->y_min = node->y_min;
01879     node->nodes[0]->z_min = node->z_min;
01880     node->nodes[0]->x = node->nodes[0]->x_min + size_x/2;
01881     node->nodes[0]->y = node->nodes[0]->y_min + size_y/2;
01882     node->nodes[0]->z = node->nodes[0]->z_min + size_z/2;
01883     
01884     node->nodes[1]->x_min = x;
01885     node->nodes[1]->y_min = node->y_min;
01886     node->nodes[1]->z_min = node->z_min;
01887     node->nodes[1]->x = node->nodes[1]->x_min + size_x/2;
01888     node->nodes[1]->y = node->nodes[1]->y_min + size_y/2;
01889     node->nodes[1]->z = node->nodes[1]->z_min + size_z/2;
01890 
01891     node->nodes[2]->x_min = x;
01892     node->nodes[2]->y_min = y;
01893     node->nodes[2]->z_min = node->z_min;
01894     node->nodes[2]->x = node->nodes[2]->x_min + size_x/2;
01895     node->nodes[2]->y = node->nodes[2]->y_min + size_y/2;
01896     node->nodes[2]->z = node->nodes[2]->z_min + size_z/2;
01897 
01898     node->nodes[3]->x_min = node->x_min;
01899     node->nodes[3]->y_min = y;
01900     node->nodes[3]->z_min = node->z_min;
01901     node->nodes[3]->x = node->nodes[3]->x_min + size_x/2;
01902     node->nodes[3]->y = node->nodes[3]->y_min + size_y/2;
01903     node->nodes[3]->z = node->nodes[3]->z_min + size_z/2;
01904 
01905     node->nodes[4]->x_min = node->x_min;
01906     node->nodes[4]->y_min = node->y_min;
01907     node->nodes[4]->z_min = z;
01908     node->nodes[4]->x = node->nodes[4]->x_min + size_x/2;
01909     node->nodes[4]->y = node->nodes[4]->y_min + size_y/2;
01910     node->nodes[4]->z = node->nodes[4]->z_min + size_z/2;
01911     
01912     node->nodes[5]->x_min = x;
01913     node->nodes[5]->y_min = node->y_min;
01914     node->nodes[5]->z_min = z;
01915     node->nodes[5]->x = node->nodes[5]->x_min + size_x/2;
01916     node->nodes[5]->y = node->nodes[5]->y_min + size_y/2;
01917     node->nodes[5]->z = node->nodes[5]->z_min + size_z/2;
01918 
01919     node->nodes[6]->x_min = x;
01920     node->nodes[6]->y_min = y;
01921     node->nodes[6]->z_min = z;
01922     node->nodes[6]->x = node->nodes[6]->x_min + size_x/2;
01923     node->nodes[6]->y = node->nodes[6]->y_min + size_y/2;
01924     node->nodes[6]->z = node->nodes[6]->z_min + size_z/2;
01925 
01926     node->nodes[7]->x_min = node->x_min;
01927     node->nodes[7]->y_min = y;
01928     node->nodes[7]->z_min = z;
01929     node->nodes[7]->x = node->nodes[7]->x_min + size_x/2;
01930     node->nodes[7]->y = node->nodes[7]->y_min + size_y/2;
01931     node->nodes[7]->z = node->nodes[7]->z_min + size_z/2;
01932 
01933     ml_p= node->elems.first;
01934     
01935     /* setting up references of MetaElems for new nodes */
01936     while(ml_p){
01937         ml= ml_p->ml;
01938         if(ml->bb->vec[0][2] < z){
01939             if(ml->bb->vec[0][1] < y){
01940                 /* vec[0][0] lies in first octant */
01941                 if(ml->bb->vec[0][0] < x){
01942                     /* ml belongs to the (0)1st node */
01943                     fill_metaball_octal_node(node, ml, 0);
01944 
01945                     /* ml belongs to the (3)4th node */
01946                     if(ml->bb->vec[6][1] >= y){
01947                         fill_metaball_octal_node(node, ml, 3);
01948 
01949                         /* ml belongs to the (7)8th node */
01950                         if(ml->bb->vec[6][2] >= z){
01951                             fill_metaball_octal_node(node, ml, 7);
01952                         }
01953                     }
01954     
01955                     /* ml belongs to the (1)2nd node */
01956                     if(ml->bb->vec[6][0] >= x){
01957                         fill_metaball_octal_node(node, ml, 1);
01958 
01959                         /* ml belongs to the (5)6th node */
01960                         if(ml->bb->vec[6][2] >= z){
01961                             fill_metaball_octal_node(node, ml, 5);
01962                         }
01963                     }
01964 
01965                     /* ml belongs to the (2)3th node */
01966                     if((ml->bb->vec[6][0] >= x) && (ml->bb->vec[6][1] >= y)){
01967                         fill_metaball_octal_node(node, ml, 2);
01968                         
01969                         /* ml belong to the (6)7th node */
01970                         if(ml->bb->vec[6][2] >= z){
01971                             fill_metaball_octal_node(node, ml, 6);
01972                         }
01973                         
01974                     }
01975             
01976                     /* ml belongs to the (4)5th node too */ 
01977                     if(ml->bb->vec[6][2] >= z){
01978                         fill_metaball_octal_node(node, ml, 4);
01979                     }
01980 
01981                     
01982                     
01983                 }
01984                 /* vec[0][0] is in the (1)second octant */
01985                 else{
01986                     /* ml belong to the (1)2nd node */
01987                     fill_metaball_octal_node(node, ml, 1);
01988 
01989                     /* ml belongs to the (2)3th node */
01990                     if(ml->bb->vec[6][1] >= y){
01991                         fill_metaball_octal_node(node, ml, 2);
01992 
01993                         /* ml belongs to the (6)7th node */
01994                         if(ml->bb->vec[6][2] >= z){
01995                             fill_metaball_octal_node(node, ml, 6);
01996                         }
01997                         
01998                     }
01999                     
02000                     /* ml belongs to the (5)6th node */
02001                     if(ml->bb->vec[6][2] >= z){
02002                         fill_metaball_octal_node(node, ml, 5);
02003                     }
02004                 }
02005             }
02006             else{
02007                 /* vec[0][0] is in the (3)4th octant */
02008                 if(ml->bb->vec[0][0] < x){
02009                     /* ml belongs to the (3)4nd node */
02010                     fill_metaball_octal_node(node, ml, 3);
02011                     
02012                     /* ml belongs to the (7)8th node */
02013                     if(ml->bb->vec[6][2] >= z){
02014                         fill_metaball_octal_node(node, ml, 7);
02015                     }
02016                 
02017 
02018                     /* ml belongs to the (2)3th node */
02019                     if(ml->bb->vec[6][0] >= x){
02020                         fill_metaball_octal_node(node, ml, 2);
02021                     
02022                         /* ml belongs to the (6)7th node */
02023                         if(ml->bb->vec[6][2] >= z){
02024                             fill_metaball_octal_node(node, ml, 6);
02025                         }
02026                     }
02027                 }
02028 
02029             }
02030 
02031             /* vec[0][0] is in the (2)3th octant */
02032             if((ml->bb->vec[0][0] >= x) && (ml->bb->vec[0][1] >= y)){
02033                 /* ml belongs to the (2)3th node */
02034                 fill_metaball_octal_node(node, ml, 2);
02035                 
02036                 /* ml belongs to the (6)7th node */
02037                 if(ml->bb->vec[6][2] >= z){
02038                     fill_metaball_octal_node(node, ml, 6);
02039                 }
02040             }
02041         }
02042         else{
02043             if(ml->bb->vec[0][1] < y){
02044                 /* vec[0][0] lies in (4)5th octant */
02045                 if(ml->bb->vec[0][0] < x){
02046                     /* ml belongs to the (4)5th node */
02047                     fill_metaball_octal_node(node, ml, 4);
02048 
02049                     if(ml->bb->vec[6][0] >= x){
02050                         fill_metaball_octal_node(node, ml, 5);
02051                     }
02052 
02053                     if(ml->bb->vec[6][1] >= y){
02054                         fill_metaball_octal_node(node, ml, 7);
02055                     }
02056                     
02057                     if((ml->bb->vec[6][0] >= x) && (ml->bb->vec[6][1] >= y)){
02058                         fill_metaball_octal_node(node, ml, 6);
02059                     }
02060                 }
02061                 /* vec[0][0] lies in (5)6th octant */
02062                 else{
02063                     fill_metaball_octal_node(node, ml, 5);
02064 
02065                     if(ml->bb->vec[6][1] >= y){
02066                         fill_metaball_octal_node(node, ml, 6);
02067                     }
02068                 }
02069             }
02070             else{
02071                 /* vec[0][0] lies in (7)8th octant */
02072                 if(ml->bb->vec[0][0] < x){
02073                     fill_metaball_octal_node(node, ml, 7);
02074 
02075                     if(ml->bb->vec[6][0] >= x){
02076                         fill_metaball_octal_node(node, ml, 6);
02077                     }
02078                 }
02079 
02080             }
02081             
02082             /* vec[0][0] lies in (6)7th octant */
02083             if((ml->bb->vec[0][0] >= x) && (ml->bb->vec[0][1] >= y)){
02084                 fill_metaball_octal_node(node, ml, 6);
02085             }
02086         }
02087         ml_p= ml_p->next;
02088     }
02089 
02090     /* free references of MetaElems for curent node (it is not needed anymore) */
02091     BLI_freelistN(&node->elems);
02092 
02093     depth--;
02094     
02095     if(depth>0){
02096         for(a=0;a<8;a++){
02097             if(node->nodes[a]->count > 0) /* if node is not empty, then it is subdivided */
02098                 subdivide_metaball_octal_node(node->nodes[a], size_x, size_y, size_z, depth);
02099         }
02100     }
02101 }
02102 
02103 /* free all octal nodes recursively */
02104 void free_metaball_octal_node(octal_node *node)
02105 {
02106     int a;
02107     for(a=0;a<8;a++){
02108         if(node->nodes[a]!=NULL) free_metaball_octal_node(node->nodes[a]);
02109     }
02110     BLI_freelistN(&node->elems);
02111     MEM_freeN(node);
02112 }
02113 
02114 /* If scene include more then one MetaElem, then octree is used */
02115 void init_metaball_octal_tree(int depth)
02116 {
02117     struct octal_node *node;
02118     ml_pointer *ml_p;
02119     float size[3];
02120     int a;
02121     
02122     metaball_tree= MEM_mallocN(sizeof(octal_tree), "metaball_octal_tree");
02123     metaball_tree->first= node= MEM_mallocN(sizeof(octal_node), "metaball_octal_node");
02124     /* maximal depth of octree */
02125     metaball_tree->depth= depth;
02126 
02127     metaball_tree->neg= node->neg=0;
02128     metaball_tree->pos= node->pos=0;
02129     
02130     node->elems.first= NULL;
02131     node->elems.last= NULL;
02132     node->count=0;
02133 
02134     for(a=0;a<8;a++)
02135         node->nodes[a]=NULL;
02136 
02137     node->x_min= node->y_min= node->z_min= FLT_MAX;
02138     node->x_max= node->y_max= node->z_max= -FLT_MAX;
02139 
02140     /* size of octal tree scene */
02141     for(a=0;a<totelem;a++) {
02142         if(mainb[a]->bb->vec[0][0] < node->x_min) node->x_min= mainb[a]->bb->vec[0][0];
02143         if(mainb[a]->bb->vec[0][1] < node->y_min) node->y_min= mainb[a]->bb->vec[0][1];
02144         if(mainb[a]->bb->vec[0][2] < node->z_min) node->z_min= mainb[a]->bb->vec[0][2];
02145         
02146         if(mainb[a]->bb->vec[6][0] > node->x_max) node->x_max= mainb[a]->bb->vec[6][0];
02147         if(mainb[a]->bb->vec[6][1] > node->y_max) node->y_max= mainb[a]->bb->vec[6][1];
02148         if(mainb[a]->bb->vec[6][2] > node->z_max) node->z_max= mainb[a]->bb->vec[6][2];
02149 
02150         ml_p= MEM_mallocN(sizeof(ml_pointer), "ml_pointer");
02151         ml_p->ml= mainb[a];
02152         BLI_addtail(&node->elems, ml_p);
02153 
02154         if(mainb[a]->flag & MB_NEGATIVE) {
02155             /* number of negative MetaElem in scene */
02156             metaball_tree->neg++;
02157         }
02158         else{
02159             /* number of positive MetaElem in scene */
02160             metaball_tree->pos++;
02161         }
02162     }
02163 
02164     /* size of first node */    
02165     size[0]= node->x_max - node->x_min;
02166     size[1]= node->y_max - node->y_min;
02167     size[2]= node->z_max - node->z_min;
02168 
02169     /* first node is subdivided recursively */
02170     subdivide_metaball_octal_node(node, size[0], size[1], size[2], metaball_tree->depth);
02171 }
02172 
02173 void metaball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
02174 {
02175     PROCESS mbproc;
02176     MetaBall *mb;
02177     DispList *dl;
02178     int a, nr_cubes;
02179     float *ve, *no, totsize, width;
02180 
02181     mb= ob->data;
02182 
02183     if(totelem==0) return;
02184     if(!(G.rendering) && (mb->flag==MB_UPDATE_NEVER)) return;
02185     if(G.moving && mb->flag==MB_UPDATE_FAST) return;
02186 
02187     curindex= totindex= 0;
02188     indices= NULL;
02189     thresh= mb->thresh;
02190 
02191     /* total number of MetaElems (totelem) is precomputed in find_basis_mball() function */
02192     mainb= MEM_mallocN(sizeof(void *)*totelem, "mainb");
02193     
02194     /* initialize all mainb (MetaElems) */
02195     totsize= init_meta(scene, ob);
02196 
02197     if(metaball_tree){
02198         free_metaball_octal_node(metaball_tree->first);
02199         MEM_freeN(metaball_tree);
02200         metaball_tree= NULL;
02201     }
02202 
02203     /* if scene includes more then one MetaElem, then octal tree optimalisation is used */  
02204     if((totelem > 1) && (totelem <= 64)) init_metaball_octal_tree(1);
02205     if((totelem > 64) && (totelem <= 128)) init_metaball_octal_tree(2);
02206     if((totelem > 128) && (totelem <= 512)) init_metaball_octal_tree(3);
02207     if((totelem > 512) && (totelem <= 1024)) init_metaball_octal_tree(4);
02208     if(totelem > 1024) init_metaball_octal_tree(5);
02209 
02210     /* don't polygonize metaballs with too high resolution (base mball to small)
02211      * note: Eps was 0.0001f but this was giving problems for blood animation for durian, using 0.00001f */
02212     if(metaball_tree) {
02213         if( ob->size[0] <= 0.00001f * (metaball_tree->first->x_max - metaball_tree->first->x_min) ||
02214             ob->size[1] <= 0.00001f * (metaball_tree->first->y_max - metaball_tree->first->y_min) ||
02215             ob->size[2] <= 0.00001f * (metaball_tree->first->z_max - metaball_tree->first->z_min))
02216         {
02217             new_pgn_element(-1); /* free values created by init_meta */
02218 
02219             MEM_freeN(mainb);
02220 
02221             /* free tree */
02222             free_metaball_octal_node(metaball_tree->first);
02223             MEM_freeN(metaball_tree);
02224             metaball_tree= NULL;
02225 
02226             return;
02227         }
02228     }
02229 
02230     /* width is size per polygonize cube */
02231     if(G.rendering) width= mb->rendersize;
02232     else {
02233         width= mb->wiresize;
02234         if(G.moving && mb->flag==MB_UPDATE_HALFRES) width*= 2;
02235     }
02236     /* nr_cubes is just for safety, minimum is totsize */
02237     nr_cubes= (int)(0.5f+totsize/width);
02238 
02239     /* init process */
02240     mbproc.function = metaball;
02241     mbproc.size = width;
02242     mbproc.bounds = nr_cubes;
02243     mbproc.cubes= NULL;
02244     mbproc.delta = width/(float)(RES*RES);
02245 
02246     polygonize(&mbproc, mb);
02247     
02248     MEM_freeN(mainb);
02249 
02250     /* free octal tree */
02251     if(totelem > 1){
02252         free_metaball_octal_node(metaball_tree->first);
02253         MEM_freeN(metaball_tree);
02254         metaball_tree= NULL;
02255     }
02256 
02257     if(curindex) {
02258         dl= MEM_callocN(sizeof(DispList), "mbaldisp");
02259         BLI_addtail(dispbase, dl);
02260         dl->type= DL_INDEX4;
02261         dl->nr= mbproc.vertices.count;
02262         dl->parts= curindex;
02263 
02264         dl->index= indices;
02265         indices= NULL;
02266         
02267         a= mbproc.vertices.count;
02268         dl->verts= ve= MEM_mallocN(sizeof(float)*3*a, "mballverts");
02269         dl->nors= no= MEM_mallocN(sizeof(float)*3*a, "mballnors");
02270 
02271         for(a=0; a<mbproc.vertices.count; a++, no+=3, ve+=3) {
02272             ve[0]= mbproc.vertices.ptr[a].position.x;
02273             ve[1]= mbproc.vertices.ptr[a].position.y;
02274             ve[2]= mbproc.vertices.ptr[a].position.z;
02275 
02276             no[0]= mbproc.vertices.ptr[a].normal.x;
02277             no[1]= mbproc.vertices.ptr[a].normal.y;
02278             no[2]= mbproc.vertices.ptr[a].normal.z;
02279         }
02280     }
02281 
02282     freepolygonize(&mbproc);
02283 }
02284