Cleanup: Rename callback flags from library_query to `IDWALK_CB_...`
[blender-staging.git] / source / blender / modifiers / intern / MOD_uvproject.c
index 1b96c586cbf0d91d139333f4b45080c065a1a8f1..78dc1ea8bcb2968b821c2ceee96ade28f7f62cb5 100644 (file)
 #include "DNA_meshdata_types.h"
 #include "DNA_camera_types.h"
 #include "DNA_object_types.h"
-#include "DNA_scene_types.h"
 
 #include "BLI_math.h"
-#include "BLI_string.h"
 #include "BLI_uvproject.h"
 #include "BLI_utildefines.h"
 
 
 #include "BKE_camera.h"
+#include "BKE_library_query.h"
 #include "BKE_mesh.h"
 #include "BKE_DerivedMesh.h"
 
 #include "MOD_modifiertypes.h"
-#include "MOD_util.h"
 
 #include "MEM_guardedalloc.h"
+
 #include "depsgraph_private.h"
+#include "DEG_depsgraph_build.h"
 
 static void initData(ModifierData *md)
 {
-       UVProjectModifierData *umd = (UVProjectModifierData*) md;
-       int i;
+       UVProjectModifierData *umd = (UVProjectModifierData *) md;
 
-       for (i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
-               umd->projectors[i] = NULL;
-       umd->image = NULL;
        umd->flags = 0;
        umd->num_projectors = 1;
        umd->aspectx = umd->aspecty = 1.0f;
@@ -72,20 +68,11 @@ static void initData(ModifierData *md)
 
 static void copyData(ModifierData *md, ModifierData *target)
 {
-       UVProjectModifierData *umd = (UVProjectModifierData*) md;
-       UVProjectModifierData *tumd = (UVProjectModifierData*) target;
-       int i;
-
-       for (i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
-               tumd->projectors[i] = umd->projectors[i];
-       tumd->image = umd->image;
-       tumd->flags = umd->flags;
-       tumd->num_projectors = umd->num_projectors;
-       tumd->aspectx = umd->aspectx;
-       tumd->aspecty = umd->aspecty;
-       tumd->scalex = umd->scalex;
-       tumd->scaley = umd->scaley;
-       BLI_strncpy(tumd->uvlayer_name, umd->uvlayer_name, sizeof(umd->uvlayer_name));
+#if 0
+       UVProjectModifierData *umd = (UVProjectModifierData *) md;
+       UVProjectModifierData *tumd = (UVProjectModifierData *) target;
+#endif
+       modifier_copyData_generic(md, target);
 }
 
 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md))
@@ -93,38 +80,38 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(
        CustomDataMask dataMask = 0;
 
        /* ask for UV coordinates */
-       dataMask |= CD_MASK_MTFACE;
+       dataMask |= CD_MLOOPUV | CD_MTEXPOLY;
 
        return dataMask;
 }
 
 static void foreachObjectLink(ModifierData *md, Object *ob,
-               ObjectWalkFunc walk, void *userData)
+                              ObjectWalkFunc walk, void *userData)
 {
-       UVProjectModifierData *umd = (UVProjectModifierData*) md;
+       UVProjectModifierData *umd = (UVProjectModifierData *) md;
        int i;
 
        for (i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
-               walk(userData, ob, &umd->projectors[i]);
+               walk(userData, ob, &umd->projectors[i], IDWALK_CB_NOP);
 }
 
 static void foreachIDLink(ModifierData *md, Object *ob,
-                                               IDWalkFunc walk, void *userData)
+                          IDWalkFunc walk, void *userData)
 {
-       UVProjectModifierData *umd = (UVProjectModifierData*) md;
+       UVProjectModifierData *umd = (UVProjectModifierData *) md;
 
-       walk(userData, ob, (ID **)&umd->image);
+       walk(userData, ob, (ID **)&umd->image, IDWALK_CB_USER);
 
-       foreachObjectLink(md, ob, (ObjectWalkFunc)walk,
-                                               userData);
+       foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
 }
 
 static void updateDepgraph(ModifierData *md, DagForest *forest,
-                                               struct Scene *UNUSED(scene),
-                                               Object *UNUSED(ob),
-                                               DagNode *obNode)
+                           struct Main *UNUSED(bmain),
+                           struct Scene *UNUSED(scene),
+                           Object *UNUSED(ob),
+                           DagNode *obNode)
 {
-       UVProjectModifierData *umd = (UVProjectModifierData*) md;
+       UVProjectModifierData *umd = (UVProjectModifierData *) md;
        int i;
 
        for (i = 0; i < umd->num_projectors; ++i) {
@@ -132,20 +119,35 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
                        DagNode *curNode = dag_get_node(forest, umd->projectors[i]);
 
                        dag_add_relation(forest, curNode, obNode,
-                                        DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "UV Project Modifier");
+                                        DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "UV Project Modifier");
+               }
+       }
+}
+
+static void updateDepsgraph(ModifierData *md,
+                            struct Main *UNUSED(bmain),
+                            struct Scene *UNUSED(scene),
+                            Object *UNUSED(ob),
+                            struct DepsNodeHandle *node)
+{
+       UVProjectModifierData *umd = (UVProjectModifierData *)md;
+       int i;
+       for (i = 0; i < umd->num_projectors; ++i) {
+               if (umd->projectors[i] != NULL) {
+                       DEG_add_object_relation(node, umd->projectors[i], DEG_OB_COMP_TRANSFORM, "UV Project Modifier");
                }
        }
 }
 
 typedef struct Projector {
-       Object *ob;                             /* object this projector is derived from */
-       float projmat[4][4];    /* projection matrix */ 
-       float normal[3];                /* projector normal in world space */
-       void *uci;                              /* optional uv-project info (panorama projection) */
+       Object *ob;             /* object this projector is derived from */
+       float projmat[4][4];    /* projection matrix */
+       float normal[3];        /* projector normal in world space */
+       void *uci;              /* optional uv-project info (panorama projection) */
 } Projector;
 
 static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
-                                        Object *ob, DerivedMesh *dm)
+                                         Object *ob, DerivedMesh *dm)
 {
        float (*coords)[3], (*co)[3];
        MLoopUV *mloop_uv;
@@ -154,18 +156,15 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
        Image *image = umd->image;
        MPoly *mpoly, *mp;
        MLoop *mloop;
-       int override_image = ((umd->flags & MOD_UVPROJECT_OVERRIDEIMAGE) != 0);
+       const bool override_image = (umd->flags & MOD_UVPROJECT_OVERRIDEIMAGE) != 0;
        Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
        int num_projectors = 0;
-       float aspect;
        char uvname[MAX_CUSTOMDATA_LAYER_NAME];
-       float aspx= umd->aspectx ? umd->aspectx : 1.0f;
-       float aspy= umd->aspecty ? umd->aspecty : 1.0f;
-       float scax= umd->scalex ? umd->scalex : 1.0f;
-       float scay= umd->scaley ? umd->scaley : 1.0f;
-       int free_uci= 0;
-
-       aspect = aspx / aspy;
+       float aspx = umd->aspectx ? umd->aspectx : 1.0f;
+       float aspy = umd->aspecty ? umd->aspecty : 1.0f;
+       float scax = umd->scalex ? umd->scalex : 1.0f;
+       float scay = umd->scaley ? umd->scaley : 1.0f;
+       int free_uci = 0;
 
        for (i = 0; i < umd->num_projectors; ++i)
                if (umd->projectors[i])
@@ -188,50 +187,34 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
                /* calculate projection matrix */
                invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat);
 
-               projectors[i].uci= NULL;
+               projectors[i].uci = NULL;
 
                if (projectors[i].ob->type == OB_CAMERA) {
                        
                        cam = (Camera *)projectors[i].ob->data;
-                       if (cam->flag & CAM_PANORAMA) {
-                               projectors[i].uciproject_camera_info(projectors[i].ob, NULL, aspx, aspy);
-                               project_camera_info_scale(projectors[i].uci, scax, scay);
-                               free_uci= 1;
+                       if (cam->type == CAM_PANO) {
+                               projectors[i].uci = BLI_uvproject_camera_info(projectors[i].ob, NULL, aspx, aspy);
+                               BLI_uvproject_camera_info_scale(projectors[i].uci, scax, scay);
+                               free_uci = 1;
                        }
                        else {
-                               float sensor= camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
-                               int sensor_fit= camera_sensor_fit(cam->sensor_fit, aspx, aspy);
-                               float scale= (cam->type == CAM_PERSP) ? cam->clipsta * sensor / cam->lens : cam->ortho_scale;
-                               float xmax, xmin, ymax, ymin;
-
-                               if (sensor_fit==CAMERA_SENSOR_FIT_HOR) {
-                                       xmax = 0.5f * scale;
-                                       ymax = xmax / aspect;
-                               }
-                               else {
-                                       ymax = 0.5f * scale;
-                                       xmax = ymax * aspect;
-                               }
+                               CameraParams params;
 
-                               xmin = -xmax;
-                               ymin = -ymax;
+                               /* setup parameters */
+                               BKE_camera_params_init(&params);
+                               BKE_camera_params_from_object(&params, projectors[i].ob);
 
-                               /* scale the matrix */
-                               xmin *= scax;
-                               xmax *= scax;
-                               ymin *= scay;
-                               ymax *= scay;
+                               /* compute matrix, viewplane, .. */
+                               BKE_camera_params_compute_viewplane(&params, 1, 1, aspx, aspy);
 
-                               if (cam->type == CAM_PERSP) {
-                                       float perspmat[4][4];
-                                       perspective_m4( perspmat,xmin, xmax, ymin, ymax, cam->clipsta, cam->clipend);
-                                       mult_m4_m4m4(tmpmat, perspmat, projectors[i].projmat);
-                               }
-                               else { /* if (cam->type == CAM_ORTHO) */
-                                       float orthomat[4][4];
-                                       orthographic_m4( orthomat,xmin, xmax, ymin, ymax, cam->clipsta, cam->clipend);
-                                       mult_m4_m4m4(tmpmat, orthomat, projectors[i].projmat);
-                               }
+                               /* scale the view-plane */
+                               params.viewplane.xmin *= scax;
+                               params.viewplane.xmax *= scax;
+                               params.viewplane.ymin *= scay;
+                               params.viewplane.ymax *= scay;
+
+                               BKE_camera_params_compute_matrix(&params);
+                               mul_m4_m4m4(tmpmat, params.winmat, projectors[i].projmat);
                        }
                }
                else {
@@ -241,23 +224,8 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
                unit_m4(offsetmat);
                mul_mat3_m4_fl(offsetmat, 0.5);
                offsetmat[3][0] = offsetmat[3][1] = offsetmat[3][2] = 0.5;
-               
-               if (cam) {
-                       if (aspx == aspy) { 
-                               offsetmat[3][0] -= cam->shiftx;
-                               offsetmat[3][1] -= cam->shifty;
-                       }
-                       else if (aspx < aspy) {
-                               offsetmat[3][0] -=(cam->shiftx * aspy/aspx);
-                               offsetmat[3][1] -= cam->shifty;
-                       }
-                       else {
-                               offsetmat[3][0] -= cam->shiftx;
-                               offsetmat[3][1] -=(cam->shifty * aspx/aspy);
-                       }
-               }
-               
-               mult_m4_m4m4(projectors[i].projmat, offsetmat, tmpmat);
+
+               mul_m4_m4m4(projectors[i].projmat, offsetmat, tmpmat);
 
                /* calculate worldspace projector normal (for best projector test) */
                projectors[i].normal[0] = 0;
@@ -271,16 +239,16 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
 
        /* make sure we are not modifying the original UV map */
        mloop_uv = CustomData_duplicate_referenced_layer_named(&dm->loopData,
-                       CD_MLOOPUV, uvname, numLoops);
+                                                              CD_MLOOPUV, uvname, numLoops);
 
        /* can be NULL */
        mt = mtexpoly = CustomData_duplicate_referenced_layer_named(&dm->polyData,
-                       CD_MTEXPOLY, uvname, numPolys);
+                                                                   CD_MTEXPOLY, uvname, numPolys);
 
        numVerts = dm->getNumVerts(dm);
 
-       coords = MEM_callocN(sizeof(*coords) * numVerts,
-                                "uvprojectModifier_do coords");
+       coords = MEM_mallocN(sizeof(*coords) * numVerts,
+                            "uvprojectModifier_do coords");
        dm->getVertCos(dm, coords);
 
        /* convert coords to world space */
@@ -288,7 +256,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
                mul_m4_v3(ob->obmat, *co);
        
        /* if only one projector, project coords to UVs */
-       if (num_projectors == 1 && projectors[0].uci==NULL)
+       if (num_projectors == 1 && projectors[0].uci == NULL)
                for (i = 0, co = coords; i < numVerts; ++i, ++co)
                        mul_project_m4_v3(projectors[0].projmat, *co);
 
@@ -300,19 +268,19 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
                if (override_image || !image || (mtexpoly == NULL || mt->tpage == image)) {
                        if (num_projectors == 1) {
                                if (projectors[0].uci) {
-                                       unsigned int fidx= mp->totloop - 1;
+                                       unsigned int fidx = mp->totloop - 1;
                                        do {
-                                               unsigned int lidx= mp->loopstart + fidx;
-                                               unsigned int vidx= mloop[lidx].v;
-                                               project_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci);
+                                               unsigned int lidx = mp->loopstart + fidx;
+                                               unsigned int vidx = mloop[lidx].v;
+                                               BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci);
                                        } while (fidx--);
                                }
                                else {
                                        /* apply transformed coords as UVs */
-                                       unsigned int fidx= mp->totloop - 1;
+                                       unsigned int fidx = mp->totloop - 1;
                                        do {
-                                               unsigned int lidx= mp->loopstart + fidx;
-                                               unsigned int vidx= mloop[lidx].v;
+                                               unsigned int lidx = mp->loopstart + fidx;
+                                               unsigned int vidx = mloop[lidx].v;
                                                copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]);
                                        } while (fidx--);
                                }
@@ -325,7 +293,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
                                float best_dot;
 
                                /* get the untransformed face normal */
-                               mesh_calc_poly_normal_coords(mp, mloop + mp->loopstart, (const float (*)[3])coords, face_no);
+                               BKE_mesh_calc_poly_normal_coords(mp, mloop + mp->loopstart, (const float (*)[3])coords, face_no);
 
                                /* find the projector which the face points at most directly
                                 * (projector normal with largest dot product is best)
@@ -335,7 +303,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
 
                                for (j = 1; j < num_projectors; ++j) {
                                        float tmp_dot = dot_v3v3(projectors[j].normal,
-                                                       face_no);
+                                                                face_no);
                                        if (tmp_dot > best_dot) {
                                                best_dot = tmp_dot;
                                                best_projector = &projectors[j];
@@ -343,24 +311,19 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
                                }
 
                                if (best_projector->uci) {
-                                       unsigned int fidx= mp->totloop - 1;
+                                       unsigned int fidx = mp->totloop - 1;
                                        do {
-                                               unsigned int lidx= mp->loopstart + fidx;
-                                               unsigned int vidx= mloop[lidx].v;
-                                               project_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci);
+                                               unsigned int lidx = mp->loopstart + fidx;
+                                               unsigned int vidx = mloop[lidx].v;
+                                               BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci);
                                        } while (fidx--);
                                }
                                else {
-                                       unsigned int fidx= mp->totloop - 1;
+                                       unsigned int fidx = mp->totloop - 1;
                                        do {
-                                               unsigned int lidx= mp->loopstart + fidx;
-                                               unsigned int vidx= mloop[lidx].v;
-                                               float tco[3];
-
-                                               copy_v3_v3(tco, coords[vidx]);
-                                               mul_project_m4_v3(best_projector->projmat, tco);
-                                               copy_v2_v2(mloop_uv[lidx].uv, tco);
-
+                                               unsigned int lidx = mp->loopstart + fidx;
+                                               unsigned int vidx = mloop[lidx].v;
+                                               mul_v2_project_m4_v3(mloop_uv[lidx].uv, best_projector->projmat, coords[vidx]);
                                        } while (fidx--);
                                }
                        }
@@ -389,35 +352,27 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
 }
 
 static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
-                                               DerivedMesh *derivedData,
-                                               int UNUSED(useRenderParams),
-                                               int UNUSED(isFinalCalc))
+                                  DerivedMesh *derivedData,
+                                  ModifierApplyFlag UNUSED(flag))
 {
        DerivedMesh *result;
-       UVProjectModifierData *umd = (UVProjectModifierData*) md;
+       UVProjectModifierData *umd = (UVProjectModifierData *) md;
 
        result = uvprojectModifier_do(umd, ob, derivedData);
 
        return result;
 }
 
-static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
-                                               struct BMEditMesh *UNUSED(editData),
-                                               DerivedMesh *derivedData)
-{
-       return applyModifier(md, ob, derivedData, 0, 1);
-}
-
 
 ModifierTypeInfo modifierType_UVProject = {
        /* name */              "UVProject",
        /* structName */        "UVProjectModifierData",
        /* structSize */        sizeof(UVProjectModifierData),
        /* type */              eModifierTypeType_NonGeometrical,
-       /* flags */             eModifierTypeFlag_AcceptsMesh
-                                                       | eModifierTypeFlag_SupportsMapping
-                                                       | eModifierTypeFlag_SupportsEditmode
-                                                       | eModifierTypeFlag_EnableInEditmode,
+       /* flags */             eModifierTypeFlag_AcceptsMesh |
+                               eModifierTypeFlag_SupportsMapping |
+                               eModifierTypeFlag_SupportsEditmode |
+                               eModifierTypeFlag_EnableInEditmode,
 
        /* copyData */          copyData,
        /* deformVerts */       NULL,
@@ -425,12 +380,13 @@ ModifierTypeInfo modifierType_UVProject = {
        /* deformVertsEM */     NULL,
        /* deformMatricesEM */  NULL,
        /* applyModifier */     applyModifier,
-       /* applyModifierEM */   applyModifierEM,
+       /* applyModifierEM */   NULL,
        /* initData */          initData,
        /* requiredDataMask */  requiredDataMask,
        /* freeData */          NULL,
        /* isDisabled */        NULL,
        /* updateDepgraph */    updateDepgraph,
+       /* updateDepsgraph */   updateDepsgraph,
        /* dependsOnTime */     NULL,
        /* dependsOnNormals */  NULL,
        /* foreachObjectLink */ foreachObjectLink,