svn merge -r36651:36672 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / blender / blenlib / intern / scanfill.c
index 47a07d86e6660bd2cbc9c00fa24c2207d5a74ec6..c5a5cdeb5b087c6a25c03ff26d99956589a81669 100644 (file)
  *  \ingroup bli
  */
 
  *  \ingroup bli
  */
 
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include "MEM_guardedalloc.h"
 
 
 #include "MEM_guardedalloc.h"
 
@@ -40,6 +44,8 @@
 #include "BLI_listbase.h"
 #include "BLI_math.h"
 #include "BLI_scanfill.h"
 #include "BLI_listbase.h"
 #include "BLI_math.h"
 #include "BLI_scanfill.h"
+#include "BLI_utildefines.h"
+#include "BLI_threads.h"
 
 /* callbacks for errors and interrupts and some goo */
 static void (*BLI_localErrorCallBack)(const char*) = NULL;
 
 /* callbacks for errors and interrupts and some goo */
 static void (*BLI_localErrorCallBack)(const char*) = NULL;
@@ -144,7 +150,7 @@ static void *new_mem_element(int size)
 {
        int blocksize= 16384;
        static int offs= 0;             /* the current free address */
 {
        int blocksize= 16384;
        static int offs= 0;             /* the current free address */
-       static struct mem_elements *cur= 0;
+       static struct mem_elements *cur= 0, *first;
        static ListBase lb= {0, 0};
        void *adr;
        
        static ListBase lb= {0, 0};
        void *adr;
        
@@ -152,6 +158,10 @@ static void *new_mem_element(int size)
                printf("incorrect use of new_mem_element\n");
        }
        else if(size== -1) {
                printf("incorrect use of new_mem_element\n");
        }
        else if(size== -1) {
+               /*BMESH_TODO: keep the first block, gives memory leak on exit with 'newmem' */
+               first = lb.first;
+               BLI_remlink(&lb, first);
+
                cur= lb.first;
                while(cur) {
                        MEM_freeN(cur->data);
                cur= lb.first;
                while(cur) {
                        MEM_freeN(cur->data);
@@ -159,6 +169,12 @@ static void *new_mem_element(int size)
                }
                BLI_freelistN(&lb);
                
                }
                BLI_freelistN(&lb);
                
+               /*reset the block we're keeping*/
+               BLI_addtail(&lb, first);
+               memset(first->data, 0, blocksize);
+               cur= first;
+               offs= 0;
+
                return NULL;    
        }
        
                return NULL;    
        }
        
@@ -187,6 +203,8 @@ void BLI_end_edgefill(void)
        fillvertbase.first= fillvertbase.last= 0;
        filledgebase.first= filledgebase.last= 0;
        fillfacebase.first= fillfacebase.last= 0;
        fillvertbase.first= fillvertbase.last= 0;
        filledgebase.first= filledgebase.last= 0;
        fillfacebase.first= fillfacebase.last= 0;
+       
+       BLI_unlock_thread(LOCK_SCANFILL);       
 }
 
 /* ****  FILL ROUTINES *************************** */
 }
 
 /* ****  FILL ROUTINES *************************** */
@@ -500,7 +518,7 @@ static int scanfill(PolyFill *pf, short mat_nr)
        EditVert *eve,*v1,*v2,*v3;
        EditEdge *eed,*nexted,*ed1,*ed2,*ed3;
        float miny = 0.0;
        EditVert *eve,*v1,*v2,*v3;
        EditEdge *eed,*nexted,*ed1,*ed2,*ed3;
        float miny = 0.0;
-       int a,b,verts, maxface, totface;        
+       int a,b,verts, maxface, totface;
        short nr, test, twoconnected=0;
 
        nr= pf->nr;
        short nr, test, twoconnected=0;
 
        nr= pf->nr;
@@ -752,6 +770,12 @@ static int scanfill(PolyFill *pf, short mat_nr)
 }
 
 
 }
 
 
+int BLI_begin_edgefill(void)
+{
+       BLI_lock_thread(LOCK_SCANFILL);
+
+       return 1;
+}
 
 int BLI_edgefill(short mat_nr)
 {
 
 int BLI_edgefill(short mat_nr)
 {
@@ -767,17 +791,48 @@ int BLI_edgefill(short mat_nr)
        EditVert *eve;
        EditEdge *eed,*nexted;
        PolyFill *pflist,*pf;
        EditVert *eve;
        EditEdge *eed,*nexted;
        PolyFill *pflist,*pf;
-       float *minp, *maxp, *v1, *v2, norm[3], len;
+       float limit, *minp, *maxp, *v1, *v2, norm[3], len;
        short a,c,poly=0,ok=0,toggle=0;
        int totfaces= 0; /* total faces added */
 
        /* reset variables */
        eve= fillvertbase.first;
        short a,c,poly=0,ok=0,toggle=0;
        int totfaces= 0; /* total faces added */
 
        /* reset variables */
        eve= fillvertbase.first;
+       a = 0;
        while(eve) {
                eve->f= 0;
                eve->xs= 0;
                eve->h= 0;
                eve= eve->next;
        while(eve) {
                eve->f= 0;
                eve->xs= 0;
                eve->h= 0;
                eve= eve->next;
+               a += 1;
+       }
+
+       if (a == 3 && (mat_nr & 2)) {
+               eve = fillvertbase.first;
+
+               addfillface(eve, eve->next, eve->next->next, 0);
+               return 1;
+       } else if (a == 4 && (mat_nr & 2)) {
+               float vec1[3], vec2[3];
+
+               eve = fillvertbase.first;
+               
+               if (1 && eve->next && eve->next->next && eve->next->next->next) { //BMESH_TODO) {
+                       /*use shortest diagonal for quad*/
+                       sub_v3_v3v3(vec1, eve->co, eve->next->next->co);
+                       sub_v3_v3v3(vec2, eve->next->co, eve->next->next->next->co);
+                       
+                       if (INPR(vec1, vec1) < INPR(vec2, vec2)) {
+                               addfillface(eve, eve->next, eve->next->next, 0);
+                               addfillface(eve->next->next, eve->next->next->next, eve, 0);
+                       } else{
+                               addfillface(eve->next, eve->next->next, eve->next->next->next, 0);
+                               addfillface(eve->next->next->next, eve, eve->next, 0);
+                       }
+               } else {
+                               addfillface(eve, eve->next, eve->next->next, 0);
+                               addfillface(eve->next->next, eve->next->next->next, eve, 0);
+               }
+               return 2;
        }
 
        /* first test vertices if they are in edges */
        }
 
        /* first test vertices if they are in edges */
@@ -812,9 +867,17 @@ int BLI_edgefill(short mat_nr)
        v1= eve->co;
        v2= 0;
        eve= fillvertbase.first;
        v1= eve->co;
        v2= 0;
        eve= fillvertbase.first;
+       limit = a < 5 ? FLT_EPSILON*200 : M_PI/24.0;
        while(eve) {
                if(v2) {
                        if( compare_v3v3(v2, eve->co, COMPLIMIT)==0) {
        while(eve) {
                if(v2) {
                        if( compare_v3v3(v2, eve->co, COMPLIMIT)==0) {
+                               float inner = angle_v3v3v3(v1, v2, eve->co);
+                               
+                               if (fabs(inner-M_PI) < limit || fabs(inner) < limit) {
+                                       eve = eve->next;        
+                                       continue;
+                               }
+
                                len= normal_tri_v3( norm,v1, v2, eve->co);
                                if(len != 0.0) break;
                        }
                                len= normal_tri_v3( norm,v1, v2, eve->co);
                                if(len != 0.0) break;
                        }