Grease Pencil - Curve Conversion Improvements:
authorJoshua Leung <aligorith@gmail.com>
Thu, 28 Aug 2008 10:19:34 +0000 (10:19 +0000)
committerJoshua Leung <aligorith@gmail.com>
Thu, 28 Aug 2008 10:19:34 +0000 (10:19 +0000)
* Changed hotkey from Alt-C to Alt-Shift-C so that it works when the active object cannot be deselected/deactivated.
* Added option to convert to bezier curves. Note that currently, the handles are simply placed to the same location as the point so that there is an exact match with the gpencil strokes. In future, it would be interesting to investigate using proper curve-fitting algos instead.

source/blender/src/editobject.c
source/blender/src/gpencil.c
source/blender/src/space.c

index b1205668faae2badc18a645edeca5b50a4477d5e..1ba7bce6dabfc77114a0c0d82cd9e4869fdc6c5f 100644 (file)
@@ -2828,10 +2828,6 @@ void convertmenu(void)
        if(G.scene->id.lib) return;
 
        obact= OBACT;
-       if(obact==0) {
-               gpencil_convert_menu();
-               return;
-       }
        if(!obact->flag & SELECT) return;
        if(G.obedit) return;
        
index d1599d765b5216e95c9ac47bf4afd3de917655c1..150a5548fcfba7a9f86ff851e55765f4dd195ca8 100644 (file)
@@ -719,14 +719,91 @@ static void gp_strokepoint_convertcoords (bGPDstroke *gps, bGPDspoint *pt, float
        }
 }
 
+/* convert stroke to 3d path */
+static void gp_layer_to_path (bGPDlayer *gpl, bGPDstroke *gps, Curve *cu)
+{
+       bGPDspoint *pt;
+       Nurb *nu;
+       BPoint *bp;
+       int i;
+       
+       /* create new 'nurb' within the curve */
+       nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_path(nurb)");
+       
+       nu->pntsu= gps->totpoints;
+       nu->pntsv= 1;
+       nu->orderu= gps->totpoints;
+       nu->flagu= 2;   /* endpoint */
+       nu->resolu= 32;
+       
+       nu->bp= (BPoint *)MEM_callocN(sizeof(BPoint)*gps->totpoints, "bpoints");
+       
+       /* add points */
+       for (i=0, pt=gps->points, bp=nu->bp; i < gps->totpoints; i++, pt++, bp++) {
+               float p3d[3];
+               
+               /* get coordinates to add at */
+               gp_strokepoint_convertcoords(gps, pt, p3d);
+               VecCopyf(bp->vec, p3d);
+               
+               /* set settings */
+               bp->f1= SELECT;
+               bp->radius = bp->weight = pt->pressure * gpl->thickness;
+       }
+       
+       /* add nurb to curve */
+       BLI_addtail(&cu->nurb, nu);
+}
+
+/* convert stroke to 3d bezier */
+static void gp_layer_to_bezier (bGPDlayer *gpl, bGPDstroke *gps, Curve *cu)
+{
+       bGPDspoint *pt;
+       Nurb *nu;
+       BezTriple *bezt;
+       int i;
+       
+       /* create new 'nurb' within the curve */
+       nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_bezier(nurb)");
+       
+       nu->pntsu= gps->totpoints;
+       nu->resolu= 12;
+       nu->resolv= 12;
+       nu->type= CU_BEZIER;
+       nu->bezt = (BezTriple *)MEM_callocN(gps->totpoints*sizeof(BezTriple), "bezts");
+       
+       /* add points */
+       for (i=0, pt=gps->points, bezt=nu->bezt; i < gps->totpoints; i++, pt++, bezt++) {
+               float p3d[3];
+               
+               /* get coordinates to add at */
+               gp_strokepoint_convertcoords(gps, pt, p3d);
+               
+               /* TODO: maybe in future the handles shouldn't be in same place */
+               VecCopyf(bezt->vec[0], p3d);
+               VecCopyf(bezt->vec[1], p3d);
+               VecCopyf(bezt->vec[2], p3d);
+               
+               /* set settings */
+               bezt->h1= bezt->h2= HD_ALIGN; // fixme...
+               bezt->f1= bezt->f2= bezt->f3= SELECT;
+               bezt->radius = bezt->weight = pt->pressure * gpl->thickness;
+       }
+       
+       /* must calculate handles or else we crash */
+       calchandlesNurb(nu);
+       
+       /* add nurb to curve */
+       BLI_addtail(&cu->nurb, nu);
+}
+
 /* convert a given grease-pencil layer to a 3d-curve representation (using current view if appropriate) */
-static void gp_layer_to_curve (bGPdata *gpd, bGPDlayer *gpl)
+static void gp_layer_to_curve (bGPdata *gpd, bGPDlayer *gpl, short mode)
 {
        bGPDframe *gpf= gpencil_layer_getframe(gpl, CFRA, 0);
        bGPDstroke *gps;
        Object *ob;
        Curve *cu;
-       float *fp= give_cursor();
        char name[140];
        
        /* error checking */
@@ -745,65 +822,46 @@ static void gp_layer_to_curve (bGPdata *gpd, bGPDlayer *gpl)
        /* init the curve object (remove rotation and assign curve data to it) */
        add_object_draw(OB_CURVE);
        ob= OBACT;
+       ob->loc[0]= ob->loc[1]= ob->loc[2]= 0;
        ob->rot[0]= ob->rot[1]= ob->rot[2]= 0;
        ob->data= cu;
        
-       /* initialise 3d-cursor correction globals */
-       initgrabz(fp[0], fp[1], fp[2]);
-       
        /* add points to curve */
        for (gps= gpf->strokes.first; gps; gps= gps->next) {
-               bGPDspoint *pt;
-               Nurb *nu;
-               BPoint *bp;
-               int i;
-               
-               /* create new 'nurb' within the curve */
-               nu = (Nurb *)MEM_callocN(sizeof(Nurb), "gpstroke_to_curve(nurb)");
-               
-               nu->pntsu= gps->totpoints;
-               nu->pntsv= 1;
-               nu->orderu= gps->totpoints;
-               nu->flagu= 2;   /* endpoint */
-               nu->resolu= 32;
-               
-               nu->bp= MEM_callocN(sizeof(BPoint)*gps->totpoints, "bezts");
-               
-               /* add points */
-               for (i=0, pt=gps->points, bp=nu->bp; i < gps->totpoints; i++, pt++, bp++) {
-                       float p3d[3];
-                       
-                       /* get coordinates to add at */
-                       gp_strokepoint_convertcoords(gps, pt, p3d);
-                       VecCopyf(bp->vec, p3d);
-                       
-                       /* set settings */
-                       bp->f1= SELECT;
-                       bp->radius = bp->weight = pt->pressure * gpl->thickness;
+               switch (mode) {
+                       case 1: 
+                               gp_layer_to_path(gpl, gps, cu);
+                               break;
+                       case 2:
+                               gp_layer_to_bezier(gpl, gps, cu);
+                               break;
                }
-               
-               /* add nurb to curve */
-               BLI_addtail(&cu->nurb, nu);
        }
 }
 
 /* convert grease-pencil strokes to another representation 
- *     mode:   1 - Active layer to curve
+ *     mode:   1 - Active layer to path
+ *                     2 - Active layer to bezier
  */
 void gpencil_convert_operation (short mode)
 {
        bGPdata *gpd;   
+       float *fp= give_cursor();
        
        /* get datablock to work on */
        gpd= gpencil_data_getactive(NULL);
        if (gpd == NULL) return;
        
+       /* initialise 3d-cursor correction globals */
+       initgrabz(fp[0], fp[1], fp[2]);
+       
        /* handle selection modes */
        switch (mode) {
-               case 1: /* active layer only */
+               case 1: /* active layer only (to path) */
+               case 2: /* active layer only (to bezier) */
                {
                        bGPDlayer *gpl= gpencil_layer_getactive(gpd);
-                       gp_layer_to_curve(gpd, gpl);
+                       gp_layer_to_curve(gpd, gpl, mode);
                }
                        break;
        }
@@ -823,7 +881,7 @@ void gpencil_convert_menu (void)
        /* only show menu if it will be relevant */
        if (gpd == NULL) return;
        
-       mode= pupmenu("Grease Pencil Convert %t|Active Layer To Curve%x1");
+       mode= pupmenu("Grease Pencil Convert %t|Active Layer To Path%x1|Active Layer to Bezier%x2");
        if (mode <= 0) return;
        
        gpencil_convert_operation(mode);
index 8787cf9efc44e90e357028e0c25027a0772046a5..8ca26ea57ab245c33a06f392e6fe29fe96da56c9 100644 (file)
@@ -1906,6 +1906,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        else
                                                copy_attr_menu();
                                }
+                               else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) 
+                                       gpencil_convert_menu(); /* gpencil.c */
                                else if(G.qual==LR_ALTKEY) {
                                        if(ob && (ob->flag & OB_POSEMODE))
                                                pose_clear_constraints();       /* poseobject.c */