diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2021-07-20 19:02:06 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2021-07-20 19:02:06 +0300 |
commit | a41bef88abd3d873a080423481a5557d54a7ce24 (patch) | |
tree | b228ad807d1bb114e3248a6177f75206c246275e /source/blender | |
parent | 17863303bc4711da57834a20d5d854ced6474197 (diff) |
GPencil: Cleanup of function names, variables and comments
Also some code reorganization.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_asset.c | 587 |
1 files changed, 285 insertions, 302 deletions
diff --git a/source/blender/editors/gpencil/gpencil_asset.c b/source/blender/editors/gpencil/gpencil_asset.c index 85c7a6e7b33..96fc91f6a0d 100644 --- a/source/blender/editors/gpencil/gpencil_asset.c +++ b/source/blender/editors/gpencil/gpencil_asset.c @@ -13,9 +13,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * The Original Code is Copyright (C) 2021, Blender Foundation - * This is a new part of Blender - * Operators for editing Grease Pencil strokes */ /** \file @@ -108,36 +105,40 @@ typedef struct tGPDasset { rctf rect_cage; /** 2D cage center. */ float cage_center[2]; - /** Transform centerr. */ + /** Normal vector for cage. */ + float cage_normal[3]; + /** Transform center. */ float transform_center[2]; + /** 2D cage manipulator points * * - * 8 9 (Rotation) + * NW-R NE-R (Rotation) * \ / - * 0----1----2 - * | | - * 7 3 - * | | - * 6----5----4 + * NW----N----NE + * | | + * W E + * | | + * SW----S----SE * / \ - * 11 10 + * SW-R SE-R */ float manipulator[12][2]; /** Manipulator index (-1 means not set). */ int manipulator_index; /** Manipulator vector used to determine the effect. */ float manipulator_vector[3]; - /** Normal vector for cage. */ - float normal_vec[3]; /** 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. */ - struct GHash *asset_strokes; + /** 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. */ @@ -318,8 +319,8 @@ void GPENCIL_OT_asset_create(wmOperatorType *ot) RNA_def_boolean(ot->srna, "reset_origin", 1, - "Reset Origin to Strokes", - "Set origin of the strokes in the center of the bounding box"); + "Reset Origin to Geometry", + "Set origin of the asset in the center of the strokes bounding box"); } /** \} */ @@ -336,177 +337,6 @@ static void gpencil_asset_import_update_strokes(bContext *C, tGPDasset *tgpa) WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); } -/* Helper: Draw status message while the user is running the operator */ -static void gpencil_asset_import_status_indicators(bContext *C, tGPDasset *tgpa) -{ - char status_str[UI_MAX_DRAW_STR]; - char msg_str[UI_MAX_DRAW_STR]; - bGPdata *gpd_asset = tgpa->gpd_asset; - const char *mode_txt[] = {"", "(Location)", "(Rotation)", "(Scale)"}; - - BLI_strncpy(msg_str, TIP_("Importing Asset"), UI_MAX_DRAW_STR); - - BLI_snprintf(status_str, - sizeof(status_str), - "%s %s %s", - msg_str, - gpd_asset->id.name + 2, - mode_txt[tgpa->mode]); - - ED_area_status_text(tgpa->area, status_str); - ED_workspace_status_text( - C, TIP_("ESC/RMB to cancel, Enter/LMB(outside cage) to confirm, Shift to Scale uniform")); -} - -/* Update screen and stroke */ -static void gpencil_asset_import_update(bContext *C, wmOperator *op, tGPDasset *tgpa) -{ - /* Update shift indicator in header. */ - gpencil_asset_import_status_indicators(C, tgpa); - /* Update points position. */ - gpencil_asset_import_update_strokes(C, tgpa); -} - -/* ----------------------- */ - -/* Exit and free memory */ -static void gpencil_asset_import_exit(bContext *C, wmOperator *op) -{ - tGPDasset *tgpa = op->customdata; - bGPdata *gpd = tgpa->gpd; - - /* don't assume that operator data exists at all */ - if (tgpa) { - /* clear status message area */ - ED_area_status_text(tgpa->area, NULL); - ED_workspace_status_text(C, NULL); - - /* Clear any temp stroke. */ - // TODO - - /* Free Hash tablets. */ - if (tgpa->asset_layers != NULL) { - BLI_ghash_free(tgpa->asset_layers, NULL, NULL); - } - if (tgpa->asset_frames != NULL) { - BLI_ghash_free(tgpa->asset_frames, NULL, NULL); - } - if (tgpa->asset_strokes != NULL) { - BLI_ghash_free(tgpa->asset_strokes, NULL, NULL); - BLI_ghash_free(tgpa->asset_strokes_layer, NULL, NULL); - } - - if (tgpa->asset_materials != NULL) { - BLI_ghash_free(tgpa->asset_materials, NULL, NULL); - } - - /* Remove drawing handler. */ - if (tgpa->draw_handle_3d) { - ED_region_draw_cb_exit(tgpa->region->type, tgpa->draw_handle_3d); - } - - MEM_SAFE_FREE(tgpa); - } - DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); - - /* clear pointer */ - op->customdata = NULL; -} - -/* Init new temporary interpolation data */ -static bool gpencil_asset_import_set_init_values(bContext *C, - wmOperator *op, - ID *id, - tGPDasset *tgpa) -{ - /* Save current settings. */ - tgpa->win = CTX_wm_window(C); - tgpa->bmain = CTX_data_main(C); - tgpa->depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - tgpa->scene = CTX_data_scene(C); - tgpa->area = CTX_wm_area(C); - tgpa->region = CTX_wm_region(C); - tgpa->rv3d = CTX_wm_region_view3d(C); - tgpa->ob = CTX_data_active_object(C); - - /* Setup space conversions data. */ - gpencil_point_conversion_init(C, &tgpa->gsc); - - /* Save current frame number. */ - tgpa->cframe = tgpa->scene->r.cfra; - - /* Target GP datablock. */ - tgpa->gpd = tgpa->ob->data; - /* Asset GP datablock. */ - tgpa->gpd_asset = (bGPdata *)id; - - tgpa->mode = GP_ASSET_TRANSFORM_LOC; - tgpa->flag |= GP_ASSET_FLAG_IDLE; - - /* Manipulator point is not set yet. */ - tgpa->manipulator_index = -1; - - tgpa->asset_layers = NULL; - tgpa->asset_frames = NULL; - tgpa->asset_strokes = NULL; - tgpa->asset_strokes_layer = NULL; - tgpa->asset_materials = NULL; - - return true; -} - -/* Allocate memory and initialize values */ -static tGPDasset *gpencil_session_init_asset_import(bContext *C, wmOperator *op) -{ - Main *bmain = CTX_data_main(C); - ID *id = NULL; - - PropertyRNA *prop_name = RNA_struct_find_property(op->ptr, "name"); - PropertyRNA *prop_type = RNA_struct_find_property(op->ptr, "type"); - - /* These shouldn't fail when created by outliner dropping as it checks the ID is valid. */ - if (!RNA_property_is_set(op->ptr, prop_name) || !RNA_property_is_set(op->ptr, prop_type)) { - return NULL; - } - const short id_type = RNA_property_enum_get(op->ptr, prop_type); - char name[MAX_ID_NAME - 2]; - RNA_property_string_get(op->ptr, prop_name, name); - id = BKE_libblock_find_name(bmain, id_type, name); - if (id == NULL) { - return NULL; - } - const int object_type = BKE_object_obdata_to_type(id); - if (object_type == -1) { - return NULL; - } - - tGPDasset *tgpa = MEM_callocN(sizeof(tGPDasset), "GPencil Asset Import Data"); - - /* Save initial values. */ - gpencil_asset_import_set_init_values(C, op, id, tgpa); - - /* return context data for running operator */ - return tgpa; -} - -/* Init interpolation: Allocate memory and set init values */ -static int gpencil_asset_import_init(bContext *C, wmOperator *op) -{ - tGPDasset *tgpa; - - /* check context */ - tgpa = op->customdata = gpencil_session_init_asset_import(C, op); - if (tgpa == NULL) { - /* something wasn't set correctly in context */ - gpencil_asset_import_exit(C, op); - return 0; - } - - /* everything is now setup ok */ - return 1; -} - /* Helper: Compute 2D cage size in screen pixels. */ static void gpencil_2d_cage_calc(tGPDasset *tgpa) { @@ -592,9 +422,85 @@ static void gpencil_2d_cage_calc(tGPDasset *tgpa) gpencil_point_xy_to_3d(&tgpa->gsc, tgpa->scene, tgpa->manipulator[CAGE_CORNER_SW], co3); sub_v3_v3v3(vec1, co2, co1); sub_v3_v3v3(vec2, co3, co2); + /* Vector orthogonal to polygon plane. */ - cross_v3_v3v3(tgpa->normal_vec, vec1, vec2); - normalize_v3(tgpa->normal_vec); + cross_v3_v3v3(tgpa->cage_normal, vec1, vec2); + normalize_v3(tgpa->cage_normal); +} + +/* Draw a cage for manipulate asset */ +static void gpencil_2d_cage_draw(tGPDasset *tgpa) +{ + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + GPU_blend(GPU_BLEND_ALPHA); + + /* Draw dash box. */ + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); + GPU_line_width(1.0f); + + float viewport_size[4]; + GPU_viewport_size_get_f(viewport_size); + immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); + + immUniform1i("colors_len", 0); /* "simple" mode */ + immUniform1f("dash_width", 6.0f); + immUniform1f("dash_factor", 0.5f); + + float box_color[4]; + UI_GetThemeColor4fv(TH_VERTEX_SELECT, box_color); + immUniformColor4fv(box_color); + + immBegin(GPU_PRIM_LINE_LOOP, 4); + immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_NW][0], tgpa->manipulator[CAGE_CORNER_NW][1]); + immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_NE][0], tgpa->manipulator[CAGE_CORNER_NE][1]); + immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_SE][0], tgpa->manipulator[CAGE_CORNER_SE][1]); + immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_SW][0], tgpa->manipulator[CAGE_CORNER_SW][1]); + immEnd(); + + /* Rotation box */ + const float gap = 2.0f; + for (int i = 0; i < 4; i++) { + imm_draw_box_wire_2d(pos, + tgpa->manipulator[CAGE_CORNER_ROT_NW + i][0] - gap, + tgpa->manipulator[CAGE_CORNER_ROT_NW + i][1] - gap, + tgpa->manipulator[CAGE_CORNER_ROT_NW + i][0] + gap, + tgpa->manipulator[CAGE_CORNER_ROT_NW + i][1] + gap); + } + + /* Draw a line while is doing a transform. */ + if ((tgpa->flag & GP_ASSET_FLAG_TRANSFORMING) && (tgpa->mode == GP_ASSET_TRANSFORM_ROT)) { + const float line_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + immUniformColor4fv(line_color); + immBegin(GPU_PRIM_LINES, 2); + immVertex2f(pos, tgpa->transform_center[0], tgpa->transform_center[1]); + immVertex2f(pos, tgpa->mouse[0], tgpa->mouse[1]); + immEnd(); + } + + immUnbindProgram(); + + /* Draw Points. */ + GPU_program_point_size(true); + + immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); + + float point_color[4]; + UI_GetThemeColor4fv(TH_SELECT, point_color); + immUniformColor4fv(point_color); + + immUniform1f("size", UI_GetThemeValuef(TH_VERTEX_SIZE) * 1.5f * U.dpi_fac); + + immBegin(GPU_PRIM_POINTS, 8); + for (int i = 0; i < 8; i++) { + immVertex2fv(pos, tgpa->manipulator[i]); + } + immEnd(); + immUnbindProgram(); + GPU_program_point_size(false); + + GPU_blend(GPU_BLEND_NONE); } /* Helper: Detect mouse over cage areas. */ @@ -602,7 +508,7 @@ static void gpencil_2d_cage_area_detect(tGPDasset *tgpa, const int mouse[2]) { const float gap = 5.0f; - /* Check if over any of the corners for scale with a small gap. */ + /* Check if mouse is over any of the manipualtor points with a small gap. */ rctf rect_mouse = { (float)mouse[0] - gap, (float)mouse[0] + gap, (float)mouse[1] - gap, (float)mouse[1] + gap}; @@ -614,6 +520,7 @@ static void gpencil_2d_cage_area_detect(tGPDasset *tgpa, const int mouse[2]) tgpa->mode = (tgpa->manipulator_index < 8) ? GP_ASSET_TRANSFORM_SCALE : GP_ASSET_TRANSFORM_ROT; + /* For rotation don't need to do more. */ if (tgpa->mode == GP_ASSET_TRANSFORM_ROT) { WM_cursor_modal_set(tgpa->win, WM_CURSOR_HAND); return; @@ -637,6 +544,7 @@ static void gpencil_2d_cage_area_detect(tGPDasset *tgpa, const int mouse[2]) default: break; } + /* Determine the vector of the cage effect. For corners is always full effect. */ if (ELEM(tgpa->manipulator_index, CAGE_CORNER_NW, @@ -663,7 +571,7 @@ static void gpencil_2d_cage_area_detect(tGPDasset *tgpa, const int mouse[2]) } } - /* Check if mouse is inside cage for Location. */ + /* Check if mouse is inside cage for Location transform. */ if (BLI_rctf_isect_pt(&tgpa->rect_cage, (float)mouse[0], (float)mouse[1])) { tgpa->mode = GP_ASSET_TRANSFORM_LOC; WM_cursor_modal_set(tgpa->win, WM_CURSOR_DEFAULT); @@ -679,9 +587,9 @@ static void gpencil_asset_rotation_matrix_get(float angle, float axis[3], float rotation_matrix[4][4]) { - float u2 = axis[0] * axis[0]; - float v2 = axis[1] * axis[1]; - float w2 = axis[2] * axis[2]; + const float u2 = axis[0] * axis[0]; + const float v2 = axis[1] * axis[1]; + const float w2 = axis[2] * axis[2]; const float length = (u2 + v2 + w2); const float length_sqr = sqrt(length); const float cos_value = cos(angle); @@ -720,7 +628,7 @@ static void gpencil_asset_rotation_matrix_get(float angle, rotation_matrix[3][3] = 1.0f; } -/* Helper: Transfrom the stroke with mouse movements. */ +/* Helper: Transform the stroke with mouse movements. */ static void gpencil_asset_transform_strokes(tGPDasset *tgpa, const int mouse[2], const bool shift_key) @@ -774,10 +682,11 @@ static void gpencil_asset_transform_strokes(tGPDasset *tgpa, sub_v2_v2v2(vr, vr, tgpa->transform_center); normalize_v2(vr); float angle = angle_signed_v2v2(tgpa->vinit_rotation, vr); - gpencil_asset_rotation_matrix_get(angle, tgpa->normal_vec, rot_matrix); + 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) { + GHASH_ITER (gh_iter, tgpa->asset_strokes_frame) { bGPDstroke *gps = (bGPDstroke *)BLI_ghashIterator_getKey(&gh_iter); bGPDspoint *pt; int i; @@ -815,7 +724,7 @@ static void gpencil_asset_transform_strokes(tGPDasset *tgpa, } } - /* In scale mode recal geometry. */ + /* In scale mode recal stroke geometry because fill triangulation can change. */ if (tgpa->mode == GP_ASSET_TRANSFORM_SCALE) { BKE_gpencil_stroke_geometry_update(tgpa->gpd, gps); } @@ -830,12 +739,13 @@ static void gpencil_asset_transform_strokes(tGPDasset *tgpa, add_v3_v3(tgpa->asset_center, vec); } - /* Update mouse position and transform data to avoid acumulation. */ + /* Update mouse position and transform data to avoid acumulation for next transformation. */ copy_v2_v2_int(tgpa->mouse, mouse); tgpa->initial_dist = dist; copy_v2_v2(tgpa->vinit_rotation, vr); } +/* Helper: Get a material from the datablock */ static Material *gpencil_asset_material_get_from_id(ID *id, const int slot_index) { const short *tot_slots_data_ptr = BKE_id_material_len_p(id); @@ -851,7 +761,7 @@ static Material *gpencil_asset_material_get_from_id(ID *id, const int slot_index return material; } -/* Helper: Load all strokes in the target datablock. */ +/* Helper: Add all strokes from the asset in the target datablock. */ static void gpencil_asset_add_strokes(tGPDasset *tgpa) { bGPdata *gpd_target = tgpa->gpd; @@ -877,7 +787,7 @@ static void gpencil_asset_add_strokes(tGPDasset *tgpa) if (tgpa->asset_layers == NULL) { tgpa->asset_layers = BLI_ghash_ptr_new(__func__); } - /* Add to the hash to remove if operator is canceled. */ + /* Add layer to the hash to remove if operator is canceled. */ BLI_ghash_insert(tgpa->asset_layers, gpl_target, gpl_target); } @@ -893,15 +803,15 @@ static void gpencil_asset_add_strokes(tGPDasset *tgpa) if (tgpa->asset_frames == NULL) { tgpa->asset_frames = BLI_ghash_ptr_new(__func__); } - /* Add to the hash to remove if operator is canceled. */ + /* Add frame to the hash to remove if 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); } } /* Loop all strokes and duplicate. */ - if (tgpa->asset_strokes == NULL) { - tgpa->asset_strokes = BLI_ghash_ptr_new(__func__); + if (tgpa->asset_strokes_frame == NULL) { + tgpa->asset_strokes_frame = BLI_ghash_ptr_new(__func__); tgpa->asset_strokes_layer = BLI_ghash_ptr_new(__func__); } @@ -940,25 +850,26 @@ static void gpencil_asset_add_strokes(tGPDasset *tgpa) /* Update geometry. */ BKE_gpencil_stroke_geometry_update(gpd_target, gps_target); - /* Add the hash key with a reference to the frame. */ - BLI_ghash_insert(tgpa->asset_strokes, gps_target, gpf_target); + /* Add the hash key with a reference to the 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); } } } + /* Prepare 2D cage. */ gpencil_2d_cage_calc(tgpa); BKE_gpencil_centroid_3d(tgpa->gpd_asset, tgpa->asset_center); add_v3_v3(tgpa->asset_center, vec); } -/* Helper: Clean any temp data. */ -static void gpencil_asset_clean_data(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 != NULL) { - GHASH_ITER (gh_iter, tgpa->asset_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); @@ -993,79 +904,170 @@ static void gpencil_asset_clean_data(tGPDasset *tgpa) } } -/* Draw a cage for manipulate asset */ -static void gpencil_draw_cage(tGPDasset *tgpa) +/* Helper: Draw status message while the user is running the operator. */ +static void gpencil_asset_import_status_indicators(bContext *C, tGPDasset *tgpa) { - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + char status_str[UI_MAX_DRAW_STR]; + char msg_str[UI_MAX_DRAW_STR]; + bGPdata *gpd_asset = tgpa->gpd_asset; + const char *mode_txt[] = {"", "(Location)", "(Rotation)", "(Scale)"}; - GPU_blend(GPU_BLEND_ALPHA); + BLI_strncpy(msg_str, TIP_("Importing Asset"), UI_MAX_DRAW_STR); - /* Draw dash box. */ - immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); - GPU_line_width(1.0f); + BLI_snprintf(status_str, + sizeof(status_str), + "%s %s %s", + msg_str, + gpd_asset->id.name + 2, + mode_txt[tgpa->mode]); - float viewport_size[4]; - GPU_viewport_size_get_f(viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); + ED_area_status_text(tgpa->area, status_str); + ED_workspace_status_text( + C, TIP_("ESC/RMB to cancel, Enter/LMB(outside cage) to confirm, Shift to Scale uniform")); +} - immUniform1i("colors_len", 0); /* "simple" mode */ - immUniform1f("dash_width", 6.0f); - immUniform1f("dash_factor", 0.5f); +/* Update screen and stroke. */ +static void gpencil_asset_import_update(bContext *C, wmOperator *op, tGPDasset *tgpa) +{ + /* Update shift indicator in header. */ + gpencil_asset_import_status_indicators(C, tgpa); + /* Update points position. */ + gpencil_asset_import_update_strokes(C, tgpa); +} - float box_color[4]; - UI_GetThemeColor4fv(TH_VERTEX_SELECT, box_color); - immUniformColor4fv(box_color); +/* ----------------------- */ - immBegin(GPU_PRIM_LINE_LOOP, 4); - immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_NW][0], tgpa->manipulator[CAGE_CORNER_NW][1]); - immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_NE][0], tgpa->manipulator[CAGE_CORNER_NE][1]); - immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_SE][0], tgpa->manipulator[CAGE_CORNER_SE][1]); - immVertex2f(pos, tgpa->manipulator[CAGE_CORNER_SW][0], tgpa->manipulator[CAGE_CORNER_SW][1]); - immEnd(); +/* Exit and free memory */ +static void gpencil_asset_import_exit(bContext *C, wmOperator *op) +{ + tGPDasset *tgpa = op->customdata; + bGPdata *gpd = tgpa->gpd; - /* Rotation box */ - const float gap = 2.0f; - for (int i = 0; i < 4; i++) { - imm_draw_box_wire_2d(pos, - tgpa->manipulator[CAGE_CORNER_ROT_NW + i][0] - gap, - tgpa->manipulator[CAGE_CORNER_ROT_NW + i][1] - gap, - tgpa->manipulator[CAGE_CORNER_ROT_NW + i][0] + gap, - tgpa->manipulator[CAGE_CORNER_ROT_NW + i][1] + gap); + if (tgpa) { + /* Clear status message area. */ + ED_area_status_text(tgpa->area, NULL); + ED_workspace_status_text(C, NULL); + + /* Free Hash tablets. */ + if (tgpa->asset_layers != NULL) { + BLI_ghash_free(tgpa->asset_layers, NULL, NULL); + } + if (tgpa->asset_frames != NULL) { + BLI_ghash_free(tgpa->asset_frames, NULL, NULL); + } + if (tgpa->asset_strokes_frame != NULL) { + BLI_ghash_free(tgpa->asset_strokes_frame, NULL, NULL); + BLI_ghash_free(tgpa->asset_strokes_layer, NULL, NULL); + } + + if (tgpa->asset_materials != NULL) { + BLI_ghash_free(tgpa->asset_materials, NULL, NULL); + } + + /* Remove drawing handler. */ + if (tgpa->draw_handle_3d) { + ED_region_draw_cb_exit(tgpa->region->type, tgpa->draw_handle_3d); + } + + MEM_SAFE_FREE(tgpa); } + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); - /* Draw a line while is doing a transform. */ - if ((tgpa->flag & GP_ASSET_FLAG_TRANSFORMING) && (tgpa->mode == GP_ASSET_TRANSFORM_ROT)) { - const float line_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - immUniformColor4fv(line_color); - immBegin(GPU_PRIM_LINES, 2); - immVertex2f(pos, tgpa->transform_center[0], tgpa->transform_center[1]); - immVertex2f(pos, tgpa->mouse[0], tgpa->mouse[1]); - immEnd(); + /* Clear pointer. */ + op->customdata = NULL; +} + +/* Init new temporary data. */ +static bool gpencil_asset_import_set_init_values(bContext *C, + wmOperator *op, + ID *id, + tGPDasset *tgpa) +{ + /* Save current settings. */ + tgpa->win = CTX_wm_window(C); + tgpa->bmain = CTX_data_main(C); + tgpa->depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + tgpa->scene = CTX_data_scene(C); + tgpa->area = CTX_wm_area(C); + tgpa->region = CTX_wm_region(C); + tgpa->rv3d = CTX_wm_region_view3d(C); + tgpa->ob = CTX_data_active_object(C); + + /* Setup space conversions data. */ + gpencil_point_conversion_init(C, &tgpa->gsc); + + /* Save current frame number. */ + tgpa->cframe = tgpa->scene->r.cfra; + + /* Target GP datablock. */ + tgpa->gpd = tgpa->ob->data; + /* Asset GP datablock. */ + tgpa->gpd_asset = (bGPdata *)id; + + tgpa->mode = GP_ASSET_TRANSFORM_LOC; + tgpa->flag |= GP_ASSET_FLAG_IDLE; + + /* Manipulator point is not set yet. */ + tgpa->manipulator_index = -1; + + tgpa->asset_layers = NULL; + tgpa->asset_frames = NULL; + tgpa->asset_strokes_frame = NULL; + tgpa->asset_strokes_layer = NULL; + tgpa->asset_materials = NULL; + + return true; +} + +/* Allocate memory and initialize values */ +static tGPDasset *gpencil_session_init_asset_import(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + ID *id = NULL; + + PropertyRNA *prop_name = RNA_struct_find_property(op->ptr, "name"); + PropertyRNA *prop_type = RNA_struct_find_property(op->ptr, "type"); + + /* These shouldn't fail when created by outliner dropping as it checks the ID is valid. */ + if (!RNA_property_is_set(op->ptr, prop_name) || !RNA_property_is_set(op->ptr, prop_type)) { + return NULL; + } + const short id_type = RNA_property_enum_get(op->ptr, prop_type); + char name[MAX_ID_NAME - 2]; + RNA_property_string_get(op->ptr, prop_name, name); + id = BKE_libblock_find_name(bmain, id_type, name); + if (id == NULL) { + return NULL; + } + const int object_type = BKE_object_obdata_to_type(id); + if (object_type == -1) { + return NULL; } - immUnbindProgram(); + tGPDasset *tgpa = MEM_callocN(sizeof(tGPDasset), "GPencil Asset Import Data"); - /* Draw Points. */ - GPU_program_point_size(true); + /* Save initial values. */ + gpencil_asset_import_set_init_values(C, op, id, tgpa); - immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); + /* return context data for running operator */ + return tgpa; +} - float point_color[4]; - UI_GetThemeColor4fv(TH_SELECT, point_color); - immUniformColor4fv(point_color); +/* Init: Allocate memory and set init values */ +static bool gpencil_asset_import_init(bContext *C, wmOperator *op) +{ + tGPDasset *tgpa; - immUniform1f("size", UI_GetThemeValuef(TH_VERTEX_SIZE) * 1.5f * U.dpi_fac); - /* Draw points. */ - immBegin(GPU_PRIM_POINTS, 8); - for (int i = 0; i < 8; i++) { - immVertex2fv(pos, tgpa->manipulator[i]); + /* check context */ + tgpa = op->customdata = gpencil_session_init_asset_import(C, op); + if (tgpa == NULL) { + /* something wasn't set correctly in context */ + gpencil_asset_import_exit(C, op); + return false; } - immEnd(); - immUnbindProgram(); - GPU_program_point_size(false); - GPU_blend(GPU_BLEND_NONE); + return true; } /* Drawing callback for modal operator. */ @@ -1077,17 +1079,16 @@ static void gpencil_asset_draw(const bContext *C, ARegion *UNUSED(region), void if (region != tgpa->region) { return; } - gpencil_draw_cage(tgpa); + gpencil_2d_cage_draw(tgpa); } -/* ----------------------- */ -/* Invoke handler: Initialize the operator */ +/* Invoke handler: Initialize the operator. */ static int gpencil_asset_import_invoke(bContext *C, wmOperator *op, const wmEvent *event) { bGPdata *gpd = CTX_data_gpencil_data(C); tGPDasset *tgpa = NULL; - /* try to initialize context data needed */ + /* Try to initialize context data needed. */ if (!gpencil_asset_import_init(C, op)) { if (op->customdata) { MEM_freeN(op->customdata); @@ -1106,18 +1107,19 @@ static int gpencil_asset_import_invoke(bContext *C, wmOperator *op, const wmEven tgpa->draw_handle_3d = ED_region_draw_cb_activate( tgpa->region->type, gpencil_asset_draw, tgpa, REGION_DRAW_POST_PIXEL); - /* update shift indicator in header */ + /* Update screen. */ gpencil_asset_import_status_indicators(C, tgpa); + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); - /* add a modal handler for this operator */ + /* Add a modal handler for this operator. */ WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } -/* Modal handler: Events handling during interactive part */ +/* Modal handler: Events handling during interactive part. */ static int gpencil_asset_import_modal(bContext *C, wmOperator *op, const wmEvent *event) { tGPDasset *tgpa = op->customdata; @@ -1170,10 +1172,10 @@ static int gpencil_asset_import_modal(bContext *C, wmOperator *op, const wmEvent break; } } - /* Confirm */ + /* Confirm. */ case EVT_PADENTER: case EVT_RETKEY: { - /* return to normal cursor and header status */ + /* Return to normal cursor and header status. */ ED_area_status_text(tgpa->area, NULL); ED_workspace_status_text(C, NULL); WM_cursor_modal_restore(win); @@ -1181,15 +1183,15 @@ static int gpencil_asset_import_modal(bContext *C, wmOperator *op, const wmEvent /* Clean up temp data. */ gpencil_asset_import_exit(C, op); - /* done! */ + /* Done! */ return OPERATOR_FINISHED; } - case EVT_ESCKEY: /* cancel */ + case EVT_ESCKEY: /* Cancel */ case RIGHTMOUSE: { /* Delete temp strokes. */ - gpencil_asset_clean_data(tgpa); - /* Return to normal cursor and header status */ + gpencil_asset_clean_temp_data(tgpa); + /* Return to normal cursor and header status. */ ED_area_status_text(tgpa->area, NULL); ED_workspace_status_text(C, NULL); WM_cursor_modal_restore(win); @@ -1197,12 +1199,10 @@ static int gpencil_asset_import_modal(bContext *C, wmOperator *op, const wmEvent /* Clean up temp data. */ gpencil_asset_import_exit(C, op); - /* canceled! */ + /* Canceled! */ return OPERATOR_CANCELLED; } - - case MOUSEMOVE: /* calculate new position */ - { + case MOUSEMOVE: { /* Apply transform. */ if (tgpa->flag & GP_ASSET_FLAG_TRANSFORMING) { gpencil_asset_transform_strokes(tgpa, event->mval, event->shift); @@ -1217,33 +1217,16 @@ static int gpencil_asset_import_modal(bContext *C, wmOperator *op, const wmEvent gpencil_asset_import_update(C, op, tgpa); break; } - case WHEELUPMOUSE: { - // Scale - // TODO - - /* Update screen. */ - gpencil_asset_import_update(C, op, tgpa); - break; - } - case WHEELDOWNMOUSE: { - // Scale - // TODO - - /* Update screen. */ - gpencil_asset_import_update(C, op, tgpa); - break; - } - default: { /* Unhandled event - allow to pass through. */ return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH; } } - /* still running... */ + /* Still running... */ return OPERATOR_RUNNING_MODAL; } -/* Cancel handler */ +/* Cancel handler. */ static void gpencil_asset_import_cancel(bContext *C, wmOperator *op) { /* this is just a wrapper around exit() */ |