Esempio n. 1
0
static bool shape_key_move_poll(bContext *C)
{
  /* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */
  Object *ob = ED_object_context(C);
  ID *data = (ob) ? ob->data : NULL;
  Key *key = BKE_key_from_object(ob);

  return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT &&
          key && key->totkey > 1);
}
Esempio n. 2
0
static bool shape_key_mode_exists_poll(bContext *C)
{
  Object *ob = ED_object_context(C);
  ID *data = (ob) ? ob->data : NULL;

  /* same as shape_key_mode_poll */
  return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT) &&
         /* check a keyblock exists */
         (BKE_keyblock_from_object(ob) != NULL);
}
Esempio n. 3
0
/* This function is used to process the necessary updates for */
void ED_armature_enter_posemode(bContext *C, Base *base)
{
	ReportList *reports = CTX_wm_reports(C);
	Object *ob = base->object;
	
	if (ID_IS_LINKED(ob)) {
		BKE_report(reports, RPT_WARNING, "Cannot pose libdata");
		return;
	}
	
	switch (ob->type) {
		case OB_ARMATURE:
			ob->restore_mode = ob->mode;
			ob->mode |= OB_MODE_POSE;
			
			WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
			
			break;
		default:
			return;
	}
	
	/* XXX: disabled as this would otherwise cause a nasty loop... */
	//ED_object_toggle_modes(C, ob->mode);
}
Esempio n. 4
0
/** Similar to libblock_relink_ex, but is remapping IDs to their newid value if non-NULL, in given \a id.
 *
 * Very specific usage, not sure we'll keep it on the long run, currently only used in Object duplication code...
 */
void BKE_libblock_relink_to_newid(ID *id)
{
	if (ID_IS_LINKED(id))
		return;

	BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0);
}
Esempio n. 5
0
/**
 * Hide/show all the elements of a collection.
 * Don't change the collection children enable/disable state,
 * but it may change it for the collection itself.
 *
 * Return true if depsgraph needs update.
 */
bool BKE_layer_collection_set_visible(ViewLayer *view_layer,
                                      LayerCollection *lc,
                                      const bool visible,
                                      const bool hierarchy)
{
  bool depsgraph_changed = false;

  if (visible && (!ID_IS_LINKED(lc->collection)) &&
      ((lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) != 0)) {
    lc->collection->flag &= ~COLLECTION_RESTRICT_VIEWPORT;
    depsgraph_changed = true;
  }

  if (hierarchy) {
    if (visible) {
      layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_HIDE);
      layer_collection_bases_show_recursive(view_layer, lc);
    }
    else {
      layer_collection_flag_set_recursive(lc, LAYER_COLLECTION_HIDE);
      layer_collection_bases_hide_recursive(view_layer, lc);
    }
  }
  else {
    if (visible) {
      lc->flag &= ~LAYER_COLLECTION_HIDE;
    }
    else {
      lc->flag |= LAYER_COLLECTION_HIDE;
    }
  }
  return depsgraph_changed;
}
static bool depthdropper_poll(bContext *C)
{
  PointerRNA ptr;
  PropertyRNA *prop;
  int index_dummy;
  uiBut *but;

  /* check if there's an active button taking depth value */
  if ((CTX_wm_window(C) != NULL) &&
      (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
      (but->type == UI_BTYPE_NUM) && (prop != NULL)) {
    if ((RNA_property_type(prop) == PROP_FLOAT) &&
        (RNA_property_subtype(prop) & PROP_UNIT_LENGTH) &&
        (RNA_property_array_check(prop) == false)) {
      return 1;
    }
  }
  else {
    RegionView3D *rv3d = CTX_wm_region_view3d(C);
    if (rv3d && rv3d->persp == RV3D_CAMOB) {
      View3D *v3d = CTX_wm_view3d(C);
      if (v3d->camera && v3d->camera->data && !ID_IS_LINKED(v3d->camera->data)) {
        return 1;
      }
    }
  }

  return 0;
}
Esempio n. 7
0
void ED_editors_init(bContext *C)
{
	wmWindowManager *wm = CTX_wm_manager(C);
	Main *bmain = CTX_data_main(C);
	Scene *sce = CTX_data_scene(C);
	Object *ob, *obact = (sce && sce->basact) ? sce->basact->object : NULL;
	ID *data;

	if (wm->undo_stack == NULL) {
		wm->undo_stack = BKE_undosys_stack_create();
	}

	/* This is called during initialization, so we don't want to store any reports */
	ReportList *reports = CTX_wm_reports(C);
	int reports_flag_prev = reports->flag & ~RPT_STORE;

	SWAP(int, reports->flag, reports_flag_prev);

	/* toggle on modes for objects that were saved with these enabled. for
	 * e.g. linked objects we have to ensure that they are actually the
	 * active object in this scene. */
	for (ob = bmain->object.first; ob; ob = ob->id.next) {
		int mode = ob->mode;

		if (!ELEM(mode, OB_MODE_OBJECT, OB_MODE_POSE)) {
			ob->mode = OB_MODE_OBJECT;
			data = ob->data;

			if (ob == obact && !ID_IS_LINKED(ob) && !(data && ID_IS_LINKED(data)))
				ED_object_mode_toggle(C, mode);
		}
	}

	/* image editor paint mode */
	if (sce) {
		ED_space_image_paint_update(bmain, wm, sce);
	}

	SWAP(int, reports->flag, reports_flag_prev);
}
Esempio n. 8
0
void BKE_pose_eval_proxy_copy(EvaluationContext *UNUSED(eval_ctx), Object *ob)
{
	BLI_assert(ID_IS_LINKED(ob) && ob->proxy_from != NULL);
	DEG_debug_print_eval(__func__, ob->id.name, ob);
	if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) {
		printf("Proxy copy error, lib Object: %s proxy Object: %s\n",
		       ob->id.name + 2, ob->proxy_from->id.name + 2);
	}
	/* Rest of operations are NO-OP in depsgraph, so can clear
	 * flag now.
	 */
	ob->recalc &= ~OB_RECALC_ALL;
}
Esempio n. 9
0
/* no libraries for now */
void packAll(Main *bmain, ReportList *reports, bool verbose)
{
	Image *ima;
	VFont *vfont;
	bSound *sound;
	int tot = 0;

	for (ima = bmain->image.first; ima; ima = ima->id.next) {
		if (BKE_image_has_packedfile(ima) == false && !ID_IS_LINKED(ima)) {
			if (ima->source == IMA_SRC_FILE) {
				BKE_image_packfiles(reports, ima, ID_BLEND_PATH(bmain, &ima->id));
				tot ++;
			}
			else if (BKE_image_is_animated(ima) && verbose) {
				BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported",
				            ima->id.name + 2);
			}
		}
	}

	for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next) {
		if (vfont->packedfile == NULL && !ID_IS_LINKED(vfont) && BKE_vfont_is_builtin(vfont) == false) {
			vfont->packedfile = newPackedFile(reports, vfont->name, BKE_main_blendfile_path(bmain));
			tot ++;
		}
	}

	for (sound = bmain->sound.first; sound; sound = sound->id.next) {
		if (sound->packedfile == NULL && !ID_IS_LINKED(sound)) {
			sound->packedfile = newPackedFile(reports, sound->name, BKE_main_blendfile_path(bmain));
			tot++;
		}
	}

	if (tot > 0)
		BKE_reportf(reports, RPT_INFO, "Packed %d files", tot);
	else if (verbose)
		BKE_report(reports, RPT_INFO, "No new files have been packed");
}
Esempio n. 10
0
static int gpencil_edit_modifier_poll_generic(bContext *C, StructRNA *rna_type, int obtype_flag)
{
  PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
  Object *ob = (ptr.id.data) ? ptr.id.data : ED_object_active_context(C);

  if (!ob || ID_IS_LINKED(ob)) {
    return 0;
  }
  if (obtype_flag && ((1 << ob->type) & obtype_flag) == 0) {
    return 0;
  }
  if (ptr.id.data && ID_IS_LINKED(ptr.id.data)) {
    return 0;
  }

  if (ID_IS_STATIC_OVERRIDE(ob)) {
    CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers coming from static override");
    return (((GpencilModifierData *)ptr.data)->flag & eGpencilModifierFlag_StaticOverride_Local) !=
           0;
  }

  return 1;
}
static int depthdropper_init(bContext *C, wmOperator *op)
{
  int index_dummy;

  SpaceType *st;
  ARegionType *art;

  st = BKE_spacetype_from_id(SPACE_VIEW3D);
  art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);

  DepthDropper *ddr = MEM_callocN(sizeof(DepthDropper), __func__);

  uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);

  /* fallback to the active camera's dof */
  if (ddr->prop == NULL) {
    RegionView3D *rv3d = CTX_wm_region_view3d(C);
    if (rv3d && rv3d->persp == RV3D_CAMOB) {
      View3D *v3d = CTX_wm_view3d(C);
      if (v3d->camera && v3d->camera->data && !ID_IS_LINKED(v3d->camera->data)) {
        RNA_id_pointer_create(v3d->camera->data, &ddr->ptr);
        ddr->prop = RNA_struct_find_property(&ddr->ptr, "dof_distance");
        ddr->is_undo = true;
      }
    }
  }
  else {
    ddr->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
  }

  if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) ||
      (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
      (RNA_property_type(ddr->prop) != PROP_FLOAT)) {
    MEM_freeN(ddr);
    return false;
  }
  op->customdata = ddr;

  ddr->art = art;
  ddr->draw_handle_pixel = ED_region_draw_cb_activate(
      art, depthdropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);
  ddr->init_depth = RNA_property_float_get(&ddr->ptr, ddr->prop);

  return true;
}
Esempio n. 12
0
void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac)
{
	DLRBT_Tree keys, blocks;

	bool locked = (act && ID_IS_LINKED(act));

	BLI_dlrbTree_init(&keys);
	BLI_dlrbTree_init(&blocks);

	action_to_keylist(adt, act, &keys, &blocks);

	BLI_dlrbTree_linkedlist_sync(&keys);
	BLI_dlrbTree_linkedlist_sync(&blocks);

	draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, locked);

	BLI_dlrbTree_free(&keys);
	BLI_dlrbTree_free(&blocks);
}
Esempio n. 13
0
void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local)
{
	bool is_local = false, is_lib = false;

	/* - only lib users: do nothing (unless force_local is set)
	 * - only local users: set flag
	 * - mixed: make copy
	 */

	if (!ID_IS_LINKED(brush)) {
		return;
	}

	if (brush->clone.image) {
		/* Special case: ima always local immediately. Clone image should only have one user anyway. */
		id_make_local(bmain, &brush->clone.image->id, false, false);
	}

	BKE_library_ID_test_usages(bmain, brush, &is_local, &is_lib);

	if (lib_local || is_local) {
		if (!is_lib) {
			id_clear_lib_data(bmain, &brush->id);
			BKE_id_expand_local(bmain, &brush->id);

			/* enable fake user by default */
			id_fake_user_set(&brush->id);
		}
		else {
			Brush *brush_new = BKE_brush_copy(bmain, brush);  /* Ensures FAKE_USER is set */

			brush_new->id.us = 0;

			/* setting newid is mandatory for complex make_lib_local logic... */
			ID_NEW_SET(brush, brush_new);

			if (!lib_local) {
				BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
			}
		}
	}
}
Esempio n. 14
0
void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac)
{
	DLRBT_Tree keys, blocks;

	bool locked = (agrp->flag & AGRP_PROTECTED) ||
	              ((adt && adt->action) && ID_IS_LINKED(adt->action));

	BLI_dlrbTree_init(&keys);
	BLI_dlrbTree_init(&blocks);

	agroup_to_keylist(adt, agrp, &keys, &blocks);

	BLI_dlrbTree_linkedlist_sync(&keys);
	BLI_dlrbTree_linkedlist_sync(&blocks);

	draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, locked);

	BLI_dlrbTree_free(&keys);
	BLI_dlrbTree_free(&blocks);
}
Esempio n. 15
0
void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac)
{
	DLRBT_Tree keys, blocks;

	bool locked = (fcu->flag & FCURVE_PROTECTED) ||
	              ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
	              ((adt && adt->action) && ID_IS_LINKED(adt->action));

	BLI_dlrbTree_init(&keys);
	BLI_dlrbTree_init(&blocks);

	fcurve_to_keylist(adt, fcu, &keys, &blocks);

	BLI_dlrbTree_linkedlist_sync(&keys);
	BLI_dlrbTree_linkedlist_sync(&blocks);

	draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, locked);

	BLI_dlrbTree_free(&keys);
	BLI_dlrbTree_free(&blocks);
}
Esempio n. 16
0
/**
 * Isolate the collection - hide all other collections but this one.
 * Make sure to show all the direct parents and all children of the layer collection as well.
 * When extending we simply show the collections and its direct family.
 *
 * If the collection or any of its parents is disabled, make it enabled.
 * Don't change the children disable state though.
 *
 * Return whether depsgraph needs update.
 */
bool BKE_layer_collection_isolate(Scene *scene,
                                  ViewLayer *view_layer,
                                  LayerCollection *lc,
                                  bool extend)
{
  bool depsgraph_need_update = false;
  LayerCollection *lc_master = view_layer->layer_collections.first;
  bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE);

  if ((!ID_IS_LINKED(lc->collection) && !hide_it)) {
    if (lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) {
      lc->collection->flag &= ~COLLECTION_RESTRICT_VIEWPORT;
      depsgraph_need_update = true;
    }
  }

  if (!extend) {
    /* Hide all collections . */
    for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter;
         lc_iter = lc_iter->next) {
      layer_collection_flag_set_recursive(lc_iter, LAYER_COLLECTION_HIDE);
    }
  }

  /* Make all the direct parents visible. */
  if (hide_it) {
    lc->flag |= LAYER_COLLECTION_HIDE;
  }
  else {
    LayerCollection *lc_parent = lc;
    for (LayerCollection *lc_iter = lc_master->layer_collections.first; lc_iter;
         lc_iter = lc_iter->next) {
      if (BKE_layer_collection_has_layer_collection(lc_iter, lc)) {
        lc_parent = lc_iter;
        break;
      }
    }

    while (lc_parent != lc) {
      if (!ID_IS_LINKED(lc_parent->collection)) {
        if (lc_parent->collection->flag & COLLECTION_RESTRICT_VIEWPORT) {
          lc_parent->collection->flag &= ~COLLECTION_RESTRICT_VIEWPORT;
          depsgraph_need_update = true;
        }
      }

      lc_parent->flag &= ~LAYER_COLLECTION_HIDE;

      for (LayerCollection *lc_iter = lc_parent->layer_collections.first; lc_iter;
           lc_iter = lc_iter->next) {
        if (BKE_layer_collection_has_layer_collection(lc_iter, lc)) {
          lc_parent = lc_iter;
          break;
        }
      }
    }

    /* Make all the children visible, but respect their disable state. */
    layer_collection_flag_unset_recursive(lc, LAYER_COLLECTION_HIDE);

    BKE_layer_collection_activate(view_layer, lc);
  }

  BKE_layer_collection_sync(scene, view_layer);

  return depsgraph_need_update;
}
Esempio n. 17
0
static bool shape_key_mode_poll(bContext *C)
{
  Object *ob = ED_object_context(C);
  ID *data = (ob) ? ob->data : NULL;
  return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT);
}
Esempio n. 18
0
static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event)
{
	wmWindow *win = CTX_wm_window(C);
	rctf viewborder;

	float upvec[3]; /* tmp */
	float mat[3][3];

	fly->rv3d = CTX_wm_region_view3d(C);
	fly->v3d = CTX_wm_view3d(C);
	fly->ar = CTX_wm_region(C);
	fly->scene = CTX_data_scene(C);

#ifdef NDOF_FLY_DEBUG
	puts("\n-- fly begin --");
#endif

	/* sanity check: for rare but possible case (if lib-linking the camera fails) */
	if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) {
		fly->rv3d->persp = RV3D_PERSP;
	}

	if (fly->rv3d->persp == RV3D_CAMOB && ID_IS_LINKED(fly->v3d->camera)) {
		BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
		return false;
	}

	if (ED_view3d_offset_lock_check(fly->v3d, fly->rv3d)) {
		BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view offset is locked");
		return false;
	}

	if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->constraints.first) {
		BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
		return false;
	}

	fly->state = FLY_RUNNING;
	fly->speed = 0.0f;
	fly->axis = 2;
	fly->pan_view = false;
	fly->xlock = FLY_AXISLOCK_STATE_OFF;
	fly->zlock = FLY_AXISLOCK_STATE_OFF;
	fly->xlock_momentum = 0.0f;
	fly->zlock_momentum = 0.0f;
	fly->grid = 1.0f;
	fly->use_precision = false;
	fly->use_freelook = false;

#ifdef NDOF_FLY_DRAW_TOOMUCH
	fly->redraw = 1;
#endif
	zero_v3(fly->dvec_prev);

	fly->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);

	copy_v2_v2_int(fly->mval, event->mval);

#ifdef WITH_INPUT_NDOF
	fly->ndof = NULL;
#endif

	fly->time_lastdraw = fly->time_lastwheel = PIL_check_seconds_timer();

	fly->draw_handle_pixel = ED_region_draw_cb_activate(fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL);

	fly->rv3d->rflag |= RV3D_NAVIGATING;

	/* detect whether to start with Z locking */
	copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
	copy_m3_m4(mat, fly->rv3d->viewinv);
	mul_m3_v3(mat, upvec);
	if (fabsf(upvec[2]) < 0.1f) {
		fly->zlock = FLY_AXISLOCK_STATE_IDLE;
	}

	fly->v3d_camera_control = ED_view3d_cameracontrol_acquire(
	        fly->scene, fly->v3d, fly->rv3d,
	        (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0);

	/* calculate center */
	if (fly->scene->camera) {
		ED_view3d_calc_camera_border(fly->scene, fly->ar, fly->v3d, fly->rv3d, &viewborder, false);

		fly->width = BLI_rctf_size_x(&viewborder);
		fly->height = BLI_rctf_size_y(&viewborder);

		fly->center_mval[0] = viewborder.xmin + fly->width / 2;
		fly->center_mval[1] = viewborder.ymin + fly->height / 2;
	}
	else {
		fly->width = fly->ar->winx;
		fly->height = fly->ar->winy;

		fly->center_mval[0] = fly->width / 2;
		fly->center_mval[1] = fly->height / 2;
	}

	/* center the mouse, probably the UI mafia are against this but without its quite annoying */
	WM_cursor_warp(win, fly->ar->winrct.xmin + fly->center_mval[0], fly->ar->winrct.ymin + fly->center_mval[1]);

	fly_update_header(C, op, fly);
	return 1;
}
Esempio n. 19
0
bool UI_context_copy_to_selected_list(bContext *C,
                                      PointerRNA *ptr,
                                      PropertyRNA *prop,
                                      ListBase *r_lb,
                                      bool *r_use_path_from_id,
                                      char **r_path)
{
  *r_use_path_from_id = false;
  *r_path = NULL;

  if (RNA_struct_is_a(ptr->type, &RNA_EditBone)) {
    *r_lb = CTX_data_collection_get(C, "selected_editable_bones");
  }
  else if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) {
    *r_lb = CTX_data_collection_get(C, "selected_pose_bones");
  }
  else if (RNA_struct_is_a(ptr->type, &RNA_Bone)) {
    ListBase lb;
    lb = CTX_data_collection_get(C, "selected_pose_bones");

    if (!BLI_listbase_is_empty(&lb)) {
      CollectionPointerLink *link;
      for (link = lb.first; link; link = link->next) {
        bPoseChannel *pchan = link->ptr.data;
        RNA_pointer_create(link->ptr.id.data, &RNA_Bone, pchan->bone, &link->ptr);
      }
    }

    *r_lb = lb;
  }
  else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
    *r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
  }
  else if (RNA_struct_is_a(ptr->type, &RNA_FCurve)) {
    *r_lb = CTX_data_collection_get(C, "selected_editable_fcurves");
  }
  else if (RNA_struct_is_a(ptr->type, &RNA_Node) || RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
    ListBase lb = {NULL, NULL};
    char *path = NULL;
    bNode *node = NULL;

    /* Get the node we're editing */
    if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
      bNodeTree *ntree = ptr->id.data;
      bNodeSocket *sock = ptr->data;
      if (nodeFindNode(ntree, sock, &node, NULL)) {
        if ((path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Node)) != NULL) {
          /* we're good! */
        }
        else {
          node = NULL;
        }
      }
    }
    else {
      node = ptr->data;
    }

    /* Now filter by type */
    if (node) {
      CollectionPointerLink *link, *link_next;
      lb = CTX_data_collection_get(C, "selected_nodes");

      for (link = lb.first; link; link = link_next) {
        bNode *node_data = link->ptr.data;
        link_next = link->next;

        if (node_data->type != node->type) {
          BLI_remlink(&lb, link);
          MEM_freeN(link);
        }
      }
    }

    *r_lb = lb;
    *r_path = path;
  }
  else if (ptr->id.data) {
    ID *id = ptr->id.data;

    if (GS(id->name) == ID_OB) {
      *r_lb = CTX_data_collection_get(C, "selected_editable_objects");
      *r_use_path_from_id = true;
      *r_path = RNA_path_from_ID_to_property(ptr, prop);
    }
    else if (OB_DATA_SUPPORT_ID(GS(id->name))) {
      /* check we're using the active object */
      const short id_code = GS(id->name);
      ListBase lb = CTX_data_collection_get(C, "selected_editable_objects");
      char *path = RNA_path_from_ID_to_property(ptr, prop);

      /* de-duplicate obdata */
      if (!BLI_listbase_is_empty(&lb)) {
        CollectionPointerLink *link, *link_next;

        for (link = lb.first; link; link = link->next) {
          Object *ob = link->ptr.id.data;
          if (ob->data) {
            ID *id_data = ob->data;
            id_data->tag |= LIB_TAG_DOIT;
          }
        }

        for (link = lb.first; link; link = link_next) {
          Object *ob = link->ptr.id.data;
          ID *id_data = ob->data;
          link_next = link->next;

          if ((id_data == NULL) || (id_data->tag & LIB_TAG_DOIT) == 0 || ID_IS_LINKED(id_data) ||
              (GS(id_data->name) != id_code)) {
            BLI_remlink(&lb, link);
            MEM_freeN(link);
          }
          else {
            /* avoid prepending 'data' to the path */
            RNA_id_pointer_create(id_data, &link->ptr);
          }

          if (id_data) {
            id_data->tag &= ~LIB_TAG_DOIT;
          }
        }
      }

      *r_lb = lb;
      *r_path = path;
    }
    else if (GS(id->name) == ID_SCE) {
      /* Sequencer's ID is scene :/ */
      /* Try to recursively find an RNA_Sequence ancestor,
       * to handle situations like T41062... */
      if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != NULL) {
        *r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
      }
    }
    return (*r_path != NULL);
  }
  else {
    return false;
  }

  return true;
}
Esempio n. 20
0
static bool shape_key_poll(bContext *C)
{
  Object *ob = ED_object_context(C);
  ID *data = (ob) ? ob->data : NULL;
  return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data));
}