Advertisement
Guest User

Untitled

a guest
Mar 26th, 2014
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 13.16 KB | None | 0 0
  1. diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
  2. index 44a9885..3b675f2 100644
  3. --- a/source/blender/blenkernel/BKE_library.h
  4. +++ b/source/blender/blenkernel/BKE_library.h
  5. @@ -106,6 +106,10 @@ struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_
  6.  void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowManager *) );
  7.  void set_free_notifier_reference_cb(void (*func)(const void *) );
  8.  
  9. +/* Call a callback for each ID link which the given ID uses. */
  10. +typedef void (*LibraryIDLinkCallback) (void *user_data, struct ID *id);
  11. +void BKE_library_foreach_ID_link(struct ID *id, LibraryIDLinkCallback callback, void *user_data);
  12. +
  13.  /* use when "" is given to new_id() */
  14.  #define ID_FALLBACK_NAME N_("Untitled")
  15.  
  16. diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
  17. index f831378..d13899c 100644
  18. --- a/source/blender/blenkernel/intern/library.c
  19. +++ b/source/blender/blenkernel/intern/library.c
  20. @@ -46,6 +46,7 @@
  21.  #include "DNA_armature_types.h"
  22.  #include "DNA_brush_types.h"
  23.  #include "DNA_camera_types.h"
  24. +#include "DNA_constraint_types.h"
  25.  #include "DNA_group_types.h"
  26.  #include "DNA_gpencil_types.h"
  27.  #include "DNA_ipo_types.h"
  28. @@ -59,6 +60,7 @@
  29.  #include "DNA_mask_types.h"
  30.  #include "DNA_nla_types.h"
  31.  #include "DNA_node_types.h"
  32. +#include "DNA_object_force.h"
  33.  #include "DNA_scene_types.h"
  34.  #include "DNA_screen_types.h"
  35.  #include "DNA_speaker_types.h"
  36. @@ -80,6 +82,7 @@
  37.  #include "BKE_bpath.h"
  38.  #include "BKE_brush.h"
  39.  #include "BKE_camera.h"
  40. +#include "BKE_constraint.h"
  41.  #include "BKE_context.h"
  42.  #include "BKE_curve.h"
  43.  #include "BKE_depsgraph.h"
  44. @@ -101,6 +104,7 @@
  45.  #include "BKE_material.h"
  46.  #include "BKE_main.h"
  47.  #include "BKE_mball.h"
  48. +#include "BKE_modifier.h"
  49.  #include "BKE_movieclip.h"
  50.  #include "BKE_mask.h"
  51.  #include "BKE_node.h"
  52. @@ -113,6 +117,7 @@
  53.  #include "BKE_scene.h"
  54.  #include "BKE_text.h"
  55.  #include "BKE_texture.h"
  56. +#include "BKE_tracking.h"
  57.  #include "BKE_world.h"
  58.  
  59.  #include "RNA_access.h"
  60. @@ -1582,3 +1587,329 @@ void BKE_library_filepath_set(Library *lib, const char *filepath)
  61.         BLI_path_abs(lib->filepath, basepath);
  62.     }
  63.  }
  64. +
  65. +typedef struct LibraryForeachIDData {
  66. +   LibraryIDLinkCallback callback;
  67. +   void *user_data;
  68. +} LibraryForeachIDData;
  69. +
  70. +static void library_foreach_modifiersForeachIDLink(void *user_data, Object *UNUSED(object),
  71. +                                                   ID **id_pointer)
  72. +{
  73. +   if (*id_pointer) {
  74. +       LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
  75. +       data->callback(data->user_data, *id_pointer);
  76. +   }
  77. +}
  78. +
  79. +static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con), ID **id_pointer,
  80. +                                                   short UNUSED(isReference), void *user_data)
  81. +{
  82. +   if (*id_pointer) {
  83. +       LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
  84. +       data->callback(data->user_data, *id_pointer);
  85. +   }
  86. +}
  87. +
  88. +static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *adt)
  89. +{
  90. +   FCurve *fcu;
  91. +
  92. +   for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
  93. +       ChannelDriver *driver = fcu->driver;
  94. +       DriverVar *dvar;
  95. +
  96. +       for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
  97. +           /* only used targets */
  98. +           DRIVER_TARGETS_USED_LOOPER(dvar)
  99. +           {
  100. +               if (dtar->id) {
  101. +                   data->callback(data->user_data, dtar->id);
  102. +               }
  103. +           }
  104. +           DRIVER_TARGETS_LOOPER_END
  105. +       }
  106. +   }
  107. +}
  108. +
  109. +
  110. +static void library_foreach_mtex(LibraryForeachIDData *data, MTex *mtex)
  111. +{
  112. +   if (mtex->object) {
  113. +       data->callback(data->user_data, &mtex->object->id);
  114. +   }
  115. +   if (mtex->tex) {
  116. +       data->callback(data->user_data, &mtex->tex->id);
  117. +   }
  118. +}
  119. +
  120. +void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *user_data)
  121. +{
  122. +   AnimData *adt;
  123. +   LibraryForeachIDData data;
  124. +   int i;
  125. +
  126. +   /* callback wrapper that does NULL check */
  127. +#define CALLBACK_CHECK(user_data, id_test) \
  128. +   CHECK_TYPE(&(id_test)->id, ID *); \
  129. +   if (id_test) { \
  130. +       callback(user_data, &(id_test)->id); \
  131. +   } (void)0
  132. +
  133. +#define CALLBACK_CHECK_ID(user_data, id_test) \
  134. +   CHECK_TYPE(id_test, ID *); \
  135. +   if (id_test) { \
  136. +       callback(user_data, id_test); \
  137. +   } (void)0
  138. +
  139. +   data.callback = callback;
  140. +   data.user_data = user_data;
  141. +
  142. +   adt = BKE_animdata_from_id(id);
  143. +   if (adt) {
  144. +       library_foreach_animationData(&data, adt);
  145. +   }
  146. +
  147. +   switch (GS(id->name)) {
  148. +       case ID_OB:
  149. +       {
  150. +           Object *object = (Object *) id;
  151. +           CALLBACK_CHECK(user_data, object->parent);
  152. +           CALLBACK_CHECK(user_data, object->track);
  153. +           CALLBACK_CHECK(user_data, object->proxy);
  154. +           CALLBACK_CHECK(user_data, object->proxy_group);
  155. +           CALLBACK_CHECK(user_data, object->proxy_from);
  156. +           CALLBACK_CHECK(user_data, object->poselib);
  157. +
  158. +           for (i = 0; i < object->totcol; i++) {
  159. +               CALLBACK_CHECK(user_data, object->mat[i]);
  160. +           }
  161. +           CALLBACK_CHECK(user_data, object->gpd);
  162. +           CALLBACK_CHECK(user_data, object->dup_group);
  163. +           if (object->particlesystem.first) {
  164. +               ParticleSystem *particle_system;
  165. +               for (particle_system = object->particlesystem.first;
  166. +                    particle_system;
  167. +                    particle_system = particle_system->next)
  168. +               {
  169. +                   CALLBACK_CHECK(user_data, particle_system->target_ob);
  170. +                   CALLBACK_CHECK(user_data, particle_system->parent);
  171. +
  172. +               }
  173. +           }
  174. +
  175. +           modifiers_foreachIDLink(object,
  176. +                                   library_foreach_modifiersForeachIDLink,
  177. +                                   &data);
  178. +           BKE_id_loop_constraints(&object->constraints,
  179. +                                   library_foreach_constraintObjectLooper,
  180. +                                   &data);
  181. +           break;
  182. +       }
  183. +
  184. +       case ID_ME:
  185. +       {
  186. +           Mesh *mesh = (Mesh *) id;
  187. +
  188. +           CALLBACK_CHECK(user_data, mesh->texcomesh);
  189. +           CALLBACK_CHECK(user_data, mesh->key);
  190. +
  191. +           for (i = 0; i < mesh->totcol; i++) {
  192. +               CALLBACK_CHECK(user_data, mesh->mat[i]);
  193. +           }
  194. +           break;
  195. +       }
  196. +
  197. +       case ID_CU:
  198. +       {
  199. +           Curve *curve = (Curve *) id;
  200. +           CALLBACK_CHECK(user_data, curve->bevobj);
  201. +           CALLBACK_CHECK(user_data, curve->taperobj);
  202. +           CALLBACK_CHECK(user_data, curve->textoncurve);
  203. +           CALLBACK_CHECK(user_data, curve->key);
  204. +           for (i = 0; i < curve->totcol; i++) {
  205. +               CALLBACK_CHECK(user_data, curve->mat[i]);
  206. +           }
  207. +           CALLBACK_CHECK(user_data, curve->vfont);
  208. +           CALLBACK_CHECK(user_data, curve->vfontb);
  209. +           CALLBACK_CHECK(user_data, curve->vfonti);
  210. +           CALLBACK_CHECK(user_data, curve->vfontbi);
  211. +           break;
  212. +       }
  213. +
  214. +       case ID_MB:
  215. +       {
  216. +           MetaBall *metaball = (MetaBall *) id;
  217. +           for (i = 0; i < metaball->totcol; i++) {
  218. +               CALLBACK_CHECK(user_data, metaball->mat[i]);
  219. +           }
  220. +           break;
  221. +       }
  222. +
  223. +       case ID_MA:
  224. +       {
  225. +           Material *material = (Material *) id;
  226. +           for (i = 0; i < MAX_MTEX; i++) {
  227. +               if (material->mtex[i]) {
  228. +                   library_foreach_mtex(&data, material->mtex[i]);
  229. +               }
  230. +           }
  231. +           CALLBACK_CHECK(user_data, material->nodetree);
  232. +           CALLBACK_CHECK(user_data, material->group);
  233. +           break;
  234. +       }
  235. +
  236. +       case ID_TE:
  237. +       {
  238. +           Tex *texture = (Tex *) id;
  239. +           CALLBACK_CHECK(user_data, texture->nodetree);
  240. +           CALLBACK_CHECK(user_data, texture->ima);
  241. +           break;
  242. +       }
  243. +
  244. +       case ID_LT:
  245. +       {
  246. +           Lattice *lattice = (Lattice *) id;
  247. +           CALLBACK_CHECK(user_data, lattice->key);
  248. +           break;
  249. +       }
  250. +
  251. +       case ID_LA:
  252. +       {
  253. +           Lamp *lamp = (Lamp *) id;
  254. +           for (i = 0; i < MAX_MTEX; i++) {
  255. +               library_foreach_mtex(&data, lamp->mtex[i]);
  256. +           }
  257. +           CALLBACK_CHECK(user_data, lamp->nodetree);
  258. +           break;
  259. +       }
  260. +
  261. +       case ID_CA:
  262. +       {
  263. +           Camera *camera = (Camera *) id;
  264. +           CALLBACK_CHECK(user_data, camera->dof_ob);
  265. +           break;
  266. +       }
  267. +
  268. +       case ID_KE:
  269. +       {
  270. +           Key *key = (Key *) id;
  271. +           CALLBACK_CHECK_ID(user_data, key->from);
  272. +           break;
  273. +       }
  274. +
  275. +       case ID_WO:
  276. +       {
  277. +           World *world = (World *) id;
  278. +           for (i = 0; i < MAX_MTEX; i++) {
  279. +               if (world->mtex[i]) {
  280. +                   library_foreach_mtex(&data, world->mtex[i]);
  281. +               }
  282. +           }
  283. +           CALLBACK_CHECK(user_data, world->nodetree);
  284. +           break;
  285. +       }
  286. +
  287. +       case ID_SPK:
  288. +       {
  289. +           Speaker *speaker = (Speaker *) id;
  290. +           CALLBACK_CHECK(user_data, speaker->sound);
  291. +           break;
  292. +       }
  293. +
  294. +       case ID_GR:
  295. +       {
  296. +           Group *group = (Group *) id;
  297. +           GroupObject *group_object;
  298. +           for (group_object = group->gobject.first;
  299. +                group_object;
  300. +                group_object = group_object->next)
  301. +           {
  302. +               CALLBACK_CHECK(user_data, group_object->ob);
  303. +           }
  304. +           break;
  305. +       }
  306. +
  307. +       case ID_NT:
  308. +       {
  309. +           bNodeTree *ntree = (bNodeTree *) id;
  310. +           bNode *node;
  311. +           for (node = ntree->nodes.first; node; node = node->next) {
  312. +               if (node->id) {
  313. +                   callback(user_data, node->id);
  314. +               }
  315. +           }
  316. +           break;
  317. +       }
  318. +
  319. +       case ID_BR:
  320. +       {
  321. +           Brush *brush = (Brush *) id;
  322. +           CALLBACK_CHECK(user_data, brush->toggle_brush);
  323. +           library_foreach_mtex(&data, &brush->mtex);
  324. +           library_foreach_mtex(&data, &brush->mask_mtex);
  325. +           break;
  326. +       }
  327. +
  328. +       case ID_PA:
  329. +       {
  330. +           ParticleSettings *particle_settings = (ParticleSettings *) id;
  331. +           CALLBACK_CHECK(user_data, particle_settings->dup_group);
  332. +           CALLBACK_CHECK(user_data, particle_settings->dup_ob);
  333. +           CALLBACK_CHECK(user_data, particle_settings->bb_ob);
  334. +
  335. +           if (particle_settings->effector_weights) {
  336. +               CALLBACK_CHECK(user_data, particle_settings->effector_weights->group);
  337. +           }
  338. +           break;
  339. +       }
  340. +
  341. +       case ID_MC:
  342. +       {
  343. +           MovieClip *clip = (MovieClip *) id;
  344. +           MovieTracking *tracking = &clip->tracking;
  345. +           MovieTrackingObject *object;
  346. +           CALLBACK_CHECK(user_data, clip->gpd);
  347. +           for (object = tracking->objects.first;
  348. +                object;
  349. +                object = object->next)
  350. +           {
  351. +               ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
  352. +               MovieTrackingTrack *track;
  353. +               for (track = tracksbase->first;
  354. +                    track;
  355. +                    track = track->next)
  356. +               {
  357. +                   CALLBACK_CHECK(user_data, track->gpd);
  358. +               }
  359. +           }
  360. +           break;
  361. +       }
  362. +
  363. +       case ID_MSK:
  364. +       {
  365. +           Mask *mask = (Mask *) id;
  366. +           MaskLayer *mask_layer;
  367. +           for (mask_layer = mask->masklayers.first;
  368. +                mask_layer;
  369. +                mask_layer = mask_layer->next)
  370. +           {
  371. +               MaskSpline *mask_spline;
  372. +
  373. +               CALLBACK_CHECK_ID(user_data, mask_spline->parent.id);
  374. +
  375. +               for (mask_spline = mask_layer->splines.first;
  376. +                    mask_spline;
  377. +                    mask_spline = mask_spline->next)
  378. +               {
  379. +                   int i;
  380. +                   for (i = 0; i < mask_spline->tot_point; i++) {
  381. +                       MaskSplinePoint *point = &mask_spline->points[i];
  382. +                       CALLBACK_CHECK_ID(user_data, point->parent.id);
  383. +                   }
  384. +               }
  385. +           }
  386. +           break;
  387. +       }
  388. +   }
  389. +}
  390. diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
  391. index 5fd6fcf..7554155 100644
  392. --- a/source/blender/editors/object/object_relations.c
  393. +++ b/source/blender/editors/object/object_relations.c
  394. @@ -2080,6 +2080,53 @@ enum {
  395.     MAKE_LOCAL_ALL
  396.  };
  397.  
  398. +static void tag_localizable_looper(void *UNUSED(user_data), ID *id)
  399. +{
  400. +   id->flag &= ~LIB_DOIT;
  401. +}
  402. +
  403. +static void tag_localizable_objects(bContext *C, int mode)
  404. +{
  405. +   Main *bmain = CTX_data_main(C);
  406. +   Object *object;
  407. +
  408. +   BKE_main_id_tag_all(bmain, false);
  409. +
  410. +   /* Set LIB_DOIT flag for all selected objects, so next we can check whether
  411. +    * object is gonna to become local or not.
  412. +    */
  413. +   CTX_DATA_BEGIN (C, Object *, object, selected_objects)
  414. +   {
  415. +       object->id.flag |= LIB_DOIT;
  416. +
  417. +       /* If data is also gonna to become local, mark data we're interested in
  418. +        * as gonna-to-be-local.
  419. +        */
  420. +       if (mode == MAKE_LOCAL_SELECT_OBDATA) {
  421. +           ID *data_id = (ID *) object->data;
  422. +           data_id->flag |= LIB_DOIT;
  423. +       }
  424. +   }
  425. +   CTX_DATA_END;
  426. +
  427. +   /* Also forbid making objects local if other library objects are using
  428. +    * them for modifiers or constraints.
  429. +    */
  430. +   for (object = bmain->object.first; object; object = object->id.next) {
  431. +       if ((object->id.flag & LIB_DOIT) == 0) {
  432. +           BKE_library_foreach_ID_link(&object->id, tag_localizable_looper, NULL);
  433. +       }
  434. +       if (object->data) {
  435. +           ID *data_id = (ID *) object->data;
  436. +           if ((data_id->flag & LIB_DOIT) == 0) {
  437. +               BKE_library_foreach_ID_link(data_id, tag_localizable_looper, NULL);
  438. +           }
  439. +       }
  440. +   }
  441. +
  442. +   /* TODO(sergey): Drivers targets? */
  443. +}
  444. +
  445.  static int make_local_exec(bContext *C, wmOperator *op)
  446.  {
  447.     Main *bmain = CTX_data_main(C);
  448. @@ -2096,10 +2143,15 @@ static int make_local_exec(bContext *C, wmOperator *op)
  449.         return OPERATOR_FINISHED;
  450.     }
  451.  
  452. +   tag_localizable_objects(C, mode);
  453.     BKE_main_id_clear_newpoins(bmain);
  454.    
  455.     CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
  456.     {
  457. +       if ((ob->id.flag & LIB_DOIT) == 0) {
  458. +           continue;
  459. +       }
  460. +
  461.         if (ob->id.lib)
  462.             id_make_local(&ob->id, false);
  463.     }
  464. @@ -2116,6 +2168,10 @@ static int make_local_exec(bContext *C, wmOperator *op)
  465.  
  466.     CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
  467.     {
  468. +       if ((ob->id.flag & LIB_DOIT) == 0) {
  469. +           continue;
  470. +       }
  471. +
  472.         id = ob->data;
  473.            
  474.         if (id && (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL))) {
  475. @@ -2145,6 +2201,10 @@ static int make_local_exec(bContext *C, wmOperator *op)
  476.     if (mode == MAKE_LOCAL_SELECT_OBDATA_MATERIAL) {
  477.         CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
  478.         {
  479. +           if ((ob->id.flag & LIB_DOIT) == 0) {
  480. +               continue;
  481. +           }
  482. +
  483.             if (ob->type == OB_LAMP) {
  484.                 la = ob->data;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement