Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/gpencil.c
| Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_gpencil.h" | #include "BKE_gpencil.h" | ||||
| static CLG_LogRef LOG = {"bke.gpencil"}; | static CLG_LogRef LOG = {"bke.gpencil"}; | ||||
| static void greasepencil_copy_data(Main *UNUSED(bmain), | static void greasepencil_copy_data(Main *UNUSED(bmain), | ||||
| ID *id_dst, | ID *id_dst, | ||||
| const ID *id_src, | const ID *id_src, | ||||
| const int UNUSED(flag)) | const int flag) | ||||
| { | { | ||||
| bGPdata *gpd_dst = (bGPdata *)id_dst; | bGPdata *gpd_dst = (bGPdata *)id_dst; | ||||
| const bGPdata *gpd_src = (const bGPdata *)id_src; | const bGPdata *gpd_src = (const bGPdata *)id_src; | ||||
| /* duplicate material array */ | /* duplicate material array */ | ||||
| if (gpd_src->mat) { | if (gpd_src->mat) { | ||||
| gpd_dst->mat = MEM_dupallocN(gpd_src->mat); | gpd_dst->mat = MEM_dupallocN(gpd_src->mat); | ||||
| } | } | ||||
| Show All 31 Lines | if (gpl_dst->actframe != NULL) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BLI_addtail(&gpd_dst->layers, gpl_dst); | BLI_addtail(&gpd_dst->layers, gpl_dst); | ||||
| } | } | ||||
| if (flag & LIB_ID_COPY_NO_PREVIEW) { | |||||
| gpd_dst->preview = NULL; | |||||
| } | |||||
| else { | |||||
| BKE_previewimg_id_copy(&gpd_dst->id, &gpd_src->id); | |||||
| } | |||||
| } | } | ||||
| static void greasepencil_free_data(ID *id) | static void greasepencil_free_data(ID *id) | ||||
| { | { | ||||
| /* Really not ideal, but for now will do... In theory custom behaviors like not freeing cache | /* Really not ideal, but for now will do... In theory custom behaviors like not freeing cache | ||||
| * should be handled through specific API, and not be part of the generic one. */ | * should be handled through specific API, and not be part of the generic one. */ | ||||
| BKE_gpencil_free_data((bGPdata *)id, true); | BKE_gpencil_free_data((bGPdata *)id, true); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { | ||||
| if (gps->editcurve != NULL) { | if (gps->editcurve != NULL) { | ||||
| bGPDcurve *gpc = gps->editcurve; | bGPDcurve *gpc = gps->editcurve; | ||||
| BLO_write_struct(writer, bGPDcurve, gpc); | BLO_write_struct(writer, bGPDcurve, gpc); | ||||
| BLO_write_struct_array( | BLO_write_struct_array( | ||||
| writer, bGPDcurve_point, gpc->tot_curve_points, gpc->curve_points); | writer, bGPDcurve_point, gpc->tot_curve_points, gpc->curve_points); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BKE_previewimg_blend_write(writer, gpd->preview); | |||||
| } | } | ||||
| } | } | ||||
| void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd) | void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd) | ||||
| { | { | ||||
| /* We must firstly have some grease-pencil data to link! */ | /* We must firstly have some grease-pencil data to link! */ | ||||
| if (gpd == NULL) { | if (gpd == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Relink anim-data. */ | /* Relink anim-data. */ | ||||
| BLO_read_data_address(reader, &gpd->adt); | BLO_read_data_address(reader, &gpd->adt); | ||||
| BKE_animdata_blend_read_data(reader, gpd->adt); | BKE_animdata_blend_read_data(reader, gpd->adt); | ||||
| /* Preview. */ | |||||
| BLO_read_data_address(reader, &gpd->preview); | |||||
| BKE_previewimg_blend_read(reader, gpd->preview); | |||||
| /* Ensure full objectmode for linked grease pencil. */ | /* Ensure full objectmode for linked grease pencil. */ | ||||
| if (ID_IS_LINKED(gpd)) { | if (ID_IS_LINKED(gpd)) { | ||||
| gpd->flag &= ~GP_DATA_STROKE_PAINTMODE; | gpd->flag &= ~GP_DATA_STROKE_PAINTMODE; | ||||
| gpd->flag &= ~GP_DATA_STROKE_EDITMODE; | gpd->flag &= ~GP_DATA_STROKE_EDITMODE; | ||||
| gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE; | gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE; | ||||
| gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE; | gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE; | ||||
| gpd->flag &= ~GP_DATA_STROKE_VERTEXMODE; | gpd->flag &= ~GP_DATA_STROKE_VERTEXMODE; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 286 Lines • ▼ Show 20 Lines | void BKE_gpencil_free_data(bGPdata *gpd, bool free_all) | ||||
| BKE_gpencil_free_update_cache(gpd); | BKE_gpencil_free_update_cache(gpd); | ||||
| /* free all data */ | /* free all data */ | ||||
| if (free_all) { | if (free_all) { | ||||
| /* clear cache */ | /* clear cache */ | ||||
| BKE_gpencil_batch_cache_free(gpd); | BKE_gpencil_batch_cache_free(gpd); | ||||
| } | } | ||||
| /* Preview. */ | |||||
| BKE_previewimg_free(&gpd->preview); | |||||
| } | } | ||||
| void BKE_gpencil_eval_delete(bGPdata *gpd_eval) | void BKE_gpencil_eval_delete(bGPdata *gpd_eval) | ||||
| { | { | ||||
| BKE_gpencil_free_data(gpd_eval, true); | BKE_gpencil_free_data(gpd_eval, true); | ||||
| BKE_libblock_free_data(&gpd_eval->id, false); | BKE_libblock_free_data(&gpd_eval->id, false); | ||||
| BLI_assert(!gpd_eval->id.py_instance); /* Or call #BKE_libblock_free_data_py. */ | BLI_assert(!gpd_eval->id.py_instance); /* Or call #BKE_libblock_free_data_py. */ | ||||
| MEM_freeN(gpd_eval); | MEM_freeN(gpd_eval); | ||||
| ▲ Show 20 Lines • Show All 1,686 Lines • ▼ Show 20 Lines | |||||
| int BKE_gpencil_object_material_index_get_by_name(Object *ob, const char *name) | int BKE_gpencil_object_material_index_get_by_name(Object *ob, const char *name) | ||||
| { | { | ||||
| short *totcol = BKE_object_material_len_p(ob); | short *totcol = BKE_object_material_len_p(ob); | ||||
| Material *read_ma = NULL; | Material *read_ma = NULL; | ||||
| for (short i = 0; i < *totcol; i++) { | for (short i = 0; i < *totcol; i++) { | ||||
| read_ma = BKE_object_material_get(ob, i + 1); | read_ma = BKE_object_material_get(ob, i + 1); | ||||
| /* Material names are like "MAMaterial.001" */ | /* Material names are like "MAMaterial.001" */ | ||||
| if (STREQ(name, &read_ma->id.name[2])) { | if ((read_ma) && (STREQ(name, &read_ma->id.name[2]))) { | ||||
| return i; | return i; | ||||
| } | } | ||||
| } | } | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| Material *BKE_gpencil_object_material_ensure_by_name(Main *bmain, | Material *BKE_gpencil_object_material_ensure_by_name(Main *bmain, | ||||
| ▲ Show 20 Lines • Show All 826 Lines • ▼ Show 20 Lines | void BKE_gpencil_update_on_write(bGPdata *gpd_orig, bGPdata *gpd_eval) | ||||
| BKE_gpencil_traverse_update_cache(update_cache, &ts, &data); | BKE_gpencil_traverse_update_cache(update_cache, &ts, &data); | ||||
| gpd_eval->flag |= GP_DATA_CACHE_IS_DIRTY; | gpd_eval->flag |= GP_DATA_CACHE_IS_DIRTY; | ||||
| /* TODO: This might cause issues when we have multiple depsgraphs? */ | /* TODO: This might cause issues when we have multiple depsgraphs? */ | ||||
| BKE_gpencil_free_update_cache(gpd_orig); | BKE_gpencil_free_update_cache(gpd_orig); | ||||
| } | } | ||||
| /* Get min and max frame number for all layers. */ | |||||
| void BKE_gpencil_frame_min_max(const bGPdata *gpd, int *r_min, int *r_max) | |||||
| { | |||||
| *r_min = INT_MAX; | |||||
| *r_max = INT_MIN; | |||||
| LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { | |||||
| LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { | |||||
| if (gpf->framenum < *r_min) { | |||||
| *r_min = gpf->framenum; | |||||
| } | |||||
| if (gpf->framenum > *r_max) { | |||||
| *r_max = gpf->framenum; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||