doxygen: blender/editors tagged.
[blender.git] / source / blender / editors / gpencil / gpencil_paint.c
index baa6f7d6a25907d94a4615bc7125a9d527c03976..472750113b91d27db3bafd40535e55b3250d6732 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/editors/gpencil/gpencil_paint.c
+ *  \ingroup edgpencil
+ */
+
+
 #include <stdio.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -379,10 +384,18 @@ static short gp_stroke_addpoint (tGPsdata *p, int mval[2], float pressure)
        return GP_STROKEADD_INVALID;
 }
 
+
+/* temp struct for gp_stroke_smooth() */
+typedef struct tGpSmoothCo {
+       short x;
+       short y;
+} tGpSmoothCo;
+
 /* smooth a stroke (in buffer) before storing it */
 static void gp_stroke_smooth (tGPsdata *p)
 {
        bGPdata *gpd= p->gpd;
+       tGpSmoothCo *smoothArray, *spc;
        int i=0, cmx=gpd->sbuffer_size;
        
        /* only smooth if smoothing is enabled, and we're not doing a straight line */
@@ -393,17 +406,31 @@ static void gp_stroke_smooth (tGPsdata *p)
        if ((cmx <= 2) || (gpd->sbuffer == NULL))
                return;
        
-       /* apply weighting-average (note doing this along path sequentially does introduce slight error) */
-       for (i=0; i < gpd->sbuffer_size; i++) {
+       /* create a temporary smoothing coordinates buffer, use to store calculated values to prevent sequential error */
+       smoothArray = MEM_callocN(sizeof(tGpSmoothCo)*cmx, "gp_stroke_smooth smoothArray");
+       
+       /* first pass: calculate smoothing coordinates using weighted-averages */
+       for (i=0, spc=smoothArray; i < gpd->sbuffer_size; i++, spc++) {
+               const tGPspoint *pc= (((tGPspoint *)gpd->sbuffer) + i);
+               const tGPspoint *pb= (i-1 > 0)?(pc-1):(pc);
+               const tGPspoint *pa= (i-2 > 0)?(pc-2):(pb);
+               const tGPspoint *pd= (i+1 < cmx)?(pc+1):(pc);
+               const tGPspoint *pe= (i+2 < cmx)?(pc+2):(pd);
+               
+               spc->x= (short)(0.1*pa->x + 0.2*pb->x + 0.4*pc->x + 0.2*pd->x + 0.1*pe->x);
+               spc->y= (short)(0.1*pa->y + 0.2*pb->y + 0.4*pc->y + 0.2*pd->y + 0.1*pe->y);
+       }
+       
+       /* second pass: apply smoothed coordinates */
+       for (i=0, spc=smoothArray; i < gpd->sbuffer_size; i++, spc++) {
                tGPspoint *pc= (((tGPspoint *)gpd->sbuffer) + i);
-               tGPspoint *pb= (i-1 > 0)?(pc-1):(pc);
-               tGPspoint *pa= (i-2 > 0)?(pc-2):(pb);
-               tGPspoint *pd= (i+1 < cmx)?(pc+1):(pc);
-               tGPspoint *pe= (i+2 < cmx)?(pc+2):(pd);
                
-               pc->x= (short)(0.1*pa->x + 0.2*pb->x + 0.4*pc->x + 0.2*pd->x + 0.1*pe->x);
-               pc->y= (short)(0.1*pa->y + 0.2*pb->y + 0.4*pc->y + 0.2*pd->y + 0.1*pe->y);
+               pc->x = spc->x;
+               pc->y = spc->y;
        }
+       
+       /* free temp array */
+       MEM_freeN(smoothArray);
 }
 
 /* simplify a stroke (in buffer) before storing it 
@@ -547,18 +574,25 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
                
                /* get an array of depths, far depths are blended */
                if (gpencil_project_check(p)) {
-                       short mval[2];
+                       short mval[2], mval_prev[2]= {0};
                        int interp_depth = 0;
                        int found_depth = 0;
                        
                        depth_arr= MEM_mallocN(sizeof(float) * gpd->sbuffer_size, "depth_points");
-                       
+
                        for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size; i++, ptc++, pt++) {
                                mval[0]= ptc->x; mval[1]= ptc->y;
-                               if (view_autodist_depth(p->ar, mval, depth_margin, depth_arr+i) == 0)
+
+                               if ((view_autodist_depth(p->ar, mval, depth_margin, depth_arr+i) == 0) &&
+                                       (i && (view_autodist_depth_segment(p->ar, mval, mval_prev, depth_margin + 1, depth_arr+i) == 0))
+                               ) {
                                        interp_depth= TRUE;
-                               else
+                               }
+                               else {
                                        found_depth= TRUE;
+                               }
+
+                               VECCOPY2D(mval_prev, mval);
                        }
                        
                        if (found_depth == FALSE) {