[Bf-blender-cvs] [b6a8d21be86] asset-greasepencil: GPencil: Remove Hash tables and use arrays
Antonio Vazquez
noreply at git.blender.org
Mon Jul 26 16:39:39 CEST 2021
Commit: b6a8d21be867387c7f06ca7c01c2d9b314c056be
Author: Antonio Vazquez
Date: Mon Jul 26 16:38:21 2021 +0200
Branches: asset-greasepencil
https://developer.blender.org/rBb6a8d21be867387c7f06ca7c01c2d9b314c056be
GPencil: Remove Hash tables and use arrays
Simplify the code and use an array instead to use several hash tables. This is faster and the code is more simple.
===================================================================
M source/blender/editors/gpencil/gpencil_asset.c
===================================================================
diff --git a/source/blender/editors/gpencil/gpencil_asset.c b/source/blender/editors/gpencil/gpencil_asset.c
index 141bdb12179..0de56228cd2 100644
--- a/source/blender/editors/gpencil/gpencil_asset.c
+++ b/source/blender/editors/gpencil/gpencil_asset.c
@@ -20,7 +20,6 @@
*/
#include "BLI_blenlib.h"
-#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -67,6 +66,15 @@
#define ROTATION_CONTROL_GAP 15.0f
+typedef struct tGPDAssetStroke {
+ bGPDlayer *gpl;
+ bGPDframe *gpf;
+ bGPDstroke *gps;
+ int slot_index;
+ bool is_new_gpl;
+ bool is_new_gpf;
+} tGPDAssetStroke;
+
/* Temporary Asset import operation data. */
typedef struct tGPDasset {
struct wmWindow *win;
@@ -129,19 +137,11 @@ typedef struct tGPDasset {
/** Vector with the original orientation for rotation. */
float vinit_rotation[2];
- /* All the hash below are used to keep a reference of the asset data inserted in the target
- * object. */
-
- /** Hash of new created layers. */
- struct GHash *asset_layers;
- /** Hash of new created frames. */
- struct GHash *asset_frames;
- /** Hash of new created strokes linked to frame. */
- struct GHash *asset_strokes_frame;
- /** Hash of new created strokes linked to layer. */
- struct GHash *asset_strokes_layer;
- /** Hash of new created materials. */
- struct GHash *asset_materials;
+ /* Data to keep a reference of the asset data inserted in the target object. */
+ /** Number of elements in data. */
+ int data_len;
+ /** Array of data with all strokes append. */
+ tGPDAssetStroke *data;
/** Handle for drawing while operator is running. */
void *draw_handle_3d;
@@ -458,10 +458,10 @@ static void gpencil_2d_cage_calc(tGPDasset *tgpa)
float cage_max[2];
INIT_MINMAX2(cage_min, cage_max);
- GHashIterator gh_iter;
- GHASH_ITER (gh_iter, tgpa->asset_strokes_layer) {
- bGPDstroke *gps = (bGPDstroke *)BLI_ghashIterator_getKey(&gh_iter);
- bGPDlayer *gpl = (bGPDlayer *)BLI_ghashIterator_getValue(&gh_iter);
+ for (int index = 0; index < tgpa->data_len; index++) {
+ tGPDAssetStroke *data = &tgpa->data[index];
+ bGPDstroke *gps = data->gps;
+ bGPDlayer *gpl = data->gpl;
BKE_gpencil_layer_transform_matrix_get(tgpa->depsgraph, tgpa->ob, gpl, diff_mat);
if (is_zero_v3(gps->boundbox_min)) {
@@ -793,9 +793,9 @@ static void gpencil_asset_transform_strokes(tGPDasset *tgpa,
gpencil_asset_rotation_matrix_get(angle, tgpa->cage_normal, rot_matrix);
/* Loop all strokes and apply transformation. */
- GHashIterator gh_iter;
- GHASH_ITER (gh_iter, tgpa->asset_strokes_frame) {
- bGPDstroke *gps = (bGPDstroke *)BLI_ghashIterator_getKey(&gh_iter);
+ for (int index = 0; index < tgpa->data_len; index++) {
+ tGPDAssetStroke *data = &tgpa->data[index];
+ bGPDstroke *gps = data->gps;
bGPDspoint *pt;
int i;
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
@@ -884,51 +884,49 @@ static void gpencil_asset_append_strokes(tGPDasset *tgpa)
float vec[3];
sub_v3_v3v3(vec, dest_pt, tgpa->ob->loc);
+ /* Count total of strokes. */
+ tgpa->data_len = 0;
+ LISTBASE_FOREACH (bGPDlayer *, gpl_asset, &gpd_asset->layers) {
+ LISTBASE_FOREACH (bGPDframe *, gpf_asset, &gpl_asset->frames) {
+ tgpa->data_len += BLI_listbase_count(&gpf_asset->strokes);
+ }
+ }
+ /* Alloc array of strokes. */
+ tgpa->data = MEM_calloc_arrayN(tgpa->data_len, sizeof(tGPDAssetStroke), __func__);
+ int data_index = 0;
+
LISTBASE_FOREACH (bGPDlayer *, gpl_asset, &gpd_asset->layers) {
/* Check if Layer is in target data block. */
bGPDlayer *gpl_target = BKE_gpencil_layer_get_by_name(gpd_target, gpl_asset->info, false);
+
+ bool is_new_gpl = false;
if (gpl_target == NULL) {
gpl_target = BKE_gpencil_layer_duplicate(gpl_asset, false, false);
BLI_assert(gpl_target != NULL);
BLI_listbase_clear(&gpl_target->frames);
BLI_addtail(&gpd_target->layers, gpl_target);
-
- /* Ensure layers hash is ready. */
- if (tgpa->asset_layers == NULL) {
- tgpa->asset_layers = BLI_ghash_ptr_new(__func__);
- }
-
- /* Add layer to the hash to remove it if the operator is canceled. */
- BLI_ghash_insert(tgpa->asset_layers, gpl_target, gpl_target);
+ is_new_gpl = true;
}
- gpl_target->actframe = NULL;
LISTBASE_FOREACH (bGPDframe *, gpf_asset, &gpl_asset->frames) {
/* Check if frame is in target layer. */
int fra = tgpa->cframe + (gpf_asset->framenum - 1);
- bGPDframe *gpf_target = BKE_gpencil_layer_frame_get(gpl_target, fra, GP_GETFRAME_USE_PREV);
-
- if ((gpf_target == NULL) || (gpf_target->framenum != fra)) {
- gpf_target = BKE_gpencil_layer_frame_get(gpl_target, fra, GP_GETFRAME_ADD_NEW);
- BLI_assert(gpf_target != NULL);
- BLI_listbase_clear(&gpf_target->strokes);
-
- /* Ensure frames hash is ready. */
- if (tgpa->asset_frames == NULL) {
- tgpa->asset_frames = BLI_ghash_ptr_new(__func__);
- }
-
- /* Add frame to the hash to remove it if the operator is canceled. */
- if (!BLI_ghash_haskey(tgpa->asset_frames, gpf_target)) {
- /* Add the hash key with a reference to the layer. */
- BLI_ghash_insert(tgpa->asset_frames, gpf_target, gpl_target);
+ bGPDframe *gpf_target = NULL;
+ /* Find a frame in same frame number. */
+ LISTBASE_FOREACH (bGPDframe *, gpf_find, &gpl_target->frames) {
+ if (gpf_find->framenum == fra) {
+ gpf_target = gpf_find;
+ break;
}
}
- /* Preapre hashes for strokes. */
- if (tgpa->asset_strokes_frame == NULL) {
- tgpa->asset_strokes_frame = BLI_ghash_ptr_new(__func__);
- tgpa->asset_strokes_layer = BLI_ghash_ptr_new(__func__);
+ bool is_new_gpf = false;
+ if (gpf_target == NULL) {
+ gpf_target = BKE_gpencil_frame_addnew(gpl_target, fra);
+ gpl_target->actframe = gpf_target;
+ BLI_assert(gpf_target != NULL);
+ BLI_listbase_clear(&gpf_target->strokes);
+ is_new_gpf = true;
}
/* Loop all strokes and duplicate. */
@@ -944,14 +942,12 @@ static void gpencil_asset_append_strokes(tGPDasset *tgpa)
int mat_index = BKE_gpencil_object_material_index_get_by_name(tgpa->ob,
ma_src->id.name + 2);
+ bool is_new_mat = false;
if (mat_index == -1) {
- if (tgpa->asset_materials == NULL) {
- tgpa->asset_materials = BLI_ghash_ptr_new(__func__);
- }
const int totcolors = tgpa->ob->totcol;
mat_index = BKE_gpencil_object_material_ensure(tgpa->bmain, tgpa->ob, ma_src);
if (tgpa->ob->totcol > totcolors) {
- BLI_ghash_insert(tgpa->asset_materials, ma_src, POINTER_FROM_INT(mat_index + 1));
+ is_new_mat = true;
}
}
@@ -968,9 +964,19 @@ static void gpencil_asset_append_strokes(tGPDasset *tgpa)
/* Calc stroke bounding box. */
BKE_gpencil_stroke_boundingbox_calc(gps_target);
- /* Add the hash key with a reference by frame and layer. */
- BLI_ghash_insert(tgpa->asset_strokes_frame, gps_target, gpf_target);
- BLI_ghash_insert(tgpa->asset_strokes_layer, gps_target, gpl_target);
+ /* Add the reference to the stroke. */
+ tGPDAssetStroke *data = &tgpa->data[data_index];
+ data->gpl = gpl_target;
+ data->gpf = gpf_target;
+ data->gps = gps_target;
+ data->is_new_gpl = is_new_gpl;
+ data->is_new_gpf = is_new_gpf;
+ data->slot_index = (is_new_mat) ? gps_target->mat_nr + 1 : -1;
+ data_index++;
+
+ /* Reset flags. */
+ is_new_gpl = false;
+ is_new_gpf = false;
}
}
}
@@ -984,42 +990,38 @@ static void gpencil_asset_append_strokes(tGPDasset *tgpa)
/* Helper: Clean any temp added data when the operator is canceled. */
static void gpencil_asset_clean_temp_data(tGPDasset *tgpa)
{
- GHashIterator gh_iter;
- /* Clean Strokes. */
- if (tgpa->asset_strokes_frame != NULL) {
- GHASH_ITER (gh_iter, tgpa->asset_strokes_frame) {
- bGPDstroke *gps = (bGPDstroke *)BLI_ghashIterator_getKey(&gh_iter);
- bGPDframe *gpf = (bGPDframe *)BLI_ghashIterator_getValue(&gh_iter);
- BLI_remlink(&gpf->strokes, gps);
- BKE_gpencil_free_stroke(gps);
+ /* Clean Strokes and materials. */
+ int actcol = tgpa->ob->actcol;
+ for (int index = 0; index < tgpa->data_len; index++) {
+ tGPDAssetStroke *data = &tgpa->data[index];
+ bGPDstroke *gps = data->gps;
+ bGPDframe *gpf = data->gpf;
+ BLI_remlink(&gpf->strokes, gps);
+ BKE_gpencil_free_stroke(gps);
+ if (data->slot_index >= 0) {
+ tgpa->ob->actcol = data->slot_index;
+ BKE_object_material_slot_remove(tgpa->bmain, tgpa->ob);
}
}
+ tgpa->ob->actcol = (actcol > tgpa->ob->totcol) ? tgpa->ob->totcol : actcol;
+
/* Clean Frames. */
- if (tgpa->asset_frames != NULL) {
- GHASH_ITER (gh_iter, tgpa->asset_frames) {
- bGPDframe *gpf = (bGPDframe *)BLI_ghashIterator_getKey(&gh_iter);
- bGPDlayer *gpl = (bGPDlayer *)BLI_ghashIterator_getValue(&gh_iter);
- BLI_remlink(&gpl->frames, gpf);
+ for (int index = 0; index < tgpa->data_len; index++) {
+ tGPDAssetStroke *data = &tgpa->data[index];
+ if (data->is_new_gpf) {
+ bGPDframe *gpf = data->gpf;
+ bGPDlayer *gpl = data->gpl;
+ BLI_freelinkN(&gpl->frames, gpf);
}
}
/* Clean Layers. */
- if (tgpa->asset_layers != NULL) {
- GHASH_ITER (gh_iter, tgpa->asset_layers) {
- bGPDlayer *gpl = (bGPDlayer *)BLI_ghashIterator_getKey(&gh_iter);
+ for (int index = 0; index < tgpa->data_len; index++) {
+ tGPDAssetStroke *data = &tgpa->data[index];
+ if (data->is_new_gpl) {
+ bGPDlayer *gpl = data->gpl;
BKE_gpencil_layer_delete(tgpa->gpd, gpl);
}
}
- /* Clean Materials. */
- if (tgpa->asset_materials != NULL) {
- int actcol = tgpa->ob->actcol;
- GHASH_ITER (gh_iter, tgpa->asset_materials) {
- const int slot = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
- tgpa->ob->actcol = slot;
- BKE_object
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list