resolve some compiler warnings with intel c/c++ compiler
[blender.git] / source / blender / blenkernel / intern / BME_eulers.c
index b83ca48db5f8bab644062e6838735260568fdc5c..801e0b8bdec9ff97cdf3115eb4228f890e9fdf05 100644 (file)
@@ -5,14 +5,12 @@
  *
  * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
  *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL 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
+ * of the License, or (at your option) any later version.
  * about this. 
  *
  * This program is distributed in the hope that it will be useful,
@@ -31,7 +29,7 @@
  *
  * Contributor(s): Geoffrey Bantle.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
 #include "MEM_guardedalloc.h"
@@ -41,6 +39,7 @@
 #include "DNA_mesh_types.h"
 
 #include "BKE_utildefines.h"
+#include "BKE_customdata.h"
 #include "BKE_bmesh.h"
 
 #include "BLI_blenlib.h"
@@ -132,7 +131,7 @@ BME_Edge *BME_ME(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2){
        int valance1=0, valance2=0, edok;
        
        /*edge must be between two distinct vertices...*/
-       if(v1 == v2) return BME_exit("ME returned NULL");
+       if(v1 == v2) return NULL;
        
        #ifndef BME_FASTEULER
        /*count valance of v1*/
@@ -199,10 +198,10 @@ BME_Poly *BME_MF(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge **elist, int
        BME_Vert *curvert, *tv, **vlist;
        int i, j, done, cont, edok;
        
-       if(len < 2) return BME_exit("MF returned NULL");
+       if(len < 2) return NULL;
        
        /*make sure that v1 and v2 are in elist[0]*/
-       if(BME_verts_in_edge(v1,v2,elist[0]) == 0) return BME_exit("MF returned NULL");
+       if(BME_verts_in_edge(v1,v2,elist[0]) == 0) return NULL;
        
        /*clear euler flags*/
        for(i=0;i<len;i++) elist[i]->eflag1=elist[i]->eflag2 = 0;
@@ -220,9 +219,9 @@ BME_Poly *BME_MF(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge **elist, int
        */
        for(i=0; i<len; i++){
                edok = BME_disk_count_edgeflag(elist[i]->v1, MF_CANDIDATE, 0);
-               if(edok != 2) return BME_exit("MF returned NULL");
+               if(edok != 2) return NULL;
                edok = BME_disk_count_edgeflag(elist[i]->v2, MF_CANDIDATE, 0);
-               if(edok != 2) return BME_exit("MF returned NULL");
+               if(edok != 2) return NULL;
        }
        
        /*set start edge, start vert and target vert for our loop traversal*/
@@ -230,9 +229,14 @@ BME_Poly *BME_MF(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge **elist, int
        tv = v1;
        curvert = v2;
        
+       if(bm->vtarlen < len){
+               MEM_freeN(bm->vtar);
+               bm->vtar = MEM_callocN(sizeof(BME_Vert *)* len, "BMesh Vert pointer array");
+               bm->vtarlen = len;
+       }
        /*insert tv into vlist since its the first vertex in face*/
        i=0;
-       vlist=MEM_callocN(sizeof(BME_Vert*)*len,"BME_MF vlist array");
+       vlist=bm->vtar;
        vlist[i] = tv;
 
        /*      Basic procedure: Starting with curv we find the edge in it's disk cycle which hasn't 
@@ -311,8 +315,6 @@ BME_Poly *BME_MF(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge **elist, int
                        if(edok != (l->e->eflag2 + 1)) BME_error();
                }
        }
-       
-       MEM_freeN(vlist);
        return f;
 }
 
@@ -430,7 +432,7 @@ BME_Vert *BME_SEMV(BME_Mesh *bm, BME_Vert *tv, BME_Edge *e, BME_Edge **re){
        BME_Edge *ne;
        int i, edok, valance1=0, valance2=0;
        
-       if(BME_vert_in_edge(e,tv) == 0) return BME_exit("SEMV returned NULL");
+       if(BME_vert_in_edge(e,tv) == 0) return NULL;
        ov = BME_edge_getothervert(e,tv);
        //v2 = tv;
 
@@ -601,7 +603,6 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
        BME_Edge *e;
        int i, len, f1len, f2len;
        
-       if(f->holes.first) return BME_exit("SFME returned NULL"); //not good, fix me
        
        /*verify that v1 and v2 are in face.*/
        len = BME_cycle_length(f->loopbase);
@@ -610,7 +611,7 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
                else if(curloop->v == v2) v2loop = curloop;
        }
        
-       if(!v1loop || !v2loop) return BME_exit("SFME returned NULL");
+       if(!v1loop || !v2loop) return NULL;
        
        /*allocate new edge between v1 and v2*/
        e = BME_addedgelist(bm, v1, v2,NULL);
@@ -618,8 +619,8 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
        BME_disk_append_edge(e, v2);
        
        f2 = BME_addpolylist(bm,f);
-       f1loop = BME_create_loop(bm,v2,e,f,NULL);
-       f2loop = BME_create_loop(bm,v1,e,f2,NULL);
+       f1loop = BME_create_loop(bm,v2,e,f,v2loop);
+       f2loop = BME_create_loop(bm,v1,e,f2,v1loop);
        
        f1loop->prev = v2loop->prev;
        f2loop->prev = v1loop->prev;
@@ -663,16 +664,16 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
  *     Takes a an edge and pointer to one of its vertices and collapses
  *     the edge on that vertex.
  *     
- *     Before:             OE      KE
+ *     Before:    OE      KE
  *                      ------- -------
  *               |     ||      |
- *                             OV     KV      TV
+ *             OV     KV      TV
  *
  *
  *   After:             OE      
  *                      ---------------
  *               |             |
- *                             OV             TV
+ *             OV             TV
  *
  *
  *     Restrictions:
@@ -723,6 +724,8 @@ int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv)
                        /*remove ke from tv's disk cycle*/
                        BME_disk_remove_edge(ke, tv);
                
+                       
+
                        /*deal with radial cycle of ke*/
                        if(ke->loop){
                                /*first step, fix the neighboring loops of all loops in ke's radial cycle*/
@@ -740,18 +743,30 @@ int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv)
                                /*second step, remove all the hanging loops attached to ke*/
                                killoop = ke->loop;
                                radlen = BME_cycle_length(&(ke->loop->radial));
+                               /*make sure we have enough room in bm->lpar*/
+                               if(bm->lparlen < radlen){
+                                       MEM_freeN(bm->lpar);
+                                       bm->lpar = MEM_callocN(sizeof(BME_Loop *)* radlen, "BMesh Loop pointer array");
+                                       bm->lparlen = bm->lparlen * radlen;
+                               }
+                               /*this should be wrapped into a bme_free_radial function to be used by BME_KF as well...*/
                                i=0;
                                while(i<radlen){
-                                       nextl = killoop->radial.next->data;
-                                       BME_free_loop(bm, killoop);
-                                       killoop = nextl;
+                                       bm->lpar[i] = killoop;
+                                       killoop = killoop->radial.next->data;
                                        i++;
-                               }       
+                               }
+                               i=0;
+                               while(i<radlen){
+                                       BME_free_loop(bm,bm->lpar[i]);
+                                       i++;
+                               }
                                /*Validate radial cycle of oe*/
                                edok = BME_cycle_validate(radlen,&(oe->loop->radial));
                                
                        }
                        
+
                        /*Validate disk cycles*/
                        diskbase = BME_disk_getpointer(ov->edge,ov);
                        edok = BME_cycle_validate(valance1, diskbase);
@@ -795,16 +810,22 @@ int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv)
 
 int BME_loop_reverse(BME_Mesh *bm, BME_Poly *f){
        BME_Loop *l = f->loopbase, *curloop, *oldprev, *oldnext;
-       BME_Edge **elist;
        int i, j, edok, len = 0;
 
        len = BME_cycle_length(l);
-       elist = MEM_callocN(sizeof(BME_Edge *)*len, "BME Loop Reverse edge array");
+       if(bm->edarlen < len){
+               MEM_freeN(bm->edar);
+               bm->edar = MEM_callocN(sizeof(BME_Edge *)* len, "BMesh Edge pointer array");
+               bm->edarlen = len;
+       }
        
        for(i=0, curloop = l; i< len; i++, curloop=curloop->next){
-               BME_radial_remove_loop(curloop, curloop->e);
                curloop->e->eflag1 = 0;
-               elist[i] = curloop->e;
+               curloop->e->eflag2 = BME_cycle_length(&curloop->radial);
+               BME_radial_remove_loop(curloop, curloop->e);
+               /*in case of border edges we HAVE to zero out curloop->radial Next/Prev*/
+               curloop->radial.next = curloop->radial.prev = NULL;
+               bm->edar[i] = curloop->e;
        }
        
        /*actually reverse the loop. This belongs in BME_cycle_reverse!*/
@@ -818,28 +839,31 @@ int BME_loop_reverse(BME_Mesh *bm, BME_Poly *f){
 
        if(len == 2){ //two edged face
                //do some verification here!
-               l->e = elist[1];
-               l->next->e = elist[0];
+               l->e = bm->edar[1];
+               l->next->e = bm->edar[0];
        }
        else{
                for(i=0, curloop = l; i < len; i++, curloop = curloop->next){
                        edok = 0;
                        for(j=0; j < len; j++){
-                               edok = BME_verts_in_edge(curloop->v, curloop->next->v, elist[j]);
+                               edok = BME_verts_in_edge(curloop->v, curloop->next->v, bm->edar[j]);
                                if(edok){
-                                       curloop->e = elist[j];
+                                       curloop->e = bm->edar[j];
                                        break;
                                }
                        }
                }
        }
        /*rebuild radial*/
+       for(i=0, curloop = l; i < len; i++, curloop = curloop->next) BME_radial_append(curloop->e, curloop);
+       
+       /*validate radial*/
        for(i=0, curloop = l; i < len; i++, curloop = curloop->next){
-               BME_radial_append(curloop->e, curloop);
-               //radok = BME_cycle_validate(curloop->e->tmp.l, &(curloop->radial));
-               //if(!radok || curloop->e->loop == NULL) BME_error();
+               edok = BME_cycle_validate(curloop->e->eflag2, &(curloop->radial));
+               if(!edok){
+                       BME_error();
+               }
        }
-       MEM_freeN(elist);
        return 1;
 }
 
@@ -881,8 +905,7 @@ BME_Poly *BME_JFKE(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e)
        BME_Loop *curloop, *f1loop=NULL, *f2loop=NULL;
        int loopok = 0, newlen = 0,i, f1len=0, f2len=0, radlen=0, edok;
        
-       if(f1->holes.first || f2->holes.first) return BME_exit("JFKE returned NULL"); //dont operate on faces with holes. Not best solution but tolerable.
-       if(f1 == f2) return BME_exit("JFKE returned NULL"); //can't join a face to itself
+       if(f1 == f2) return NULL; //can't join a face to itself
        /*verify that e is in both f1 and f2*/
        f1len = BME_cycle_length(f1->loopbase);
        f2len = BME_cycle_length(f2->loopbase);
@@ -898,23 +921,23 @@ BME_Poly *BME_JFKE(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e)
                        break;
                }
        }
-       if(!(f1loop && f2loop)) return BME_exit("JFKE returned NULL");
+       if(!(f1loop && f2loop)) return NULL;
        
        /*validate that edge is 2-manifold edge*/
        radlen = BME_cycle_length(&(f1loop->radial));
-       if(radlen != 2) return BME_exit("JFKE returned NULL");
+       if(radlen != 2) return NULL;
 
        /*validate direction of f2's loop cycle is compatible.*/
-       if(f1loop->v == f2loop->v) return BME_exit("JFKE returned NULL");
+       if(f1loop->v == f2loop->v) return NULL;
        
        /*
                Finally validate that for each face, each vertex has another edge in its disk cycle that is 
                not e, and not shared.
        */
-       if(BME_radial_find_face(f1loop->next->e,f2)) return BME_exit("JFKE returned NULL");
-       if(BME_radial_find_face(f1loop->prev->e,f2)) return BME_exit("JFKE returned NULL");
-       if(BME_radial_find_face(f2loop->next->e,f1)) return BME_exit("JFKE returned NULL");
-       if(BME_radial_find_face(f2loop->prev->e,f1)) return BME_exit("JFKE returned NULL");
+       if(BME_radial_find_face(f1loop->next->e,f2)) return NULL;
+       if(BME_radial_find_face(f1loop->prev->e,f2)) return NULL;
+       if(BME_radial_find_face(f2loop->next->e,f1)) return NULL;
+       if(BME_radial_find_face(f2loop->prev->e,f1)) return NULL;
        
        /*join the two loops*/
        f1loop->prev->next = f2loop->next;
@@ -952,56 +975,3 @@ BME_Poly *BME_JFKE(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e)
        BME_free_poly(bm, f2);  
        return f1;
 }
-
-/**
- *                     BME_MEKL
- *
- *     MAKE EDGE KILL LOOP:
- *     
- *     Bridges a perphiary loop of a face with an internal loop
- *
- *     Examples:
- *
- *     ----------------                ----------------
- *     |      f1      |                |      f1      |
- *     |     -----    |                |     -----    |
- *     |     |   |    |                |     |   |    |
- *     X     X   |    |        X-----X   |    |
- *     |     |   |    |                |     |   |    |
- *     |     -----    |                |     -----    |
- *     |                          |            |                          |
- *     ----------------                ----------------
- *
- *
- *  Returns -
- *     A BME_Poly pointer
- */
-
-/**
- *                     BME_KEML
- *
- *     KILL EDGE MAKE LOOP:
- *     
- *     Kills an edge and splits the loose loops off into an internal loop
- *
- *     Examples:
- *
- *     ----------------                ----------------
- *     |      f1      |                |      f1      |
- *     |     -----    |                |     -----    |
- *     |     |   |    |                |     |   |    |
- *     X ----X   |    |        X     X   |    |
- *     |     |   |    |                |     |   |    |
- *     |     -----    |                |     -----    |
- *     |                          |            |                          |
- *     ----------------                ----------------
- *
- *     The tool author should take care to realize that although a face may have 
- *     a hole in its topology, that hole may be filled with one or many other faces.
- *     Regardless, this does not imply a parent child relationship.
- *
- *
- *  Returns -
- *     A BME_Poly pointer
- */
-