DRW: show image empty frame when the 'side' is hidden
[blender.git] / source / blender / blenkernel / intern / object.c
index 617b5f580b1f9b7d813f0e39ee5da33acbe5d940..1743060aa97f823a52786afef965466458ea0094 100644 (file)
@@ -38,7 +38,7 @@
 #include "DNA_gpencil_types.h"
 #include "DNA_gpencil_modifier_types.h"
 #include "DNA_key_types.h"
-#include "DNA_lamp_types.h"
+#include "DNA_light_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_material_types.h"
 #include "DNA_meta_types.h"
@@ -85,7 +85,7 @@
 #include "BKE_gpencil_modifier.h"
 #include "BKE_icons.h"
 #include "BKE_key.h"
-#include "BKE_lamp.h"
+#include "BKE_light.h"
 #include "BKE_layer.h"
 #include "BKE_lattice.h"
 #include "BKE_library.h"
@@ -450,10 +450,7 @@ void BKE_object_free_derived_caches(Object *ob)
                }
        }
 
-       if (ob->runtime.bb) {
-               MEM_freeN(ob->runtime.bb);
-               ob->runtime.bb = NULL;
-       }
+       MEM_SAFE_FREE(ob->runtime.bb);
 
        object_update_from_subsurf_ccg(ob);
        BKE_object_free_derived_mesh_caches(ob);
@@ -796,7 +793,7 @@ void *BKE_object_obdata_add_from_type(Main *bmain, int type, const char *name)
                case OB_FONT:      return BKE_curve_add(bmain, name, OB_FONT);
                case OB_MBALL:     return BKE_mball_add(bmain, name);
                case OB_CAMERA:    return BKE_camera_add(bmain, name);
-               case OB_LAMP:      return BKE_lamp_add(bmain, name);
+               case OB_LAMP:      return BKE_light_add(bmain, name);
                case OB_LATTICE:   return BKE_lattice_add(bmain, name);
                case OB_ARMATURE:  return BKE_armature_add(bmain, name);
                case OB_SPEAKER:   return BKE_speaker_add(bmain, name);
@@ -813,8 +810,7 @@ void BKE_object_init(Object *ob)
 {
        /* BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(ob, id)); */  /* ob->type is already initialized... */
 
-       ob->col[0] = ob->col[1] = ob->col[2] = 1.0;
-       ob->col[3] = 1.0;
+       copy_v4_fl(ob->color, 1.0f);
 
        ob->scale[0] = ob->scale[1] = ob->scale[2] = 1.0;
        ob->dscale[0] = ob->dscale[1] = ob->dscale[2] = 1.0;
@@ -1431,6 +1427,240 @@ Object *BKE_object_copy(Main *bmain, const Object *ob)
        return ob_copy;
 }
 
+Object *BKE_object_duplicate(Main *bmain, const Object *ob, const int dupflag)
+{
+       Material ***matarar;
+       ID *id;
+       int a, didit;
+       Object *obn = BKE_object_copy(bmain, ob);
+
+       /* 0 == full linked. */
+       if (dupflag == 0) {
+               return obn;
+       }
+
+#define ID_NEW_REMAP_US(a)     if (      (a)->id.newid) { (a) = (void *)(a)->id.newid;       (a)->id.us++; }
+#define ID_NEW_REMAP_US2(a)    if (((ID *)a)->newid)    { (a) = ((ID  *)a)->newid;     ((ID *)a)->us++;    }
+
+       /* duplicates using userflags */
+       if (dupflag & USER_DUP_ACT) {
+               BKE_animdata_copy_id_action(bmain, &obn->id, true);
+       }
+
+       if (dupflag & USER_DUP_MAT) {
+               for (a = 0; a < obn->totcol; a++) {
+                       id = (ID *)obn->mat[a];
+                       if (id) {
+                               ID_NEW_REMAP_US(obn->mat[a])
+                               else {
+                                       obn->mat[a] = ID_NEW_SET(obn->mat[a], BKE_material_copy(bmain, obn->mat[a]));
+                               }
+                               id_us_min(id);
+
+                               if (dupflag & USER_DUP_ACT) {
+                                       BKE_animdata_copy_id_action(bmain, &obn->mat[a]->id, true);
+                               }
+                       }
+               }
+       }
+       if (dupflag & USER_DUP_PSYS) {
+               ParticleSystem *psys;
+               for (psys = obn->particlesystem.first; psys; psys = psys->next) {
+                       id = (ID *) psys->part;
+                       if (id) {
+                               ID_NEW_REMAP_US(psys->part)
+                               else {
+                                       psys->part = ID_NEW_SET(psys->part, BKE_particlesettings_copy(bmain, psys->part));
+                               }
+
+                               if (dupflag & USER_DUP_ACT) {
+                                       BKE_animdata_copy_id_action(bmain, &psys->part->id, true);
+                               }
+
+                               id_us_min(id);
+                       }
+               }
+       }
+
+       id = obn->data;
+       didit = 0;
+
+       switch (obn->type) {
+               case OB_MESH:
+                       if (dupflag & USER_DUP_MESH) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_mesh_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_CURVE:
+                       if (dupflag & USER_DUP_CURVE) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_SURF:
+                       if (dupflag & USER_DUP_SURF) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_FONT:
+                       if (dupflag & USER_DUP_FONT) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_MBALL:
+                       if (dupflag & USER_DUP_MBALL) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_mball_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_LAMP:
+                       if (dupflag & USER_DUP_LAMP) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_light_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_ARMATURE:
+                       DEG_id_tag_update(&obn->id, ID_RECALC_GEOMETRY);
+                       if (obn->pose)
+                               BKE_pose_tag_recalc(bmain, obn->pose);
+                       if (dupflag & USER_DUP_ARM) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data));
+                                       BKE_pose_rebuild(bmain, obn, obn->data, true);
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_LATTICE:
+                       if (dupflag != 0) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_lattice_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_CAMERA:
+                       if (dupflag != 0) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_camera_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_LIGHTPROBE:
+                       if (dupflag != 0) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_lightprobe_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_SPEAKER:
+                       if (dupflag != 0) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_speaker_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+               case OB_GPENCIL:
+                       if (dupflag != 0) {
+                               ID_NEW_REMAP_US2(obn->data)
+                               else {
+                                       obn->data = ID_NEW_SET(obn->data, BKE_gpencil_copy(bmain, obn->data));
+                                       didit = 1;
+                               }
+                               id_us_min(id);
+                       }
+                       break;
+       }
+
+       /* Check if obdata is copied. */
+       if (didit) {
+               Key *key = BKE_key_from_object(obn);
+
+               Key *oldkey = BKE_key_from_object(ob);
+               if (oldkey != NULL) {
+                       ID_NEW_SET(oldkey, key);
+               }
+
+               if (dupflag & USER_DUP_ACT) {
+                       BKE_animdata_copy_id_action(bmain, (ID *)obn->data, true);
+                       if (key) {
+                               BKE_animdata_copy_id_action(bmain, (ID *)key, true);
+                       }
+               }
+
+               if (dupflag & USER_DUP_MAT) {
+                       matarar = give_matarar(obn);
+                       if (matarar) {
+                               for (a = 0; a < obn->totcol; a++) {
+                                       id = (ID *)(*matarar)[a];
+                                       if (id) {
+                                               ID_NEW_REMAP_US((*matarar)[a])
+                                               else {
+                                                       (*matarar)[a] = ID_NEW_SET((*matarar)[a], BKE_material_copy(bmain, (*matarar)[a]));
+                                               }
+                                               id_us_min(id);
+                                       }
+                               }
+                       }
+               }
+       }
+
+#undef ID_NEW_REMAP_US
+#undef ID_NEW_REMAP_US2
+
+       BKE_libblock_relink_to_newid(&obn->id);
+
+       /* DAG_relations_tag_update(bmain); */ /* caller must do */
+
+       if (ob->data != NULL) {
+               DEG_id_tag_update_ex(bmain, (ID *)obn->data, ID_RECALC_EDITORS);
+       }
+
+       /* BKE_main_id_clear_newpoins(bmain); */ /* Called must do. */
+
+       return obn;
+}
+
 void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, const bool clear_proxy)
 {
        bool is_local = false, is_lib = false;
@@ -1665,11 +1895,6 @@ void BKE_object_obdata_size_init(struct Object *ob, const float size)
                        ob->empty_drawsize *= size;
                        break;
                }
-               case OB_GPENCIL:
-               {
-                       ob->empty_drawsize *= size;
-                       break;
-               }
                case OB_FONT:
                {
                        Curve *cu = ob->data;
@@ -1684,7 +1909,7 @@ void BKE_object_obdata_size_init(struct Object *ob, const float size)
                }
                case OB_LAMP:
                {
-                       Lamp *lamp = ob->data;
+                       Light *lamp = ob->data;
                        lamp->dist *= size;
                        lamp->area_size  *= size;
                        lamp->area_sizey *= size;
@@ -1864,6 +2089,30 @@ void BKE_object_tfm_protected_restore(Object *ob,
        }
 }
 
+void BKE_object_tfm_copy(Object *object_dst, const Object *object_src)
+{
+#define TFMCPY(_v) (object_dst->_v = object_src->_v)
+#define TFMCPY3D(_v) copy_v3_v3(object_dst->_v, object_src->_v)
+#define TFMCPY4D(_v) copy_v4_v4(object_dst->_v, object_src->_v)
+
+       TFMCPY3D(loc);
+       TFMCPY3D(dloc);
+       TFMCPY3D(scale);
+       TFMCPY3D(dscale);
+       TFMCPY3D(rot);
+       TFMCPY3D(drot);
+       TFMCPY4D(quat);
+       TFMCPY4D(dquat);
+       TFMCPY3D(rotAxis);
+       TFMCPY3D(drotAxis);
+       TFMCPY(rotAngle);
+       TFMCPY(drotAngle);
+
+#undef TFMCPY
+#undef TFMCPY3D
+#undef TFMCPY4D
+}
+
 void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
 {
        float smat[3][3];
@@ -2194,10 +2443,10 @@ static void solve_parenting(Object *ob, Object *par, float obmat[4][4],
        /* origin, for help line */
        if (set_origin) {
                if ((ob->partype & PARTYPE) == PARSKEL) {
-                       copy_v3_v3(ob->orig, par->obmat[3]);
+                       copy_v3_v3(ob->runtime.parent_display_origin, par->obmat[3]);
                }
                else {
-                       copy_v3_v3(ob->orig, totmat[3]);
+                       copy_v3_v3(ob->runtime.parent_display_origin, totmat[3]);
                }
        }
 }
@@ -2278,7 +2527,6 @@ void BKE_object_where_is_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
  */
 void BKE_object_workob_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *ob, Object *workob)
 {
-       Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
        BKE_object_workob_clear(workob);
 
        unit_m4(workob->obmat);
@@ -2288,17 +2536,17 @@ void BKE_object_workob_calc_parent(Depsgraph *depsgraph, Scene *scene, Object *o
        /* Since this is used while calculating parenting, at this moment ob_eval->parent is still NULL. */
        workob->parent = DEG_get_evaluated_object(depsgraph, ob->parent);
 
-       workob->trackflag = ob_eval->trackflag;
-       workob->upflag = ob_eval->upflag;
+       workob->trackflag = ob->trackflag;
+       workob->upflag = ob->upflag;
 
-       workob->partype = ob_eval->partype;
-       workob->par1 = ob_eval->par1;
-       workob->par2 = ob_eval->par2;
-       workob->par3 = ob_eval->par3;
+       workob->partype = ob->partype;
+       workob->par1 = ob->par1;
+       workob->par2 = ob->par2;
+       workob->par3 = ob->par3;
 
-       workob->constraints = ob_eval->constraints;
+       workob->constraints = ob->constraints;
 
-       BLI_strncpy(workob->parsubstr, ob_eval->parsubstr, sizeof(workob->parsubstr));
+       BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr));
 
        BKE_object_where_is_calc(depsgraph, scene, workob);
 }
@@ -2564,7 +2812,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const bool us
                float size[3];
 
                copy_v3_v3(size, ob->scale);
-               if ((ob->type == OB_EMPTY) || (ob->type == OB_GPENCIL)) {
+               if (ob->type == OB_EMPTY) {
                        mul_v3_fl(size, ob->empty_drawsize);
                }
 
@@ -2601,9 +2849,23 @@ void BKE_object_empty_draw_type_set(Object *ob, const int value)
        }
 }
 
-bool BKE_object_empty_image_is_visible_in_view3d(const Object *ob, const RegionView3D *rv3d)
+bool BKE_object_empty_image_frame_is_visible_in_view3d(const Object *ob, const RegionView3D *rv3d)
 {
-       char visibility_flag = ob->empty_image_visibility_flag;
+       const char visibility_flag = ob->empty_image_visibility_flag;
+       if (rv3d->is_persp) {
+               return (visibility_flag & OB_EMPTY_IMAGE_HIDE_PERSPECTIVE) == 0;
+       }
+       else {
+               return (visibility_flag & OB_EMPTY_IMAGE_HIDE_ORTHOGRAPHIC) == 0;
+       }
+}
+
+bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const RegionView3D *rv3d)
+{
+       /* Caller is expected to check this. */
+       BLI_assert(BKE_object_empty_image_frame_is_visible_in_view3d(ob, rv3d));
+
+       const char visibility_flag = ob->empty_image_visibility_flag;
 
        if ((visibility_flag & (OB_EMPTY_IMAGE_HIDE_BACK | OB_EMPTY_IMAGE_HIDE_FRONT)) != 0) {
                float eps, dot;
@@ -2632,12 +2894,7 @@ bool BKE_object_empty_image_is_visible_in_view3d(const Object *ob, const RegionV
                }
        }
 
-       if (rv3d->is_persp) {
-               return (visibility_flag & OB_EMPTY_IMAGE_HIDE_PERSPECTIVE) == 0;
-       }
-       else {
-               return (visibility_flag & OB_EMPTY_IMAGE_HIDE_ORTHOGRAPHIC) == 0;
-       }
+       return true;
 }
 
 bool BKE_object_minmax_dupli(Depsgraph *depsgraph, Scene *scene, Object *ob, float r_min[3], float r_max[3], const bool use_hidden)
@@ -2725,9 +2982,9 @@ void BKE_scene_foreach_display_point(
 
 /* copied from DNA_object_types.h */
 typedef struct ObTfmBack {
-       float loc[3], dloc[3], orig[3];
+       float loc[3], dloc[3];
        /** scale and delta scale. */
-       float size[3], dscale[3];
+       float scale[3], dscale[3];
        /** euler rotation. */
        float rot[3], drot[3];
        /** quaternion rotation. */
@@ -2751,8 +3008,7 @@ void *BKE_object_tfm_backup(Object *ob)
        ObTfmBack *obtfm = MEM_mallocN(sizeof(ObTfmBack), "ObTfmBack");
        copy_v3_v3(obtfm->loc, ob->loc);
        copy_v3_v3(obtfm->dloc, ob->dloc);
-       copy_v3_v3(obtfm->orig, ob->orig);
-       copy_v3_v3(obtfm->size, ob->scale);
+       copy_v3_v3(obtfm->scale, ob->scale);
        copy_v3_v3(obtfm->dscale, ob->dscale);
        copy_v3_v3(obtfm->rot, ob->rot);
        copy_v3_v3(obtfm->drot, ob->drot);
@@ -2775,8 +3031,7 @@ void BKE_object_tfm_restore(Object *ob, void *obtfm_pt)
        ObTfmBack *obtfm = (ObTfmBack *)obtfm_pt;
        copy_v3_v3(ob->loc, obtfm->loc);
        copy_v3_v3(ob->dloc, obtfm->dloc);
-       copy_v3_v3(ob->orig, obtfm->orig);
-       copy_v3_v3(ob->scale, obtfm->size);
+       copy_v3_v3(ob->scale, obtfm->scale);
        copy_v3_v3(ob->dscale, obtfm->dscale);
        copy_v3_v3(ob->rot, obtfm->rot);
        copy_v3_v3(ob->drot, obtfm->drot);