Revision: 17243
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17243
Author:   campbellbarton
Date:     2008-10-31 11:30:30 +0100 (Fri, 31 Oct 2008)

Log Message:
-----------
paint onto the final derived mesh rather then the original mesh data, so 
painting onto a modified mesh (subsurf, mirror etc) works as expected.

Modified Paths:
--------------
    branches/projection-paint/source/blender/src/imagepaint.c

Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c   2008-10-31 
08:43:36 UTC (rev 17242)
+++ branches/projection-paint/source/blender/src/imagepaint.c   2008-10-31 
10:30:30 UTC (rev 17243)
@@ -72,6 +72,7 @@
 #include "BKE_mesh.h"
 #include "BKE_node.h"
 #include "BKE_utildefines.h"
+#include "BKE_DerivedMesh.h"
 
 #include "BIF_interface.h"
 #include "BIF_mywindow.h"
@@ -153,6 +154,16 @@
 #define PROJ_BUCKET_TOP                3
 
 typedef struct ProjectPaintState {
+       
+       DerivedMesh    *dm;
+       int                     dm_totface;
+       int                     dm_totvert;
+       
+       MVert              *dm_mvert;
+       MFace              *dm_mface;
+       MTFace             *dm_mtface;
+       
+       
        /* projection painting only */
        MemArena *projectArena;         /* use for alocating many pixel structs 
and link-lists */
        LinkNode **projectBuckets;      /* screen sized 2D array, each pixel 
has a linked list of ImagePaintProjectPixel's */
@@ -185,8 +196,10 @@
        float viewMin2D[2];                     /* 2D bounds for mesh verts on 
the screen's plane (screenspace) */
        float viewMax2D[2]; 
        float viewWidth;                        /* Calculated from viewMin2D & 
viewMax2D */
-       float viewHeight;                       
+       float viewHeight;
        
+       
+       
 } ProjectPaintState;
 
 typedef struct ImagePaintProjectPixel {
@@ -386,7 +399,7 @@
                (       (       (int)(( (projCo2D[1] - ps->viewMin2D[1])  / 
ps->viewHeight) * ps->bucketsY)) * ps->bucketsX );
 }
 
-static void project_paint_face_init(ImagePaintState *s, ProjectPaintState *ps, 
MFace *mf, MTFace *tf, ImBuf *ibuf)
+static void project_paint_face_init(ProjectPaintState *ps, MFace *mf, MTFace 
*tf, ImBuf *ibuf)
 {
        /* Projection vars, to get the 3D locations into screen space  */
        ImagePaintProjectPixel *projPixel;
@@ -437,11 +450,11 @@
        if (xmini == xmaxi || ymini == ymaxi)
                return;
 
-       v1co = s->me->mvert[mf->v1].co;
-       v2co = s->me->mvert[mf->v2].co;
-       v3co = s->me->mvert[mf->v3].co;
+       v1co = ps->dm_mvert[mf->v1].co;
+       v2co = ps->dm_mvert[mf->v2].co;
+       v3co = ps->dm_mvert[mf->v3].co;
        if (mf->v4)
-               v4co = s->me->mvert[mf->v4].co;
+               v4co = ps->dm_mvert[mf->v4].co;
        
        for (y = ymini; y < ymaxi; y++) {
                uv[1] = (((float)y)+0.5) / (float)ibuf->y;
@@ -563,7 +576,7 @@
 }
 
 #ifdef PROJ_LAZY_INIT
-static void project_paint_bucket_init(ImagePaintState *s, ProjectPaintState 
*ps, int bucket_index)
+static void project_paint_bucket_init(ProjectPaintState *ps, int bucket_index)
 {
        
        LinkNode *node;
@@ -583,10 +596,10 @@
                                
                                ps->projectFaceFlags[face_index] |= 
PROJ_FACE_INIT;
                                
-                               tf = s->me->mtface+face_index;
+                               tf = ps->dm_mtface+face_index;
                                ibuf = BKE_image_get_ibuf((Image *)tf->tpage, 
NULL); /* TODO - this may be slow */
                                
-                               project_paint_face_init(s, ps, s->me->mface + 
face_index, tf, ibuf);
+                               project_paint_face_init(ps, ps->dm_mface + 
face_index, tf, ibuf);
                        }
                        node = node->next;
                } while (node);
@@ -661,7 +674,7 @@
        return 0;
 }
 
-static void project_paint_begin_face_delayed_init(ImagePaintState *s, 
ProjectPaintState *ps, MFace *mf, MTFace *tf, int face_index)
+static void project_paint_begin_face_delayed_init(ProjectPaintState *ps, MFace 
*mf, MTFace *tf, int face_index)
 {
        float min[2], max[2];
        int bucket_min[2], bucket_max[2]; /* for  ps->projectBuckets indexing */
@@ -726,6 +739,17 @@
 
        /* ---- end defines ---- */
        
+       /* paint onto the derived mesh
+        * note get_viewedit_datamask checks for paint mode and will always 
give UVs */
+       ps->dm = mesh_get_derived_final(s->ob, get_viewedit_datamask());
+       
+       ps->dm_mvert = ps->dm->getVertArray( ps->dm );
+       ps->dm_mface = ps->dm->getFaceArray( ps->dm );
+       ps->dm_mtface= ps->dm->getFaceDataArray( ps->dm, CD_MTFACE );
+       
+       ps->dm_totvert = ps->dm->getNumVerts( ps->dm );
+       ps->dm_totface = ps->dm->getNumFaces( ps->dm );
+       
        printf("\n\nstarting\n");
        
        ps->bucketsX = PROJ_BUCKET_DIV;
@@ -748,7 +772,7 @@
        tot_bucketMem =         sizeof(LinkNode *) * ps->bucketsX * 
ps->bucketsY;
 #ifdef PROJ_LAZY_INIT
        tot_faceListMem =       sizeof(LinkNode *) * ps->bucketsX * 
ps->bucketsY;
-       tot_faceFlagMem =       sizeof(char) * s->me->totface;
+       tot_faceFlagMem =       sizeof(char) * ps->dm_totface;
        tot_bucketFlagMem =     sizeof(char) * ps->bucketsX * ps->bucketsY;
        
 #endif
@@ -770,7 +794,7 @@
 #endif
        
        /* view raytrace stuff */
-       mvert_static = s->me->mvert;
+       mvert_static = ps->dm_mvert;
        
        memset(&ps->isec, 0, sizeof(ps->isec)); /* Initialize ray intersection 
*/
        ps->isec.mode= RE_RAY_SHADOW;
@@ -809,14 +833,14 @@
        printmatrix4( "s->ob->imat",  s->ob->imat);
        
        /* calculate vert screen coords */
-       ps->projectVertCos2D = BLI_memarena_alloc( ps->projectArena, 
sizeof(float) * s->me->totvert * 2);
+       ps->projectVertCos2D = BLI_memarena_alloc( ps->projectArena, 
sizeof(float) * ps->dm_totvert * 2);
        projCo2D = ps->projectVertCos2D;
        
        INIT_MINMAX(min, max);
        INIT_MINMAX2(ps->viewMin2D, ps->viewMax2D);
        
-       for(a=0; a<s->me->totvert; a++, projCo2D++) {
-               VECCOPY(projCo, s->me->mvert[a].co);            
+       for(a=0; a < ps->dm_totvert; a++, projCo2D++) {
+               VECCOPY(projCo, ps->dm_mvert[a].co);            
                
                /* ray-tree needs worldspace min/max, do here and save another 
loop */
                if (ps->projectOcclude) {
@@ -844,8 +868,8 @@
        if (ps->projectOcclude) {
                
                if (G.f & G_FACESELECT) {
-                       mf = s->me->mface;
-                       a = s->me->totface - 1;
+                       mf = ps->dm_mface;
+                       a = ps->dm_totface - 1;
                        do {
                                if (!(mf->flag & ME_HIDE)) {
                                        i++;
@@ -859,8 +883,8 @@
                                        project_paint_begin_check_func,
                                        NULL, NULL);
                        
-                       mf = s->me->mface;
-                       a = s->me->totface - 1;
+                       mf = ps->dm_mface;
+                       a = ps->dm_totface - 1;
                        
                        do {
                                if (!(mf->flag & ME_HIDE)) {
@@ -870,13 +894,13 @@
                        
                } else { 
                        ps->projectRayTree =    RE_ray_tree_create(
-                                       64, s->me->totface, min, max,
+                                       64, ps->dm_totface, min, max,
                                        project_paint_begin_coords_func,
                                        project_paint_begin_check_func,
                                        NULL, NULL);
                        
-                       mf = s->me->mface;
-                       a = s->me->totface - 1;
+                       mf = ps->dm_mface;
+                       a = ps->dm_totface - 1;
                        do {
                                RE_ray_tree_add_face(ps->projectRayTree, 0, mf);
                                mf++;
@@ -887,13 +911,13 @@
        }
        
        
-       for( a = 0, tf = s->me->mtface, mf = s->me->mface; a < s->me->totface; 
mf++, tf++, a++ ) {
+       for( a = 0, tf = ps->dm_mtface, mf = ps->dm_mface; a < ps->dm_totface; 
mf++, tf++, a++ ) {
                if (tf->tpage && ((G.f & G_FACESELECT)==0 || mf->flag & 
ME_FACE_SEL)) {
                        
                        if (ps->projectBackfaceCull) {
                                /* TODO - we dont really need the normal, just 
the direction, save a sqrt? */
-                               if (mf->v4)     
CalcNormFloat4(s->me->mvert[mf->v1].co, s->me->mvert[mf->v2].co, 
s->me->mvert[mf->v3].co, s->me->mvert[mf->v4].co, f_no);
-                               else            
CalcNormFloat(s->me->mvert[mf->v1].co, s->me->mvert[mf->v2].co, 
s->me->mvert[mf->v3].co, f_no);
+                               if (mf->v4)     
CalcNormFloat4(ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, 
ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, f_no);
+                               else            
CalcNormFloat(ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, 
ps->dm_mvert[mf->v3].co, f_no);
                                
                                if (Inpf(f_no, ps->viewDir) < 0) {
                                        continue;
@@ -924,9 +948,9 @@
                                /* Initialize the faces screen pixels */
 #ifdef PROJ_LAZY_INIT
                                /* Add this to a list to initialize later */
-                               project_paint_begin_face_delayed_init(s, ps, 
mf, tf, a);
+                               project_paint_begin_face_delayed_init(ps, mf, 
tf, a);
 #else
-                               project_paint_face_init(s, ps, mf, tf, ibuf);
+                               project_paint_face_init(ps, mf, tf, ibuf);
 #endif
                        }
                }
@@ -950,6 +974,8 @@
        BLI_memarena_free(ps->projectArena);
        if (ps->projectOcclude)
                RE_ray_tree_free(ps->projectRayTree);
+       
+       ps->dm->release(ps->dm);
 }
 
 
@@ -1515,7 +1541,7 @@
        #ifdef PROJ_LAZY_INIT
                                if (ps->projectBucketFlags[bucket_index] == 
PROJ_BUCKET_NULL) {
                                        /* This bucket may hold some 
uninitialized faces, initialize it */
-                                       project_paint_bucket_init(s, ps, 
bucket_index);
+                                       project_paint_bucket_init(ps, 
bucket_index);
                                }
        #endif
 


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to