diff options
Diffstat (limited to 'source/blender/editors')
63 files changed, 211 insertions, 17953 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 85bcfb603cd..2a5c01fc671 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -2062,24 +2062,6 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, return 0; switch (GS(owner_id->name)) { - case ID_MA: - { - Material *ma = (Material *)owner_id; - mtex = (MTex **)(&ma->mtex); - break; - } - case ID_LA: - { - Lamp *la = (Lamp *)owner_id; - mtex = (MTex **)(&la->mtex); - break; - } - case ID_WO: - { - World *wo = (World *)owner_id; - mtex = (MTex **)(&wo->mtex); - break; - } case ID_PA: { ParticleSettings *part = (ParticleSettings *)owner_id; diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h index 64c16605dec..5cc695b6ce8 100644 --- a/source/blender/editors/include/ED_buttons.h +++ b/source/blender/editors/include/ED_buttons.h @@ -27,14 +27,4 @@ #ifndef __ED_BUTTONS_H__ #define __ED_BUTTONS_H__ -#include "BLI_utildefines.h" - -/* Used to check whether a given texture context is valid in current context. */ -bool ED_texture_context_check_world(const struct bContext *C); -bool ED_texture_context_check_material(const struct bContext *C); -bool ED_texture_context_check_lamp(const struct bContext *C); -bool ED_texture_context_check_particles(const struct bContext *C); -bool ED_texture_context_check_linestyle(const struct bContext *C); -bool ED_texture_context_check_others(const struct bContext *C); - #endif /* __ED_BUTTONS_H__ */ diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index b7317d75cd4..2615847e90a 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -54,7 +54,6 @@ void ED_render_engine_area_exit(struct Main *bmain, struct ScrArea *sa); void ED_render_id_flush_update(const struct DEGEditorUpdateContext *update_ctx, struct ID *id); void ED_render_scene_update(const struct DEGEditorUpdateContext *update_ctx, int updated); -void ED_viewport_render_kill_jobs(struct wmWindowManager *wm, struct Main *bmain, bool free_database); struct Scene *ED_render_job_get_scene(const struct bContext *C); struct Scene *ED_render_job_get_current_scene(const struct bContext *C); diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index fd532e70478..d6e8b6e9504 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -50,8 +50,6 @@ struct wmKeyConfig; void ED_operatortypes_uvedit(void); void ED_keymap_uvedit(struct wmKeyConfig *keyconf); -void ED_uvedit_assign_image( - struct Main *bmain, struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma); bool ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float min[2], float max[2]); bool ED_uvedit_center(Scene *scene, Image *ima, struct Object *obedit, float cent[2], char mode); void ED_uvedit_select_all(struct BMesh *bm); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 9cc4cb692e3..3ab08967a0d 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -382,15 +382,11 @@ void ED_draw_object_facemap(struct Depsgraph *depsgraph, struct Scene *scene, s struct RenderEngineType *ED_view3d_engine_type(struct Scene *scene, int drawtype); bool ED_view3d_context_activate(struct bContext *C); -void ED_view3d_draw_offscreen_init( - struct Depsgraph *depsgraph, struct Scene *scene, - struct ViewLayer *view_layer, struct View3D *v3d, - int drawtype); void ED_view3d_draw_offscreen( struct Depsgraph *depsgraph, struct Scene *scene, - struct ViewLayer *view_layer, int drawtype, + int drawtype, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4], - float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname, + float winmat[4][4], bool do_sky, bool is_persp, const char *viewname, struct GPUFXSettings *fx_settings, struct GPUOffScreen *ofs, struct GPUViewport *viewport); void ED_view3d_draw_setup_view( @@ -400,25 +396,24 @@ void ED_view3d_draw_setup_view( enum { V3D_OFSDRAW_NONE = (0), - V3D_OFSDRAW_USE_BACKGROUND = (1 << 0), - V3D_OFSDRAW_USE_FULL_SAMPLE = (1 << 1), + V3D_OFSDRAW_USE_FULL_SAMPLE = (1 << 0), /* Only works with ED_view3d_draw_offscreen_imbuf_simple(). */ - V3D_OFSDRAW_USE_GPENCIL = (1 << 2), + V3D_OFSDRAW_USE_GPENCIL = (1 << 1), V3D_OFSDRAW_USE_SOLID_TEX = (1 << 2), V3D_OFSDRAW_USE_CAMERA_DOF = (1 << 3), }; struct ImBuf *ED_view3d_draw_offscreen_imbuf( struct Depsgraph *depsgraph, struct Scene *scene, - struct ViewLayer *view_layer, int drawtype, + int drawtype, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, unsigned int draw_flags, int alpha_mode, int samples, const char *viewname, struct GPUOffScreen *ofs, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple( struct Depsgraph *depsgraph, struct Scene *scene, - struct ViewLayer *view_layer, int drawtype, + int drawtype, struct Object *camera, int width, int height, unsigned int flag, unsigned int draw_flags, int alpha_mode, int samples, const char *viewname, diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 576b24ed4b4..a3cbdb57fed 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -184,6 +184,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) export_settings.sampling_rate = sampling_rate; export_settings.active_uv_only = active_uv_only != 0; + export_settings.include_material_textures = include_material_textures != 0; export_settings.use_texture_copies = use_texture_copies != 0; export_settings.triangulate = triangulate != 0; diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 53f21a1e32f..6d1f478249a 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -51,7 +51,6 @@ #include "WM_types.h" #include "GPU_draw.h" -#include "GPU_buffers.h" /* own include */ @@ -99,11 +98,6 @@ void paintface_flush_flags(Object *ob, short flag) } } - if (flag & ME_HIDE) { - /* draw-object caches hidden faces, force re-generation T46867 */ - GPU_drawobject_free(dm); - } - BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_ALL); } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 94365be6b2e..dbf38864730 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5605,84 +5605,6 @@ void MESH_OT_sort_elements(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Noise (Deform Vertices) Operator - * \{ */ - -static int edbm_noise_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - Material *ma; - Tex *tex; - BMVert *eve; - BMIter iter; - const float fac = RNA_float_get(op->ptr, "factor"); - - if (em == NULL) { - return OPERATOR_FINISHED; - } - - if ((ma = give_current_material(obedit, obedit->actcol)) == NULL || - (tex = give_current_material_texture(ma)) == NULL) - { - BKE_report(op->reports, RPT_WARNING, "Mesh has no material or texture assigned"); - return OPERATOR_FINISHED; - } - - if (tex->type == TEX_STUCCI) { - float b2, vec[3]; - float ofs = tex->turbul / 200.0f; - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - b2 = BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]); - if (tex->stype) ofs *= (b2 * b2); - vec[0] = fac * (b2 - BLI_hnoise(tex->noisesize, eve->co[0] + ofs, eve->co[1], eve->co[2])); - vec[1] = fac * (b2 - BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1] + ofs, eve->co[2])); - vec[2] = fac * (b2 - BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2] + ofs)); - - add_v3_v3(eve->co, vec); - } - } - } - else { - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - float tin = 0.0f, dum; - if (ma->mtex[ma->texact] != NULL) { - externtex(ma->mtex[ma->texact], eve->co, &tin, &dum, &dum, &dum, &dum, 0, NULL, false, false); - } - eve->co[2] += fac * tin; - } - } - } - - EDBM_mesh_normals_update(em); - - EDBM_update_generic(em, true, false); - - return OPERATOR_FINISHED; -} - -void MESH_OT_noise(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Noise"; - ot->description = "Use vertex coordinate as texture coordinate"; - ot->idname = "MESH_OT_noise"; - - /* api callbacks */ - ot->exec = edbm_noise_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_float(ot->srna, "factor", 0.1f, -1e4f, 1e4f, "Factor", "", 0.0f, 1.0f); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Bridge Operator * \{ */ diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 69e265f7315..676af4fea5b 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -538,7 +538,6 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot) static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); Base *base; @@ -578,8 +577,6 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e if (me->edit_btmesh == NULL) return OPERATOR_CANCELLED; - ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL); - if (exitmode) { EDBM_mesh_load(obedit); EDBM_mesh_free(me->edit_btmesh); diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 788887e872a..87a17eb8fd4 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -210,7 +210,6 @@ void MESH_OT_hide(struct wmOperatorType *ot); void MESH_OT_reveal(struct wmOperatorType *ot); void MESH_OT_mark_seam(struct wmOperatorType *ot); void MESH_OT_mark_sharp(struct wmOperatorType *ot); -void MESH_OT_noise(struct wmOperatorType *ot); void MESH_OT_flip_normals(struct wmOperatorType *ot); void MESH_OT_solidify(struct wmOperatorType *ot); void MESH_OT_knife_cut(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index a2c996c7f42..6f663ddbf14 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -141,7 +141,6 @@ void ED_operatortypes_mesh(void) #endif WM_operatortype_append(MESH_OT_vertices_smooth); WM_operatortype_append(MESH_OT_vertices_smooth_laplacian); - WM_operatortype_append(MESH_OT_noise); WM_operatortype_append(MESH_OT_flip_normals); WM_operatortype_append(MESH_OT_rip); WM_operatortype_append(MESH_OT_rip_edge); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 6f9f18d301e..7327c563104 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -115,8 +115,6 @@ #include "UI_resources.h" -#include "GPU_lamp.h" - #include "object_intern.h" /* this is an exact copy of the define in rna_lamp.c @@ -1019,7 +1017,7 @@ static int object_lamp_add_exec(bContext *C, wmOperator *op) la = (Lamp *)ob->data; la->type = type; - if (BKE_scene_use_new_shading_nodes(scene)) { + if (BKE_scene_uses_cycles(scene)) { ED_node_shader_default(C, &la->id); la->use_nodes = true; } @@ -1184,17 +1182,6 @@ void OBJECT_OT_speaker_add(wmOperatorType *ot) /**************************** Delete Object *************************/ -static void object_delete_check_glsl_update(Object *ob) -{ - /* some objects could affect on GLSL shading, make sure GLSL settings - * are being tagged to be updated when object is removing from scene - */ - if (ob->type == OB_LAMP) { - if (ob->gpulamp.first) - GPU_lamp_free(ob); - } -} - /* remove base from a specific scene */ /* note: now unlinks constraints as well */ void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob) @@ -1210,7 +1197,6 @@ void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob) DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_BASE_FLAGS_UPDATE); - object_delete_check_glsl_update(ob); BKE_collections_object_remove(bmain, &scene->id, ob, true); } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index a38b9959dab..b10b35618fb 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -79,9 +79,26 @@ #include "ED_object.h" #include "ED_screen.h" +#include "ED_uvedit.h" #include "object_intern.h" +static Image *bake_object_image_get(Object *ob, int mat_nr) +{ + Image *image = NULL; + ED_object_get_active_image(ob, mat_nr + 1, &image, NULL, NULL, NULL); + return image; +} + +static Image **bake_object_image_get_array(Object *ob) +{ + Image **image_array = MEM_mallocN(sizeof(Material *) * ob->totcol, __func__); + for (int i = 0; i < ob->totcol; i++) { + image_array[i] = bake_object_image_get(ob, i); + } + return image_array; +} + /* ****************** multires BAKING ********************** */ /* holder of per-object data needed for bake job @@ -108,8 +125,6 @@ typedef struct { bool use_lores_mesh; /* Use low-resolution mesh when baking displacement maps */ int number_of_rays; /* Number of rays to be cast when doing AO baking */ float bias; /* Bias between object and start ray point when doing AO baking */ - int raytrace_structure; /* Optimization structure to be used for AO baking */ - int octree_resolution; /* Reslution of octotree when using octotree optimization structure */ int threads; /* Number of threads to be used for baking */ float user_scale; /* User scale used to scale displacement when baking derivative map. */ } MultiresBakeJob; @@ -167,7 +182,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) else { a = me->totpoly; while (ok && a--) { - Image *ima = BKE_object_material_edit_image_get(ob, me->mpoly[a].mat_nr); + Image *ima = bake_object_image_get(ob, me->mpoly[a].mat_nr); if (!ima) { BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker"); @@ -334,12 +349,12 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) if (scene->r.bake_mode == RE_BAKE_NORMALS) { clear_flag = CLEAR_TANGENT_NORMAL; } - else if (ELEM(scene->r.bake_mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) { + else if (scene->r.bake_mode == RE_BAKE_DISPLACEMENT) { clear_flag = CLEAR_DISPLACEMENT; } { - Image **ob_image_array = BKE_object_material_edit_image_get_array(ob); + Image **ob_image_array = bake_object_image_get_array(ob); clear_images_poly(ob_image_array, ob->totcol, clear_flag); MEM_freeN(ob_image_array); } @@ -361,14 +376,12 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; bkr.bias = scene->r.bake_biasdist; bkr.number_of_rays = scene->r.bake_samples; - bkr.raytrace_structure = scene->r.raytrace_structure; - bkr.octree_resolution = scene->r.ocres; bkr.threads = BKE_scene_num_threads(scene); bkr.user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; //bkr.reports= op->reports; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - bkr.ob_image.array = BKE_object_material_edit_image_get_array(ob); + bkr.ob_image.array = bake_object_image_get_array(ob); bkr.ob_image.len = ob->totcol; bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); @@ -406,8 +419,6 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR; bkj->bias = scene->r.bake_biasdist; bkj->number_of_rays = scene->r.bake_samples; - bkj->raytrace_structure = scene->r.raytrace_structure; - bkj->octree_resolution = scene->r.ocres; bkj->threads = BKE_scene_num_threads(scene); bkj->user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; //bkj->reports = op->reports; @@ -423,7 +434,7 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); - data->ob_image.array = BKE_object_material_edit_image_get_array(ob); + data->ob_image.array = bake_object_image_get_array(ob); data->ob_image.len = ob->totcol; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ @@ -451,7 +462,7 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa if (bkj->mode == RE_BAKE_NORMALS) { clear_flag = CLEAR_TANGENT_NORMAL; } - else if (ELEM(bkj->mode, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE)) { + else if (bkj->mode == RE_BAKE_DISPLACEMENT) { clear_flag = CLEAR_DISPLACEMENT; } @@ -488,8 +499,6 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa bkr.bias = bkj->bias; bkr.number_of_rays = bkj->number_of_rays; - bkr.raytrace_structure = bkj->raytrace_structure; - bkr.octree_resolution = bkj->octree_resolution; bkr.threads = bkj->threads; RE_multires_bake_images(&bkr); @@ -566,203 +575,6 @@ static int multiresbake_image_exec(bContext *C, wmOperator *op) /* ****************** render BAKING ********************** */ -/* threaded break test */ -static int thread_break(void *UNUSED(arg)) -{ - return G.is_break; -} - -typedef struct BakeRender { - Render *re; - Main *main; - Scene *scene; - ViewLayer *view_layer; - struct Object *actob; - int result, ready; - - ReportList *reports; - - short *stop; - short *do_update; - float *progress; - - ListBase threads; - - /* backup */ - short prev_wo_amb_occ; - short prev_r_raytrace; - - /* for redrawing */ - ScrArea *sa; -} BakeRender; - -/* use by exec and invoke */ -static int test_bake_internal(bContext *C, ReportList *reports) -{ - Scene *scene = CTX_data_scene(C); - - if ((scene->r.bake_flag & R_BAKE_TO_ACTIVE) && CTX_data_active_object(C) == NULL) { - BKE_report(reports, RPT_ERROR, "No active object"); - } - else if (scene->r.bake_mode == RE_BAKE_AO && scene->world == NULL) { - BKE_report(reports, RPT_ERROR, "No world set up"); - } - else { - return 1; - } - - return 0; -} - -static void init_bake_internal(BakeRender *bkr, bContext *C) -{ - Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); - bScreen *sc = CTX_wm_screen(C); - - /* get editmode results */ - ED_object_editmode_load(CTX_data_edit_object(C)); - - bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL; /* can be NULL */ - bkr->main = CTX_data_main(C); - bkr->scene = scene; - bkr->view_layer = view_layer; - bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(view_layer) : NULL; - bkr->re = RE_NewRender("_Bake View_"); - - if (scene->r.bake_mode == RE_BAKE_AO) { - /* If raytracing or AO is disabled, switch it on temporarily for baking. */ - bkr->prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0; - scene->world->mode |= WO_AMB_OCC; - } - if (scene->r.bake_mode == RE_BAKE_AO || bkr->actob) { - bkr->prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0; - scene->r.mode |= R_RAYTRACE; - } -} - -static void finish_bake_internal(BakeRender *bkr) -{ - Image *ima; - - RE_Database_Free(bkr->re); - - /* restore raytrace and AO */ - if (bkr->scene->r.bake_mode == RE_BAKE_AO) - if (bkr->prev_wo_amb_occ == 0) - bkr->scene->world->mode &= ~WO_AMB_OCC; - - if (bkr->scene->r.bake_mode == RE_BAKE_AO || bkr->actob) - if (bkr->prev_r_raytrace == 0) - bkr->scene->r.mode &= ~R_RAYTRACE; - - /* force OpenGL reload and mipmap recalc */ - if ((bkr->scene->r.bake_flag & R_BAKE_VCOL) == 0) { - for (ima = G.main->image.first; ima; ima = ima->id.next) { - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - - /* some of the images could have been changed during bake, - * so recreate mipmaps regardless bake result status - */ - if (ima->ok == IMA_OK_LOADED) { - if (ibuf) { - if (ibuf->userflags & IB_BITMAPDIRTY) { - GPU_free_image(ima); - imb_freemipmapImBuf(ibuf); - } - - /* invalidate display buffers for changed images */ - if (ibuf->userflags & IB_BITMAPDIRTY) - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - } - } - - /* freed when baking is done, but if its canceled we need to free here */ - if (ibuf) { - if (ibuf->userdata) { - BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata; - if (userdata->mask_buffer) - MEM_freeN(userdata->mask_buffer); - if (userdata->displacement_buffer) - MEM_freeN(userdata->displacement_buffer); - MEM_freeN(userdata); - ibuf->userdata = NULL; - } - } - - BKE_image_release_ibuf(ima, ibuf, NULL); - DEG_id_tag_update(&ima->id, 0); - } - } - - if (bkr->scene->r.bake_flag & R_BAKE_VCOL) { - /* update all tagged meshes */ - Mesh *me; - BLI_assert(BLI_thread_is_main()); - for (me = G.main->mesh.first; me; me = me->id.next) { - if (me->id.tag & LIB_TAG_DOIT) { - DEG_id_tag_update(&me->id, OB_RECALC_DATA); - BKE_mesh_tessface_clear(me); - } - } - } - -} - -static void *do_bake_render(void *bake_v) -{ - BakeRender *bkr = bake_v; - - bkr->result = RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress); - bkr->ready = 1; - - return NULL; -} - -static void bake_startjob(void *bkv, short *stop, short *do_update, float *progress) -{ - BakeRender *bkr = bkv; - Scene *scene = bkr->scene; - Main *bmain = bkr->main; - - bkr->stop = stop; - bkr->do_update = do_update; - bkr->progress = progress; - - RE_test_break_cb(bkr->re, NULL, thread_break); - G.is_break = false; /* BKE_blender_test_break uses this global */ - - RE_Database_Baking(bkr->re, bmain, scene, bkr->view_layer, scene->lay, scene->r.bake_mode, bkr->actob); - - /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */ - bkr->result = RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress); -} - -static void bake_update(void *bkv) -{ - BakeRender *bkr = bkv; - - if (bkr->sa && bkr->sa->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */ - SpaceImage *sima = bkr->sa->spacedata.first; - if (sima) - sima->image = RE_bake_shade_get_image(); - } -} - -static void bake_freejob(void *bkv) -{ - BakeRender *bkr = bkv; - finish_bake_internal(bkr); - - if (bkr->result == BAKE_RESULT_NO_OBJECTS) - BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to"); - else if (bkr->result == BAKE_RESULT_FEEDBACK_LOOP) - BKE_report(bkr->reports, RPT_WARNING, "Circular reference in texture stack"); - - MEM_freeN(bkr); - G.is_rendering = false; -} - /* catch esc */ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { @@ -780,7 +592,7 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const static bool is_multires_bake(Scene *scene) { - if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_AO)) + if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO)) return scene->r.bake_flag & R_BAKE_MULTIRES; return 0; @@ -791,44 +603,7 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent Scene *scene = CTX_data_scene(C); int result = OPERATOR_CANCELLED; - if (is_multires_bake(scene)) { - result = multiresbake_image_exec(C, op); - } - else { - /* only one render job at a time */ - if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE)) - return OPERATOR_CANCELLED; - - if (test_bake_internal(C, op->reports) == 0) { - return OPERATOR_CANCELLED; - } - else { - BakeRender *bkr = MEM_callocN(sizeof(BakeRender), "render bake"); - wmJob *wm_job; - - init_bake_internal(bkr, C); - bkr->reports = op->reports; - - /* setup job */ - wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", - WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE); - WM_jobs_customdata_set(wm_job, bkr, bake_freejob); - WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ - WM_jobs_callbacks(wm_job, bake_startjob, NULL, bake_update, NULL); - - G.is_break = false; - G.is_rendering = true; - - WM_jobs_start(CTX_wm_manager(C), wm_job); - - WM_cursor_wait(0); - - /* add modal handler for ESC */ - WM_event_add_modal_handler(C, op); - } - - result = OPERATOR_RUNNING_MODAL; - } + result = multiresbake_image_exec(C, op); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); @@ -838,56 +613,11 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent static int bake_image_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); int result = OPERATOR_CANCELLED; - if (is_multires_bake(scene)) { - result = multiresbake_image_exec_locked(C, op); - } - else { - if (test_bake_internal(C, op->reports) == 0) { - return OPERATOR_CANCELLED; - } - else { - ListBase threads; - BakeRender bkr = {NULL}; - - init_bake_internal(&bkr, C); - bkr.reports = op->reports; - - RE_test_break_cb(bkr.re, NULL, thread_break); - G.is_break = false; /* BKE_blender_test_break uses this global */ - - RE_Database_Baking(bkr.re, bmain, scene, bkr.view_layer, scene->lay, scene->r.bake_mode, - (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(bkr.view_layer) : NULL); - - /* baking itself is threaded, cannot use test_break in threads */ - BLI_threadpool_init(&threads, do_bake_render, 1); - bkr.ready = 0; - BLI_threadpool_insert(&threads, &bkr); - - while (bkr.ready == 0) { - PIL_sleep_ms(50); - if (bkr.ready) - break; - - /* used to redraw in 2.4x but this is just for exec in 2.5 */ - if (!G.background) - BKE_blender_test_break(); - } - BLI_threadpool_end(&threads); - - if (bkr.result == BAKE_RESULT_NO_OBJECTS) - BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to"); - else if (bkr.result == BAKE_RESULT_FEEDBACK_LOOP) - BKE_report(op->reports, RPT_ERROR, "Circular reference in texture stack"); - - finish_bake_internal(&bkr); - - result = OPERATOR_FINISHED; - } - } + BLI_assert(is_multires_bake(scene)); + result = multiresbake_image_exec_locked(C, op); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 2550c4006f2..d051e42cb32 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1295,68 +1295,6 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot) /* ********************** */ -static void UNUSED_FUNCTION(image_aspect) (Scene *scene, ViewLayer *view_layer, Object *obedit) -{ - /* all selected objects with an image map: scale in image aspect */ - Base *base; - Object *ob; - Material *ma; - Tex *tex; - float x, y, space; - int a, b, done; - - if (obedit) return; - if (ID_IS_LINKED(scene)) return; - - for (base = FIRSTBASE(view_layer); base; base = base->next) { - if (TESTBASELIB(base)) { - ob = base->object; - done = false; - - for (a = 1; a <= ob->totcol; a++) { - ma = give_current_material(ob, a); - if (ma) { - for (b = 0; b < MAX_MTEX; b++) { - if (ma->mtex[b] && ma->mtex[b]->tex) { - tex = ma->mtex[b]->tex; - if (tex->type == TEX_IMAGE && tex->ima) { - ImBuf *ibuf = BKE_image_acquire_ibuf(tex->ima, NULL, NULL); - - /* texturespace */ - space = 1.0; - if (ob->type == OB_MESH) { - float size[3]; - BKE_mesh_texspace_get(ob->data, NULL, NULL, size); - space = size[0] / size[1]; - } - else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) { - float size[3]; - BKE_curve_texspace_get(ob->data, NULL, NULL, size); - space = size[0] / size[1]; - } - - x = ibuf->x / space; - y = ibuf->y; - - if (x > y) ob->size[0] = ob->size[1] * x / y; - else ob->size[1] = ob->size[0] * y / x; - - done = true; - DEG_id_tag_update(&ob->id, OB_RECALC_OB); - - BKE_image_release_ibuf(tex->ima, ibuf, NULL); - } - } - if (done) break; - } - } - if (done) break; - } - } - } - -} - static const EnumPropertyItem *object_mode_set_itemsf( bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 3cef80db032..d2ac0f77c78 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1773,7 +1773,6 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer Mesh *me; Lattice *lat; ID *id; - int a; FOREACH_OBJECT_FLAG_BEGIN(scene, view_layer, flag, ob) { @@ -1786,11 +1785,6 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer switch (ob->type) { case OB_LAMP: ob->data = la = ID_NEW_SET(ob->data, BKE_lamp_copy(bmain, ob->data)); - for (a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a]) { - ID_NEW_REMAP(la->mtex[a]->object); - } - } break; case OB_CAMERA: ob->data = ID_NEW_SET(ob->data, BKE_camera_copy(bmain, ob->data)); @@ -1870,11 +1864,10 @@ static void single_object_action_users(Scene *scene, ViewLayer *view_layer, cons FOREACH_OBJECT_FLAG_END; } -static void single_mat_users(Main *bmain, Scene *scene, ViewLayer *view_layer, const int flag, const bool do_textures) +static void single_mat_users(Main *bmain, Scene *scene, ViewLayer *view_layer, const int flag) { Material *ma, *man; - Tex *tex; - int a, b; + int a; FOREACH_OBJECT_FLAG_BEGIN(scene, view_layer, flag, ob) { @@ -1890,19 +1883,6 @@ static void single_mat_users(Main *bmain, Scene *scene, ViewLayer *view_layer, c man->id.us = 0; assign_material(ob, man, a, BKE_MAT_ASSIGN_USERPREF); - - if (do_textures) { - for (b = 0; b < MAX_MTEX; b++) { - if (ma->mtex[b] && (tex = ma->mtex[b]->tex)) { - if (tex->id.us > 1) { - id_us_min(&tex->id); - tex = BKE_texture_copy(bmain, tex); - BKE_animdata_copy_id_action(&tex->id, false); - man->mtex[b]->tex = tex; - } - } - } - } } } } @@ -1911,66 +1891,6 @@ static void single_mat_users(Main *bmain, Scene *scene, ViewLayer *view_layer, c FOREACH_OBJECT_FLAG_END; } -static void do_single_tex_user(Main *bmain, Tex **from) -{ - Tex *tex, *texn; - - tex = *from; - if (tex == NULL) return; - - if (tex->id.newid) { - *from = (Tex *)tex->id.newid; - id_us_plus(tex->id.newid); - id_us_min(&tex->id); - } - else if (tex->id.us > 1) { - texn = ID_NEW_SET(tex, BKE_texture_copy(bmain, tex)); - BKE_animdata_copy_id_action(&texn->id, false); - tex->id.newid = (ID *)texn; - id_us_min(&tex->id); - *from = texn; - } -} - -static void single_tex_users_expand(Main *bmain) -{ - /* only when 'parent' blocks are LIB_TAG_NEW */ - Material *ma; - Lamp *la; - World *wo; - int b; - - for (ma = bmain->mat.first; ma; ma = ma->id.next) { - if (ma->id.tag & LIB_TAG_NEW) { - for (b = 0; b < MAX_MTEX; b++) { - if (ma->mtex[b] && ma->mtex[b]->tex) { - do_single_tex_user(bmain, &(ma->mtex[b]->tex)); - } - } - } - } - - for (la = bmain->lamp.first; la; la = la->id.next) { - if (la->id.tag & LIB_TAG_NEW) { - for (b = 0; b < MAX_MTEX; b++) { - if (la->mtex[b] && la->mtex[b]->tex) { - do_single_tex_user(bmain, &(la->mtex[b]->tex)); - } - } - } - } - - for (wo = bmain->world.first; wo; wo = wo->id.next) { - if (wo->id.tag & LIB_TAG_NEW) { - for (b = 0; b < MAX_MTEX; b++) { - if (wo->mtex[b] && wo->mtex[b]->tex) { - do_single_tex_user(bmain, &(wo->mtex[b]->tex)); - } - } - } - } -} - static void single_mat_users_expand(Main *bmain) { /* only when 'parent' blocks are LIB_TAG_NEW */ @@ -1978,8 +1898,6 @@ static void single_mat_users_expand(Main *bmain) Mesh *me; Curve *cu; MetaBall *mb; - Material *ma; - int a; for (ob = bmain->object.first; ob; ob = ob->id.next) if (ob->id.tag & LIB_TAG_NEW) @@ -1996,13 +1914,6 @@ static void single_mat_users_expand(Main *bmain) for (mb = bmain->mball.first; mb; mb = mb->id.next) if (mb->id.tag & LIB_TAG_NEW) new_id_matar(bmain, mb->mat, mb->totcol); - - /* material imats */ - for (ma = bmain->mat.first; ma; ma = ma->id.next) - if (ma->id.tag & LIB_TAG_NEW) - for (a = 0; a < MAX_MTEX; a++) - if (ma->mtex[a]) - ID_NEW_REMAP(ma->mtex[a]->object); } /* used for copying scenes */ @@ -2014,7 +1925,6 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo single_obdata_users(bmain, scene, NULL, 0); single_object_action_users(scene, NULL, 0); single_mat_users_expand(bmain); - single_tex_users_expand(bmain); } /* Relink nodetrees' pointers that have been duplicated. */ @@ -2201,12 +2111,6 @@ static void make_local_material_tag(Material *ma) make_local_animdata_tag(BKE_animdata_from_id(&ma->id)); /* About nodetrees: root one is made local together with material, others we keep linked for now... */ - - for (int a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a] && ma->mtex[a]->tex) { - ma->mtex[a]->tex->id.tag &= ~LIB_TAG_PRE_EXISTING; - } - } } } @@ -2216,7 +2120,6 @@ static int make_local_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); ParticleSystem *psys; Material *ma, ***matarar; - Lamp *la; const int mode = RNA_enum_get(op->ptr, "type"); int a; @@ -2267,16 +2170,6 @@ static int make_local_exec(bContext *C, wmOperator *op) } } } - - if (ob->type == OB_LAMP) { - BLI_assert(ob->data != NULL); - la = ob->data; - for (a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a] && la->mtex[a]->tex) { - la->id.tag &= ~LIB_TAG_PRE_EXISTING; - } - } - } } if (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL) && ob->data != NULL) { @@ -2553,13 +2446,9 @@ static int make_single_user_exec(bContext *C, wmOperator *op) } if (RNA_boolean_get(op->ptr, "material")) { - single_mat_users(bmain, scene, view_layer, flag, RNA_boolean_get(op->ptr, "texture")); + single_mat_users(bmain, scene, view_layer, flag); } -#if 0 /* can't do this separate from materials */ - if (RNA_boolean_get(op->ptr, "texture")) - single_mat_users(scene, flag, true); -#endif if (RNA_boolean_get(op->ptr, "animation")) { single_object_action_users(scene, view_layer, flag); } @@ -2601,8 +2490,6 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot) RNA_def_boolean(ot->srna, "object", 0, "Object", "Make single user objects"); RNA_def_boolean(ot->srna, "obdata", 0, "Object Data", "Make single user object data"); RNA_def_boolean(ot->srna, "material", 0, "Materials", "Make materials local to each data-block"); - RNA_def_boolean(ot->srna, "texture", 0, "Textures", - "Make textures local to each material (needs 'Materials' to be set too)"); RNA_def_boolean(ot->srna, "animation", 0, "Object Animation", "Make animation data local to each object"); } diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index d958381efe7..d0d0418c861 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -203,7 +203,6 @@ enum { OBJECT_SELECT_LINKED_IPO = 1, OBJECT_SELECT_LINKED_OBDATA, OBJECT_SELECT_LINKED_MATERIAL, - OBJECT_SELECT_LINKED_TEXTURE, OBJECT_SELECT_LINKED_DUPGROUP, OBJECT_SELECT_LINKED_PARTICLE, OBJECT_SELECT_LINKED_LIBRARY, @@ -214,7 +213,6 @@ static const EnumPropertyItem prop_select_linked_types[] = { //{OBJECT_SELECT_LINKED_IPO, "IPO", 0, "Object IPO", ""}, // XXX deprecated animation system stuff... {OBJECT_SELECT_LINKED_OBDATA, "OBDATA", 0, "Object Data", ""}, {OBJECT_SELECT_LINKED_MATERIAL, "MATERIAL", 0, "Material", ""}, - {OBJECT_SELECT_LINKED_TEXTURE, "TEXTURE", 0, "Texture", ""}, {OBJECT_SELECT_LINKED_DUPGROUP, "DUPGROUP", 0, "Dupligroup", ""}, {OBJECT_SELECT_LINKED_PARTICLE, "PARTICLE", 0, "Particle System", ""}, {OBJECT_SELECT_LINKED_LIBRARY, "LIBRARY", 0, "Library", ""}, @@ -240,7 +238,7 @@ static bool object_select_all_by_obdata(bContext *C, void *obdata) return changed; } -static bool object_select_all_by_material_texture(bContext *C, int use_texture, Material *mat, Tex *tex) +static bool object_select_all_by_material(bContext *C, Material *mat) { bool changed = false; @@ -249,27 +247,14 @@ static bool object_select_all_by_material_texture(bContext *C, int use_texture, if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { Object *ob = base->object; Material *mat1; - int a, b; + int a; for (a = 1; a <= ob->totcol; a++) { mat1 = give_current_material(ob, a); - if (!use_texture) { - if (mat1 == mat) { - ED_object_base_select(base, BA_SELECT); - changed = true; - } - } - else if (mat1 && use_texture) { - for (b = 0; b < MAX_MTEX; b++) { - if (mat1->mtex[b]) { - if (tex == mat1->mtex[b]->tex) { - ED_object_base_select(base, BA_SELECT); - changed = true; - break; - } - } - } + if (mat1 == mat) { + ED_object_base_select(base, BA_SELECT); + changed = true; } } } @@ -373,7 +358,7 @@ void ED_object_select_linked_by_id(bContext *C, ID *id) changed = object_select_all_by_obdata(C, id); } else if (idtype == ID_MA) { - changed = object_select_all_by_material_texture(C, false, (Material *)id, NULL); + changed = object_select_all_by_material(C, (Material *)id); } else if (idtype == ID_LI) { changed = object_select_all_by_library(C, (Library *) id); @@ -420,21 +405,13 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) changed = object_select_all_by_obdata(C, ob->data); } - else if (nr == OBJECT_SELECT_LINKED_MATERIAL || nr == OBJECT_SELECT_LINKED_TEXTURE) { + else if (nr == OBJECT_SELECT_LINKED_MATERIAL) { Material *mat = NULL; - Tex *tex = NULL; - bool use_texture = false; mat = give_current_material(ob, ob->actcol); if (mat == NULL) return OPERATOR_CANCELLED; - if (nr == OBJECT_SELECT_LINKED_TEXTURE) { - use_texture = true; - - if (mat->mtex[(int)mat->texact]) tex = mat->mtex[(int)mat->texact]->tex; - if (tex == NULL) return OPERATOR_CANCELLED; - } - changed = object_select_all_by_material_texture(C, use_texture, mat, tex); + changed = object_select_all_by_material(C, mat); } else if (nr == OBJECT_SELECT_LINKED_DUPGROUP) { if (ob->dup_group == NULL) diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 7012046fc31..a509a909111 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3587,7 +3587,7 @@ static int brush_add(const bContext *C, PEData *data, short number) tree=BLI_kdtree_new(psys->totpart); for (i=0, pa=psys->particles; i<totpart; i++, pa++) { - psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0, 0); + psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0); BLI_kdtree_insert(tree, i, cur_co); } @@ -3631,7 +3631,7 @@ static int brush_add(const bContext *C, PEData *data, short number) int w, maxw; float maxd, totw=0.0, weight[3]; - psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0, 0); + psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0); maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3); maxd= ptn[maxw-1].dist; diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index 2bc96a7f218..a1f646aefc1 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -83,15 +83,10 @@ void SCENE_OT_freestyle_stroke_material_create(struct wmOperatorType *ot); void TEXTURE_OT_slot_copy(struct wmOperatorType *ot); void TEXTURE_OT_slot_paste(struct wmOperatorType *ot); void TEXTURE_OT_slot_move(struct wmOperatorType *ot); -void TEXTURE_OT_envmap_save(struct wmOperatorType *ot); -void TEXTURE_OT_envmap_clear(struct wmOperatorType *ot); -void TEXTURE_OT_envmap_clear_all(struct wmOperatorType *ot); /* render_internal.c */ void RENDER_OT_render(struct wmOperatorType *ot); void RENDER_OT_shutter_curve_preset(struct wmOperatorType *ot); -void render_view3d_update(struct RenderEngine *engine, const struct bContext *C); -void render_view3d_draw(struct RenderEngine *engine, const struct bContext *C); /* render_view.c */ struct ScrArea *render_view_open(struct bContext *C, int mx, int my, struct ReportList *reports); diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 22e62c9ba0a..89dbd3da16d 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1078,623 +1078,6 @@ void RENDER_OT_render(wmOperatorType *ot) } -/* ************** preview for 3d viewport ***************** */ - -#define PR_UPDATE_VIEW 1 -#define PR_UPDATE_RENDERSIZE 2 -#define PR_UPDATE_MATERIAL 4 -#define PR_UPDATE_DATABASE 8 - -typedef struct RenderPreview { - /* from wmJob */ - void *owner; - short *stop, *do_update; - wmJob *job; - - Scene *scene; - Depsgraph *depsgraph; - ScrArea *sa; - ARegion *ar; - View3D *v3d; - RegionView3D *rv3d; - Main *bmain; - RenderEngine *engine; - - float viewmat[4][4]; - - int start_resolution_divider; - int resolution_divider; - bool has_freestyle; -} RenderPreview; - -static int render_view3d_disprect(Scene *scene, Depsgraph *depsgraph, - ARegion *ar, View3D *v3d, RegionView3D *rv3d, rcti *disprect) -{ - /* copied code from view3d_draw.c */ - rctf viewborder; - int draw_border; - - if (rv3d->persp == RV3D_CAMOB) - draw_border = (scene->r.mode & R_BORDER) != 0; - else - draw_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0; - - if (draw_border) { - if (rv3d->persp == RV3D_CAMOB) { - ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &viewborder, false); - - disprect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); - disprect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); - disprect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); - disprect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); - } - else { - disprect->xmin = v3d->render_border.xmin * ar->winx; - disprect->xmax = v3d->render_border.xmax * ar->winx; - disprect->ymin = v3d->render_border.ymin * ar->winy; - disprect->ymax = v3d->render_border.ymax * ar->winy; - } - - return 1; - } - - BLI_rcti_init(disprect, 0, 0, 0, 0); - return 0; -} - -/* returns true if OK */ -static bool render_view3d_get_rects( - Depsgraph *depsgraph, - ARegion *ar, View3D *v3d, RegionView3D *rv3d, rctf *viewplane, RenderEngine *engine, - float *r_clipsta, float *r_clipend, float *r_pixsize, bool *r_ortho) -{ - - if (ar->winx < 4 || ar->winy < 4) return false; - - *r_ortho = ED_view3d_viewplane_get(depsgraph, v3d, rv3d, ar->winx, ar->winy, viewplane, r_clipsta, r_clipend, r_pixsize); - - engine->resolution_x = ar->winx; - engine->resolution_y = ar->winy; - - return true; -} - -static bool render_view3d_is_valid(RenderPreview *rp) -{ - return (rp->rv3d->render_engine != NULL); -} - -/* called by renderer, checks job value */ -static int render_view3d_break(void *rpv) -{ - RenderPreview *rp = rpv; - - if (G.is_break) - return 1; - - /* during render, rv3d->engine can get freed */ - if (render_view3d_is_valid(rp) == false) { - *rp->stop = 1; - } - - return *(rp->stop); -} - -static void render_view3d_display_update(void *rpv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect)) -{ - RenderPreview *rp = rpv; - - *(rp->do_update) = true; -} - -static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs) -{ - RenderPreview *rp = rjp; - - /* during render, rv3d->engine can get freed */ - if (rp->rv3d->render_engine == NULL) { - *rp->stop = 1; - } - else { - make_renderinfo_string(rs, rp->scene, false, NULL, rp->engine->text); - - /* make jobs timer to send notifier */ - *(rp->do_update) = true; - } -} - -BLI_INLINE void rcti_scale_coords(rcti *scaled_rect, const rcti *rect, - const float scale) -{ - scaled_rect->xmin = rect->xmin * scale; - scaled_rect->ymin = rect->ymin * scale; - scaled_rect->xmax = rect->xmax * scale; - scaled_rect->ymax = rect->ymax * scale; -} - -static void render_update_resolution(Render *re, const RenderPreview *rp, - bool use_border, const rcti *clip_rect) -{ - int winx = rp->ar->winx / rp->resolution_divider; - int winy = rp->ar->winy / rp->resolution_divider; - if (use_border) { - rcti scaled_cliprct; - rcti_scale_coords(&scaled_cliprct, clip_rect, - 1.0f / rp->resolution_divider); - RE_ChangeResolution(re, winx, winy, &scaled_cliprct); - } - else { - RE_ChangeResolution(re, winx, winy, NULL); - } - - if (rp->has_freestyle) { - if (rp->resolution_divider == BKE_render_preview_pixel_size(&rp->scene->r)) { - RE_ChangeModeFlag(re, R_EDGE_FRS, false); - } - else { - RE_ChangeModeFlag(re, R_EDGE_FRS, true); - } - } -} - -static void render_view3d_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress)) -{ - RenderPreview *rp = customdata; - Render *re; - RenderStats *rstats; - rctf viewplane; - rcti cliprct; - float clipsta, clipend, pixsize; - bool orth, restore = 0; - char name[32]; - int update_flag; - bool use_border; - int ob_inst_update_flag = 0; - - update_flag = rp->engine->job_update_flag; - rp->engine->job_update_flag = 0; - - //printf("ma %d res %d view %d db %d\n", update_flag & PR_UPDATE_MATERIAL, update_flag & PR_UPDATE_RENDERSIZE, update_flag & PR_UPDATE_VIEW, update_flag & PR_UPDATE_DATABASE); - - G.is_break = false; - - if (false == render_view3d_get_rects(rp->depsgraph, rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &pixsize, &orth)) - return; - - rp->stop = stop; - rp->do_update = do_update; - - // printf("Enter previewrender\n"); - - /* ok, are we rendering all over? */ - sprintf(name, "View3dPreview %p", (void *)rp->ar); - re = rp->engine->re = RE_GetRender(name); - - /* set this always, rp is different for each job */ - RE_test_break_cb(re, rp, render_view3d_break); - RE_display_update_cb(re, rp, render_view3d_display_update); - RE_stats_draw_cb(re, rp, render_view3d_renderinfo_cb); - - rstats = RE_GetStats(re); - - if (update_flag & PR_UPDATE_VIEW) { - Object *object; - rp->resolution_divider = rp->start_resolution_divider; - - /* Same as database_init_objects(), loop over all objects. - * We might consider de-duplicating the code between this two cases. - */ - for (object = rp->bmain->object.first; object; object = object->id.next) { - float mat[4][4]; - mul_m4_m4m4(mat, rp->viewmat, object->obmat); - invert_m4_m4(object->imat_ren, mat); - } - } - - use_border = render_view3d_disprect(rp->scene, rp->depsgraph, - rp->ar, rp->v3d, rp->rv3d, - &cliprct); - - if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE | PR_UPDATE_VIEW)) || rstats->convertdone == 0) { - RenderData rdata; - - /* no osa, blur, seq, layers, savebuffer etc for preview render */ - rdata = rp->scene->r; - rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA); - rdata.scemode &= ~(R_DOSEQ | R_DOCOMP | R_FREE_IMAGE | R_EXR_TILE_FILE | R_FULL_SAMPLE); - rdata.scemode |= R_VIEWPORT_PREVIEW; - - /* we do use layers, but only active */ - rdata.scemode |= R_SINGLE_LAYER; - - /* initalize always */ - if (use_border) { - rdata.mode |= R_BORDER; - RE_InitState(re, NULL, &rdata, &rp->scene->view_layers, rp->scene->active_view_layer, NULL, rp->ar->winx, rp->ar->winy, &cliprct); - } - else - RE_InitState(re, NULL, &rdata, &rp->scene->view_layers, rp->scene->active_view_layer, NULL, rp->ar->winx, rp->ar->winy, NULL); - } - - if (orth) - RE_SetOrtho(re, &viewplane, clipsta, clipend); - else - RE_SetWindow(re, &viewplane, clipsta, clipend); - - RE_SetPixelSize(re, pixsize); - - if ((update_flag & PR_UPDATE_DATABASE) || rstats->convertdone == 0) { - unsigned int lay = rp->scene->lay; - - /* allow localview render for objects with lights in normal layers */ - if (rp->v3d->lay & 0xFF000000) - lay |= rp->v3d->lay; - else lay = rp->v3d->lay; - - RE_SetView(re, rp->viewmat); - - /* copying blender data while main thread is locked, to avoid crashes */ - WM_job_main_thread_lock_acquire(rp->job); - RE_Database_Free(re); - RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0); // 0= dont use camera view - WM_job_main_thread_lock_release(rp->job); - - /* do preprocessing like building raytree, shadows, volumes, SSS */ - RE_Database_Preprocess(rp->depsgraph, re); - - /* conversion not completed, need to do it again */ - if (!rstats->convertdone) { - if (render_view3d_is_valid(rp)) { - rp->engine->job_update_flag |= PR_UPDATE_DATABASE; - } - } - - // printf("dbase update\n"); - } - else { - // printf("dbase rotate\n"); - RE_DataBase_IncrementalView(re, rp->viewmat, 0); - restore = 1; - } - - RE_DataBase_ApplyWindow(re); - - /* OK, can we enter render code? */ - if (rstats->convertdone) { - bool first_time = true; - - if (update_flag & PR_UPDATE_VIEW) { - ob_inst_update_flag |= RE_OBJECT_INSTANCES_UPDATE_VIEW; - } - - RE_updateRenderInstances(re, ob_inst_update_flag); - - for (;;) { - int pixel_size = BKE_render_preview_pixel_size(&rp->scene->r); - if (first_time == false) { - if (restore) - RE_DataBase_IncrementalView(re, rp->viewmat, 1); - - rp->resolution_divider = MAX2(rp->resolution_divider / 2, pixel_size); - *do_update = 1; - - render_update_resolution(re, rp, use_border, &cliprct); - - RE_DataBase_IncrementalView(re, rp->viewmat, 0); - RE_DataBase_ApplyWindow(re); - restore = 1; - } - else { - render_update_resolution(re, rp, use_border, &cliprct); - } - - RE_TileProcessor(re); - - first_time = false; - - if (*stop || rp->resolution_divider == pixel_size) { - break; - } - } - - /* always rotate back */ - if (restore) - RE_DataBase_IncrementalView(re, rp->viewmat, 1); - } -} - -static void render_view3d_free(void *customdata) -{ - RenderPreview *rp = customdata; - - MEM_freeN(rp); -} - -static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C) -{ - RegionView3D *rv3d = CTX_wm_region_view3d(C); - View3D *v3d = CTX_wm_view3d(C); - ARegion *ar = CTX_wm_region(C); - Scene *scene = CTX_data_scene(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); - Render *re; - rctf viewplane; - rcti disprect; - float clipsta, clipend; - bool orth; - int job_update_flag = 0; - char name[32]; - - /* ensure render engine exists */ - re = engine->re; - - if (!re) { - sprintf(name, "View3dPreview %p", (void *)ar); - re = engine->re = RE_GetRender(name); - if (!re) - re = engine->re = RE_NewRender(name); - - engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; - } - - /* check update_flag */ - if (engine->update_flag & RE_ENGINE_UPDATE_MA) - job_update_flag |= PR_UPDATE_MATERIAL; - - if (engine->update_flag & RE_ENGINE_UPDATE_OTHER) - job_update_flag |= PR_UPDATE_MATERIAL; - - if (engine->update_flag & RE_ENGINE_UPDATE_DATABASE) { - job_update_flag |= PR_UPDATE_DATABASE; - - /* load editmesh */ - Object *obedit = CTX_data_edit_object(C); - if (obedit) { - ED_object_editmode_load(obedit); - } - } - - engine->update_flag = 0; - - /* check if viewport changed */ - if (engine->last_winx != ar->winx || engine->last_winy != ar->winy) { - engine->last_winx = ar->winx; - engine->last_winy = ar->winy; - job_update_flag |= PR_UPDATE_RENDERSIZE; - } - - if (compare_m4m4(engine->last_viewmat, rv3d->viewmat, 0.00001f) == 0) { - copy_m4_m4(engine->last_viewmat, rv3d->viewmat); - job_update_flag |= PR_UPDATE_VIEW; - } - - render_view3d_get_rects(depsgraph, ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth); - - if (BLI_rctf_compare(&viewplane, &engine->last_viewplane, 0.00001f) == 0) { - engine->last_viewplane = viewplane; - job_update_flag |= PR_UPDATE_VIEW; - } - - render_view3d_disprect(scene, depsgraph, ar, v3d, rv3d, &disprect); - if (BLI_rcti_compare(&disprect, &engine->last_disprect) == 0) { - engine->last_disprect = disprect; - job_update_flag |= PR_UPDATE_RENDERSIZE; - } - - /* any changes? go ahead and rerender */ - if (job_update_flag) { - engine->job_update_flag |= job_update_flag; - return true; - } - - return false; -} - -static void render_view3d_do(RenderEngine *engine, const bContext *C) -{ - wmJob *wm_job; - RenderPreview *rp; - Scene *scene = CTX_data_scene(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); - ARegion *ar = CTX_wm_region(C); - int width = ar->winx, height = ar->winy; - int divider = BKE_render_preview_pixel_size(&scene->r); - int resolution_threshold = scene->r.preview_start_resolution * - scene->r.preview_start_resolution; - - if (CTX_wm_window(C) == NULL) - return; - if (!render_view3d_flag_changed(engine, C)) - return; - - wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview", - WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); - rp = MEM_callocN(sizeof(RenderPreview), "render preview"); - rp->job = wm_job; - - while (width * height > resolution_threshold) { - width = max_ii(1, width / 2); - height = max_ii(1, height / 2); - divider *= 2; - } - - /* customdata for preview thread */ - rp->scene = scene; - rp->depsgraph = depsgraph; - rp->engine = engine; - rp->sa = CTX_wm_area(C); - rp->ar = CTX_wm_region(C); - rp->v3d = rp->sa->spacedata.first; - rp->rv3d = CTX_wm_region_view3d(C); - rp->bmain = CTX_data_main(C); - rp->resolution_divider = divider; - rp->start_resolution_divider = divider; - rp->has_freestyle = (scene->r.mode & R_EDGE_FRS) != 0; - copy_m4_m4(rp->viewmat, rp->rv3d->viewmat); - - /* clear info text */ - engine->text[0] = '\0'; - - /* setup job */ - WM_jobs_customdata_set(wm_job, rp, render_view3d_free); - WM_jobs_timer(wm_job, 0.1, NC_SPACE | ND_SPACE_VIEW3D, NC_SPACE | ND_SPACE_VIEW3D); - WM_jobs_callbacks(wm_job, render_view3d_startjob, NULL, NULL, NULL); - - WM_jobs_start(CTX_wm_manager(C), wm_job); - - engine->flag &= ~RE_ENGINE_DO_UPDATE; -} - -/* callback for render engine, on changes */ -void render_view3d_update(RenderEngine *engine, const bContext *C) -{ - /* this shouldn't be needed and causes too many database rebuilds, but we - * aren't actually tracking updates for all relevant datablocks so this is - * a catch-all for updates */ - engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; - - render_view3d_do(engine, C); -} - -void render_view3d_draw(RenderEngine *engine, const bContext *C) -{ - Render *re = engine->re; - RenderResult rres; - char name[32]; - - render_view3d_do(engine, C); - - if (re == NULL) { - sprintf(name, "View3dPreview %p", (void *)CTX_wm_region(C)); - re = RE_GetRender(name); - - if (re == NULL) return; - } - - /* Viewport render preview doesn't support multiview, view hardcoded to 0 */ - RE_AcquireResultImage(re, &rres, 0); - - if (rres.rectf) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); - ARegion *ar = CTX_wm_region(C); - bool force_fallback = false; - bool need_fallback = true; - float dither = scene->r.dither_intensity; - float scale_x, scale_y; - rcti clip_rect; - int xof, yof; - - if (render_view3d_disprect(scene, depsgraph, ar, v3d, rv3d, &clip_rect)) { - scale_x = (float) BLI_rcti_size_x(&clip_rect) / rres.rectx; - scale_y = (float) BLI_rcti_size_y(&clip_rect) / rres.recty; - xof = clip_rect.xmin; - yof = clip_rect.ymin; - } - else { - scale_x = (float) ar->winx / rres.rectx; - scale_y = (float) ar->winy / rres.recty; - xof = rres.xof; - yof = rres.yof; - } - - /* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */ - force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL); - - /* Try using GLSL display transform. */ - if (force_fallback == false) { - if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, dither, true)) { - glEnable(GL_BLEND); - IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); - immDrawPixelsTex(&state, xof, yof, rres.rectx, rres.recty, - GL_RGBA, GL_FLOAT, GL_NEAREST, rres.rectf, - scale_x, scale_y, NULL);; - glDisable(GL_BLEND); - - IMB_colormanagement_finish_glsl_draw(); - need_fallback = false; - } - } - - /* If GLSL failed, use old-school CPU-based transform. */ - if (need_fallback) { - unsigned char *display_buffer = MEM_mallocN(4 * rres.rectx * rres.recty * sizeof(char), - "render_view3d_draw"); - - IMB_colormanagement_buffer_make_display_space(rres.rectf, display_buffer, rres.rectx, rres.recty, - 4, dither, &scene->view_settings, &scene->display_settings); - - glEnable(GL_BLEND); - IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); - immDrawPixelsTex(&state, xof, yof, rres.rectx, rres.recty, - GL_RGBA, GL_UNSIGNED_BYTE, - GL_NEAREST, display_buffer, - scale_x, scale_y, NULL); - glDisable(GL_BLEND); - - MEM_freeN(display_buffer); - } - } - - RE_ReleaseResultImage(re); -} - -void ED_viewport_render_kill_jobs(wmWindowManager *wm, - Main *bmain, - bool free_database) -{ - bScreen *sc; - ScrArea *sa; - ARegion *ar; - - if (!wm) - return; - - /* kill all actively running jobs */ - WM_jobs_kill(wm, NULL, render_view3d_startjob); - - /* loop over 3D view render engines */ - for (sc = bmain->screen.first; sc; sc = sc->id.next) { - for (sa = sc->areabase.first; sa; sa = sa->next) { - if (sa->spacetype != SPACE_VIEW3D) - continue; - - for (ar = sa->regionbase.first; ar; ar = ar->next) { - RegionView3D *rv3d; - - if (ar->regiontype != RGN_TYPE_WINDOW) - continue; - - rv3d = ar->regiondata; - - if (rv3d->render_engine) { - /* free render database now before we change data, because - * RE_Database_Free will also loop over blender data */ - if (free_database) { - char name[32]; - Render *re; - - sprintf(name, "View3dPreview %p", (void *)ar); - re = RE_GetRender(name); - - if (re) - RE_Database_Free(re); - - /* tag render engine to update entire database */ - rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; - } - else { - /* quick shader update */ - rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_MA; - } - } - } - } - } -} - Scene *ED_render_job_get_scene(const bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); @@ -1716,6 +1099,7 @@ Scene *ED_render_job_get_current_scene(const bContext *C) return NULL; } + /* Motion blur curve preset */ static int render_shutter_curve_preset_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 840c5c2b5aa..1c6938cbdb3 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -270,7 +270,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R { Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = oglrender->scene; - ViewLayer *view_layer = oglrender->view_layer; ARegion *ar = oglrender->ar; View3D *v3d = oglrender->v3d; RegionView3D *rv3d = oglrender->rv3d; @@ -278,7 +277,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R int sizex = oglrender->sizex; int sizey = oglrender->sizey; const short view_context = (v3d != NULL); - bool draw_bgpic = true; bool draw_sky = (scene->r.alphamode == R_ADDSKY); float *rectf = NULL; const char *viewname = RE_GetActiveRenderView(oglrender->re); @@ -356,10 +354,8 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R draw_flags |= (oglrender->ofs_full_samples) ? V3D_OFSDRAW_USE_FULL_SAMPLE : 0; if (view_context) { - draw_flags |= (draw_bgpic) ? V3D_OFSDRAW_USE_BACKGROUND : 0; - ibuf_view = ED_view3d_draw_offscreen_imbuf( - depsgraph, scene, view_layer, v3d->drawtype, + depsgraph, scene, v3d->drawtype, v3d, ar, sizex, sizey, IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname, oglrender->ofs, err_out); @@ -370,9 +366,9 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R } } else { - draw_flags |= (V3D_OFSDRAW_USE_GPENCIL | V3D_OFSDRAW_USE_BACKGROUND); + draw_flags |= V3D_OFSDRAW_USE_GPENCIL; ibuf_view = ED_view3d_draw_offscreen_imbuf_simple( - depsgraph, scene, view_layer, OB_SOLID, + depsgraph, scene, OB_SOLID, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname, diff --git a/source/blender/editors/render/render_ops.c b/source/blender/editors/render/render_ops.c index bd75c6879e1..13fe40e768a 100644 --- a/source/blender/editors/render/render_ops.c +++ b/source/blender/editors/render/render_ops.c @@ -85,9 +85,6 @@ void ED_operatortypes_render(void) WM_operatortype_append(TEXTURE_OT_slot_copy); WM_operatortype_append(TEXTURE_OT_slot_paste); WM_operatortype_append(TEXTURE_OT_slot_move); - WM_operatortype_append(TEXTURE_OT_envmap_save); - WM_operatortype_append(TEXTURE_OT_envmap_clear); - WM_operatortype_append(TEXTURE_OT_envmap_clear_all); /* render_internal.c */ WM_operatortype_append(RENDER_OT_view_show); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index f2f147ab874..9a179ce3b47 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -242,32 +242,6 @@ void ED_preview_free_dbase(void) BKE_main_free(G_pr_main_cycles); } -static int preview_mat_has_sss(Material *mat, bNodeTree *ntree) -{ - if (mat) { - if (mat->sss_flag & MA_DIFF_SSS) - return 1; - if (mat->nodetree) - if (preview_mat_has_sss(NULL, mat->nodetree)) - return 1; - } - else if (ntree) { - bNode *node; - for (node = ntree->nodes.first; node; node = node->next) { - if (node->type == NODE_GROUP && node->id) { - if (preview_mat_has_sss(NULL, (bNodeTree *)node->id)) - return 1; - } - else if (node->id && ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) { - mat = (Material *)node->id; - if (mat->sss_flag & MA_DIFF_SSS) - return 1; - } - } - } - return 0; -} - static Scene *preview_get_scene(Main *pr_main) { if (pr_main == NULL) return NULL; @@ -382,7 +356,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty * seems commonly used render engines does not support * such kind of rendering. */ - BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine)); + BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(sce->r.engine)); } else { BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->r.engine)); @@ -397,83 +371,22 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty sp->matcopy = mat; BLI_addtail(&pr_main->mat, mat); - if (!BKE_scene_use_new_shading_nodes(scene)) { - init_render_material(mat, 0, NULL); /* call that retrieves mode_l */ - end_render_material(mat); - - /* un-useful option */ - if (sp->pr_method == PR_ICON_RENDER) - mat->shade_flag &= ~MA_OBCOLOR; - - /* turn on raytracing if needed */ - if (mat->mode_l & MA_RAYMIRROR) - sce->r.mode |= R_RAYTRACE; - if (mat->material_type == MA_TYPE_VOLUME) - sce->r.mode |= R_RAYTRACE; - if ((mat->mode_l & MA_RAYTRANSP) && (mat->mode_l & MA_TRANSP)) - sce->r.mode |= R_RAYTRACE; - if (preview_mat_has_sss(mat, NULL)) - sce->r.mode |= R_SSS; - - /* turn off fake shadows if needed */ - /* this only works in a specific case where the preview.blend contains - * an object starting with 'c' which has a material linked to it (not the obdata) - * and that material has a fake shadow texture in the active texture slot */ - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - Object *ob = base->object; - if (ob->id.name[2] == 'c') { - Material *shadmat = give_current_material(ob, ob->actcol); - if (shadmat) { - if (mat->mode2 & MA_CASTSHADOW) { - shadmat->septex = 0; - } - else { - shadmat->septex |= 1; - } - } - } - } - - /* turn off bounce lights for volume, - * doesn't make much visual difference and slows it down too */ - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - Object *ob = base->object; - if (ob->type == OB_LAMP) { - /* if doesn't match 'Lamp.002' --> main key light */ - if (!STREQ(ob->id.name + 2, "Lamp.002")) { - if (mat->material_type == MA_TYPE_VOLUME) { - base->flag &= ~BASE_VISIBLED; - } - else { - base->flag |= BASE_VISIBLED; - } - } - } - } + /* use current scene world to light sphere */ + if (mat->pr_type == MA_SPHERE_A && sp->pr_method == PR_BUTS_RENDER) { + /* Use current scene world to light sphere. */ + sce->world = preview_get_localized_world(sp, scene->world); } - else { - /* use current scene world to light sphere */ - if (mat->pr_type == MA_SPHERE_A && sp->pr_method == PR_BUTS_RENDER) { - /* Use current scene world to light sphere. */ - sce->world = preview_get_localized_world(sp, scene->world); - } - else if (sce->world) { - /* Use a default world color. Using the current - * scene world can be slow if it has big textures. */ - sce->world->use_nodes = false; - sce->world->horr = 0.5f; - sce->world->horg = 0.5f; - sce->world->horb = 0.5f; - } + else if (sce->world) { + /* Use a default world color. Using the current + * scene world can be slow if it has big textures. */ + sce->world->use_nodes = false; + sce->world->horr = 0.5f; + sce->world->horg = 0.5f; + sce->world->horb = 0.5f; } if (sp->pr_method == PR_ICON_RENDER) { - if (mat->material_type == MA_TYPE_HALO) { - set_preview_layer(view_layer, MA_FLAT); - } - else { - set_preview_layer(view_layer, MA_SPHERE_A); - } + set_preview_layer(view_layer, MA_SPHERE_A); } else { set_preview_layer(view_layer, mat->pr_type); @@ -486,7 +399,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } } else { - sce->r.mode &= ~(R_OSA | R_RAYTRACE | R_SSS); + sce->r.mode &= ~(R_OSA); } @@ -519,29 +432,6 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty } set_preview_layer(view_layer, MA_TEXTURE); - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (base->object->id.name[2] == 't') { - Material *mat = give_current_material(base->object, base->object->actcol); - if (mat && mat->mtex[0]) { - mat->mtex[0]->tex = tex; - - if (tex && sp->slot) - mat->mtex[0]->which_output = sp->slot->which_output; - - mat->mtex[0]->mapto &= ~MAP_ALPHA; - mat->alpha = 1.0f; - - /* show alpha in this case */ - if (tex == NULL || (tex->flag & TEX_PRV_ALPHA)) { - if (!(tex && tex->type == TEX_IMAGE && (tex->imaflag & (TEX_USEALPHA | TEX_CALCALPHA)) == 0)) { - mat->mtex[0]->mapto |= MAP_ALPHA; - mat->alpha = 0.0f; - } - } - } - } - } - if (tex && tex->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, true); @@ -558,28 +448,14 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty BLI_addtail(&pr_main->lamp, la); } - if (!BKE_scene_use_new_shading_nodes(scene)) { - if (la && la->type == LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) { - set_preview_layer(view_layer, MA_ATMOS); - sce->world = preview_get_localized_world(sp, scene->world); - sce->camera = (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name) + 2); - } - else { - sce->world = NULL; - sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2); - set_preview_layer(view_layer, MA_LAMP); - } - } - else { - set_preview_layer(view_layer, MA_LAMP); + set_preview_layer(view_layer, MA_LAMP); - if (sce->world) { - /* Only use lighting from the lamp. */ - sce->world->use_nodes = false; - sce->world->horr = 0.0f; - sce->world->horg = 0.0f; - sce->world->horb = 0.0f; - } + if (sce->world) { + /* Only use lighting from the lamp. */ + sce->world->use_nodes = false; + sce->world->horr = 0.0f; + sce->world->horg = 0.0f; + sce->world->horb = 0.0f; } for (Base *base = view_layer->object_bases.first; base; base = base->next) { @@ -1132,12 +1008,6 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat if (idtype == ID_WO) { set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); } - else if (idtype == ID_MA) { - Material *ma = (Material *)id; - - if (ma->material_type == MA_TYPE_HALO) - set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); - } } } } @@ -1182,7 +1052,6 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short { IconPreview *ip = (IconPreview *)customdata; IconPreviewSize *cur_size; - const bool use_new_shading = BKE_scene_use_new_shading_nodes(ip->scene); for (cur_size = ip->sizes.first; cur_size; cur_size = cur_size->next) { PreviewImage *prv = ip->owner; @@ -1207,19 +1076,14 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short if (is_render) { BLI_assert(ip->id); - if (use_new_shading) { - /* texture icon rendering is hardcoded to use BI, - * so don't even think of using cycle's bmain for - * texture icons - */ - if (GS(ip->id->name) != ID_TE) - sp->pr_main = G_pr_main_cycles; - else - sp->pr_main = G_pr_main; - } - else { + /* texture icon rendering is hardcoded to use the BI scene, + * so don't even think of using cycle's bmain for + * texture icons + */ + if (GS(ip->id->name) != ID_TE) + sp->pr_main = G_pr_main_cycles; + else sp->pr_main = G_pr_main; - } } common_preview_startjob(sp, stop, do_update, progress); @@ -1344,10 +1208,9 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M short id_type = GS(id->name); /* Use workspace render only for buttons Window, since the other previews are related to the datablock. */ - bool use_new_shading = BKE_scene_use_new_shading_nodes(scene); /* Only texture node preview is supported with Cycles. */ - if (use_new_shading && method == PR_NODE_RENDER && id_type != ID_TE) { + if (method == PR_NODE_RENDER && id_type != ID_TE) { return; } @@ -1368,9 +1231,9 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M sp->slot = slot; sp->bmain = CTX_data_main(C); - /* hardcoded preview .blend for Eevee + cycles/internal, this should be solved + /* hardcoded preview .blend for Eevee + Cycles, this should be solved * once with custom preview .blend path for external engines */ - if ((method != PR_NODE_RENDER) && id_type != ID_TE && use_new_shading) { + if ((method != PR_NODE_RENDER) && id_type != ID_TE) { sp->pr_main = G_pr_main_cycles; } else { @@ -1388,11 +1251,9 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M WM_jobs_start(CTX_wm_manager(C), wm_job); } -void ED_preview_kill_jobs(wmWindowManager *wm, Main *bmain) +void ED_preview_kill_jobs(wmWindowManager *wm, Main *UNUSED(bmain)) { if (wm) WM_jobs_kill(wm, NULL, common_preview_startjob); - - ED_viewport_render_kill_jobs(wm, bmain, false); } diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 270ba2a7947..c5787a1d46c 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -460,7 +460,6 @@ void OBJECT_OT_material_slot_move(wmOperatorType *ot) static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) { - Scene *scene = CTX_data_scene(C); Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data; Main *bmain = CTX_data_main(C); PointerRNA ptr, idptr; @@ -472,11 +471,8 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) } else { ma = BKE_material_add(bmain, DATA_("Material")); - - if (BKE_scene_use_new_shading_nodes(scene)) { - ED_node_shader_default(C, &ma->id); - ma->use_nodes = true; - } + ED_node_shader_default(C, &ma->id); + ma->use_nodes = true; } /* hook into UI */ @@ -536,14 +532,6 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op)) * pointer use also increases user, so this compensates it */ id_us_min(&tex->id); - if (ptr.id.data && GS(((ID *)ptr.id.data)->name) == ID_MA && - RNA_property_pointer_get(&ptr, prop).id.data == NULL) - { - /* In case we are assigning new texture to a material, and active slot was empty, reset 'use' flag. */ - Material *ma = (Material *)ptr.id.data; - ma->septex &= ~(1 << ma->texact); - } - RNA_id_pointer_create(&tex->id, &idptr); RNA_property_pointer_set(&ptr, prop, idptr); RNA_property_update(C, &ptr, prop); @@ -572,7 +560,6 @@ void TEXTURE_OT_new(wmOperatorType *ot) static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) { - Scene *scene = CTX_data_scene(C); World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data; Main *bmain = CTX_data_main(C); PointerRNA ptr, idptr; @@ -584,11 +571,8 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) } else { wo = BKE_world_add(bmain, DATA_("World")); - - if (BKE_scene_use_new_shading_nodes(scene)) { - ED_node_shader_default(C, &wo->id); - wo->use_nodes = true; - } + ED_node_shader_default(C, &wo->id); + wo->use_nodes = true; } /* hook into UI */ @@ -1457,15 +1441,6 @@ static int texture_slot_move_exec(bContext *C, wmOperator *op) BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act - 1, -1, 0); BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act - 1, 0); BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0); - - if (GS(id->name) == ID_MA) { - Material *ma = (Material *)id; - int mtexuse = ma->septex & (1 << act); - ma->septex &= ~(1 << act); - ma->septex |= (ma->septex & (1 << (act - 1))) << 1; - ma->septex &= ~(1 << (act - 1)); - ma->septex |= mtexuse >> 1; - } set_active_mtex(id, act - 1); } @@ -1479,15 +1454,6 @@ static int texture_slot_move_exec(bContext *C, wmOperator *op) BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act + 1, -1, 0); BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act + 1, 0); BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0); - - if (GS(id->name) == ID_MA) { - Material *ma = (Material *)id; - int mtexuse = ma->septex & (1 << act); - ma->septex &= ~(1 << act); - ma->septex |= (ma->septex & (1 << (act + 1))) >> 1; - ma->septex &= ~(1 << (act + 1)); - ma->septex |= mtexuse << 1; - } set_active_mtex(id, act + 1); } @@ -1524,180 +1490,6 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot) -/********************** environment map operators *********************/ - -static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, const char imtype) -{ - PropertyRNA *prop; - float layout[12]; - - if ((prop = RNA_struct_find_property(op->ptr, "layout"))) { - RNA_property_float_get_array(op->ptr, prop, layout); - } - else { - memcpy(layout, default_envmap_layout, sizeof(layout)); - } - - if (RE_WriteEnvmapResult(op->reports, scene, env, path, imtype, layout)) { - return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } - -} - -static int envmap_save_exec(bContext *C, wmOperator *op) -{ - Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - Scene *scene = CTX_data_scene(C); - //int imtype = RNA_enum_get(op->ptr, "file_type"); - char imtype = scene->r.im_format.imtype; - char path[FILE_MAX]; - - RNA_string_get(op->ptr, "filepath", path); - - if (scene->r.scemode & R_EXTENSION) { - BKE_image_path_ensure_ext_from_imformat(path, &scene->r.im_format); - } - - WM_cursor_wait(1); - - save_envmap(op, scene, tex->env, path, imtype); - - WM_cursor_wait(0); - - WM_event_add_notifier(C, NC_TEXTURE, tex); - - return OPERATOR_FINISHED; -} - -static int envmap_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - //Scene *scene= CTX_data_scene(C); - - if (RNA_struct_property_is_set(op->ptr, "filepath")) - return envmap_save_exec(C, op); - - //RNA_enum_set(op->ptr, "file_type", scene->r.im_format.imtype); - RNA_string_set(op->ptr, "filepath", G.main->name); - WM_event_add_fileselect(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int envmap_save_poll(bContext *C) -{ - Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - - if (!tex) - return 0; - if (!tex->env || !tex->env->ok) - return 0; - if (tex->env->cube[1] == NULL) - return 0; - - return 1; -} - -void TEXTURE_OT_envmap_save(wmOperatorType *ot) -{ - PropertyRNA *prop; - /* identifiers */ - ot->name = "Save Environment Map"; - ot->idname = "TEXTURE_OT_envmap_save"; - ot->description = "Save the current generated Environment map to an image file"; - - /* api callbacks */ - ot->exec = envmap_save_exec; - ot->invoke = envmap_save_invoke; - ot->poll = envmap_save_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; /* no undo since this doesnt modify the env-map */ - - /* properties */ - prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, - "File layout", - "Flat array describing the X,Y position of each cube face in the output image, " - "where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " - "(use -1 to skip a face)", 0.0f, 0.0f); - RNA_def_property_flag(prop, PROP_HIDDEN); - - WM_operator_properties_filesel( - ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_SAVE, - WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); -} - -static int envmap_clear_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - - BKE_texture_envmap_free_data(tex->env); - - WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex); - - return OPERATOR_FINISHED; -} - -static int envmap_clear_poll(bContext *C) -{ - Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; - - if (!tex) - return 0; - if (!tex->env || !tex->env->ok) - return 0; - if (tex->env->cube[1] == NULL) - return 0; - - return 1; -} - -void TEXTURE_OT_envmap_clear(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Clear Environment Map"; - ot->idname = "TEXTURE_OT_envmap_clear"; - ot->description = "Discard the environment map and free it from memory"; - - /* api callbacks */ - ot->exec = envmap_clear_exec; - ot->poll = envmap_clear_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; -} - -static int envmap_clear_all_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Main *bmain = CTX_data_main(C); - Tex *tex; - - for (tex = bmain->tex.first; tex; tex = tex->id.next) - if (tex->env) - BKE_texture_envmap_free_data(tex->env); - - WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex); - - return OPERATOR_FINISHED; -} - -void TEXTURE_OT_envmap_clear_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Clear All Environment Maps"; - ot->idname = "TEXTURE_OT_envmap_clear_all"; - ot->description = "Discard all environment maps in the .blend file and free them from memory"; - - /* api callbacks */ - ot->exec = envmap_clear_all_exec; - ot->poll = envmap_clear_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - /********************** material operators *********************/ /* material copy/paste */ @@ -1769,17 +1561,6 @@ static void copy_mtex_copybuf(ID *id) MTex **mtex = NULL; switch (GS(id->name)) { - case ID_MA: - mtex = &(((Material *)id)->mtex[(int)((Material *)id)->texact]); - break; - case ID_LA: - mtex = &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]); - // la->mtex[(int)la->texact] // TODO - break; - case ID_WO: - mtex = &(((World *)id)->mtex[(int)((World *)id)->texact]); - // mtex= wrld->mtex[(int)wrld->texact]; // TODO - break; case ID_PA: mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]); break; @@ -1807,17 +1588,6 @@ static void paste_mtex_copybuf(ID *id) return; switch (GS(id->name)) { - case ID_MA: - mtex = &(((Material *)id)->mtex[(int)((Material *)id)->texact]); - break; - case ID_LA: - mtex = &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]); - // la->mtex[(int)la->texact] // TODO - break; - case ID_WO: - mtex = &(((World *)id)->mtex[(int)((World *)id)->texact]); - // mtex= wrld->mtex[(int)wrld->texact]; // TODO - break; case ID_PA: mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]); break; diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 9ae103ae017..1864cb0af6a 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -59,9 +59,7 @@ #include "BKE_scene.h" #include "BKE_workspace.h" -#include "GPU_lamp.h" #include "GPU_material.h" -#include "GPU_buffers.h" #include "RE_engine.h" #include "RE_pipeline.h" @@ -145,20 +143,18 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update } else { - RenderEngineType *engine_type = RE_engines_find(win->scene->r.engine); - if ((engine_type->flag & RE_USE_LEGACY_PIPELINE) == 0) { - if (updated) { - DRW_notify_view_update( - (&(DRWUpdateContext){ - .bmain = bmain, - .depsgraph = update_ctx->depsgraph, - .scene = scene, - .view_layer = view_layer, - .ar = ar, - .v3d = (View3D *)sa->spacedata.first, - .engine_type = engine_type - })); - } + RenderEngineType *engine_type = RE_engines_find(scene->r.engine); + if (updated) { + DRW_notify_view_update( + (&(DRWUpdateContext){ + .bmain = bmain, + .depsgraph = update_ctx->depsgraph, + .scene = scene, + .view_layer = view_layer, + .ar = ar, + .v3d = (View3D *)sa->spacedata.first, + .engine_type = engine_type + })); } } } @@ -243,69 +239,8 @@ static void render_engine_flag_changed(Main *bmain, int update_flag) } } -static int mtex_use_tex(MTex **mtex, int tot, Tex *tex) +static void material_changed(Main *UNUSED(bmain), Material *ma) { - int a; - - if (!mtex) - return 0; - - for (a = 0; a < tot; a++) - if (mtex[a] && mtex[a]->tex == tex) - return 1; - - return 0; -} - -static int nodes_use_tex(bNodeTree *ntree, Tex *tex) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id) { - if (node->id == (ID *)tex) { - return 1; - } - else if (GS(node->id->name) == ID_MA) { - if (mtex_use_tex(((Material *)node->id)->mtex, MAX_MTEX, tex)) - return 1; - } - else if (node->type == NODE_GROUP) { - if (nodes_use_tex((bNodeTree *)node->id, tex)) - return 1; - } - } - } - - return 0; -} - -static int nodes_use_material(bNodeTree *ntree, Material *ma) -{ - bNode *node; - - for (node = ntree->nodes.first; node; node = node->next) { - if (node->id) { - if (node->id == (ID *)ma) { - return 1; - } - else if (node->type == NODE_GROUP) { - if (nodes_use_material((bNodeTree *)node->id, ma)) - return 1; - } - } - } - - return 0; -} - -static void material_changed(Main *bmain, Material *ma) -{ - Material *parent; - Object *ob; - Scene *scene; - int texture_draw = false; - /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&ma->id)); @@ -315,86 +250,22 @@ static void material_changed(Main *bmain, Material *ma) GPU_material_free(&ma->gpumaterial); } } - - /* find node materials using this */ - for (parent = bmain->mat.first; parent; parent = parent->id.next) { - if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) { - /* pass */ - } - else { - continue; - } - - BKE_icon_changed(BKE_icon_id_ensure(&parent->id)); - - if (parent->gpumaterial.first) - GPU_material_free(&parent->gpumaterial); - } - - /* find if we have a scene with textured display */ - for (scene = bmain->scene.first; scene; scene = scene->id.next) { - if (scene->customdata_mask & CD_MASK_MTFACE) { - texture_draw = true; - break; - } - } - - /* find textured objects */ - if (texture_draw) { - for (ob = bmain->object.first; ob; ob = ob->id.next) { - DerivedMesh *dm = ob->derivedFinal; - Material ***material = give_matarar(ob); - short a, *totmaterial = give_totcolp(ob); - - if (dm && totmaterial && material) { - for (a = 0; a < *totmaterial; a++) { - if ((*material)[a] == ma) { - GPU_drawobject_free(dm); - break; - } - } - } - } - } - } -static void lamp_changed(Main *bmain, Lamp *la) +static void lamp_changed(Main *UNUSED(bmain), Lamp *la) { - Object *ob; - /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&la->id)); - /* glsl */ - for (ob = bmain->object.first; ob; ob = ob->id.next) - if (ob->data == la && ob->gpulamp.first) - GPU_lamp_free(ob); - if (defmaterial.gpumaterial.first) GPU_material_free(&defmaterial.gpumaterial); } -static int material_uses_texture(Material *ma, Tex *tex) -{ - if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) - return true; - else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) - return true; - - return false; -} - static void texture_changed(Main *bmain, Tex *tex) { - Material *ma; - Lamp *la; - World *wo; Scene *scene; ViewLayer *view_layer; - Object *ob; bNode *node; - bool texture_draw = false; /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&tex->id)); @@ -406,48 +277,6 @@ static void texture_changed(Main *bmain, Tex *tex) } } - /* find materials */ - for (ma = bmain->mat.first; ma; ma = ma->id.next) { - if (!material_uses_texture(ma, tex)) - continue; - - BKE_icon_changed(BKE_icon_id_ensure(&ma->id)); - - if (ma->gpumaterial.first) - GPU_material_free(&ma->gpumaterial); - } - - /* find lamps */ - for (la = bmain->lamp.first; la; la = la->id.next) { - if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) { - lamp_changed(bmain, la); - } - else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) { - lamp_changed(bmain, la); - } - else { - continue; - } - } - - /* find worlds */ - for (wo = bmain->world.first; wo; wo = wo->id.next) { - if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) { - /* pass */ - } - else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) { - /* pass */ - } - else { - continue; - } - - BKE_icon_changed(BKE_icon_id_ensure(&wo->id)); - - if (wo->gpumaterial.first) - GPU_material_free(&wo->gpumaterial); - } - /* find compositing nodes */ for (scene = bmain->scene.first; scene; scene = scene->id.next) { if (scene->use_nodes && scene->nodetree) { @@ -456,32 +285,6 @@ static void texture_changed(Main *bmain, Tex *tex) ED_node_tag_update_id(&scene->id); } } - - if (scene->customdata_mask & CD_MASK_MTFACE) - texture_draw = true; - } - - /* find textured objects */ - if (texture_draw) { - for (ob = bmain->object.first; ob; ob = ob->id.next) { - DerivedMesh *dm = ob->derivedFinal; - Material ***material = give_matarar(ob); - short a, *totmaterial = give_totcolp(ob); - - if (dm && totmaterial && material) { - for (a = 0; a < *totmaterial; a++) { - if (ob->matbits && ob->matbits[a]) - ma = ob->mat[a]; - else - ma = (*material)[a]; - - if (ma && material_uses_texture(ma, tex)) { - GPU_drawobject_free(dm); - break; - } - } - } - } } } @@ -526,7 +329,6 @@ static void scene_changed(Main *bmain, Scene *scene) if (ob->mode & OB_MODE_TEXTURE_PAINT) { BKE_texpaint_slots_refresh_object(scene, ob); BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); - GPU_drawobject_free(ob->derivedFinal); } } } @@ -568,12 +370,3 @@ void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id) } } - -void ED_render_internal_init(void) -{ - RenderEngineType *ret = RE_engines_find(RE_engine_id_BLENDER_RENDER); - - ret->view_update = render_view3d_update; - ret->render_to_view = render_view3d_draw; - -} diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index ae26de8b269..dbb12282d0a 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -78,7 +78,6 @@ #include "RNA_define.h" #include "GPU_draw.h" -#include "GPU_buffers.h" #include "GPU_immediate.h" #include "BIF_gl.h" @@ -1121,7 +1120,6 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) // ED_workspace_object_mode_sync_from_object(wm, workspace, ob); - GPU_drawobject_free(ob->derivedFinal); WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 469498f927a..cacb75b2668 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -283,7 +283,6 @@ typedef struct ProjPaintState { bool do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */ bool do_mask_normal; /* mask out pixels based on their normals */ bool do_mask_cavity; /* mask out pixels based on cavity */ - bool do_new_shading_nodes; /* cache BKE_scene_use_new_shading_nodes value */ float normal_angle; /* what angle to mask at */ float normal_angle__cos; /* cos(normal_angle), faster to compare */ float normal_angle_inner; @@ -5102,7 +5101,6 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int else { ps->do_backfacecull = ps->do_occlude = ps->do_mask_normal = 0; } - ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */ if (ps->tool == PAINT_TOOL_CLONE) ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) ? 1 : 0; @@ -5438,7 +5436,6 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); ToolSettings *settings = scene->toolsettings; View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -5455,7 +5452,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (h > maxsize) h = maxsize; ibuf = ED_view3d_draw_offscreen_imbuf( - depsgraph, scene, view_layer, v3d->drawtype, + depsgraph, scene, v3d->drawtype, v3d, CTX_wm_region(C), w, h, IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL, NULL, err_out); @@ -5626,20 +5623,11 @@ bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *m /* Add layer operator */ static const EnumPropertyItem layer_type_items[] = { - {MAP_COL, "DIFFUSE_COLOR", 0, "Diffuse Color", ""}, - {MAP_REF, "DIFFUSE_INTENSITY", 0, "Diffuse Intensity", ""}, - {MAP_ALPHA, "ALPHA", 0, "Alpha", ""}, - {MAP_TRANSLU, "TRANSLUCENCY", 0, "Translucency", ""}, - {MAP_COLSPEC, "SPECULAR_COLOR", 0, "Specular Color", ""}, - {MAP_SPEC, "SPECULAR_INTENSITY", 0, "Specular Intensity", ""}, - {MAP_HAR, "SPECULAR_HARDNESS", 0, "Specular Hardness", ""}, - {MAP_AMB, "AMBIENT", 0, "Ambient", ""}, - {MAP_EMIT, "EMIT", 0, "Emit", ""}, - {MAP_COLMIR, "MIRROR_COLOR", 0, "Mirror Color", ""}, - {MAP_RAYMIRR, "RAYMIRROR", 0, "Ray Mirror", ""}, - {MAP_NORM, "NORMAL", 0, "Normal", ""}, - {MAP_WARP, "WARP", 0, "Warp", ""}, - {MAP_DISPLACE, "DISPLACE", 0, "Displace", ""}, + {0, "BASE_COLOR", 0, "Base Color", ""}, + {1, "EMISSION", 0, "Emission", ""}, + {2, "NORMAL", 0, "Normal", ""}, + {3, "BUMP", 0, "Bump", ""}, + {4, "DISPLACEMENT", 0, "Displacement", ""}, {0, NULL, 0, NULL, NULL} }; @@ -5674,7 +5662,6 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene); Image *ima = NULL; if (!ob) @@ -5683,55 +5670,29 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op) ma = give_current_material(ob, ob->actcol); if (ma) { + /* TODO: use type to link to proper socket. */ Main *bmain = CTX_data_main(C); - if (!is_bi && BKE_scene_use_new_shading_nodes(scene)) { - bNode *imanode; - bNodeTree *ntree = ma->nodetree; - - if (!ntree) { - ED_node_shader_default(C, &ma->id); - ntree = ma->nodetree; - } - - ma->use_nodes = true; - - /* try to add an image node */ - imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); - - ima = proj_paint_image_create(op, bmain); - imanode->id = &ima->id; - - nodeSetActive(ntree, imanode); - - ntreeUpdateTree(CTX_data_main(C), ntree); - } - else { - MTex *mtex = BKE_texture_mtex_add_id(&ma->id, -1); - - /* successful creation of mtex layer, now create set */ - if (mtex) { - int type = MAP_COL; - char imagename_buff[MAX_ID_NAME - 2]; - const char *imagename = DATA_("Diffuse Color"); - - if (op) { - type = RNA_enum_get(op->ptr, "type"); - RNA_string_get(op->ptr, "name", imagename_buff); - imagename = imagename_buff; - } - - mtex->tex = BKE_texture_add(bmain, imagename); - mtex->mapto = type; - - if (mtex->tex) { - ima = mtex->tex->ima = proj_paint_image_create(op, bmain); - } + bNode *imanode; + bNodeTree *ntree = ma->nodetree; - WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex); - } + if (!ntree) { + ED_node_shader_default(C, &ma->id); + ntree = ma->nodetree; } + ma->use_nodes = true; + + /* try to add an image node */ + imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE); + + ima = proj_paint_image_create(op, bmain); + imanode->id = &ima->id; + + nodeSetActive(ntree, imanode); + + ntreeUpdateTree(CTX_data_main(C), ntree); + if (ima) { BKE_texpaint_slot_refresh_cache(scene, ma); BKE_image_signal(ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE); @@ -5822,59 +5783,6 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot) RNA_def_boolean(ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth"); } -static int texture_paint_delete_texture_paint_slot_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *ob = CTX_data_active_object(C); - Scene *scene = CTX_data_scene(C); - Material *ma; - bool is_bi = BKE_scene_uses_blender_internal(scene); - TexPaintSlot *slot; - - /* not supported for node-based engines */ - if (!ob || !is_bi) - return OPERATOR_CANCELLED; - - ma = give_current_material(ob, ob->actcol); - - if (!ma->texpaintslot || ma->use_nodes) - return OPERATOR_CANCELLED; - - slot = ma->texpaintslot + ma->paint_active_slot; - - if (ma->mtex[slot->index]->tex) { - id_us_min(&ma->mtex[slot->index]->tex->id); - - if (ma->mtex[slot->index]->tex->ima) { - id_us_min(&ma->mtex[slot->index]->tex->ima->id); - } - } - MEM_freeN(ma->mtex[slot->index]); - ma->mtex[slot->index] = NULL; - - BKE_texpaint_slot_refresh_cache(scene, ma); - DEG_id_tag_update(&ma->id, 0); - WM_event_add_notifier(C, NC_MATERIAL, ma); - /* we need a notifier for data change since we change the displayed modifier uvs */ - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); - return OPERATOR_FINISHED; -} - - -void PAINT_OT_delete_texture_paint_slot(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Delete Texture Paint Slot"; - ot->description = "Delete selected texture paint slot"; - ot->idname = "PAINT_OT_delete_texture_paint_slot"; - - /* api callbacks */ - ot->exec = texture_paint_delete_texture_paint_slot_exec; - ot->poll = ED_operator_region_view3d_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) { /* no checks here, poll function does them for us */ diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 4298fba3b2b..ca82ca52463 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -216,7 +216,6 @@ void PAINT_OT_texture_paint_toggle(struct wmOperatorType *ot); void PAINT_OT_project_image(struct wmOperatorType *ot); void PAINT_OT_image_from_view(struct wmOperatorType *ot); void PAINT_OT_add_texture_paint_slot(struct wmOperatorType *ot); -void PAINT_OT_delete_texture_paint_slot(struct wmOperatorType *ot); void PAINT_OT_image_paint(struct wmOperatorType *ot); void PAINT_OT_add_simple_uvs(struct wmOperatorType *ot); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 004d2757a71..ad3047d6345 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -1035,7 +1035,6 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_image_from_view); WM_operatortype_append(PAINT_OT_brush_colors_flip); WM_operatortype_append(PAINT_OT_add_texture_paint_slot); - WM_operatortype_append(PAINT_OT_delete_texture_paint_slot); WM_operatortype_append(PAINT_OT_add_simple_uvs); /* weight */ diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 0ae6db1f41d..1775d4b9c8b 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -3100,10 +3100,6 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P * avoid this if we can! */ DEG_id_tag_update(ob->data, 0); } - else { - /* If using new VBO drawing, mark mcol as dirty to force colors gpu buffer refresh! */ - ob->derivedFinal->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW; - } } static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 3af789d4ebe..1d1c8460cfd 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -87,9 +87,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "GPU_buffers.h" -#include "GPU_extensions.h" - #include "UI_interface.h" #include "UI_resources.h" @@ -4866,8 +4863,6 @@ static void sculpt_flush_update(bContext *C) if (mmd) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); - if (ob->derivedFinal) /* VBO no longer valid */ - GPU_drawobject_free(ob->derivedFinal); if (ss->kb || ss->modifiers_active) { DEG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -5734,11 +5729,6 @@ void ED_object_sculptmode_enter_ex( } // ED_workspace_object_mode_sync_from_object(G.main->wm.first, workspace, ob); - - /* VBO no longer valid */ - if (ob->derivedFinal) { - GPU_drawobject_free(ob->derivedFinal); - } } void ED_object_sculptmode_enter(struct bContext *C, ReportList *reports) @@ -5791,11 +5781,6 @@ void ED_object_sculptmode_exit_ex( BKE_sculptsession_free(ob); paint_cursor_delete_textures(); - - /* VBO no longer valid */ - if (ob->derivedFinal) { - GPU_drawobject_free(ob->derivedFinal); - } } void ED_object_sculptmode_exit(bContext *C) diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 3feb8e105e6..b819fe8e97d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -66,8 +66,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "GPU_buffers.h" - #include "ED_paint.h" #include "ED_object.h" #include "ED_sculpt.h" @@ -585,9 +583,6 @@ static void sculpt_undo_restore_list(bContext *C, ListBase *lb) else { sculpt_update_object_bounding_box(ob); } - - /* for non-PBVH drawing, need to recreate VBOs */ - GPU_drawobject_free(ob->derivedFinal); } } diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 3f3cb8bce4b..fbdf543e5c4 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -147,9 +147,6 @@ void ED_spacetypes_init(void) type->operatortypes(); } } - - /* register internal render callbacks */ - ED_render_internal_init(); } void ED_spacemacros_init(void) diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 8866c6b6c40..b7ba8b5e065 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -279,7 +279,7 @@ static int buttons_context_path_modifier(ButsContextPath *path) return 0; } -static int buttons_context_path_material(ButsContextPath *path, bool for_texture, bool new_shading) +static int buttons_context_path_material(ButsContextPath *path) { Object *ob; PointerRNA *ptr = &path->ptr[path->len - 1]; @@ -297,18 +297,6 @@ static int buttons_context_path_material(ButsContextPath *path, bool for_texture ma = give_current_material(ob, ob->actcol); RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); path->len++; - - if (for_texture && give_current_material_texture_node(ma)) - return 1; - - if (!new_shading) { - /* Only try to get mat from node in case of old shading system (see T40331). */ - ma = give_node_material(ma); - if (ma) { - RNA_id_pointer_create(&ma->id, &path->ptr[path->len]); - path->len++; - } - } return 1; } } @@ -441,132 +429,38 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path) static int buttons_context_path_texture(const bContext *C, ButsContextPath *path, ButsContextTexture *ct) { - if (ct) { - /* new shading system */ - PointerRNA *ptr = &path->ptr[path->len - 1]; - ID *id; - - /* if we already have a (pinned) texture, we're done */ - if (RNA_struct_is_a(ptr->type, &RNA_Texture)) - return 1; - - if (!ct->user) - return 0; - - id = ct->user->id; - - if (id) { - if (GS(id->name) == ID_BR) - buttons_context_path_brush(C, path); - else if (GS(id->name) == ID_MA) - buttons_context_path_material(path, false, true); - else if (GS(id->name) == ID_WO) - buttons_context_path_world(path); - else if (GS(id->name) == ID_LA) - buttons_context_path_data(path, OB_LAMP); - else if (GS(id->name) == ID_PA) - buttons_context_path_particle(path); - else if (GS(id->name) == ID_OB) - buttons_context_path_object(path); - else if (GS(id->name) == ID_LS) - buttons_context_path_linestyle(path); - } + PointerRNA *ptr = &path->ptr[path->len - 1]; + ID *id; - if (ct->texture) { - RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]); - path->len++; - } + if (!ct) + return 0; + /* if we already have a (pinned) texture, we're done */ + if (RNA_struct_is_a(ptr->type, &RNA_Texture)) return 1; - } - else { - /* old shading system */ - Material *ma; - Lamp *la; - World *wo; - ParticleSystem *psys; - FreestyleLineStyle *ls; - Tex *tex; - PointerRNA *ptr = &path->ptr[path->len - 1]; - - /* if we already have a (pinned) texture, we're done */ - if (RNA_struct_is_a(ptr->type, &RNA_Texture)) { - return 1; - } - /* try world */ - else if ((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) { - wo = path->ptr[path->len - 1].data; - - if (wo && GS(wo->id.name) == ID_WO) { - tex = give_current_world_texture(wo); - - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } - /* try particles */ - else if ((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) { - if (path->ptr[path->len - 1].type == &RNA_ParticleSettings) { - ParticleSettings *part = path->ptr[path->len - 1].data; - - tex = give_current_particle_texture(part); - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - else { - psys = path->ptr[path->len - 1].data; - - if (psys && psys->part && GS(psys->part->id.name) == ID_PA) { - tex = give_current_particle_texture(psys->part); - - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } - } - /* try material */ - else if ((path->tex_ctx == SB_TEXC_MATERIAL) && buttons_context_path_material(path, true, false)) { - ma = path->ptr[path->len - 1].data; - - if (ma) { - tex = give_current_material_texture(ma); - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } - /* try lamp */ - else if ((path->tex_ctx == SB_TEXC_LAMP) && buttons_context_path_data(path, OB_LAMP)) { - la = path->ptr[path->len - 1].data; - - if (la) { - tex = give_current_lamp_texture(la); - - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } - /* try linestyle */ - else if ((path->tex_ctx == SB_TEXC_LINESTYLE) && buttons_context_path_linestyle(path)) { - ls = path->ptr[path->len - 1].data; + if (!ct->user) + return 0; + + id = ct->user->id; - if (ls) { - tex = give_current_linestyle_texture(ls); + if (id) { + if (GS(id->name) == ID_BR) + buttons_context_path_brush(C, path); + else if (GS(id->name) == ID_PA) + buttons_context_path_particle(path); + else if (GS(id->name) == ID_OB) + buttons_context_path_object(path); + else if (GS(id->name) == ID_LS) + buttons_context_path_linestyle(path); + } - RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); - path->len++; - return 1; - } - } + if (ct->texture) { + RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]); + path->len++; } - /* no path to a texture possible */ - return 0; + return 1; } #ifdef WITH_FREESTYLE @@ -606,7 +500,6 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma memset(path, 0, sizeof(*path)); path->flag = flag; - path->tex_ctx = sbuts->texture_context; const bool use_scene_settings = BKE_workspace_use_scene_settings_get(workspace); @@ -679,7 +572,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma found = buttons_context_path_particle(path); break; case BCONTEXT_MATERIAL: - found = buttons_context_path_material(path, false, (sbuts->texuser != NULL)); + found = buttons_context_path_material(path); break; case BCONTEXT_TEXTURE: found = buttons_context_path_texture(C, path, sbuts->texuser); @@ -737,7 +630,7 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts) path = sbuts->path; - /* We need to set Scene path now! Else, buttons_texture_context_compute() might not get a valid scene. */ + /* Set scene path. */ buttons_context_path(C, path, BCONTEXT_SCENE, pflag); buttons_texture_context_compute(C, sbuts); @@ -890,13 +783,8 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r ButsContextTexture *ct = sbuts->texuser; if (ct) { - /* new shading system */ CTX_data_pointer_set(result, &ct->texture->id, &RNA_Texture, ct->texture); } - else { - /* old shading system */ - set_pointer_type(path, result, &RNA_Texture); - } return 1; } @@ -920,7 +808,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r ButsContextTexture *ct = sbuts->texuser; if (!ct) - return -1; /* old shading system (found but not available) */ + return -1; if (ct->user && ct->user->ptr.data) { ButsTextureUser *user = ct->user; @@ -933,7 +821,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r ButsContextTexture *ct = sbuts->texuser; if (!ct) - return -1; /* old shading system (found but not available) */ + return -1; if (ct->user && ct->user->ptr.data) { ButsTextureUser *user = ct->user; @@ -953,21 +841,6 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r return 1; } - else { - /* old shading system */ - PointerRNA *ptr; - - if ((ptr = get_pointer_type(path, &RNA_Material))) { - Material *ma = ptr->data; - - if (ma) { - bNode *node = give_current_material_texture_node(ma); - CTX_data_pointer_set(result, &ma->nodetree->id, &RNA_Node, node); - } - } - - return 1; - } } else if (CTX_data_equals(member, "texture_slot")) { ButsContextTexture *ct = sbuts->texuser; @@ -983,38 +856,6 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r else if (ct) { return 0; /* new shading system */ } - else if ((ptr = get_pointer_type(path, &RNA_Material))) { - Material *ma = ptr->data; - - /* if we have a node material, get slot from material in material node */ - if (ma && ma->use_nodes && ma->nodetree) { - /* if there's an active texture node in the node tree, - * then that texture is in context directly, without a texture slot */ - if (give_current_material_texture_node(ma)) - return 0; - - ma = give_node_material(ma); - if (ma) - CTX_data_pointer_set(result, &ma->id, &RNA_MaterialTextureSlot, ma->mtex[(int)ma->texact]); - else - return 0; - } - else if (ma) { - CTX_data_pointer_set(result, &ma->id, &RNA_MaterialTextureSlot, ma->mtex[(int)ma->texact]); - } - } - else if ((ptr = get_pointer_type(path, &RNA_Lamp))) { - Lamp *la = ptr->data; - - if (la) - CTX_data_pointer_set(result, &la->id, &RNA_LampTextureSlot, la->mtex[(int)la->texact]); - } - else if ((ptr = get_pointer_type(path, &RNA_World))) { - World *wo = ptr->data; - - if (wo) - CTX_data_pointer_set(result, &wo->id, &RNA_WorldTextureSlot, wo->mtex[(int)wo->texact]); - } else if ((ptr = get_pointer_type(path, &RNA_FreestyleLineStyle))) { FreestyleLineStyle *ls = ptr->data; diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index e6d19caad47..84c935dd737 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -64,7 +64,6 @@ typedef struct ButsContextPath { PointerRNA ptr[8]; int len; int flag; - int tex_ctx; int collection_ctx; } ButsContextPath; diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 809480baece..df06eee3fd5 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -41,8 +41,6 @@ #include "DNA_brush_types.h" #include "DNA_ID.h" -#include "DNA_lamp_types.h" -#include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_object_force_types.h" @@ -50,13 +48,11 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" -#include "DNA_world_types.h" #include "DNA_linestyle_types.h" #include "BKE_context.h" #include "BKE_layer.h" #include "BKE_linestyle.h" -#include "BKE_material.h" #include "BKE_modifier.h" #include "BKE_node.h" #include "BKE_paint.h" @@ -79,172 +75,6 @@ #include "buttons_intern.h" // own include -/****************** "Old Shading" Texture Context ****************/ - -bool ED_texture_context_check_world(const bContext *C) -{ - Scene *scene = CTX_data_scene(C); - return (scene && scene->world); -} - -bool ED_texture_context_check_material(const bContext *C) -{ - Object *ob = CTX_data_active_object(C); - return (ob && (ob->totcol != 0)); -} - -bool ED_texture_context_check_lamp(const bContext *C) -{ - Object *ob = CTX_data_active_object(C); - return (ob && (ob->type == OB_LAMP)); -} - -bool ED_texture_context_check_particles(const bContext *C) -{ - Object *ob = CTX_data_active_object(C); - return (ob && ob->particlesystem.first); -} - -bool ED_texture_context_check_linestyle(const bContext *C) -{ -#ifdef WITH_FREESTYLE - Scene *scene = CTX_data_scene(C); - ViewLayer *active_view_layer; - FreestyleConfig *config; - FreestyleLineSet *lineset; - FreestyleLineStyle *linestyle; - - if (scene && (scene->r.mode & R_EDGE_FRS)) { - active_view_layer = BLI_findlink(&scene->view_layers, scene->active_view_layer); - config = &active_view_layer->freestyle_config; - if (config->mode == FREESTYLE_CONTROL_EDITOR_MODE) { - lineset = BKE_freestyle_lineset_get_active(config); - if (lineset) { - linestyle = lineset->linestyle; - return linestyle && (linestyle->flag & LS_TEXTURE); - } - } - } -#else - (void)C; -#endif - return false; -} - -static void texture_context_check_modifier_foreach(void *userData, Object *UNUSED(ob), ModifierData *UNUSED(md), - const char *UNUSED(propname)) -{ - *((bool *)userData) = true; -} - -bool ED_texture_context_check_others(const bContext *C) -{ - /* We cannot rely on sbuts->texuser here, as it is NULL when in "old" tex handling, non-OTHERS tex context. */ - Object *ob = CTX_data_active_object(C); - - /* object */ - if (ob) { - /* Tex force field. */ - if (ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) { - return true; - } - - /* modifiers */ - { - bool check = false; - modifiers_foreachTexLink(ob, texture_context_check_modifier_foreach, &check); - if (check) { - return true; - } - } - } - - /* brush */ - if (BKE_paint_brush(BKE_paint_get_active_from_context(C))) { - return true; - } - - return false; -} - -static void set_texture_context(const bContext *C, SpaceButs *sbuts) -{ - Scene *scene = CTX_data_scene(C); - - if (BKE_scene_use_new_shading_nodes(scene)) { - return; /* No texture context in new shading mode */ - } - - { - bool valid_world = ED_texture_context_check_world(C); - bool valid_material = ED_texture_context_check_material(C); - bool valid_lamp = ED_texture_context_check_lamp(C); - bool valid_particles = ED_texture_context_check_particles(C); - bool valid_linestyle = ED_texture_context_check_linestyle(C); - bool valid_others = ED_texture_context_check_others(C); - - /* this is similar to direct user action, no need to keep "better" ctxt in _prev */ - if ((sbuts->mainb == BCONTEXT_WORLD) && valid_world) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_WORLD; - } - else if ((sbuts->mainb == BCONTEXT_MATERIAL) && valid_material) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_MATERIAL; - } - else if ((sbuts->mainb == BCONTEXT_DATA) && valid_lamp) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_LAMP; - } - else if ((sbuts->mainb == BCONTEXT_PARTICLE) && valid_particles) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_PARTICLES; - } - else if ((sbuts->mainb == BCONTEXT_VIEW_LAYER) && valid_linestyle) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_LINESTYLE; - } - else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && valid_others) { - sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_OTHER; - } - /* Else, try to revive a previous "better" ctxt... */ - else if ((sbuts->texture_context_prev != sbuts->texture_context) && - (((sbuts->texture_context_prev == SB_TEXC_WORLD) && valid_world) || - ((sbuts->texture_context_prev == SB_TEXC_MATERIAL) && valid_material) || - ((sbuts->texture_context_prev == SB_TEXC_LAMP) && valid_lamp) || - ((sbuts->texture_context_prev == SB_TEXC_PARTICLES) && valid_particles) || - ((sbuts->texture_context_prev == SB_TEXC_LINESTYLE) && valid_linestyle) || - ((sbuts->texture_context_prev == SB_TEXC_OTHER) && valid_others))) - { - sbuts->texture_context = sbuts->texture_context_prev; - } - /* Else, just be sure that current context is valid! */ - else if (((sbuts->texture_context == SB_TEXC_WORLD) && !valid_world) || - ((sbuts->texture_context == SB_TEXC_MATERIAL) && !valid_material) || - ((sbuts->texture_context == SB_TEXC_LAMP) && !valid_lamp) || - ((sbuts->texture_context == SB_TEXC_PARTICLES) && !valid_particles) || - ((sbuts->texture_context == SB_TEXC_LINESTYLE) && !valid_linestyle) || - ((sbuts->texture_context == SB_TEXC_OTHER) && !valid_others)) - { - /* this is default fallback, do keep "better" ctxt in _prev */ - sbuts->texture_context_prev = sbuts->texture_context; - if (valid_material) { - sbuts->texture_context = SB_TEXC_MATERIAL; - } - else if (valid_lamp) { - sbuts->texture_context = SB_TEXC_LAMP; - } - else if (valid_particles) { - sbuts->texture_context = SB_TEXC_PARTICLES; - } - else if (valid_linestyle) { - sbuts->texture_context = SB_TEXC_LINESTYLE; - } - else if (valid_world) { - sbuts->texture_context = SB_TEXC_WORLD; - } - else if (valid_others) { - sbuts->texture_context = SB_TEXC_OTHER; - } - } - } -} - /************************* Texture User **************************/ static void buttons_texture_user_property_add(ListBase *users, ID *id, @@ -322,9 +152,6 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * { Scene *scene = NULL; Object *ob = NULL; - Material *ma = NULL; - Lamp *la = NULL; - World *wrld = NULL; WorkSpace *workspace = NULL; FreestyleLineStyle *linestyle = NULL; Brush *brush = NULL; @@ -337,12 +164,6 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * scene = (Scene *)pinid; else if (GS(pinid->name) == ID_OB) ob = (Object *)pinid; - else if (GS(pinid->name) == ID_LA) - la = (Lamp *)pinid; - else if (GS(pinid->name) == ID_WO) - wrld = (World *)pinid; - else if (GS(pinid->name) == ID_MA) - ma = (Material *)pinid; else if (GS(pinid->name) == ID_BR) brush = (Brush *)pinid; else if (GS(pinid->name) == ID_LS) @@ -360,7 +181,6 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); if (workspace == NULL) { - wrld = scene->world; linestyle = BKE_linestyle_active_from_scene(scene); workspace = CTX_wm_workspace(C); } @@ -369,20 +189,9 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * ob = OBACT(view_layer); } - if (ob && ob->type == OB_LAMP && !la) - la = ob->data; - if (ob && !ma) - ma = give_current_material(ob, ob->actcol); - /* fill users */ BLI_listbase_clear(users); - if (ma && !limited_mode) - buttons_texture_users_find_nodetree(users, &ma->id, ma->nodetree, N_("Material")); - if (la && !limited_mode) - buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, N_("Lamp")); - if (wrld && !limited_mode) - buttons_texture_users_find_nodetree(users, &wrld->id, wrld->nodetree, N_("World")); if (linestyle && !limited_mode) buttons_texture_users_find_nodetree(users, &linestyle->id, linestyle->nodetree, N_("Line Style")); @@ -451,21 +260,8 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts) /* gather available texture users in context. runs on every draw of * properties editor, before the buttons are created. */ ButsContextTexture *ct = sbuts->texuser; - Scene *scene = CTX_data_scene(C); ID *pinid = sbuts->pinid; - set_texture_context(C, sbuts); - - if (!((sbuts->texture_context == SB_TEXC_OTHER) || BKE_scene_use_new_shading_nodes(scene))) { - if (ct) { - BLI_freelistN(&ct->users); - MEM_freeN(ct); - sbuts->texuser = NULL; - } - - return; - } - if (!ct) { ct = MEM_callocN(sizeof(ButsContextTexture), "ButsContextTexture"); sbuts->texuser = ct; @@ -699,4 +495,3 @@ void uiTemplateTextureShow(uiLayout *layout, bContext *C, PointerRNA *ptr, Prope UI_but_func_set(but, template_texture_show, user->ptr.data, user->prop); } } - diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index c719af9e0e2..c598e486a7e 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -63,11 +63,8 @@ Image *ED_space_image(SpaceImage *sima) } /* called to assign images to UV faces */ -void ED_space_image_set(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima) +void ED_space_image_set(SpaceImage *sima, Scene *UNUSED(scene), Object *obedit, Image *ima) { - /* context may be NULL, so use global */ - ED_uvedit_assign_image(G.main, scene, obedit, ima, sima->image); - /* change the space ima after because uvedit_face_visible_test uses the space ima * to check if the face is displayed in UV-localview */ sima->image = ima; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 9162b8b76a9..a905e61dd88 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -73,7 +73,6 @@ #include "DEG_depsgraph.h" #include "GPU_draw.h" -#include "GPU_buffers.h" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" @@ -2445,7 +2444,6 @@ static int image_new_exec(bContext *C, wmOperator *op) bScreen *sc; Object *ob = CTX_data_active_object(C); - GPU_drawobject_free(ob->derivedFinal); if (scene->toolsettings->imapaint.canvas) id_us_min(&scene->toolsettings->imapaint.canvas->id); scene->toolsettings->imapaint.canvas = ima; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 54037059cc3..38a850568fd 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -410,7 +410,6 @@ static void image_refresh(const bContext *C, ScrArea *sa) { Scene *scene = CTX_data_scene(C); SpaceImage *sima = sa->spacedata.first; - Object *obedit = CTX_data_edit_object(C); Image *ima; ima = ED_space_image(sima); @@ -426,32 +425,6 @@ static void image_refresh(const bContext *C, ScrArea *sa) } } } - else if (ima && (ima->source == IMA_SRC_VIEWER || sima->pin)) { - /* pass */ - } - else if (obedit && obedit->type == OB_MESH) { - Mesh *me = (Mesh *)obedit->data; - struct BMEditMesh *em = me->edit_btmesh; - bool sloppy = true; /* partially selected face is ok */ - bool selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION); /* only selected active face? */ - - if (BKE_scene_use_new_shading_nodes(scene)) { - /* new shading system does not alter image */ - } - else { - /* old shading system, we set texface */ - if (em && EDBM_uv_check(em)) { - BMFace *efa = BM_mesh_active_face_get(em->bm, sloppy, selected); - - if (efa) { - /* don't need to check for pin here, see above */ - Image *image = BKE_object_material_edit_image_get(obedit, efa->mat_nr); - - sima->image = image; - } - } - } - } } static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *scene, diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 448286c7c3d..ca6ae5955a9 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -679,21 +679,6 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr, } } -static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr) -{ - bNode *node = ptr->data; - uiLayout *col; - - uiTemplateID(layout, C, ptr, "material", "MATERIAL_OT_new", NULL, NULL, UI_TEMPLATE_ID_FILTER_ALL); - - if (!node->id) return; - - col = uiLayoutColumn(layout, false); - uiItemR(col, ptr, "use_diffuse", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "use_specular", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "invert_normal", 0, NULL, ICON_NONE); -} - static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiLayout *row, *col, *sub; @@ -741,30 +726,6 @@ static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C uiItemR(layout, ptr, "convert_to", 0, "", ICON_NONE); } -static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA *ptr) -{ - PointerRNA obptr = CTX_data_pointer_get(C, "active_object"); - uiLayout *col; - - col = uiLayoutColumn(layout, false); - - if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) { - PointerRNA dataptr = RNA_pointer_get(&obptr, "data"); - - uiItemPointerR(col, ptr, "uv_layer", &dataptr, "uv_layers", "", ICON_NONE); - uiItemPointerR(col, ptr, "color_layer", &dataptr, "vertex_colors", "", ICON_NONE); - } - else { - uiItemR(col, ptr, "uv_layer", 0, IFACE_("UV"), ICON_NONE); - uiItemR(col, ptr, "color_layer", 0, IFACE_("VCol"), ICON_NONE); - } -} - -static void node_shader_buts_lamp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) -{ - uiItemR(layout, ptr, "lamp_object", 0, IFACE_("Lamp Object"), ICON_NONE); -} - static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "attribute_name", 0, IFACE_("Name"), ICON_NONE); @@ -1108,13 +1069,6 @@ static void node_shader_buts_bevel(uiLayout *layout, bContext *UNUSED(C), Pointe static void node_shader_set_butfunc(bNodeType *ntype) { switch (ntype->type) { - case SH_NODE_MATERIAL: - case SH_NODE_MATERIAL_EXT: - ntype->draw_buttons = node_shader_buts_material; - break; - case SH_NODE_TEXTURE: - ntype->draw_buttons = node_buts_texture; - break; case SH_NODE_NORMAL: ntype->draw_buttons = node_buts_normal; break; @@ -1148,12 +1102,6 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_VECT_TRANSFORM: ntype->draw_buttons = node_shader_buts_vect_transform; break; - case SH_NODE_GEOMETRY: - ntype->draw_buttons = node_shader_buts_geometry; - break; - case SH_NODE_LAMP: - ntype->draw_buttons = node_shader_buts_lamp; - break; case SH_NODE_ATTRIBUTE: ntype->draw_buttons = node_shader_buts_attribute; break; diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index ec35727d176..c200c5a7612 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -316,10 +316,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op) switch (snode->nodetree->type) { case NTREE_SHADER: - if (BKE_scene_use_new_shading_nodes(CTX_data_scene(C))) - type = SH_NODE_TEX_IMAGE; - else - type = SH_NODE_TEXTURE; + type = SH_NODE_TEX_IMAGE; break; case NTREE_TEXTURE: type = TEX_NODE_IMAGE; @@ -340,14 +337,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (type == SH_NODE_TEXTURE) { - Tex *tex = BKE_texture_add(CTX_data_main(C), DATA_(ima->id.name)); - tex->ima = ima; - node->id = (ID *)tex; - WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, node->id); - } - else - node->id = (ID *)ima; + node->id = (ID *)ima; /* When adding new image file via drag-drop we need to load imbuf in order * to get proper image source. diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index c82c56ea648..ae810b0fde0 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -879,10 +879,6 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN char showname[128]; /* 128 used below */ View2D *v2d = &ar->v2d; - /* XXX hack: copy values from linked ID data where displayed as sockets */ - if (node->block) - nodeSynchronizeID(node, false); - /* skip if out of view */ if (BLI_rctf_isect(&node->totr, &v2d->cur, NULL) == false) { UI_block_end(C, node->block); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index b6680d8560f..340184845b8 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -383,7 +383,6 @@ bool ED_node_is_texture(struct SpaceNode *snode) /* called from shading buttons or header */ void ED_node_shader_default(const bContext *C, ID *id) { - Scene *scene = CTX_data_scene(C); bNode *in, *out; bNodeSocket *fromsock, *tosock, *sock; bNodeTree *ntree; @@ -398,18 +397,8 @@ void ED_node_shader_default(const bContext *C, ID *id) Material *ma = (Material *)id; ma->nodetree = ntree; - if (BKE_scene_uses_blender_eevee(scene)) { - output_type = SH_NODE_OUTPUT_MATERIAL; - shader_type = SH_NODE_BSDF_PRINCIPLED; - } - else if (BKE_scene_use_new_shading_nodes(scene)) { - output_type = SH_NODE_OUTPUT_MATERIAL; - shader_type = SH_NODE_BSDF_DIFFUSE; - } - else { - output_type = SH_NODE_OUTPUT; - shader_type = SH_NODE_MATERIAL; - } + output_type = SH_NODE_OUTPUT_MATERIAL; + shader_type = SH_NODE_BSDF_PRINCIPLED; copy_v3_v3(color, &ma->r); strength = 0.0f; @@ -460,18 +449,16 @@ void ED_node_shader_default(const bContext *C, ID *id) nodeAddLink(ntree, in, fromsock, out, tosock); /* default values */ - if (BKE_scene_use_new_shading_nodes(scene)) { - PointerRNA sockptr; - sock = in->inputs.first; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr); - - RNA_float_set_array(&sockptr, "default_value", color); + PointerRNA sockptr; + sock = in->inputs.first; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr); + + RNA_float_set_array(&sockptr, "default_value", color); - if (strength != 0.0f) { - sock = in->inputs.last; - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr); - RNA_float_set(&sockptr, "default_value", strength); - } + if (strength != 0.0f) { + sock = in->inputs.last; + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sockptr); + RNA_float_set(&sockptr, "default_value", strength); } ntreeUpdateTree(CTX_data_main(C), ntree); @@ -550,12 +537,6 @@ void snode_set_context(const bContext *C) bNodeTree *ntree = snode->nodetree; ID *id = snode->id, *from = snode->from; - /* we use this to signal warnings, when node shaders are drawn in wrong render engine */ - if (BKE_scene_use_new_shading_nodes(CTX_data_scene(C))) - snode->flag |= SNODE_NEW_SHADERS; - else - snode->flag &= ~SNODE_NEW_SHADERS; - /* check the tree type */ if (!treetype || (treetype->poll && !treetype->poll(C, treetype))) @@ -643,7 +624,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) if (node->id && ELEM(GS(node->id->name), ID_MA, ID_LA, ID_WO)) nodeClearActiveID(ntree, ID_TE); - if (ELEM(node->type, SH_NODE_OUTPUT, SH_NODE_OUTPUT_MATERIAL, + if (ELEM(node->type, SH_NODE_OUTPUT_MATERIAL, SH_NODE_OUTPUT_WORLD, SH_NODE_OUTPUT_LAMP, SH_NODE_OUTPUT_LINESTYLE)) { bNode *tnode; @@ -1321,40 +1302,6 @@ void NODE_OT_read_viewlayers(wmOperatorType *ot) ot->flag = 0; } -static int node_read_fullsamplelayers_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Main *bmain = CTX_data_main(C); - SpaceNode *snode = CTX_wm_space_node(C); - Scene *curscene = CTX_data_scene(C); - Render *re = RE_NewSceneRender(curscene); - - WM_cursor_wait(1); - RE_MergeFullSample(re, bmain, curscene, snode->nodetree); - WM_cursor_wait(0); - - /* note we are careful to send the right notifier, as otherwise the - * compositor would reexecute and overwrite the full sample result */ - WM_event_add_notifier(C, NC_SCENE | ND_COMPO_RESULT, NULL); - - return OPERATOR_FINISHED; -} - - -void NODE_OT_read_fullsamplelayers(wmOperatorType *ot) -{ - - ot->name = "Read Full Sample Layers"; - ot->idname = "NODE_OT_read_fullsamplelayers"; - ot->description = "Read all render layers of current scene, in full sample"; - - ot->exec = node_read_fullsamplelayers_exec; - - ot->poll = composite_node_active; - - /* flags */ - ot->flag = 0; -} - int node_render_changed_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *sce = CTX_data_scene(C); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 1859785173c..c9c29212f02 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -95,7 +95,6 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_insert_offset); WM_operatortype_append(NODE_OT_read_viewlayers); - WM_operatortype_append(NODE_OT_read_fullsamplelayers); WM_operatortype_append(NODE_OT_render_changed); WM_operatortype_append(NODE_OT_backimage_move); @@ -336,7 +335,6 @@ void node_keymap(struct wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "exit", true); WM_keymap_add_item(keymap, "NODE_OT_read_viewlayers", RKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "NODE_OT_read_fullsamplelayers", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "NODE_OT_render_changed", ZKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_clipboard_copy", CKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 173c919e38c..ed64cb6a6e1 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -455,10 +455,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) int compatibility = 0; if (ntree->type == NTREE_SHADER) { - if (BKE_scene_use_new_shading_nodes(arg->scene)) - compatibility = NODE_NEW_SHADING; - else - compatibility = NODE_OLD_SHADING; + compatibility = NODE_NEW_SHADING; } /* generate array of node types sorted by UI name */ diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 6fc5ac62949..a6a178b570d 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -382,13 +382,13 @@ static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) } -static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *scene, +static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene), WorkSpace *UNUSED(workspace)) { /* note, ED_area_tag_refresh will re-execute compositor */ SpaceNode *snode = sa->spacedata.first; /* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */ - short shader_type = BKE_scene_use_new_shading_nodes(scene) ? snode->shaderfrom : SNODE_SHADER_OBJECT; + short shader_type = snode->shaderfrom; /* preview renders */ switch (wmn->category) { diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 9ddaf6d7642..73f450e9392 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -253,93 +253,6 @@ static eOLDrawState tree_element_active_material( return OL_DRAWSEL_NONE; } -static eOLDrawState tree_element_active_texture( - bContext *C, Scene *scene, ViewLayer *view_layer, SpaceOops *UNUSED(soops), - TreeElement *te, const eOLSetState set) -{ - TreeElement *tep; - TreeStoreElem /* *tselem,*/ *tselemp; - Object *ob = OBACT(view_layer); - SpaceButs *sbuts = NULL; - - if (ob == NULL) { - /* no active object */ - return OL_DRAWSEL_NONE; - } - - /*tselem = TREESTORE(te);*/ /*UNUSED*/ - - /* find buttons region (note, this is undefined really still, needs recode in blender) */ - /* XXX removed finding sbuts */ - - /* where is texture linked to? */ - tep = te->parent; - tselemp = TREESTORE(tep); - - if (tep->idcode == ID_WO) { - World *wrld = (World *)tselemp->id; - - if (set != OL_SETSEL_NONE) { - if (sbuts) { - // XXX sbuts->tabo = TAB_SHADING_TEX; // hack from header_buttonswin.c - // XXX sbuts->texfrom = 1; - } -// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture - wrld->texact = te->index; - } - else if (tselemp->id == (ID *)(scene->world)) { - if (wrld->texact == te->index) { - return OL_DRAWSEL_NORMAL; - } - } - } - else if (tep->idcode == ID_LA) { - Lamp *la = (Lamp *)tselemp->id; - if (set != OL_SETSEL_NONE) { - if (sbuts) { - // XXX sbuts->tabo = TAB_SHADING_TEX; // hack from header_buttonswin.c - // XXX sbuts->texfrom = 2; - } -// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture - la->texact = te->index; - } - else { - if (tselemp->id == ob->data) { - if (la->texact == te->index) { - return OL_DRAWSEL_NORMAL; - } - } - } - } - else if (tep->idcode == ID_MA) { - Material *ma = (Material *)tselemp->id; - if (set != OL_SETSEL_NONE) { - if (sbuts) { - //sbuts->tabo = TAB_SHADING_TEX; // hack from header_buttonswin.c - // XXX sbuts->texfrom = 0; - } -// XXX extern_set_butspace(F6KEY, 0); // force shading buttons texture - ma->texact = (char)te->index; - - /* also set active material */ - ob->actcol = tep->index + 1; - } - else if (tep->flag & TE_ACTIVE) { // this is active material - if (ma->texact == te->index) { - return OL_DRAWSEL_NORMAL; - } - } - } - - if (set != OL_SETSEL_NONE) { - WM_event_add_notifier(C, NC_TEXTURE, NULL); - } - - /* no active object */ - return OL_DRAWSEL_NONE; -} - - static eOLDrawState tree_element_active_lamp( bContext *UNUSED(C), Scene *UNUSED(scene), ViewLayer *view_layer, SpaceOops *soops, TreeElement *te, const eOLSetState set) @@ -827,8 +740,6 @@ eOLDrawState tree_element_active(bContext *C, Scene *scene, ViewLayer *view_laye return tree_element_active_world(C, scene, view_layer, soops, te, set); case ID_LA: return tree_element_active_lamp(C, scene, view_layer, soops, te, set); - case ID_TE: - return tree_element_active_texture(C, scene, view_layer, soops, te, set); case ID_TXT: return tree_element_active_text(C, scene, view_layer, soops, te, set); case ID_CA: diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 735e2b5a37a..89c0712c217 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -196,19 +196,7 @@ static void unlink_texture_cb( MTex **mtex = NULL; int a; - if (GS(tsep->id->name) == ID_MA) { - Material *ma = (Material *)tsep->id; - mtex = ma->mtex; - } - else if (GS(tsep->id->name) == ID_LA) { - Lamp *la = (Lamp *)tsep->id; - mtex = la->mtex; - } - else if (GS(tsep->id->name) == ID_WO) { - World *wrld = (World *)tsep->id; - mtex = wrld->mtex; - } - else if (GS(tsep->id->name) == ID_LS) { + if (GS(tsep->id->name) == ID_LS) { FreestyleLineStyle *ls = (FreestyleLineStyle *)tsep->id; mtex = ls->mtex; } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index d418c571a8d..cd171bbc8ce 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -408,11 +408,6 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s outliner_add_element(soops, lb, sce, te, TSE_ANIM_DATA, 0); outliner_add_element(soops, lb, sce->gpd, te, 0, 0); - -#ifdef WITH_FREESTYLE - if (STREQ(sce->view_render->engine_id, RE_engine_id_BLENDER_RENDER) && (sce->r.mode & R_EDGE_FRS)) - outliner_add_line_styles(soops, lb, sce, te); -#endif } TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) @@ -750,14 +745,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor case ID_MA: { Material *ma = (Material *)id; - int a; if (outliner_animdata_test(ma->adt)) outliner_add_element(soops, &te->subtree, ma, te, TSE_ANIM_DATA, 0); - - for (a = 0; a < MAX_MTEX; a++) { - if (ma->mtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a); - } break; } case ID_TE: @@ -791,14 +781,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor case ID_LA: { Lamp *la = (Lamp *)id; - int a; if (outliner_animdata_test(la->adt)) outliner_add_element(soops, &te->subtree, la, te, TSE_ANIM_DATA, 0); - - for (a = 0; a < MAX_MTEX; a++) { - if (la->mtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a); - } break; } case ID_SPK: @@ -820,14 +805,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor case ID_WO: { World *wrld = (World *)id; - int a; if (outliner_animdata_test(wrld->adt)) outliner_add_element(soops, &te->subtree, wrld, te, TSE_ANIM_DATA, 0); - - for (a = 0; a < MAX_MTEX; a++) { - if (wrld->mtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a); - } break; } case ID_KE: diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index d027729c7a7..f8e38587117 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -43,11 +43,7 @@ set(INC_SYS ) set(SRC - drawanimviz.c - drawarmature.c - drawmesh.c drawobject.c - drawsimdebug.c drawvolume.c space_view3d.c view3d_buttons.c diff --git a/source/blender/editors/space_view3d/drawanimviz.c b/source/blender/editors/space_view3d/drawanimviz.c deleted file mode 100644 index 9fa85b55362..00000000000 --- a/source/blender/editors/space_view3d/drawanimviz.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * 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) 2009 by the Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Joshua Leung - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/drawanimviz.c - * \ingroup spview3d - */ - - -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#include "BLI_sys_types.h" - -#include "DNA_anim_types.h" -#include "DNA_armature_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" -#include "DNA_object_types.h" - -#include "BLI_math.h" -#include "BLI_dlrbTree.h" - -#include "BKE_animsys.h" -#include "BKE_action.h" - -#include "GPU_immediate.h" -#include "GPU_matrix.h" - -#include "ED_keyframes_draw.h" - - -#include "UI_resources.h" - -#include "view3d_intern.h" - -/* ************************************ Motion Paths ************************************* */ - -/* TODO: - * - options to draw paths with lines - * - include support for editing the path verts */ - -/* Set up drawing environment for drawing motion paths */ -void draw_motion_paths_init(View3D *v3d, ARegion *ar) -{ - RegionView3D *rv3d = ar->regiondata; - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); -} - -/* set color - * - more intense for active/selected bones, less intense for unselected bones - * - black for before current frame, green for current frame, blue for after current frame - * - intensity decreases as distance from current frame increases - * - * If the user select custom color, the color is replaced for the color selected in UI panel - * - 75% Darker color is used for previous frames - * - 50% Darker color for current frame - * - User selected color for next frames - */ -static void set_motion_path_color(Scene *scene, bMotionPath *mpath, int i, short sel, int sfra, int efra, - float prev_color[3], float frame_color[3], float next_color[3], unsigned color) -{ - int frame = sfra + i; - int blend_base = (abs(frame - CFRA) == 1) ? TH_CFRAME : TH_BACK; /* "bleed" cframe color to ease color blending */ - unsigned char ubcolor[3]; - -#define SET_INTENSITY(A, B, C, min, max) (((1.0f - ((C - B) / (C - A))) * (max - min)) + min) - float intensity; /* how faint */ - - if (frame < CFRA) { - if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) { - /* Custom color: previous frames color is darker than current frame */ - rgb_float_to_uchar(ubcolor, prev_color); - } - else { - /* black - before cfra */ - if (sel) { - /* intensity = 0.5f; */ - intensity = SET_INTENSITY(sfra, i, CFRA, 0.25f, 0.75f); - } - else { - /* intensity = 0.8f; */ - intensity = SET_INTENSITY(sfra, i, CFRA, 0.68f, 0.92f); - } - - UI_GetThemeColorBlend3ubv(TH_WIRE, blend_base, intensity, ubcolor); - } - } - else if (frame > CFRA) { - if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) { - /* Custom color: next frames color is equal to user selected color */ - rgb_float_to_uchar(ubcolor, next_color); - } - else { - /* blue - after cfra */ - if (sel) { - /* intensity = 0.5f; */ - intensity = SET_INTENSITY(CFRA, i, efra, 0.25f, 0.75f); - } - else { - /* intensity = 0.8f; */ - intensity = SET_INTENSITY(CFRA, i, efra, 0.68f, 0.92f); - } - - UI_GetThemeColorBlend3ubv(TH_BONE_POSE, blend_base, intensity, ubcolor); - } - } - else { - if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) { - /* Custom color: current frame color is slightly darker than user selected color */ - rgb_float_to_uchar(ubcolor, frame_color); - } - else { - /* green - on cfra */ - if (sel) { - intensity = 0.5f; - } - else { - intensity = 0.99f; - } - UI_GetThemeColorBlendShade3ubv(TH_CFRAME, TH_BACK, intensity, 10, ubcolor); - } - } - - immAttrib3ubv(color, ubcolor); - -#undef SET_INTENSITY -} - -/* Draw the given motion path for an Object or a Bone - * - assumes that the viewport has already been initialized properly - * i.e. draw_motion_paths_init() has been called - */ -void draw_motion_path_instance(Scene *scene, - Object *ob, bPoseChannel *pchan, bAnimVizSettings *avs, bMotionPath *mpath) -{ - //RegionView3D *rv3d = ar->regiondata; - bMotionPathVert *mpv, *mpv_start; - int i, stepsize = avs->path_step; - int sfra, efra, sind, len; - float prev_color[3]; - float frame_color[3]; - float next_color[3]; - - /* Custom color - Previous frames: color is darker than current frame */ - prev_color[0] = mpath->color[0] * 0.25f; - prev_color[1] = mpath->color[1] * 0.25f; - prev_color[2] = mpath->color[2] * 0.25f; - - /* Custom color - Current frame: color is slightly darker than user selected color */ - frame_color[0] = mpath->color[0] * 0.50f; - frame_color[1] = mpath->color[1] * 0.50f; - frame_color[2] = mpath->color[2] * 0.50f; - - /* Custom color - Next frames: color is equal to user selection */ - next_color[0] = mpath->color[0]; - next_color[1] = mpath->color[1]; - next_color[2] = mpath->color[2]; - - /* Save old line width */ - GLfloat old_width; - glGetFloatv(GL_LINE_WIDTH, &old_width); - - /* get frame ranges */ - if (avs->path_type == MOTIONPATH_TYPE_ACFRA) { - /* With "Around Current", we only choose frames from around - * the current frame to draw. - */ - sfra = CFRA - avs->path_bc; - efra = CFRA + avs->path_ac; - } - else { - /* Use the current display range */ - sfra = avs->path_sf; - efra = avs->path_ef; - } - - /* no matter what, we can only show what is in the cache and no more - * - abort if whole range is past ends of path - * - otherwise clamp endpoints to extents of path - */ - if (sfra < mpath->start_frame) { - /* start clamp */ - sfra = mpath->start_frame; - } - if (efra > mpath->end_frame) { - /* end clamp */ - efra = mpath->end_frame; - } - - if ((sfra > mpath->end_frame) || (efra < mpath->start_frame)) { - /* whole path is out of bounds */ - return; - } - - len = efra - sfra; - - if ((len <= 0) || (mpath->points == NULL)) { - return; - } - - /* get pointers to parts of path */ - sind = sfra - mpath->start_frame; - mpv_start = (mpath->points + sind); - - /* draw curve-line of path */ - /* Draw lines only if line drawing option is enabled */ - if (mpath->flag & MOTIONPATH_FLAG_LINES) { - /* set line thickness */ - glLineWidth(mpath->line_thickness); - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR); - - immBegin(GWN_PRIM_LINE_STRIP, len); - - for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - short sel = (pchan) ? (pchan->bone->flag & BONE_SELECTED) : (ob->flag & SELECT); - - /* Set color */ - set_motion_path_color(scene, mpath, i, sel, sfra, efra, prev_color, frame_color, next_color, color); - - /* draw a vertex with this color */ - immVertex3fv(pos, mpv->co); - } - - immEnd(); - - immUnbindProgram(); - - /* back to old line thickness */ - glLineWidth(old_width); - } - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - /* Point must be bigger than line thickness */ - glPointSize(mpath->line_thickness + 1.0); - - /* draw little black point at each frame */ - immUniformColor3ub(0, 0, 0); - - immBegin(GWN_PRIM_POINTS, len); - - for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - immVertex3fv(pos, mpv->co); - } - - immEnd(); - - /* Draw little white dots at each framestep value or replace with custom color */ - if (mpath->flag & MOTIONPATH_FLAG_CUSTOM) { - immUniformColor3fv(mpath->color); - } - else { - immUniformThemeColor(TH_TEXT_HI); - } - - immBegin(GWN_PRIM_POINTS, (len + stepsize - 1) / stepsize); - - for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) { - immVertex3fv(pos, mpv->co); - } - - immEnd(); - - /* Draw big green dot where the current frame is - * NOTE: this is only done when keyframes are shown, since this adds similar types of clutter - */ - if ((avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) && - (sfra < CFRA) && (CFRA <= efra)) - { - glPointSize(mpath->line_thickness + 5.0); - immUniformThemeColor(TH_CFRAME); - - immBegin(GWN_PRIM_POINTS, 1); - - mpv = mpv_start + (CFRA - sfra); - immVertex3fv(pos, mpv->co); - - immEnd(); - } - - immUnbindProgram(); - - /* XXX, this isn't up to date but probably should be kept so. */ - invert_m4_m4(ob->imat, ob->obmat); - - /* Draw frame numbers at each framestep value */ - if (avs->path_viewflag & MOTIONPATH_VIEW_FNUMS) { - unsigned char col[4]; - UI_GetThemeColor3ubv(TH_TEXT_HI, col); - col[3] = 255; - - for (i = 0, mpv = mpv_start; i < len; i += stepsize, mpv += stepsize) { - int frame = sfra + i; - char numstr[32]; - size_t numstr_len; - float co[3]; - - /* only draw framenum if several consecutive highlighted points don't occur on same point */ - if (i == 0) { - numstr_len = sprintf(numstr, " %d", frame); - mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, numstr, numstr_len, - 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); - } - else if ((i >= stepsize) && (i < len - stepsize)) { - bMotionPathVert *mpvP = (mpv - stepsize); - bMotionPathVert *mpvN = (mpv + stepsize); - - if ((equals_v3v3(mpv->co, mpvP->co) == 0) || (equals_v3v3(mpv->co, mpvN->co) == 0)) { - numstr_len = sprintf(numstr, " %d", frame); - mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, numstr, numstr_len, - 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); - } - } - } - } - - /* Keyframes - dots and numbers */ - if (avs->path_viewflag & MOTIONPATH_VIEW_KFRAS) { - unsigned char col[4]; - - AnimData *adt = BKE_animdata_from_id(&ob->id); - DLRBT_Tree keys; - - /* build list of all keyframes in active action for object or pchan */ - BLI_dlrbTree_init(&keys); - - if (adt) { - /* it is assumed that keyframes for bones are all grouped in a single group - * unless an option is set to always use the whole action - */ - if ((pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT) == 0) { - bActionGroup *agrp = BKE_action_group_find_name(adt->action, pchan->name); - - if (agrp) { - agroup_to_keylist(adt, agrp, &keys, NULL); - BLI_dlrbTree_linkedlist_sync(&keys); - } - } - else { - action_to_keylist(adt, adt->action, &keys, NULL); - BLI_dlrbTree_linkedlist_sync(&keys); - } - } - - /* Draw slightly-larger yellow dots at each keyframe */ - UI_GetThemeColor3ubv(TH_VERTEX_SELECT, col); - col[3] = 255; - - /* point must be bigger than line */ - glPointSize(mpath->line_thickness + 3.0); - - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(col); - - immBeginAtMost(GWN_PRIM_POINTS, len); - - for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - int frame = sfra + i; - float mframe = (float)(frame); - - if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) { - immVertex3fv(pos, mpv->co); - } - } - - immEnd(); - - immUnbindProgram(); - - /* Draw frame numbers of keyframes */ - if (avs->path_viewflag & MOTIONPATH_VIEW_KFNOS) { - float co[3]; - for (i = 0, mpv = mpv_start; i < len; i++, mpv++) { - float mframe = (float)(sfra + i); - - if (BLI_dlrbTree_search_exact(&keys, compare_ak_cfraPtr, &mframe)) { - char numstr[32]; - size_t numstr_len; - - numstr_len = sprintf(numstr, " %d", (sfra + i)); - mul_v3_m4v3(co, ob->imat, mpv->co); - view3d_cached_text_draw_add(co, numstr, numstr_len, - 0, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, col); - } - } - } - - BLI_dlrbTree_free(&keys); - } -} - -/* Clean up drawing environment after drawing motion paths */ -void draw_motion_paths_cleanup(View3D *v3d) -{ - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - gpuPopMatrix(); -} diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c deleted file mode 100644 index 9a82bce4b4b..00000000000 --- a/source/blender/editors/space_view3d/drawarmature.c +++ /dev/null @@ -1,3010 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * 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) 2005 by the Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/drawarmature.c - * \ingroup spview3d - */ - - -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#include "DNA_anim_types.h" -#include "DNA_armature_types.h" -#include "DNA_constraint_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" -#include "DNA_object_types.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_dlrbTree.h" -#include "BLI_utildefines.h" - -#include "BKE_animsys.h" -#include "BKE_action.h" -#include "BKE_armature.h" -#include "BKE_global.h" -#include "BKE_modifier.h" -#include "BKE_nla.h" -#include "BKE_curve.h" -#include "BKE_context.h" - -#include "DEG_depsgraph.h" - -#include "BIF_glutil.h" - -#include "ED_armature.h" -#include "ED_keyframes_draw.h" - -#include "GPU_basic_shader.h" -#include "GPU_batch.h" -#include "GPU_immediate.h" -#include "GPU_immediate_util.h" -#include "GPU_matrix.h" - -#include "UI_resources.h" - -#include "view3d_intern.h" - -#include "GPU_select.h" - -/* *************** Armature Drawing - Coloring API ***************************** */ - -/* global here is reset before drawing each bone */ -static ThemeWireColor *bcolor = NULL; -static float fcolor[4] = {0.0f}; -static bool flat_color; - -/* values of colCode for set_pchan_color */ -enum { - PCHAN_COLOR_NORMAL = 0, /* normal drawing */ - PCHAN_COLOR_SOLID, /* specific case where "solid" color is needed */ - PCHAN_COLOR_CONSTS, /* "constraint" colors (which may/may-not be suppressed) */ - - PCHAN_COLOR_SPHEREBONE_BASE, /* for the 'stick' of sphere (envelope) bones */ - PCHAN_COLOR_SPHEREBONE_END, /* for the ends of sphere (envelope) bones */ - PCHAN_COLOR_LINEBONE /* for the middle of line-bones */ -}; - -/* This function sets the color-set for coloring a certain bone */ -static void set_pchan_colorset(Object *ob, bPoseChannel *pchan) -{ - bPose *pose = (ob) ? ob->pose : NULL; - bArmature *arm = (ob) ? ob->data : NULL; - bActionGroup *grp = NULL; - short color_index = 0; - - /* sanity check */ - if (ELEM(NULL, ob, arm, pose, pchan)) { - bcolor = NULL; - return; - } - - /* only try to set custom color if enabled for armature */ - if (arm->flag & ARM_COL_CUSTOM) { - /* currently, a bone can only use a custom color set if it's group (if it has one), - * has been set to use one - */ - if (pchan->agrp_index) { - grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1)); - if (grp) - color_index = grp->customCol; - } - } - - /* bcolor is a pointer to the color set to use. If NULL, then the default - * color set (based on the theme colors for 3d-view) is used. - */ - if (color_index > 0) { - bTheme *btheme = UI_GetTheme(); - bcolor = &btheme->tarm[(color_index - 1)]; - } - else if (color_index == -1) { - /* use the group's own custom color set (grp is always != NULL here) */ - bcolor = &grp->cs; - } - else { - bcolor = NULL; - } -} - -/* This function is for brightening/darkening a given color (like UI_GetThemeColorShade3ubv()) */ -static void cp_shade_color3ub(unsigned char cp[3], const int offset) -{ - int r, g, b; - - r = offset + (int) cp[0]; - CLAMP(r, 0, 255); - g = offset + (int) cp[1]; - CLAMP(g, 0, 255); - b = offset + (int) cp[2]; - CLAMP(b, 0, 255); - - cp[0] = r; - cp[1] = g; - cp[2] = b; -} - -/* This function sets the gl-color for coloring a certain bone (based on bcolor) */ -static bool set_pchan_color(short colCode, int boneflag, short constflag) -{ - switch (colCode) { - case PCHAN_COLOR_NORMAL: - { - if (bcolor) { - unsigned char cp[4] = {255}; - - if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3_char((char *)cp, bcolor->active); - if (!(boneflag & BONE_SELECTED)) { - cp_shade_color3ub(cp, -80); - } - } - else if (boneflag & BONE_SELECTED) { - copy_v3_v3_char((char *)cp, bcolor->select); - } - else { - /* a bit darker than solid */ - copy_v3_v3_char((char *)cp, bcolor->solid); - cp_shade_color3ub(cp, -50); - } - - rgb_uchar_to_float(fcolor, cp); - } - else { - if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) { - UI_GetThemeColor4fv(TH_BONE_POSE_ACTIVE, fcolor); - } - else if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorBlendShade4fv(TH_WIRE, TH_BONE_POSE, 0.15f, 0, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColor4fv(TH_BONE_POSE, fcolor); - } - else { - UI_GetThemeColor4fv(TH_WIRE, fcolor); - } - } - - return true; - } - case PCHAN_COLOR_SOLID: - { - if (bcolor) { - rgb_uchar_to_float(fcolor, (unsigned char *)bcolor->solid); - } - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - - return true; - } - case PCHAN_COLOR_CONSTS: - { - if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) { - unsigned char cp[4]; - if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 80); - else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 80); - else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 80); - else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 80); - - rgba_uchar_to_float(fcolor, cp); - - return true; - } - return false; - } - case PCHAN_COLOR_SPHEREBONE_BASE: - { - if (bcolor) { - unsigned char cp[4] = {255}; - - if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3_char((char *)cp, bcolor->active); - } - else if (boneflag & BONE_SELECTED) { - copy_v3_v3_char((char *)cp, bcolor->select); - } - else { - copy_v3_v3_char((char *)cp, bcolor->solid); - } - - rgb_uchar_to_float(fcolor, cp); - } - else { - if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorShade4fv(TH_BONE_POSE, 40, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColor4fv(TH_BONE_POSE, fcolor); - } - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - } - - return true; - } - case PCHAN_COLOR_SPHEREBONE_END: - { - if (bcolor) { - unsigned char cp[4] = {255}; - - if (boneflag & BONE_DRAW_ACTIVE) { - copy_v3_v3_char((char *)cp, bcolor->active); - cp_shade_color3ub(cp, 10); - } - else if (boneflag & BONE_SELECTED) { - copy_v3_v3_char((char *)cp, bcolor->select); - cp_shade_color3ub(cp, -30); - } - else { - copy_v3_v3_char((char *)cp, bcolor->solid); - cp_shade_color3ub(cp, -30); - } - - rgb_uchar_to_float(fcolor, cp); - } - else { - if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorShade4fv(TH_BONE_POSE, 10, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColorShade4fv(TH_BONE_POSE, -30, fcolor); - } - else { - UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor); - } - } - break; - } - case PCHAN_COLOR_LINEBONE: - { - /* inner part in background color or constraint */ - if ((constflag) && ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS))) { - unsigned char cp[4]; - if (constflag & PCHAN_HAS_TARGET) rgba_char_args_set((char *)cp, 255, 150, 0, 255); - else if (constflag & PCHAN_HAS_IK) rgba_char_args_set((char *)cp, 255, 255, 0, 255); - else if (constflag & PCHAN_HAS_SPLINEIK) rgba_char_args_set((char *)cp, 200, 255, 0, 255); - else if (constflag & PCHAN_HAS_CONST) rgba_char_args_set((char *)cp, 0, 255, 120, 255); - else if (constflag) UI_GetThemeColor4ubv(TH_BONE_POSE, cp); /* PCHAN_HAS_ACTION */ - - rgb_uchar_to_float(fcolor, cp); - } - else { - if (bcolor) { - const char *cp = bcolor->solid; - rgb_uchar_to_float(fcolor, (unsigned char *)cp); - fcolor[3] = 204.f / 255.f; - } - else { - UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor); - } - } - - return true; - } - } - - return false; -} - -static void set_ebone_color(const unsigned int boneflag) -{ - if ((boneflag & BONE_DRAW_ACTIVE) && (boneflag & BONE_SELECTED)) { - UI_GetThemeColor4fv(TH_EDGE_SELECT, fcolor); - } - else if (boneflag & BONE_DRAW_ACTIVE) { - UI_GetThemeColorBlendShade4fv(TH_WIRE_EDIT, TH_EDGE_SELECT, 0.15f, 0, fcolor); - } - else if (boneflag & BONE_SELECTED) { - UI_GetThemeColorShade4fv(TH_EDGE_SELECT, -20, fcolor); - } - else { - UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor); - } -} - -/* *************** Armature drawing, helper calls for parts ******************* */ - -static void add_solid_flat_triangle(Gwn_VertBuf *vbo, unsigned int *vertex, unsigned int pos, unsigned int nor, - const float p1[3], const float p2[3], const float p3[3], const float n[3]) -{ - GWN_vertbuf_attr_set(vbo, nor, *vertex, n); - GWN_vertbuf_attr_set(vbo, pos, (*vertex)++, p1); - GWN_vertbuf_attr_set(vbo, nor, *vertex, n); - GWN_vertbuf_attr_set(vbo, pos, (*vertex)++, p2); - GWN_vertbuf_attr_set(vbo, nor, *vertex, n); - GWN_vertbuf_attr_set(vbo, pos, (*vertex)++, p3); -} - -/* half the cube, in Y */ -static const float cube_vert[8][3] = { - {-1.0, 0.0, -1.0}, - {-1.0, 0.0, 1.0}, - {-1.0, 1.0, 1.0}, - {-1.0, 1.0, -1.0}, - { 1.0, 0.0, -1.0}, - { 1.0, 0.0, 1.0}, - { 1.0, 1.0, 1.0}, - { 1.0, 1.0, -1.0}, -}; - -static const float cube_wire[24] = { - 0, 1, 1, 2, 2, 3, 3, 0, - 4, 5, 5, 6, 6, 7, 7, 4, - 0, 4, 1, 5, 2, 6, 3, 7, -}; - -static void drawsolidcube_size(float xsize, float ysize, float zsize) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_Batch batch = {{0}}; - const float light_vec[3] = {0.0f, 0.0f, 1.0f}; - - if (format.attrib_ct == 0) { - unsigned int i = 0; - float n[3] = {0.0f}; - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 36); - - n[0] = -1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[1], cube_vert[2], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[2], cube_vert[3], cube_vert[0], n); - n[0] = 0; - n[1] = -1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[4], cube_vert[5], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[5], cube_vert[1], cube_vert[0], n); - n[1] = 0; - n[0] = 1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[4], cube_vert[7], cube_vert[6], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[6], cube_vert[5], cube_vert[4], n); - n[0] = 0; - n[1] = 1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[7], cube_vert[3], cube_vert[2], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[2], cube_vert[6], cube_vert[7], n); - n[1] = 0; - n[2] = 1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[1], cube_vert[5], cube_vert[6], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[6], cube_vert[2], cube_vert[1], n); - n[2] = -1.0; - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[7], cube_vert[4], cube_vert[0], n); - add_solid_flat_triangle(&vbo, &i, pos, nor, cube_vert[0], cube_vert[3], cube_vert[7], n); - - GWN_batch_init(&batch, GWN_PRIM_TRIS, &vbo, NULL); - } - - gpuPushMatrix(); - gpuScale3f(xsize, ysize, zsize); - - if (flat_color) { - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - else { - /* TODO replace with good default lighting shader ? */ - GWN_batch_program_set_builtin(&batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(&batch, "light", light_vec); - } - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); - - gpuPopMatrix(); -} - -static void drawcube_size(float xsize, float ysize, float zsize) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_IndexBufBuilder elb = {0}; - static Gwn_IndexBuf el = {0}; - static Gwn_Batch batch = {{0}}; - - if (format.attrib_ct == 0) { - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Elements */ - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, 12, 8); - for (int i = 0; i < 12; ++i) { - GWN_indexbuf_add_line_verts(&elb, cube_wire[i * 2], cube_wire[i * 2 + 1]); - } - GWN_indexbuf_build_in_place(&elb, &el); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 8); - for (int i = 0; i < 8; ++i) { - GWN_vertbuf_attr_set(&vbo, pos, i, cube_vert[i]); - } - - GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, &el); - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - - gpuPushMatrix(); - gpuScale3f(xsize, ysize, zsize); - - GWN_batch_program_use_begin(&batch); - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); - - gpuPopMatrix(); -} - - -static void draw_bonevert(void) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_Batch batch = {{0}}; - - if (format.attrib_ct == 0) { - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 96); - for (int i = 0; i < 16; ++i) { - float vert[3] = {0.f, 0.f, 0.f}; - const float r = 0.05f; - - vert[0] = r * cosf(2 * M_PI * i / 16.f); - vert[1] = r * sinf(2 * M_PI * i / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 0, vert); - vert[0] = r * cosf(2 * M_PI * (i + 1) / 16.f); - vert[1] = r * sinf(2 * M_PI * (i + 1) / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 1, vert); - - vert[0] = 0.f; - vert[1] = r * cosf(2 * M_PI * i / 16.f); - vert[2] = r * sinf(2 * M_PI * i / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 2, vert); - vert[1] = r * cosf(2 * M_PI * (i + 1) / 16.f); - vert[2] = r * sinf(2 * M_PI * (i + 1) / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 3, vert); - - vert[1] = 0.f; - vert[0] = r * cosf(2 * M_PI * i / 16.f); - vert[2] = r * sinf(2 * M_PI * i / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 4, vert); - vert[0] = r * cosf(2 * M_PI * (i + 1) / 16.f); - vert[2] = r * sinf(2 * M_PI * (i + 1) / 16.f); - GWN_vertbuf_attr_set(&vbo, pos, i * 6 + 5, vert); - } - - GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, NULL); - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - - GWN_batch_program_use_begin(&batch); - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); -} - -static void draw_bonevert_solid(void) -{ - Gwn_Batch *batch = GPU_batch_preset_sphere(0); - const float light_vec[3] = {0.0f, 0.0f, 1.0f}; - - gpuPushMatrix(); - gpuScaleUniform(0.05); - - if (flat_color) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - else { - /* TODO replace with good default lighting shader ? */ - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(batch, "light", light_vec); - } - GWN_batch_uniform_4fv(batch, "color", fcolor); - GWN_batch_draw(batch); - - gpuPopMatrix(); -} - -static const float bone_octahedral_verts[6][3] = { - { 0.0f, 0.0f, 0.0f}, - { 0.1f, 0.1f, 0.1f}, - { 0.1f, 0.1f, -0.1f}, - {-0.1f, 0.1f, -0.1f}, - {-0.1f, 0.1f, 0.1f}, - { 0.0f, 1.0f, 0.0f} -}; - -static const unsigned int bone_octahedral_wire[24] = { - 0, 1, 1, 5, 5, 3, 3, 0, - 0, 4, 4, 5, 5, 2, 2, 0, - 1, 2, 2, 3, 3, 4, 4, 1, -}; - -static const unsigned int bone_octahedral_solid_tris[8][3] = { - {2, 1, 0}, /* bottom */ - {3, 2, 0}, - {4, 3, 0}, - {1, 4, 0}, - - {5, 1, 2}, /* top */ - {5, 2, 3}, - {5, 3, 4}, - {5, 4, 1} -}; - -/* aligned with bone_octahedral_solid_tris */ -static const float bone_octahedral_solid_normals[8][3] = { - { M_SQRT1_2, -M_SQRT1_2, 0.00000000f}, - {-0.00000000f, -M_SQRT1_2, -M_SQRT1_2}, - {-M_SQRT1_2, -M_SQRT1_2, 0.00000000f}, - { 0.00000000f, -M_SQRT1_2, M_SQRT1_2}, - { 0.99388373f, 0.11043154f, -0.00000000f}, - { 0.00000000f, 0.11043154f, -0.99388373f}, - {-0.99388373f, 0.11043154f, 0.00000000f}, - { 0.00000000f, 0.11043154f, 0.99388373f} -}; - -static void draw_bone_octahedral(void) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_IndexBufBuilder elb = {0}; - static Gwn_IndexBuf el = {0}; - static Gwn_Batch batch = {{0}}; - - if (format.attrib_ct == 0) { - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Elements */ - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, 12, 6); - for (int i = 0; i < 12; ++i) { - GWN_indexbuf_add_line_verts(&elb, bone_octahedral_wire[i * 2], bone_octahedral_wire[i * 2 + 1]); - } - GWN_indexbuf_build_in_place(&elb, &el); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 6); - for (int i = 0; i < 6; ++i) { - GWN_vertbuf_attr_set(&vbo, pos, i, bone_octahedral_verts[i]); - } - - GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, &el); - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - - GWN_batch_program_use_begin(&batch); - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); -} - -static void draw_bone_solid_octahedral(void) -{ - static Gwn_VertFormat format = {0}; - static Gwn_VertBuf vbo = {{0}}; - static Gwn_Batch batch = {{0}}; - const float light_vec[3] = {0.0f, 0.0f, 1.0f}; - - if (format.attrib_ct == 0) { - unsigned int v_idx = 0; - /* Vertex format */ - unsigned int pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int nor = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* Vertices */ - GWN_vertbuf_init_with_format(&vbo, &format); - GWN_vertbuf_data_alloc(&vbo, 24); - - for (int i = 0; i < 8; i++) { - add_solid_flat_triangle(&vbo, &v_idx, pos, nor, - bone_octahedral_verts[bone_octahedral_solid_tris[i][0]], - bone_octahedral_verts[bone_octahedral_solid_tris[i][1]], - bone_octahedral_verts[bone_octahedral_solid_tris[i][2]], - bone_octahedral_solid_normals[i]); - } - - GWN_batch_init(&batch, GWN_PRIM_TRIS, &vbo, NULL); - } - - if (flat_color) { - GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR); - } - else { - /* TODO replace with good default lighting shader ? */ - GWN_batch_program_set_builtin(&batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(&batch, "light", light_vec); - } - GWN_batch_uniform_4fv(&batch, "color", fcolor); - GWN_batch_draw(&batch); -} - -/* *************** Armature drawing, bones ******************* */ - - -static void draw_bone_points(const short dt, int armflag, unsigned int boneflag, int id) -{ - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (id != -1) - GPU_select_load_id(id | BONESEL_ROOT); - - if (dt <= OB_WIRE) { - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) { - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - } - } - else { - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, 0); - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - } - - if (dt > OB_WIRE) - draw_bonevert_solid(); - else - draw_bonevert(); - } - - /* Draw tip point */ - if (id != -1) - GPU_select_load_id(id | BONESEL_TIP); - - if (dt <= OB_WIRE) { - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) { - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - } - } - else { - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, 0); - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - } - - gpuPushMatrix(); - gpuTranslate2f(0.0f, 1.0f); - if (dt > OB_WIRE) - draw_bonevert_solid(); - else - draw_bonevert(); - gpuPopMatrix(); -} - -/* 16 values of sin function (still same result!) */ -static const float si[16] = { - 0.00000000f, - 0.20129852f, 0.39435585f, - 0.57126821f, 0.72479278f, - 0.84864425f, 0.93775213f, - 0.98846832f, 0.99871650f, - 0.96807711f, 0.89780453f, - 0.79077573f, 0.65137248f, - 0.48530196f, 0.29936312f, - 0.10116832f -}; -/* 16 values of cos function (still same result!) */ -static const float co[16] = { - 1.00000000f, - 0.97952994f, 0.91895781f, - 0.82076344f, 0.68896691f, - 0.52896401f, 0.34730525f, - 0.15142777f, -0.05064916f, - -0.25065253f, -0.44039415f, - -0.61210598f, -0.75875812f, - -0.87434661f, -0.95413925f, - -0.99486932f -}; - - - -/* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChannel *pchan, EditBone *ebone) -{ - float head, tail, dist /*, length*/; - float *headvec, *tailvec, dirvec[3]; - - /* figure out the sizes of spheres */ - if (ebone) { - /* this routine doesn't call get_matrix_editbone() that calculates it */ - ebone->length = len_v3v3(ebone->head, ebone->tail); - - /*length = ebone->length;*/ /*UNUSED*/ - tail = ebone->rad_tail; - dist = ebone->dist; - if (ebone->parent && (ebone->flag & BONE_CONNECTED)) - head = ebone->parent->rad_tail; - else - head = ebone->rad_head; - headvec = ebone->head; - tailvec = ebone->tail; - } - else { - /*length = pchan->bone->length;*/ /*UNUSED*/ - tail = pchan->bone->rad_tail; - dist = pchan->bone->dist; - if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) - head = pchan->parent->bone->rad_tail; - else - head = pchan->bone->rad_head; - headvec = pchan->pose_head; - tailvec = pchan->pose_tail; - } - - /* ***** draw it ***** */ - - /* move vector to viewspace */ - sub_v3_v3v3(dirvec, tailvec, headvec); - mul_mat3_m4_v3(smat, dirvec); - /* clear zcomp */ - dirvec[2] = 0.0f; - - if (head != tail) { - /* correction when viewing along the bones axis - * it pops in and out but better then artifacts, [#23841] */ - float view_dist = len_v2(dirvec); - - if (head - view_dist > tail) { - tailvec = headvec; - tail = head; - zero_v3(dirvec); - dirvec[0] = 0.00001; /* XXX. weak but ok */ - } - else if (tail - view_dist > head) { - headvec = tailvec; - head = tail; - zero_v3(dirvec); - dirvec[0] = 0.00001; /* XXX. weak but ok */ - } - } - - /* move vector back */ - mul_mat3_m4_v3(imat, dirvec); - - if (0.0f != normalize_v3(dirvec)) { - float norvec[3], vec1[3], vec2[3], vec[3]; - int a; - - //mul_v3_fl(dirvec, head); - cross_v3_v3v3(norvec, dirvec, imat[2]); - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immBegin(GWN_PRIM_TRI_STRIP, 66); - immUniformColor4ub(255, 255, 255, 50); - - for (a = 0; a < 16; a++) { - vec[0] = -si[a] * dirvec[0] + co[a] * norvec[0]; - vec[1] = -si[a] * dirvec[1] + co[a] * norvec[1]; - vec[2] = -si[a] * dirvec[2] + co[a] * norvec[2]; - - madd_v3_v3v3fl(vec1, headvec, vec, head); - madd_v3_v3v3fl(vec2, headvec, vec, head + dist); - - immVertex3fv(pos, vec1); - immVertex3fv(pos, vec2); - } - - for (a = 15; a >= 0; a--) { - vec[0] = si[a] * dirvec[0] + co[a] * norvec[0]; - vec[1] = si[a] * dirvec[1] + co[a] * norvec[1]; - vec[2] = si[a] * dirvec[2] + co[a] * norvec[2]; - - madd_v3_v3v3fl(vec1, tailvec, vec, tail); - madd_v3_v3v3fl(vec2, tailvec, vec, tail + dist); - - immVertex3fv(pos, vec1); - immVertex3fv(pos, vec2); - } - /* make it cyclic... */ - - vec[0] = -si[0] * dirvec[0] + co[0] * norvec[0]; - vec[1] = -si[0] * dirvec[1] + co[0] * norvec[1]; - vec[2] = -si[0] * dirvec[2] + co[0] * norvec[2]; - - madd_v3_v3v3fl(vec1, headvec, vec, head); - madd_v3_v3v3fl(vec2, headvec, vec, head + dist); - - immVertex3fv(pos, vec1); - immVertex3fv(pos, vec2); - - immEnd(); - immUnbindProgram(); - } -} - - -/* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4], - int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - float head, tail /*, length*/; - float *headvec, *tailvec, dirvec[3]; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - /* figure out the sizes of spheres */ - if (ebone) { - /* this routine doesn't call get_matrix_editbone() that calculates it */ - ebone->length = len_v3v3(ebone->head, ebone->tail); - - /*length = ebone->length;*/ /*UNUSED*/ - tail = ebone->rad_tail; - if (ebone->parent && (boneflag & BONE_CONNECTED)) - head = ebone->parent->rad_tail; - else - head = ebone->rad_head; - headvec = ebone->head; - tailvec = ebone->tail; - } - else { - /*length = pchan->bone->length;*/ /*UNUSED*/ - tail = pchan->bone->rad_tail; - if ((pchan->parent) && (boneflag & BONE_CONNECTED)) - head = pchan->parent->bone->rad_tail; - else - head = pchan->bone->rad_head; - headvec = pchan->pose_head; - tailvec = pchan->pose_tail; - } - - /* sphere root color */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) { - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - } - else if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - - immUniformColor4fv(fcolor); - - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (id != -1) - GPU_select_load_id(id | BONESEL_ROOT); - - imm_drawcircball(headvec, head, imat, pos); - } - - /* Draw tip point */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) { - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - } - - if (id != -1) - GPU_select_load_id(id | BONESEL_TIP); - - imm_drawcircball(tailvec, tail, imat, pos); - - /* base */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_SELECTED) { - UI_GetThemeColor4fv(TH_SELECT, fcolor); - } - else { - UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor); - } - } - - sub_v3_v3v3(dirvec, tailvec, headvec); - - /* move vector to viewspace */ - mul_mat3_m4_v3(smat, dirvec); - /* clear zcomp */ - dirvec[2] = 0.0f; - /* move vector back */ - mul_mat3_m4_v3(imat, dirvec); - - if (0.0f != normalize_v3(dirvec)) { - float norvech[3], norvect[3], vec[3]; - - copy_v3_v3(vec, dirvec); - - mul_v3_fl(dirvec, head); - cross_v3_v3v3(norvech, dirvec, imat[2]); - - mul_v3_fl(vec, tail); - cross_v3_v3v3(norvect, vec, imat[2]); - - if (id != -1) - GPU_select_load_id(id | BONESEL_BONE); - - immBegin(GWN_PRIM_LINES, 4); - - add_v3_v3v3(vec, headvec, norvech); - immVertex3fv(pos, vec); - - add_v3_v3v3(vec, tailvec, norvect); - immVertex3fv(pos, vec); - - sub_v3_v3v3(vec, headvec, norvech); - immVertex3fv(pos, vec); - - sub_v3_v3v3(vec, tailvec, norvect); - immVertex3fv(pos, vec); - - immEnd(); - } - - immUnbindProgram(); -} - -/* does wire only for outline selecting */ -static void draw_sphere_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - Gwn_Batch *sphere = GPU_batch_preset_sphere(1); - float head, tail, length; - float fac1, fac2, size1, size2; - const float light_vec[3] = {0.0f, 0.0f, 1.0f}; - - /* dt is always OB_SOlID */ - GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(sphere, "light", light_vec); - - gpuPushMatrix(); - - /* figure out the sizes of spheres */ - if (ebone) { - length = ebone->length; - tail = ebone->rad_tail; - if (ebone->parent && (boneflag & BONE_CONNECTED)) - head = ebone->parent->rad_tail; - else - head = ebone->rad_head; - } - else { - length = pchan->bone->length; - tail = pchan->bone->rad_tail; - if (pchan->parent && (boneflag & BONE_CONNECTED)) - head = pchan->parent->bone->rad_tail; - else - head = pchan->bone->rad_head; - } - - /* move to z-axis space */ - gpuRotateAxis(-90.0f, 'X'); - - /* sphere root color */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) - UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - else - UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor); - } - else if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SPHEREBONE_END, boneflag, constflag); - else if (dt == OB_SOLID) - UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor); - - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (id != -1) - GPU_select_load_id(id | BONESEL_ROOT); - gpuPushMatrix(); - gpuScaleUniform(head); - GWN_batch_uniform_4fv(sphere, "color", fcolor); - GWN_batch_draw(sphere); - gpuPopMatrix(); - } - - /* Draw tip point */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - else UI_GetThemeColorShade4fv(TH_BONE_SOLID, -30, fcolor); - } - - if (id != -1) - GPU_select_load_id(id | BONESEL_TIP); - - gpuTranslate3f(0.0f, 0.0f, length); - - gpuPushMatrix(); - gpuScaleUniform(tail); - GWN_batch_program_use_begin(sphere); /* hack to make the following uniforms stick */ - GWN_batch_uniform_4fv(sphere, "color", fcolor); - GWN_batch_draw(sphere); - gpuPopMatrix(); - - gpuTranslate3f(0.0f, 0.0f, -length); - - /* base */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_SELECTED) UI_GetThemeColor4fv(TH_SELECT, fcolor); - else UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - else if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SPHEREBONE_BASE, boneflag, constflag); - else if (dt == OB_SOLID) - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - - GWN_batch_program_use_begin(sphere); /* hack to make the following uniforms stick */ - GWN_batch_uniform_4fv(sphere, "color", fcolor); - - fac1 = (length - head) / length; - fac2 = (length - tail) / length; - - if (length > (head + tail)) { - size1 = fac2 * tail + (1.0f - fac2) * head; - size2 = fac1 * head + (1.0f - fac1) * tail; - - if (id != -1) - GPU_select_load_id(id | BONESEL_BONE); - - /* draw sphere on extrema */ - gpuPushMatrix(); - gpuTranslate3f(0.0f, 0.0f, length - tail); - gpuScaleUniform(size1); - - GWN_batch_draw(sphere); - gpuPopMatrix(); - - gpuPushMatrix(); - gpuTranslate3f(0.0f, 0.0f, head); - gpuScaleUniform(size2); - - GWN_batch_draw(sphere); - gpuPopMatrix(); - - /* draw cynlinder between spheres */ - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int nor = GWN_vertformat_attr_add(format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_SIMPLE_LIGHTING); - immUniformColor4fv(fcolor); - immUniform3fv("light", light_vec); - - gpuTranslate3f(0.0f, 0.0f, head); - imm_draw_cylinder_fill_normal_3d(pos, nor, size2, size1, length - head - tail, 16, 1); - - immUnbindProgram(); - - glDisable(GL_POLYGON_OFFSET_FILL); - } - else { - size1 = fac1 * head + (1.0f - fac1) * tail; - - /* 1 sphere in center */ - gpuTranslate3f(0.0f, 0.0f, (head + length - tail) / 2.0f); - - gpuScaleUniform(size1); - GWN_batch_draw(sphere); - } - - gpuPopMatrix(); -} - -static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - float length; - - if (pchan) - length = pchan->bone->length; - else - length = ebone->length; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - gpuPushMatrix(); - gpuScaleUniform(length); - - /* this chunk not in object mode */ - if (armflag & (ARM_EDITMODE | ARM_POSEMODE)) { - glLineWidth(4.0f); - glPointSize(8.0f); - - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - else if (armflag & ARM_EDITMODE) { - UI_GetThemeColor4fv(TH_WIRE_EDIT, fcolor); - } - - /* line */ - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4fv(fcolor); - - if (id != -1) - GPU_select_load_id(id | BONESEL_BONE); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 1.0f, 0.0f); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immEnd(); - - immUnbindProgram(); - - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR); - immUniformColor4fv(fcolor); - - /* Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (G.f & G_PICKSEL) - GPU_select_load_id(id | BONESEL_ROOT); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immEnd(); - } - - /* tip */ - if (G.f & G_PICKSEL) - GPU_select_load_id(id | BONESEL_TIP); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3f(pos, 0.0f, 1.0f, 0.0f); - immEnd(); - - immUnbindProgram(); - - - /* further we send no names */ - if (id != -1) - GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */ - - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_LINEBONE, boneflag, constflag); - } - - /* Now draw the inner color */ - glLineWidth(2.0f); - glPointSize(5.0f); - - /* line */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_SELECTED) UI_GetThemeColor4fv(TH_EDGE_SELECT, fcolor); - else UI_GetThemeColorShade4fv(TH_BACK, -30, fcolor); - } - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4fv(fcolor); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 1.0f, 0.0f); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immEnd(); - - immUnbindProgram(); - - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR); - - /*Draw root point if we are not connected */ - if ((boneflag & BONE_CONNECTED) == 0) { - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_ROOTSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - else UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - immUniformColor4fv(fcolor); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immEnd(); - } - - /* tip */ - if ((G.f & G_PICKSEL) == 0) { - /* no bitmap in selection mode, crashes 3d cards... */ - if (armflag & ARM_EDITMODE) { - if (boneflag & BONE_TIPSEL) UI_GetThemeColor4fv(TH_VERTEX_SELECT, fcolor); - else UI_GetThemeColor4fv(TH_VERTEX, fcolor); - } - immUniformColor4fv(fcolor); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3f(pos, 0.0f, 1.0f, 0.0f); - immEnd(); - } - - immUnbindProgram(); - - gpuPopMatrix(); -} - -/* A partial copy of b_bone_spline_setup(), with just the parts for previewing editmode curve settings - * - * This assumes that prev/next bones don't have any impact (since they should all still be in the "straight" - * position here anyway), and that we can simply apply the bbone settings to get the desired effect... - */ -static void ebone_spline_preview(EditBone *ebone, Mat4 result_array[MAX_BBONE_SUBDIV]) -{ - float h1[3], h2[3], length, hlength1, hlength2, roll1 = 0.0f, roll2 = 0.0f; - float mat3[3][3]; - float data[MAX_BBONE_SUBDIV + 1][4], *fp; - int a; - - length = ebone->length; - - hlength1 = ebone->ease1 * length * 0.390464f; /* 0.5f * sqrt(2) * kappa, the handle length for near-perfect circles */ - hlength2 = ebone->ease2 * length * 0.390464f; - - /* find the handle points, since this is inside bone space, the - * first point = (0, 0, 0) - * last point = (0, length, 0) - * - * we also just apply all the "extra effects", since they're the whole reason we're doing this... - */ - h1[0] = ebone->curveInX; - h1[1] = hlength1; - h1[2] = ebone->curveInY; - roll1 = ebone->roll1; - - h2[0] = ebone->curveOutX; - h2[1] = -hlength2; - h2[2] = ebone->curveOutY; - roll2 = ebone->roll2; - - /* make curve */ - if (ebone->segments > MAX_BBONE_SUBDIV) - ebone->segments = MAX_BBONE_SUBDIV; - - BKE_curve_forward_diff_bezier(0.0f, h1[0], h2[0], 0.0f, data[0], MAX_BBONE_SUBDIV, 4 * sizeof(float)); - BKE_curve_forward_diff_bezier(0.0f, h1[1], length + h2[1], length, data[0] + 1, MAX_BBONE_SUBDIV, 4 * sizeof(float)); - BKE_curve_forward_diff_bezier(0.0f, h1[2], h2[2], 0.0f, data[0] + 2, MAX_BBONE_SUBDIV, 4 * sizeof(float)); - BKE_curve_forward_diff_bezier(roll1, roll1 + 0.390464f * (roll2 - roll1), roll2 - 0.390464f * (roll2 - roll1), roll2, data[0] + 3, MAX_BBONE_SUBDIV, 4 * sizeof(float)); - - equalize_bbone_bezier(data[0], ebone->segments); /* note: does stride 4! */ - - /* make transformation matrices for the segments for drawing */ - for (a = 0, fp = data[0]; a < ebone->segments; a++, fp += 4) { - sub_v3_v3v3(h1, fp + 4, fp); - vec_roll_to_mat3(h1, fp[3], mat3); /* fp[3] is roll */ - - copy_m4_m3(result_array[a].mat, mat3); - copy_v3_v3(result_array[a].mat[3], fp); - - /* "extra" scale facs... */ - { - const int num_segments = ebone->segments; - - const float scaleFactorIn = 1.0f + (ebone->scaleIn - 1.0f) * ((float)(num_segments - a) / (float)num_segments); - const float scaleFactorOut = 1.0f + (ebone->scaleOut - 1.0f) * ((float)(a + 1) / (float)num_segments); - - const float scalefac = scaleFactorIn * scaleFactorOut; - float bscalemat[4][4], bscale[3]; - - bscale[0] = scalefac; - bscale[1] = 1.0f; - bscale[2] = scalefac; - - size_to_mat4(bscalemat, bscale); - - /* Note: don't multiply by inverse scale mat here, as it causes problems with scaling shearing and breaking segment chains */ - mul_m4_series(result_array[a].mat, result_array[a].mat, bscalemat); - } - } -} - -static void draw_b_bone_boxes(const short dt, bPoseChannel *pchan, EditBone *ebone, float xwidth, float length, float zwidth) -{ - int segments = 0; - - if (pchan) - segments = pchan->bone->segments; - else if (ebone) - segments = ebone->segments; - - if (segments > 1) { - float dlen = length / (float)segments; - Mat4 bbone[MAX_BBONE_SUBDIV]; - int a; - - if (pchan) { - b_bone_spline_setup(pchan, 0, bbone); - } - else if (ebone) { - ebone_spline_preview(ebone, bbone); - } - - for (a = 0; a < segments; a++) { - gpuPushMatrix(); - gpuMultMatrix(bbone[a].mat); - if (dt == OB_SOLID) drawsolidcube_size(xwidth, dlen, zwidth); - else drawcube_size(xwidth, dlen, zwidth); - gpuPopMatrix(); - } - } - else { - if (dt == OB_SOLID) drawsolidcube_size(xwidth, length, zwidth); - else drawcube_size(xwidth, length, zwidth); - } -} - -static void draw_b_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - float xwidth, length, zwidth; - - if (pchan) { - xwidth = pchan->bone->xwidth; - length = pchan->bone->length; - zwidth = pchan->bone->zwidth; - } - else { - xwidth = ebone->xwidth; - length = ebone->length; - zwidth = ebone->zwidth; - } - - /* draw points only if... */ - if (armflag & ARM_EDITMODE) { - /* move to unitspace */ - gpuPushMatrix(); - gpuScaleUniform(length); - draw_bone_points(dt, armflag, boneflag, id); - gpuPopMatrix(); - length *= 0.95f; /* make vertices visible */ - } - - /* colors for modes */ - if (armflag & ARM_POSEMODE) { - if (dt <= OB_WIRE) - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - else - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag); - } - else if (armflag & ARM_EDITMODE) { - if (dt == OB_WIRE) { - set_ebone_color(boneflag); - } - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - } - - if (id != -1) { - GPU_select_load_id((GLuint) id | BONESEL_BONE); - } - - /* set up solid drawing */ - if (dt > OB_WIRE) { - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag); - else { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - } - - flat_color = false; - draw_b_bone_boxes(OB_SOLID, pchan, ebone, xwidth, length, zwidth); - } - else { - /* wire */ - if (armflag & ARM_POSEMODE) { - if (constflag && ((G.f & G_PICKSEL) == 0)) { - /* set constraint colors */ - if (set_pchan_color(PCHAN_COLOR_CONSTS, boneflag, constflag)) { - glEnable(GL_BLEND); - - flat_color = true; - draw_b_bone_boxes(OB_SOLID, pchan, ebone, xwidth, length, zwidth); - - glDisable(GL_BLEND); - } - - /* restore colors */ - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - } - } - - draw_b_bone_boxes(OB_WIRE, pchan, ebone, xwidth, length, zwidth); - } -} - -static void draw_wire_bone_segments(bPoseChannel *pchan, Mat4 *bbones, float length, int segments) -{ - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4fv(fcolor); - - if ((segments > 1) && (pchan)) { - float dlen = length / (float)segments; - Mat4 *bbone = bbones; - int a; - - for (a = 0; a < segments; a++, bbone++) { - gpuPushMatrix(); - gpuMultMatrix(bbone->mat); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immVertex3f(pos, 0.0f, dlen, 0.0f); - immEnd(); - - gpuPopMatrix(); - } - } - else { - gpuPushMatrix(); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 0.0f, 0.0f); - immVertex3f(pos, 0.0f, length, 0.0f); - immEnd(); - - gpuPopMatrix(); - } - - immUnbindProgram(); -} - -static void draw_wire_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, - bPoseChannel *pchan, EditBone *ebone) -{ - Mat4 bbones_array[MAX_BBONE_SUBDIV]; - Mat4 *bbones = NULL; - int segments = 0; - float length; - - if (pchan) { - segments = pchan->bone->segments; - length = pchan->bone->length; - - if (segments > 1) { - b_bone_spline_setup(pchan, 0, bbones_array); - bbones = bbones_array; - } - } - else - length = ebone->length; - - /* draw points only if... */ - if (armflag & ARM_EDITMODE) { - /* move to unitspace */ - gpuPushMatrix(); - gpuScaleUniform(length); - flat_color = true; - draw_bone_points(dt, armflag, boneflag, id); - gpuPopMatrix(); - length *= 0.95f; /* make vertices visible */ - } - - /* this chunk not in object mode */ - if (armflag & (ARM_EDITMODE | ARM_POSEMODE)) { - if (id != -1) - GPU_select_load_id((GLuint) id | BONESEL_BONE); - - draw_wire_bone_segments(pchan, bbones, length, segments); - - /* further we send no names */ - if (id != -1) - GPU_select_load_id(id & 0xFFFF); /* object tag, for bordersel optim */ - } - - /* colors for modes */ - if (armflag & ARM_POSEMODE) { - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - } - else if (armflag & ARM_EDITMODE) { - set_ebone_color(boneflag); - } - - /* draw normal */ - draw_wire_bone_segments(pchan, bbones, length, segments); -} - -static void draw_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, float length) -{ - - /* Draw a 3d octahedral bone, we use normalized space based on length */ - gpuScaleUniform(length); - - /* set up solid drawing */ - if (dt > OB_WIRE) { - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - flat_color = false; - } - else - flat_color = true; - - /* colors for posemode */ - if (armflag & ARM_POSEMODE) { - if (dt <= OB_WIRE) - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - else - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag); - } - - - draw_bone_points(dt, armflag, boneflag, id); - - /* now draw the bone itself */ - if (id != -1) { - GPU_select_load_id((GLuint) id | BONESEL_BONE); - } - - /* wire? */ - if (dt <= OB_WIRE) { - /* colors */ - if (armflag & ARM_EDITMODE) { - set_ebone_color(boneflag); - } - else if (armflag & ARM_POSEMODE) { - if (constflag && ((G.f & G_PICKSEL) == 0)) { - /* draw constraint colors */ - if (set_pchan_color(PCHAN_COLOR_CONSTS, boneflag, constflag)) { - glEnable(GL_BLEND); - - draw_bone_solid_octahedral(); - - glDisable(GL_BLEND); - } - - /* restore colors */ - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, constflag); - } - } - draw_bone_octahedral(); - } - else { - /* solid */ - if (armflag & ARM_POSEMODE) - set_pchan_color(PCHAN_COLOR_SOLID, boneflag, constflag); - else - UI_GetThemeColor4fv(TH_BONE_SOLID, fcolor); - - draw_bone_solid_octahedral(); - } -} - -static void draw_custom_bone( - struct Depsgraph *depsgraph, - Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Object *ob, - const short dt, int armflag, int boneflag, unsigned int id, float length) -{ - if (ob == NULL) return; - - gpuScaleUniform(length); - - /* colors for posemode */ - if (armflag & ARM_POSEMODE) { - set_pchan_color(PCHAN_COLOR_NORMAL, boneflag, 0); - } - - if (id != -1) { - GPU_select_load_id((GLuint) id | BONESEL_BONE); - } - - draw_object_instance(depsgraph, scene, view_layer, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE, fcolor); -} - - -static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp) -{ - bConstraint *con; - bPoseChannel *parchan; - - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); - - float viewport_size[4]; - glGetFloatv(GL_VIEWPORT, viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - - immUniform1i("num_colors", 0); /* "simple" mode */ - immUniformColor4fv(fcolor); - immUniform1f("dash_width", 6.0f); - immUniform1f("dash_factor", 0.5f); - - for (con = pchan->constraints.first; con; con = con->next) { - if (con->enforce == 0.0f) - continue; - - switch (con->type) { - case CONSTRAINT_TYPE_KINEMATIC: - { - bKinematicConstraint *data = (bKinematicConstraint *)con->data; - int segcount = 0; - float ik_tip[3]; - - /* if only_temp, only draw if it is a temporary ik-chain */ - if ((only_temp) && !(data->flag & CONSTRAINT_IK_TEMP)) - continue; - - /* exclude tip from chain? */ - if ((data->flag & CONSTRAINT_IK_TIP) == 0) - parchan = pchan->parent; - else - parchan = pchan; - - copy_v3_v3(ik_tip, parchan->pose_tail); - - /* Find the chain's root */ - while (parchan->parent) { - segcount++; - /* FIXME: revise the breaking conditions */ - if (segcount == data->rootbone || segcount > 255) break; /* 255 is weak */ - parchan = parchan->parent; - } - - if (parchan) { - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(shdr_pos, ik_tip); - immVertex3fv(shdr_pos, parchan->pose_head); - immEnd(); - } - - break; - } - case CONSTRAINT_TYPE_SPLINEIK: - { - bSplineIKConstraint *data = (bSplineIKConstraint *)con->data; - int segcount = 0; - float ik_tip[3]; - - parchan = pchan; - copy_v3_v3(ik_tip, parchan->pose_tail); - - /* Find the chain's root */ - while (parchan->parent) { - segcount++; - /* FIXME: revise the breaking conditions */ - if (segcount == data->chainlen || segcount > 255) break; /* 255 is weak */ - parchan = parchan->parent; - } - /* Only draw line in case our chain is more than one bone long! */ - if (parchan != pchan) { /* XXX revise the breaking conditions to only stop at the tail? */ - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(shdr_pos, ik_tip); - immVertex3fv(shdr_pos, parchan->pose_head); - immEnd(); - } - break; - } - } - } - - immUnbindProgram(); -} - -static void imm_sphere_project(unsigned int pos, float ax, float az) -{ - float dir[3], sine, q3; - - sine = 1.0f - ax * ax - az * az; - q3 = (sine < 0.0f) ? 0.0f : (2.0f * sqrtf(sine)); - - dir[0] = -az * q3; - dir[1] = 1.0f - 2.0f * sine; - dir[2] = ax * q3; - - immVertex3fv(pos, dir); -} - -static void draw_dof_ellipse(unsigned int pos, float ax, float az) -{ - const int n = 16; - const int tri = n * n - 2 * n + 1; /* Yay fancy math ! */ - const float staticSine[16] = { - 0.0f, 0.104528463268f, 0.207911690818f, 0.309016994375f, - 0.406736643076f, 0.5f, 0.587785252292f, 0.669130606359f, - 0.743144825477f, 0.809016994375f, 0.866025403784f, - 0.913545457643f, 0.951056516295f, 0.978147600734f, - 0.994521895368f, 1.0f - }; - - int i, j; - float x, z, px, pz; - - glEnable(GL_BLEND); - glDepthMask(0); - - immUniformColor4ub(70, 70, 70, 50); - - immBegin(GWN_PRIM_TRIS, tri * 3); - pz = 0.0f; - for (i = 1; i < n; i++) { - z = staticSine[i]; - - px = 0.0f; - for (j = 1; j <= (n - i); j++) { - x = staticSine[j]; - - if (j == n - i) { - imm_sphere_project(pos, ax * px, az * z); - imm_sphere_project(pos, ax * px, az * pz); - imm_sphere_project(pos, ax * x, az * pz); - } - else { - imm_sphere_project(pos, ax * x, az * z); - imm_sphere_project(pos, ax * x, az * pz); - imm_sphere_project(pos, ax * px, az * pz); - - imm_sphere_project(pos, ax * px, az * pz); - imm_sphere_project(pos, ax * px, az * z); - imm_sphere_project(pos, ax * x, az * z); - } - - px = x; - } - pz = z; - } - immEnd(); - - glDisable(GL_BLEND); - glDepthMask(1); - - immUniformColor3ub(0, 0, 0); - - immBegin(GWN_PRIM_LINE_STRIP, n); - for (i = 0; i < n; i++) - imm_sphere_project(pos, staticSine[n - i - 1] * ax, staticSine[i] * az); - immEnd(); -} - -static void draw_pose_dofs(Object *ob) -{ - bArmature *arm = ob->data; - bPoseChannel *pchan; - Bone *bone; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - - if ((bone != NULL) && !(bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { - if (bone->flag & BONE_SELECTED) { - if (bone->layer & arm->layer) { - if (pchan->ikflag & (BONE_IK_XLIMIT | BONE_IK_ZLIMIT)) { - if (BKE_pose_channel_in_IK_chain(ob, pchan)) { - float corner[4][3], posetrans[3], mat[4][4]; - float phi = 0.0f, theta = 0.0f, scale; - int a, i; - - /* in parent-bone pose, but own restspace */ - gpuPushMatrix(); - - copy_v3_v3(posetrans, pchan->pose_mat[3]); - gpuTranslate3fv(posetrans); - - if (pchan->parent) { - copy_m4_m4(mat, pchan->parent->pose_mat); - mat[3][0] = mat[3][1] = mat[3][2] = 0.0f; - gpuMultMatrix(mat); - } - - copy_m4_m3(mat, pchan->bone->bone_mat); - gpuMultMatrix(mat); - - scale = bone->length * pchan->size[1]; - gpuScaleUniform(scale); - - if (((pchan->ikflag & BONE_IK_XLIMIT) != 0) && - ((pchan->ikflag & BONE_IK_ZLIMIT) != 0)) - { - float amin[3], amax[3]; - - for (i = 0; i < 3; i++) { - /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ - amin[i] = sinf(pchan->limitmin[i] * 0.5f); - amax[i] = sinf(pchan->limitmax[i] * 0.5f); - } - - gpuScale3f(1.0f, -1.0f, 1.0f); - if ((amin[0] != 0.0f) && (amin[2] != 0.0f)) - draw_dof_ellipse(pos, amin[0], amin[2]); - if ((amin[0] != 0.0f) && (amax[2] != 0.0f)) - draw_dof_ellipse(pos, amin[0], amax[2]); - if ((amax[0] != 0.0f) && (amin[2] != 0.0f)) - draw_dof_ellipse(pos, amax[0], amin[2]); - if ((amax[0] != 0.0f) && (amax[2] != 0.0f)) - draw_dof_ellipse(pos, amax[0], amax[2]); - gpuScale3f(1.0f, -1.0f, 1.0f); /* XXX same as above, is this intentional? */ - } - - /* arcs */ - if (pchan->ikflag & BONE_IK_ZLIMIT) { - /* OpenGL requires rotations in degrees; so we're taking the average angle here */ - theta = RAD2DEGF(0.5f * (pchan->limitmin[2] + pchan->limitmax[2])); - gpuPushMatrix(); - gpuRotateAxis(theta, 'Z'); - - immUniformColor3ub(50, 50, 255); /* blue, Z axis limit */ - immBegin(GWN_PRIM_LINE_STRIP, 33); - for (a = -16; a <= 16; a++) { - /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ - float fac = ((float)a) / 16.0f * 0.5f; - - phi = fac * (pchan->limitmax[2] - pchan->limitmin[2]); - - i = (a == -16) ? 0 : 1; - corner[i][0] = sinf(phi); - corner[i][1] = cosf(phi); - corner[i][2] = 0.0f; - immVertex3fv(pos, corner[i]); - } - immEnd(); - - gpuPopMatrix(); - } - - if (pchan->ikflag & BONE_IK_XLIMIT) { - /* OpenGL requires rotations in degrees; so we're taking the average angle here */ - theta = RAD2DEGF(0.5f * (pchan->limitmin[0] + pchan->limitmax[0])); - gpuPushMatrix(); - gpuRotateAxis(theta, 'X'); - - immUniformColor3ub(255, 50, 50); /* Red, X axis limit */ - immBegin(GWN_PRIM_LINE_STRIP, 33); - for (a = -16; a <= 16; a++) { - /* *0.5f here comes from M_PI/360.0f when rotations were still in degrees */ - float fac = ((float)a) / 16.0f * 0.5f; - phi = (float)M_PI_2 + fac * (pchan->limitmax[0] - pchan->limitmin[0]); - - i = (a == -16) ? 2 : 3; - corner[i][0] = 0.0f; - corner[i][1] = sinf(phi); - corner[i][2] = cosf(phi); - immVertex3fv(pos, corner[i]); - } - immEnd(); - - gpuPopMatrix(); - } - - /* out of cone, out of bone */ - gpuPopMatrix(); - } - } - } - } - } - } - - immUnbindProgram(); -} - -static void bone_matrix_translate_y(float mat[4][4], float y) -{ - float trans[3]; - - copy_v3_v3(trans, mat[1]); - mul_v3_fl(trans, y); - add_v3_v3(mat[3], trans); -} - -/* assumes object is Armature with pose */ -static void draw_pose_bones( - struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base, - const short dt, const unsigned char ob_wire_col[4], - const bool do_const_color, const bool is_outline) -{ - RegionView3D *rv3d = ar->regiondata; - Object *ob = base->object; - bArmature *arm = ob->data; - bPoseChannel *pchan; - Bone *bone; - float smat[4][4], imat[4][4], bmat[4][4]; - int index = -1; - const enum { - DASH_RELATIONSHIP_LINES = 1, - DASH_HELP_LINES = 2, - } do_dashed = ( - (is_outline ? 0 : DASH_RELATIONSHIP_LINES) | - ((v3d->flag & V3D_HIDE_HELPLINES) ? 0 : DASH_HELP_LINES)); - bool draw_wire = false; - int flag; - bool is_cull_enabled; - - /* being set below */ - arm->layer_used = 0; - - rgba_uchar_to_float(fcolor, ob_wire_col); - - /* precalc inverse matrix for drawing screen aligned */ - if (arm->drawtype == ARM_ENVELOPE) { - /* precalc inverse matrix for drawing screen aligned */ - copy_m4_m4(smat, rv3d->viewmatob); - mul_mat3_m4_fl(smat, 1.0f / len_v3(ob->obmat[0])); - invert_m4_m4(imat, smat); - - /* and draw blended distances */ - if (arm->flag & ARM_POSEMODE) { - glEnable(GL_BLEND); - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - if (bone) { - /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] - * NOTE: this is the only case with (NO_DEFORM == 0) flag, as this is for envelope influence drawing - */ - if (((bone->flag & (BONE_HIDDEN_P | BONE_NO_DEFORM | BONE_HIDDEN_PG)) == 0) && - ((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0)) - { - if (bone->flag & (BONE_SELECTED)) { - if (bone->layer & arm->layer) - draw_sphere_bone_dist(smat, imat, pchan, NULL); - } - } - } - } - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - } - } - - /* little speedup, also make sure transparent only draws once */ - glCullFace(GL_BACK); - if (v3d->flag2 & V3D_BACKFACE_CULLING) { - glEnable(GL_CULL_FACE); - is_cull_enabled = true; - } - else { - is_cull_enabled = false; - } - - /* if solid we draw that first, with selection codes, but without names, axes etc */ - if (dt > OB_WIRE) { - if (arm->flag & ARM_POSEMODE) - index = base->object->select_color; - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - arm->layer_used |= bone->layer; - - /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */ - if (((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) && - ((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0)) - { - if (bone->layer & arm->layer) { - const bool use_custom = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM); - gpuPushMatrix(); - - if (use_custom && pchan->custom_tx) { - gpuMultMatrix(pchan->custom_tx->pose_mat); - } - else { - gpuMultMatrix(pchan->pose_mat); - } - - /* catch exception for bone with hidden parent */ - flag = bone->flag; - if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { - flag &= ~BONE_CONNECTED; - } - - /* set temporary flag for drawing bone as active, but only if selected */ - if (bone == arm->act_bone) - flag |= BONE_DRAW_ACTIVE; - - if (do_const_color) { - /* keep color */ - } - else { - /* set color-set to use */ - set_pchan_colorset(ob, pchan); - } - - /* may be 2x width from custom bone's outline option */ - glLineWidth(1.0f); - - if (use_custom) { - /* if drawwire, don't try to draw in solid */ - if (pchan->bone->flag & BONE_DRAWWIRE) { - draw_wire = true; - } - else { - if (is_cull_enabled && (v3d->flag2 & V3D_BACKFACE_CULLING) == 0) { - is_cull_enabled = false; - glDisable(GL_CULL_FACE); - } - - draw_custom_bone(depsgraph, scene, view_layer, v3d, rv3d, pchan->custom, - OB_SOLID, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan)); - } - } - else { - if (is_cull_enabled == false) { - is_cull_enabled = true; - glEnable(GL_CULL_FACE); - } - - if (arm->drawtype == ARM_LINE) { - /* nothing in solid */ - } - else if (arm->drawtype == ARM_WIRE) { - /* nothing in solid */ - } - else if (arm->drawtype == ARM_ENVELOPE) { - draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); - } - else if (arm->drawtype == ARM_B_BONE) { - draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); - } - else { - draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length); - } - } - - gpuPopMatrix(); - } - } - - if (index != -1) - index += 0x10000; /* pose bones count in higher 2 bytes only */ - } - - /* very very confusing... but in object mode, solid draw, we cannot do GPU_select_load_id yet, - * stick bones and/or wire custom-shapes are drawn in next loop - */ - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && (draw_wire == false) && index != -1) { - /* object tag, for bordersel optim */ - GPU_select_load_id(index & 0xFFFF); - index = -1; - } - } - - /* custom bone may draw outline double-width */ - if (arm->flag & ARM_POSEMODE) { - glLineWidth(1.0f); - } - - /* draw custom bone shapes as wireframes */ - if (!(arm->flag & ARM_NO_CUSTOM) && - (draw_wire || (dt <= OB_WIRE)) ) - { - if (arm->flag & ARM_POSEMODE) - index = base->object->select_color; - - /* only draw custom bone shapes that need to be drawn as wires */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - - /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */ - if (((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) && - ((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0) ) - { - if (bone->layer & arm->layer) { - if (pchan->custom) { - if ((dt < OB_SOLID) || (bone->flag & BONE_DRAWWIRE)) { - gpuPushMatrix(); - - if (pchan->custom_tx) { - gpuMultMatrix(pchan->custom_tx->pose_mat); - } - else { - gpuMultMatrix(pchan->pose_mat); - } - - /* prepare colors */ - if (do_const_color) { - /* 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) */ - } - else if (arm->flag & ARM_POSEMODE) - set_pchan_colorset(ob, pchan); - else { - rgba_uchar_to_float(fcolor, ob_wire_col); - } - - /* catch exception for bone with hidden parent */ - flag = bone->flag; - if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) - flag &= ~BONE_CONNECTED; - - /* set temporary flag for drawing bone as active, but only if selected */ - if (bone == arm->act_bone) - flag |= BONE_DRAW_ACTIVE; - - draw_custom_bone(depsgraph, scene, view_layer, v3d, rv3d, pchan->custom, - OB_WIRE, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan)); - - gpuPopMatrix(); - } - } - } - } - - if (index != -1) - index += 0x10000; /* pose bones count in higher 2 bytes only */ - } - /* stick or wire bones have not been drawn yet so don't clear object selection in this case */ - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) == 0 && draw_wire && index != -1) { - /* object tag, for bordersel optim */ - GPU_select_load_id(index & 0xFFFF); - index = -1; - } - } - - /* wire draw over solid only in posemode */ - if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - /* draw line check first. we do selection indices */ - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - if (arm->flag & ARM_POSEMODE) - index = base->object->select_color; - } - /* if solid && posemode, we draw again with polygonoffset */ - else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) { - ED_view3d_polygon_offset(rv3d, 1.0); - } - else { - /* and we use selection indices if not done yet */ - if (arm->flag & ARM_POSEMODE) - index = base->object->select_color; - } - - if (is_cull_enabled == false) { - is_cull_enabled = true; - glEnable(GL_CULL_FACE); - } - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - arm->layer_used |= bone->layer; - - /* 1) bone must be visible, 2) for OpenGL select-drawing cannot have unselectable [#27194] */ - if (((bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) && - ((G.f & G_PICKSEL) == 0 || (bone->flag & BONE_UNSELECTABLE) == 0)) - { - if (bone->layer & arm->layer) { - const short constflag = pchan->constflag; - if ((do_dashed & DASH_RELATIONSHIP_LINES) && (pchan->parent)) { - /* Draw a line from our root to the parent's tip - * - only if V3D_HIDE_HELPLINES is enabled... - */ - if ((do_dashed & DASH_HELP_LINES) && ((bone->flag & BONE_CONNECTED) == 0)) { - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); - - float viewport_size[4]; - glGetFloatv(GL_VIEWPORT, viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - - immUniform1i("num_colors", 0); /* "simple" mode */ - immUniformColor4fv(fcolor); - immUniform1f("dash_width", 6.0f); - immUniform1f("dash_factor", 0.5f); - - if (arm->flag & ARM_POSEMODE) { - GPU_select_load_id(index & 0xFFFF); /* object tag, for bordersel optim */ - immUniformThemeColor(TH_WIRE); - } - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(shdr_pos, pchan->parent->pose_tail); - immVertex3fv(shdr_pos, pchan->pose_head); - immEnd(); - - immUnbindProgram(); - } - - /* Draw a line to IK root bone - * - only if temporary chain (i.e. "autoik") - */ - if (arm->flag & ARM_POSEMODE) { - if (constflag & PCHAN_HAS_IK) { - if (bone->flag & BONE_SELECTED) { - if (constflag & PCHAN_HAS_TARGET) { - rgba_float_args_set(fcolor, 200.f / 255.f, 120.f / 255.f, 0.f / 255.f, 1.0f); - } - /* add theme! */ - else rgba_float_args_set(fcolor, 200.f / 255.f, 200.f / 255.f, 50.f / 255.f, 1.0f); - - GPU_select_load_id(index & 0xFFFF); - pchan_draw_IK_root_lines(pchan, !(do_dashed & DASH_HELP_LINES)); - } - } - else if (constflag & PCHAN_HAS_SPLINEIK) { - if (bone->flag & BONE_SELECTED) { - /* add theme! */ - rgba_float_args_set(fcolor, 150.f / 255.f, 200.f / 255.f, 50.f / 255.f, 1.0f); - - GPU_select_load_id(index & 0xFFFF); - pchan_draw_IK_root_lines(pchan, !(do_dashed & DASH_HELP_LINES)); - } - } - } - } - - gpuPushMatrix(); - if (arm->drawtype != ARM_ENVELOPE) - gpuMultMatrix(pchan->pose_mat); - - /* catch exception for bone with hidden parent */ - flag = bone->flag; - if ((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) - flag &= ~BONE_CONNECTED; - - /* set temporary flag for drawing bone as active, but only if selected */ - if (bone == arm->act_bone) - flag |= BONE_DRAW_ACTIVE; - - /* extra draw service for pose mode */ - - /* set color-set to use */ - if (do_const_color) { - /* keep color */ - } - else { - set_pchan_colorset(ob, pchan); - } - - if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) { - /* custom bone shapes should not be drawn here! */ - } - else if (arm->drawtype == ARM_ENVELOPE) { - if (dt < OB_SOLID) - draw_sphere_bone_wire(smat, imat, arm->flag, flag, constflag, index, pchan, NULL); - } - else if (arm->drawtype == ARM_LINE) - draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL); - else if (arm->drawtype == ARM_WIRE) - draw_wire_bone(dt, arm->flag, flag, constflag, index, pchan, NULL); - else if (arm->drawtype == ARM_B_BONE) - draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL); - else - draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length); - - gpuPopMatrix(); - } - } - - /* pose bones count in higher 2 bytes only */ - if (index != -1) - index += 0x10000; - } - /* restore things */ - if (!ELEM(arm->drawtype, ARM_WIRE, ARM_LINE) && (dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) - ED_view3d_polygon_offset(rv3d, 0.0); - } - - /* restore */ - if (is_cull_enabled) { - glDisable(GL_CULL_FACE); - } - - /* draw DoFs */ - if (arm->flag & ARM_POSEMODE) { - if (((base->flag_legacy & OB_FROMDUPLI) == 0) && ((v3d->flag & V3D_HIDE_HELPLINES) == 0)) { - draw_pose_dofs(ob); - } - } - - /* finally names and axes */ - if ((arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) && - (is_outline == 0) && - ((base->flag_legacy & OB_FROMDUPLI) == 0)) - { - /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ - if ((G.f & G_PICKSEL) == 0) { - float vec[3]; - - unsigned char col[4]; - col[0] = ob_wire_col[0]; - col[1] = ob_wire_col[1]; - col[2] = ob_wire_col[2]; - col[3] = 255; - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if ((pchan->bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)) == 0) { - if (pchan->bone->layer & arm->layer) { - if (arm->flag & (ARM_EDITMODE | ARM_POSEMODE)) { - bone = pchan->bone; - UI_GetThemeColor3ubv((bone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col); - } - else if (dt > OB_WIRE) { - UI_GetThemeColor3ubv(TH_TEXT, col); - } - - /* Draw names of bone */ - if (arm->flag & ARM_DRAWNAMES) { - mid_v3_v3v3(vec, pchan->pose_head, pchan->pose_tail); - view3d_cached_text_draw_add(vec, pchan->name, strlen(pchan->name), 10, 0, col); - } - - /* Draw additional axes on the bone tail */ - if ((arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE)) { - gpuPushMatrix(); - copy_m4_m4(bmat, pchan->pose_mat); - bone_matrix_translate_y(bmat, pchan->bone->length); - gpuMultMatrix(bmat); - - float viewmat_pchan[4][4]; - mul_m4_m4m4(viewmat_pchan, rv3d->viewmatob, bmat); - drawaxes(viewmat_pchan, pchan->bone->length * 0.25f, OB_ARROWS, col); - - gpuPopMatrix(); - } - } - } - } - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - } - - if (index != -1) { - GPU_select_load_id(-1); - } -} - -/* in editmode, we don't store the bone matrix... */ -static void get_matrix_editbone(EditBone *ebone, float bmat[4][4]) -{ - ebone->length = len_v3v3(ebone->tail, ebone->head); - ED_armature_ebone_to_mat4(ebone, bmat); -} - -static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) -{ - RegionView3D *rv3d = ar->regiondata; - EditBone *eBone; - bArmature *arm = ob->data; - float smat[4][4], imat[4][4], bmat[4][4]; - unsigned int index; - int flag; - - /* being set in code below */ - arm->layer_used = 0; - - ED_view3d_check_mats_rv3d(rv3d); - - /* envelope (deform distance) */ - if (arm->drawtype == ARM_ENVELOPE) { - /* precalc inverse matrix for drawing screen aligned */ - copy_m4_m4(smat, rv3d->viewmatob); - mul_mat3_m4_fl(smat, 1.0f / len_v3(ob->obmat[0])); - invert_m4_m4(imat, smat); - - /* and draw blended distances */ - glEnable(GL_BLEND); - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { - if (eBone->layer & arm->layer) { - if ((eBone->flag & (BONE_HIDDEN_A | BONE_NO_DEFORM)) == 0) { - if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) - draw_sphere_bone_dist(smat, imat, NULL, eBone); - } - } - } - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - } - - /* if solid we draw it first */ - if ((dt > OB_WIRE) && (arm->drawtype != ARM_LINE)) { - for (eBone = arm->edbo->first, index = 0; eBone; eBone = eBone->next, index++) { - if (eBone->layer & arm->layer) { - if ((eBone->flag & BONE_HIDDEN_A) == 0) { - gpuPushMatrix(); - get_matrix_editbone(eBone, bmat); - gpuMultMatrix(bmat); - - /* catch exception for bone with hidden parent */ - flag = eBone->flag; - if ((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) { - flag &= ~BONE_CONNECTED; - } - - /* set temporary flag for drawing bone as active, but only if selected */ - if (eBone == arm->act_edbone) - flag |= BONE_DRAW_ACTIVE; - - if (arm->drawtype == ARM_ENVELOPE) - draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else if (arm->drawtype == ARM_B_BONE) - draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else if (arm->drawtype == ARM_WIRE) - draw_wire_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else { - draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length); - } - - gpuPopMatrix(); - } - } - } - } - - /* if wire over solid, set offset */ - index = -1; - GPU_select_load_id(-1); - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - if (G.f & G_PICKSEL) - index = 0; - } - else if (dt > OB_WIRE) - ED_view3d_polygon_offset(rv3d, 1.0); - else if (arm->flag & ARM_EDITMODE) - index = 0; /* do selection codes */ - - for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { - arm->layer_used |= eBone->layer; - if (eBone->layer & arm->layer) { - if ((eBone->flag & BONE_HIDDEN_A) == 0) { - - /* catch exception for bone with hidden parent */ - flag = eBone->flag; - if ((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent)) { - flag &= ~BONE_CONNECTED; - } - - /* set temporary flag for drawing bone as active, but only if selected */ - if (eBone == arm->act_edbone) - flag |= BONE_DRAW_ACTIVE; - - if (arm->drawtype == ARM_ENVELOPE) { - if (dt < OB_SOLID) - draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone); - } - else { - gpuPushMatrix(); - get_matrix_editbone(eBone, bmat); - gpuMultMatrix(bmat); - - if (arm->drawtype == ARM_LINE) - draw_line_bone(arm->flag, flag, 0, index, NULL, eBone); - else if (arm->drawtype == ARM_WIRE) - draw_wire_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone); - else if (arm->drawtype == ARM_B_BONE) - draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone); - else - draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length); - - gpuPopMatrix(); - } - - /* offset to parent */ - if (eBone->parent) { - const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - GPU_select_load_id(-1); /* -1 here is OK! */ - - immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); - - float viewport_size[4]; - glGetFloatv(GL_VIEWPORT, viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - - immUniform1i("num_colors", 0); /* "simple" mode */ - immUniformThemeColor(TH_WIRE_EDIT); - immUniform1f("dash_width", 6.0f); - immUniform1f("dash_factor", 0.5f); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(shdr_pos, eBone->parent->tail); - immVertex3fv(shdr_pos, eBone->head); - immEnd(); - - immUnbindProgram(); - } - } - } - if (index != -1) index++; - } - - /* restore */ - if (index != -1) { - GPU_select_load_id(-1); - } - - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - /* pass */ - } - else if (dt > OB_WIRE) { - ED_view3d_polygon_offset(rv3d, 0.0); - } - - /* finally names and axes */ - if (arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) { - /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ - if ((G.f & G_PICKSEL) == 0) { - float vec[3]; - unsigned char col[4]; - col[3] = 255; - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - for (eBone = arm->edbo->first; eBone; eBone = eBone->next) { - if (eBone->layer & arm->layer) { - if ((eBone->flag & BONE_HIDDEN_A) == 0) { - - UI_GetThemeColor3ubv((eBone->flag & BONE_SELECTED) ? TH_TEXT_HI : TH_TEXT, col); - - /* Draw name */ - if (arm->flag & ARM_DRAWNAMES) { - mid_v3_v3v3(vec, eBone->head, eBone->tail); - view3d_cached_text_draw_add(vec, eBone->name, strlen(eBone->name), 10, 0, col); - } - /* Draw additional axes */ - if (arm->flag & ARM_DRAWAXES) { - gpuPushMatrix(); - get_matrix_editbone(eBone, bmat); - bone_matrix_translate_y(bmat, eBone->length); - gpuMultMatrix(bmat); - - float viewmat_ebone[4][4]; - mul_m4_m4m4(viewmat_ebone, rv3d->viewmatob, bmat); - drawaxes(viewmat_ebone, eBone->length * 0.25f, OB_ARROWS, col); - - gpuPopMatrix(); - } - - } - } - } - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - } -} - -/* ****************************** Armature Visualization ******************************** */ - -/* ---------- Paths --------- */ - -/* draw bone paths - * - in view space - */ -static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob) -{ - bAnimVizSettings *avs = &ob->pose->avs; - bArmature *arm = ob->data; - bPoseChannel *pchan; - - /* setup drawing environment for paths */ - draw_motion_paths_init(v3d, ar); - - /* draw paths where they exist and they releated bone is visible */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if ((pchan->bone->layer & arm->layer) && (pchan->mpath)) - draw_motion_path_instance(scene, ob, pchan, avs, pchan->mpath); - } - - /* cleanup after drawing */ - draw_motion_paths_cleanup(v3d); -} - - -/* ---------- Ghosts --------- */ - -/* helper function for ghost drawing - sets/removes flags for temporarily - * hiding unselected bones while drawing ghosts - */ -static void ghost_poses_tag_unselected(Object *ob, short unset) -{ - bArmature *arm = ob->data; - bPose *pose = ob->pose; - bPoseChannel *pchan; - - /* don't do anything if no hiding any bones */ - if ((arm->flag & ARM_GHOST_ONLYSEL) == 0) - return; - - /* loop over all pchans, adding/removing tags as appropriate */ - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - if ((pchan->bone) && (arm->layer & pchan->bone->layer)) { - if (unset) { - /* remove tags from all pchans if cleaning up */ - pchan->bone->flag &= ~BONE_HIDDEN_PG; - } - else { - /* set tags on unselected pchans only */ - if ((pchan->bone->flag & BONE_SELECTED) == 0) - pchan->bone->flag |= BONE_HIDDEN_PG; - } - } - } -} - -/* draw ghosts that occur within a frame range - * note: object should be in posemode - */ -static void draw_ghost_poses_range( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base) -{ - Object *ob = base->object; - AnimData *adt = BKE_animdata_from_id(&ob->id); - bArmature *arm = ob->data; - bPose *posen, *poseo; - float start, end, stepsize, range, colfac; - int cfrao, flago; - unsigned char col[4]; - - start = (float)arm->ghostsf; - end = (float)arm->ghostef; - if (end <= start) - return; - - /* prevent infinite loops if this is set to 0 - T49527 */ - if (arm->ghostsize < 1) - arm->ghostsize = 1; - - stepsize = (float)(arm->ghostsize); - range = (float)(end - start); - - /* store values */ - ob->mode &= ~OB_MODE_POSE; - cfrao = CFRA; - flago = arm->flag; - arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES); - - /* copy the pose */ - poseo = ob->pose; - BKE_pose_copy_data(&posen, ob->pose, 1); - ob->pose = posen; - BKE_pose_rebuild(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from first frame of range to last */ - for (CFRA = (int)start; CFRA <= end; CFRA += (int)stepsize) { - colfac = (end - (float)CFRA) / range; - UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); - - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(depsgraph, scene, ob); - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); - } - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - - /* before disposing of temp pose, use it to restore object to a sane state */ - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)cfrao, ADT_RECALC_ALL); - - /* clean up temporary pose */ - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - BKE_pose_free(posen); - - /* restore */ - CFRA = cfrao; - ob->pose = poseo; - arm->flag = flago; - ob->mode |= OB_MODE_POSE; -} - -/* draw ghosts on keyframes in action within range - * - object should be in posemode - */ -static void draw_ghost_poses_keys( - struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, - View3D *v3d, ARegion *ar, Base *base) -{ - Object *ob = base->object; - AnimData *adt = BKE_animdata_from_id(&ob->id); - bAction *act = (adt) ? adt->action : NULL; - bArmature *arm = ob->data; - bPose *posen, *poseo; - DLRBT_Tree keys; - ActKeyColumn *ak, *akn; - float start, end, range, colfac, i; - int cfrao, flago; - unsigned char col[4]; - - start = (float)arm->ghostsf; - end = (float)arm->ghostef; - if (end <= start) - return; - - /* get keyframes - then clip to only within range */ - BLI_dlrbTree_init(&keys); - action_to_keylist(adt, act, &keys, NULL); - BLI_dlrbTree_linkedlist_sync(&keys); - - range = 0; - for (ak = keys.first; ak; ak = akn) { - akn = ak->next; - - if ((ak->cfra < start) || (ak->cfra > end)) - BLI_freelinkN((ListBase *)&keys, ak); - else - range++; - } - if (range == 0) return; - - /* store values */ - ob->mode &= ~OB_MODE_POSE; - cfrao = CFRA; - flago = arm->flag; - arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES); - - /* copy the pose */ - poseo = ob->pose; - BKE_pose_copy_data(&posen, ob->pose, 1); - ob->pose = posen; - BKE_pose_rebuild(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from first frame of range to last */ - for (ak = keys.first, i = 0; ak; ak = ak->next, i++) { - colfac = i / range; - UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); - - CFRA = (int)ak->cfra; - - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(depsgraph, scene, ob); - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); - } - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - - /* before disposing of temp pose, use it to restore object to a sane state */ - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)cfrao, ADT_RECALC_ALL); - - /* clean up temporary pose */ - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - BLI_dlrbTree_free(&keys); - BKE_pose_free(posen); - - /* restore */ - CFRA = cfrao; - ob->pose = poseo; - arm->flag = flago; - ob->mode |= OB_MODE_POSE; -} - -/* draw ghosts around current frame - * - object is supposed to be armature in posemode - */ -static void draw_ghost_poses( - struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, - View3D *v3d, ARegion *ar, Base *base) -{ - Object *ob = base->object; - AnimData *adt = BKE_animdata_from_id(&ob->id); - bArmature *arm = ob->data; - bPose *posen, *poseo; - float cur, start, end, stepsize, range, colfac, actframe, ctime; - int cfrao, flago; - unsigned char col[4]; - - /* pre conditions, get an action with sufficient frames */ - if (ELEM(NULL, adt, adt->action)) - return; - - calc_action_range(adt->action, &start, &end, 0); - if (start == end) - return; - - /* prevent infinite loops if this is set to 0 - T49527 */ - if (arm->ghostsize < 1) - arm->ghostsize = 1; - - stepsize = (float)(arm->ghostsize); - range = (float)(arm->ghostep) * stepsize + 0.5f; /* plus half to make the for loop end correct */ - - /* store values */ - ob->mode &= ~OB_MODE_POSE; - cfrao = CFRA; - actframe = BKE_nla_tweakedit_remap(adt, (float)CFRA, 0); - flago = arm->flag; - arm->flag &= ~(ARM_DRAWNAMES | ARM_DRAWAXES); - - /* copy the pose */ - poseo = ob->pose; - BKE_pose_copy_data(&posen, ob->pose, 1); - ob->pose = posen; - BKE_pose_rebuild(ob, ob->data); /* child pointers for IK */ - ghost_poses_tag_unselected(ob, 0); /* hide unselected bones if need be */ - - glEnable(GL_BLEND); - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - /* draw from darkest blend to lowest */ - for (cur = stepsize; cur < range; cur += stepsize) { - ctime = cur - (float)fmod(cfrao, stepsize); /* ensures consistent stepping */ - colfac = ctime / range; - UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); - - /* only within action range */ - if (actframe + ctime >= start && actframe + ctime <= end) { - CFRA = (int)BKE_nla_tweakedit_remap(adt, actframe + ctime, NLATIME_CONVERT_MAP); - - if (CFRA != cfrao) { - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(depsgraph, scene, ob); - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); - } - } - - ctime = cur + (float)fmod((float)cfrao, stepsize) - stepsize + 1.0f; /* ensures consistent stepping */ - colfac = ctime / range; - UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col); - - /* only within action range */ - if ((actframe - ctime >= start) && (actframe - ctime <= end)) { - CFRA = (int)BKE_nla_tweakedit_remap(adt, actframe - ctime, NLATIME_CONVERT_MAP); - - if (CFRA != cfrao) { - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); - BKE_pose_where_is(depsgraph, scene, ob); - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, col, true, false); - } - } - } - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - - /* before disposing of temp pose, use it to restore object to a sane state */ - BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)cfrao, ADT_RECALC_ALL); - - /* clean up temporary pose */ - ghost_poses_tag_unselected(ob, 1); /* unhide unselected bones if need be */ - BKE_pose_free(posen); - - /* restore */ - CFRA = cfrao; - ob->pose = poseo; - arm->flag = flago; - ob->mode |= OB_MODE_POSE; -} - -/* ********************************** Armature Drawing - Main ************************* */ - -/* called from drawobject.c, return true if nothing was drawn - * (ob_wire_col == NULL) when drawing ghost */ -bool draw_armature( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base, - const short dt, const short dflag, const unsigned char ob_wire_col[4], - const bool is_outline) -{ - Object *ob = base->object; - bArmature *arm = ob->data; - bool retval = false; - - if (v3d->flag2 & V3D_RENDER_OVERRIDE) - return true; - -#if 0 /* Not used until lighting is properly reimplemented */ - if (dt > OB_WIRE) { - /* we use color for solid lighting */ - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { - const float diffuse[3] = {0.64f, 0.64f, 0.64f}; - const float specular[3] = {0.5f, 0.5f, 0.5f}; - GPU_basic_shader_colors(diffuse, specular, 35, 1.0f); - } - else { - const float diffuse[3] = {1.0f, 1.0f, 1.0f}; - const float specular[3] = {1.0f, 1.0f, 1.0f}; - GPU_basic_shader_colors(diffuse, specular, 35, 1.0f); - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); /* only for lighting... */ - } - } -#endif - - /* arm->flag is being used to detect mode... */ - /* editmode? */ - if (arm->edbo) { - arm->flag |= ARM_EDITMODE; - draw_ebones(v3d, ar, ob, dt); - arm->flag &= ~ARM_EDITMODE; - } - else { - /* Draw Pose */ - if (ob->pose && ob->pose->chanbase.first) { - /* We can't safely draw non-updated pose, might contain NULL bone pointers... */ - if (ob->pose->flag & POSE_RECALC) { - BKE_pose_rebuild(ob, arm); - } - - /* drawing posemode selection indices or colors only in these cases */ - if (!(base->flag_legacy & OB_FROMDUPLI)) { - if (G.f & G_PICKSEL) { -#if 0 - /* nifty but actually confusing to allow bone selection out of posemode */ - if (OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { - if (ob == modifiers_isDeformedByArmature(OBACT)) - arm->flag |= ARM_POSEMODE; - } - else -#endif - if (ob->mode & OB_MODE_POSE) { - arm->flag |= ARM_POSEMODE; - } - } - else if (ob->mode & OB_MODE_POSE) { - if (arm->ghosttype == ARM_GHOST_RANGE) { - draw_ghost_poses_range(depsgraph, scene, view_layer, v3d, ar, base); - } - else if (arm->ghosttype == ARM_GHOST_KEYS) { - draw_ghost_poses_keys(depsgraph, scene, view_layer, v3d, ar, base); - } - else if (arm->ghosttype == ARM_GHOST_CUR) { - if (arm->ghostep) - draw_ghost_poses(depsgraph, scene, view_layer, v3d, ar, base); - } - if ((dflag & DRAW_SCENESET) == 0) { - if (ob == OBACT(view_layer)) - arm->flag |= ARM_POSEMODE; - else if (OBACT(view_layer) && (OBACT(view_layer)->mode & OB_MODE_WEIGHT_PAINT)) { - if (ob == modifiers_isDeformedByArmature(OBACT(view_layer))) - arm->flag |= ARM_POSEMODE; - } - draw_pose_paths(scene, v3d, ar, ob); - } - } - } - draw_pose_bones(depsgraph, scene, view_layer, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline); - arm->flag &= ~ARM_POSEMODE; - } - else { - retval = true; - } - } - /* restore */ - glFrontFace(GL_CCW); - - return retval; -} diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c deleted file mode 100644 index 2b3678c4812..00000000000 --- a/source/blender/editors/space_view3d/drawmesh.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * 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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): Blender Foundation, full update, glsl support - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/drawmesh.c - * \ingroup spview3d - */ - -#include <string.h> -#include <math.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_bitmap.h" -#include "BLI_math.h" - -#include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_node_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_DerivedMesh.h" -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_material.h" -#include "BKE_paint.h" -#include "BKE_editmesh.h" -#include "BKE_scene.h" - -#include "BIF_glutil.h" - -#include "UI_resources.h" - -#include "GPU_draw.h" -#include "GPU_material.h" -#include "GPU_basic_shader.h" -#include "GPU_shader.h" -#include "GPU_matrix.h" - -#include "RE_engine.h" - -#include "ED_uvedit.h" - -#include "view3d_intern.h" /* own include */ - -/* user data structures for derived mesh callbacks */ -typedef struct drawMeshFaceSelect_userData { - Mesh *me; - BLI_bitmap *edge_flags; /* pairs of edge options (visible, select) */ -} drawMeshFaceSelect_userData; - -/**************************** Face Select Mode *******************************/ - -/* mainly to be less confusing */ -BLI_INLINE int edge_vis_index(const int index) { return index * 2; } -BLI_INLINE int edge_sel_index(const int index) { return index * 2 + 1; } - -static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me, bool draw_select_edges) -{ - BLI_bitmap *bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__); - MPoly *mp; - MLoop *ml; - int i, j; - bool select_set; - - for (i = 0; i < me->totpoly; i++) { - mp = &me->mpoly[i]; - - if (!(mp->flag & ME_HIDE)) { - select_set = (mp->flag & ME_FACE_SEL) != 0; - - ml = me->mloop + mp->loopstart; - for (j = 0; j < mp->totloop; j++, ml++) { - if ((draw_select_edges == false) && - (select_set && BLI_BITMAP_TEST(bitmap_edge_flags, edge_sel_index(ml->e)))) - { - BLI_BITMAP_DISABLE(bitmap_edge_flags, edge_vis_index(ml->e)); - } - else { - BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_vis_index(ml->e)); - if (select_set) { - BLI_BITMAP_ENABLE(bitmap_edge_flags, edge_sel_index(ml->e)); - } - } - } - } - } - - return bitmap_edge_flags; -} - - -static DMDrawOption draw_mesh_face_select__setHiddenOpts(void *userData, int index) -{ - drawMeshFaceSelect_userData *data = userData; - Mesh *me = data->me; - - if (me->drawflag & ME_DRAWEDGES) { - if ((BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index)))) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; - } - else if (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index)) && - BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index))) - { - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - -static DMDrawOption draw_mesh_face_select__setSelectOpts(void *userData, int index) -{ - drawMeshFaceSelect_userData *data = userData; - return (BLI_BITMAP_TEST(data->edge_flags, edge_sel_index(index)) && - BLI_BITMAP_TEST(data->edge_flags, edge_vis_index(index))) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP; -} - -/* draws unselected */ -static DMDrawOption draw_mesh_face_select__drawFaceOptsInv(void *userData, int index) -{ - Mesh *me = (Mesh *)userData; - - MPoly *mpoly = &me->mpoly[index]; - if (!(mpoly->flag & ME_HIDE) && !(mpoly->flag & ME_FACE_SEL)) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; -} - -void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, bool draw_select_edges) -{ - drawMeshFaceSelect_userData data; - - data.me = me; - data.edge_flags = get_tface_mesh_marked_edge_info(me, draw_select_edges); - - glEnable(GL_DEPTH_TEST); - ED_view3d_polygon_offset(rv3d, 1.0); - - /* Draw (Hidden) Edges */ - setlinestyle(1); - UI_ThemeColor(TH_EDGE_FACESEL); - dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data); - setlinestyle(0); - - /* Draw Selected Faces */ - if (me->drawflag & ME_DRAWFACES) { - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - /* dull unselected faces so as not to get in the way of seeing color */ - glColor4ub(96, 96, 96, 64); - dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, NULL, (void *)me, DM_DRAW_SKIP_HIDDEN); - glDisable(GL_BLEND); - } - - ED_view3d_polygon_offset(rv3d, 1.0); - - /* Draw Stippled Outline for selected faces */ - glColor3ub(255, 255, 255); - setlinestyle(1); - dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data); - setlinestyle(0); - - ED_view3d_polygon_offset(rv3d, 0.0); /* resets correctly now, even after calling accumulated offsets */ - - MEM_freeN(data.edge_flags); -} - -/***************************** Texture Drawing ******************************/ - -/* when face select is on, use face hidden flag */ -static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int index) -{ - Mesh *me = (Mesh *)userData; - MPoly *mp = &me->mpoly[index]; - if (mp->flag & ME_HIDE) - return DM_DRAW_OPTION_SKIP; - return DM_DRAW_OPTION_NORMAL; -} - -/************************** NEW SHADING NODES ********************************/ - -typedef struct TexMatCallback { - Scene *scene; - Object *ob; - Mesh *me; - DerivedMesh *dm; - bool shadeless; - bool two_sided_lighting; -} TexMatCallback; - -void draw_mesh_textured(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, - Object *ob, DerivedMesh *dm, const int draw_flags) -{ - UNUSED_VARS(scene, view_layer, v3d, rv3d, ob, dm, draw_flags); - return; -} - -/* Vertex Paint and Weight Paint */ -static void draw_mesh_paint_light_begin(void) -{ - /* get material diffuse color from vertex colors but set default spec */ - const float specular[3] = {0.47f, 0.47f, 0.47f}; - GPU_basic_shader_colors(NULL, specular, 35, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); -} - -static void draw_mesh_paint_light_end(void) -{ - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); -} - -void draw_mesh_paint_weight_faces(DerivedMesh *dm, const bool use_light, - void *facemask_cb, void *user_data) -{ - DMSetMaterial setMaterial = GPU_object_materials_check() ? GPU_object_material_bind : NULL; - int flags = DM_DRAW_USE_COLORS; - - if (use_light) { - draw_mesh_paint_light_begin(); - flags |= DM_DRAW_NEED_NORMALS; - } - - dm->drawMappedFaces(dm, (DMSetDrawOptions)facemask_cb, setMaterial, NULL, user_data, flags); - - if (use_light) { - draw_mesh_paint_light_end(); - } -} - -void draw_mesh_paint_vcolor_faces(DerivedMesh *dm, const bool use_light, - void *facemask_cb, void *user_data, - const Mesh *me) -{ - DMSetMaterial setMaterial = GPU_object_materials_check() ? GPU_object_material_bind : NULL; - int flags = 0; - - if (use_light) { - draw_mesh_paint_light_begin(); - flags |= DM_DRAW_NEED_NORMALS; - } - - if (me->mloopcol) { - dm->drawMappedFaces(dm, facemask_cb, setMaterial, NULL, user_data, - DM_DRAW_USE_COLORS | flags); - } - else { - glColor3f(1.0f, 1.0f, 1.0f); - dm->drawMappedFaces(dm, facemask_cb, setMaterial, NULL, user_data, flags); - } - - if (use_light) { - draw_mesh_paint_light_end(); - } -} - -void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm, - const bool use_depth, const bool use_alpha, - void *edgemask_cb, void *user_data) -{ - /* weight paint in solid mode, special case. focus on making the weights clear - * rather than the shading, this is also forced in wire view */ - - if (use_depth) { - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */ - } - else { - glDisable(GL_DEPTH_TEST); - } - - if (use_alpha) { - glEnable(GL_BLEND); - } - - glColor4ub(255, 255, 255, 96); - GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); - GPU_basic_shader_line_stipple(1, 0xAAAA); - - dm->drawMappedEdges(dm, (DMSetDrawOptions)edgemask_cb, user_data); - - if (use_depth) { - ED_view3d_polygon_offset(rv3d, 0.0); - glDepthMask(1); - } - else { - glEnable(GL_DEPTH_TEST); - } - - GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); - - if (use_alpha) { - glDisable(GL_BLEND); - } -} - -void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, - Object *ob, DerivedMesh *dm, const int draw_flags) -{ - DMSetDrawOptions facemask = NULL; - Mesh *me = ob->data; - const bool use_light = (v3d->drawtype >= OB_SOLID); - - /* hide faces in face select mode */ - if (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL)) - facemask = wpaint__setSolidDrawOptions_facemask; - - if (ob->mode & OB_MODE_WEIGHT_PAINT) { - draw_mesh_paint_weight_faces(dm, use_light, facemask, me); - } - else if (ob->mode & OB_MODE_VERTEX_PAINT) { - draw_mesh_paint_vcolor_faces(dm, use_light, facemask, me, me); - } - - /* draw face selection on top */ - if (draw_flags & DRAW_FACE_SELECT) { - bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0; - draw_mesh_face_select(rv3d, me, dm, draw_select_edges); - } - else if ((use_light == false) || (ob->dtx & OB_DRAWWIRE)) { - const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT); - const bool use_alpha = (ob->mode & OB_MODE_VERTEX_PAINT) == 0; - - if (use_alpha == false) { - set_inverted_drawing(1); - } - - draw_mesh_paint_weight_edges(rv3d, dm, use_depth, use_alpha, NULL, NULL); - - if (use_alpha == false) { - set_inverted_drawing(0); - } - } -} - diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 37279c77ba0..8e04a2e17b8 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -116,136 +116,6 @@ #include "../../draw/intern/draw_cache_impl.h" /* bad level include (temporary) */ -/* prototypes */ -static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos); - -// #define USE_MESH_DM_SELECT - -/* Workaround for sequencer scene render mode. - * - * Strips doesn't use DAG to update objects or so, which - * might lead to situations when object is drawing without - * curve cache ready. - * - * Ideally we don't want to evaluate objects from drawing, - * but it'll require some major sequencer re-design. So - * for now just fallback to legacy behavior with calling - * display ist creating from draw(). - */ -#define SEQUENCER_DAG_WORKAROUND - -typedef enum eWireDrawMode { - OBDRAW_WIRE_OFF = 0, - OBDRAW_WIRE_ON = 1, - OBDRAW_WIRE_ON_DEPTH = 2 -} eWireDrawMode; - -typedef struct drawDMVerts_userData { - BMesh *bm; - - BMVert *eve_act; - char sel; - unsigned int pos, color; - - /* cached theme values */ - unsigned char th_editmesh_active[4]; - unsigned char th_vertex_select[4]; - unsigned char th_vertex[4]; - unsigned char th_skin_root[4]; - - /* for skin node drawing */ - int cd_vskin_offset; - float imat[4][4]; -} drawDMVerts_userData; - -typedef struct drawDMEdgesSel_userData { - BMesh *bm; - - unsigned char *baseCol, *selCol, *actCol; - BMEdge *eed_act; -} drawDMEdgesSel_userData; - -typedef struct drawDMEdgesSelInterp_userData { - BMesh *bm; - - unsigned char *baseCol, *selCol; - unsigned char *lastCol; -} drawDMEdgesSelInterp_userData; - -typedef struct drawDMEdgesWeightInterp_userData { - BMesh *bm; - - int cd_dvert_offset; - int defgroup_tot; - int vgroup_index; - char weight_user; - float alert_color[3]; - -} drawDMEdgesWeightInterp_userData; - -typedef struct drawDMFacesSel_userData { -#ifdef WITH_FREESTYLE - unsigned char *cols[4]; -#else - unsigned char *cols[3]; -#endif - - DerivedMesh *dm; - BMesh *bm; - - BMFace *efa_act; - const int *orig_index_mp_to_orig; -} drawDMFacesSel_userData; - -typedef struct drawDMNormal_userData { - unsigned int pos; - BMesh *bm; - int uniform_scale; - float normalsize; - float tmat[3][3]; - float imat[3][3]; -} drawDMNormal_userData; - -typedef struct drawMVertOffset_userData { - unsigned int pos, col; - MVert *mvert; - int offset; -} drawMVertOffset_userData; - -typedef struct drawDMLayer_userData { - BMesh *bm; - int cd_layer_offset; - unsigned int pos, col; -} drawDMLayer_userData; - -typedef struct drawBMOffset_userData { - unsigned int pos, col; - BMesh *bm; - int offset; -} drawBMOffset_userData; - -typedef struct drawBMSelect_userData { - BMesh *bm; - bool select; - unsigned int pos; -} drawBMSelect_userData; - - -static void drawcube_size(float size, unsigned pos); -static void drawcircle_size(float size, unsigned pos); -static void draw_empty_sphere(float size, unsigned pos); -static void draw_empty_cone(float size, unsigned pos); - -static void ob_wire_color_blend_theme_id(const unsigned char ob_wire_col[4], const int theme_id, float fac, float r_col[3]) -{ - float col_wire[3], col_bg[3]; - - rgb_uchar_to_float(col_wire, ob_wire_col); - - UI_GetThemeColor3fv(theme_id, col_bg); - interp_v3_v3v3(r_col, col_bg, col_wire, fac); -} - int view3d_effective_drawtype(const struct View3D *v3d) { if (v3d->drawtype == OB_RENDER) { @@ -254,42 +124,6 @@ int view3d_effective_drawtype(const struct View3D *v3d) return v3d->drawtype; } -/* this condition has been made more complex since editmode can draw textures */ -bool check_object_draw_texture(Scene *scene, View3D *v3d, const char drawtype) -{ - const int v3d_drawtype = view3d_effective_drawtype(v3d); - /* texture and material draw modes */ - if (ELEM(v3d_drawtype, OB_TEXTURE, OB_MATERIAL) && drawtype > OB_SOLID) { - return true; - } - - /* textured solid */ - if ((v3d_drawtype == OB_SOLID) && - (v3d->flag2 & V3D_SOLID_TEX) && - (BKE_scene_use_new_shading_nodes(scene) == false)) - { - return true; - } - - if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) { - return true; - } - - return false; -} - -static bool check_object_draw_editweight(Mesh *me, DerivedMesh *finalDM) -{ - if (me->drawflag & ME_DRAWEIGHT) { - /* editmesh handles its own weight drawing */ - if (finalDM->type != DM_TYPE_EDITBMESH) { - return true; - } - } - - return false; -} - static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) { if ((sce->toolsettings->selectmode & SCE_SELECT_FACE) == 0) @@ -311,49 +145,6 @@ static bool check_ob_drawface_dot(Scene *sce, View3D *vd, char dt) return true; } -/* ************************ */ - -/* check for glsl drawing */ - -bool draw_glsl_material(Scene *scene, ViewLayer *view_layer, Object *ob, View3D *v3d, const char dt) -{ - if (G.f & G_PICKSEL) - return false; - if (!check_object_draw_texture(scene, v3d, dt)) - return false; - if (ob == OBACT(view_layer) && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)) - return false; - - if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) - return true; - - if (v3d->drawtype == OB_TEXTURE) - return !BKE_scene_use_new_shading_nodes(scene); - else if (v3d->drawtype == OB_MATERIAL && dt > OB_SOLID) - return true; - else - return false; -} - -static bool check_alpha_pass(Base *base) -{ - if (base->flag_legacy & OB_FROMDUPLI) - return false; - - if (G.f & G_PICKSEL) - return false; - - if (base->object->mode & OB_MODE_ALL_PAINT) - return false; - - return (base->object->dtx & OB_DRAWTRANSP); -} - -/***/ -static const unsigned int colortab[] = { - 0x0, 0x403000, 0xFFFF88 -}; - /* ----------------- OpenGL Circle Drawing - Tables for Optimized Drawing Speed ------------------ */ /* 32 values of sin function (still same result!) */ #define CIRCLE_RESOL 32 @@ -429,365 +220,6 @@ static const float cosval[CIRCLE_RESOL] = { 1.00000000 }; -/** - * \param viewmat_local_unit is typically the 'rv3d->viewmatob' - * copied into a 3x3 matrix and normalized. - */ -static void draw_xyz_wire(const float viewmat_local_unit[3][3], const float c[3], float size, int axis, unsigned pos) -{ - Gwn_PrimType line_type = GWN_PRIM_LINES; - float buffer[4][3]; - int n = 0; - - float v1[3] = {0.0f, 0.0f, 0.0f}, v2[3] = {0.0f, 0.0f, 0.0f}; - float dim = size * 0.1f; - float dx[3], dy[3]; - - dx[0] = dim; dx[1] = 0.0f; dx[2] = 0.0f; - dy[0] = 0.0f; dy[1] = dim; dy[2] = 0.0f; - - switch (axis) { - case 0: /* x axis */ - /* bottom left to top right */ - negate_v3_v3(v1, dx); - sub_v3_v3(v1, dy); - copy_v3_v3(v2, dx); - add_v3_v3(v2, dy); - - copy_v3_v3(buffer[n++], v1); - copy_v3_v3(buffer[n++], v2); - - /* top left to bottom right */ - mul_v3_fl(dy, 2.0f); - add_v3_v3(v1, dy); - sub_v3_v3(v2, dy); - - copy_v3_v3(buffer[n++], v1); - copy_v3_v3(buffer[n++], v2); - - break; - case 1: /* y axis */ - /* bottom left to top right */ - mul_v3_fl(dx, 0.75f); - negate_v3_v3(v1, dx); - sub_v3_v3(v1, dy); - copy_v3_v3(v2, dx); - add_v3_v3(v2, dy); - - copy_v3_v3(buffer[n++], v1); - copy_v3_v3(buffer[n++], v2); - - /* top left to center */ - mul_v3_fl(dy, 2.0f); - add_v3_v3(v1, dy); - zero_v3(v2); - - copy_v3_v3(buffer[n++], v1); - copy_v3_v3(buffer[n++], v2); - - break; - case 2: /* z axis */ - line_type = GWN_PRIM_LINE_STRIP; - - /* start at top left */ - negate_v3_v3(v1, dx); - add_v3_v3(v1, dy); - - copy_v3_v3(buffer[n++], v1); - - mul_v3_fl(dx, 2.0f); - add_v3_v3(v1, dx); - - copy_v3_v3(buffer[n++], v1); - - mul_v3_fl(dy, 2.0f); - sub_v3_v3(v1, dx); - sub_v3_v3(v1, dy); - - copy_v3_v3(buffer[n++], v1); - - add_v3_v3(v1, dx); - - copy_v3_v3(buffer[n++], v1); - - break; - default: - BLI_assert(0); - return; - } - - immBegin(line_type, n); - for (int i = 0; i < n; i++) { - mul_transposed_m3_v3((float (*)[3])viewmat_local_unit, buffer[i]); - add_v3_v3(buffer[i], c); - immVertex3fv(pos, buffer[i]); - } - immEnd(); - - /* TODO: recode this function for clarity once we're not in a hurry to modernize GL usage */ -} - -void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]) -{ - int axis; - float v1[3] = {0.0, 0.0, 0.0}; - float v2[3] = {0.0, 0.0, 0.0}; - float v3[3] = {0.0, 0.0, 0.0}; - - glLineWidth(1.0f); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - if (color) { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4ubv(color); - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY); - } - - switch (drawtype) { - case OB_PLAINAXES: - immBegin(GWN_PRIM_LINES, 6); - for (axis = 0; axis < 3; axis++) { - v1[axis] = size; - v2[axis] = -size; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - - /* reset v1 & v2 to zero */ - v1[axis] = v2[axis] = 0.0f; - } - immEnd(); - break; - - case OB_SINGLE_ARROW: - immBegin(GWN_PRIM_LINES, 2); - /* in positive z direction only */ - v1[2] = size; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - immEnd(); - - /* square pyramid */ - immBegin(GWN_PRIM_TRIS, 12); - - v2[0] = size * 0.035f; v2[1] = size * 0.035f; - v3[0] = size * -0.035f; v3[1] = size * 0.035f; - v2[2] = v3[2] = size * 0.75f; - - for (axis = 0; axis < 4; axis++) { - if (axis % 2 == 1) { - v2[0] = -v2[0]; - v3[1] = -v3[1]; - } - else { - v2[1] = -v2[1]; - v3[0] = -v3[0]; - } - - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - immVertex3fv(pos, v3); - } - immEnd(); - break; - - case OB_CUBE: - drawcube_size(size, pos); - break; - - case OB_CIRCLE: - drawcircle_size(size, pos); - break; - - case OB_EMPTY_SPHERE: - draw_empty_sphere(size, pos); - break; - - case OB_EMPTY_CONE: - draw_empty_cone(size, pos); - break; - - case OB_ARROWS: - default: - { - float viewmat_local_unit[3][3]; - - copy_m3_m4(viewmat_local_unit, (float (*)[4])viewmat_local); - normalize_m3(viewmat_local_unit); - - for (axis = 0; axis < 3; axis++) { - const int arrow_axis = (axis == 0) ? 1 : 0; - - immBegin(GWN_PRIM_LINES, 6); - - v2[axis] = size; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - - v1[axis] = size * 0.85f; - v1[arrow_axis] = -size * 0.08f; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - - v1[arrow_axis] = size * 0.08f; - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - - immEnd(); - - v2[axis] += size * 0.125f; - - draw_xyz_wire(viewmat_local_unit, v2, size, axis, pos); - - /* reset v1 & v2 to zero */ - v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f; - } - } - } - - immUnbindProgram(); -} - - -/* Function to draw an Image on an empty Object */ -static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4], eStereoViews sview) -{ - Image *ima = ob->data; - - const float ob_alpha = ob->col[3]; - float ima_x, ima_y; - - int bindcode = 0; - - if (ima) { - ImageUser iuser = *ob->iuser; - - /* Support multi-view */ - if (ima && (sview == STEREO_RIGHT_ID)) { - iuser.multiview_eye = sview; - iuser.flag |= IMA_SHOW_STEREO; - BKE_image_multiview_index(ima, &iuser); - } - - if (ob_alpha > 0.0f) { - bindcode = GPU_verify_image(ima, &iuser, GL_TEXTURE_2D, false, false, false); - /* don't bother drawing the image if alpha = 0 */ - } - - int w, h; - BKE_image_get_size(ima, &iuser, &w, &h); - ima_x = w; - ima_y = h; - } - else { - /* if no image, make it a 1x1 empty square, honor scale & offset */ - ima_x = ima_y = 1.0f; - } - - /* Get the image aspect even if the buffer is invalid */ - float sca_x = 1.0f, sca_y = 1.0f; - if (ima) { - if (ima->aspx > ima->aspy) { - sca_y = ima->aspy / ima->aspx; - } - else if (ima->aspx < ima->aspy) { - sca_x = ima->aspx / ima->aspy; - } - } - - float scale_x; - float scale_y; - { - const float scale_x_inv = ima_x * sca_x; - const float scale_y_inv = ima_y * sca_y; - if (scale_x_inv > scale_y_inv) { - scale_x = ob->empty_drawsize; - scale_y = ob->empty_drawsize * (scale_y_inv / scale_x_inv); - } - else { - scale_x = ob->empty_drawsize * (scale_x_inv / scale_y_inv); - scale_y = ob->empty_drawsize; - } - } - - const float ofs_x = ob->ima_ofs[0] * scale_x; - const float ofs_y = ob->ima_ofs[1] * scale_y; - - const rctf rect = { - .xmin = ofs_x, - .xmax = ofs_x + scale_x, - .ymin = ofs_y, - .ymax = ofs_y + scale_y, - }; - - bool use_blend = false; - - if (bindcode) { - use_blend = ob_alpha < 1.0f || BKE_image_has_alpha(ima); - - if (use_blend) { - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int texCoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA); - immUniform1f("alpha", ob_alpha); - immUniform1i("image", 0); /* default GL_TEXTURE0 unit */ - - immBegin(GWN_PRIM_TRI_FAN, 4); - immAttrib2f(texCoord, 0.0f, 0.0f); - immVertex2f(pos, rect.xmin, rect.ymin); - - immAttrib2f(texCoord, 1.0f, 0.0f); - immVertex2f(pos, rect.xmax, rect.ymin); - - immAttrib2f(texCoord, 1.0f, 1.0f); - immVertex2f(pos, rect.xmax, rect.ymax); - - immAttrib2f(texCoord, 0.0f, 1.0f); - immVertex2f(pos, rect.xmin, rect.ymax); - immEnd(); - - immUnbindProgram(); - } - - /* Draw the image outline */ - glLineWidth(1.5f); - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - - const bool picking = dflag & DRAW_CONSTCOLOR; - if (picking) { - /* TODO: deal with picking separately, use this function just to draw */ - immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY); - if (use_blend) { - glDisable(GL_BLEND); - } - - imm_draw_box_wire_2d(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(ob_wire_col); - glEnable(GL_LINE_SMOOTH); - - if (!use_blend) { - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - - imm_draw_box_wire_2d(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - - glDisable(GL_LINE_SMOOTH); - glDisable(GL_BLEND); - } - - immUnbindProgram(); -} - static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4]) { float vx[3], vy[3]; @@ -816,8383 +248,11 @@ void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], un immEnd(); } -/* circle for object centers, special_color is for library or ob users */ -static void drawcentercircle(View3D *v3d, RegionView3D *UNUSED(rv3d), const float co[3], int selstate, bool special_color) -{ - const float outlineWidth = 1.0f * U.pixelsize; - const float size = U.obcenter_dia * U.pixelsize + outlineWidth; - - if (v3d->zbuf) { - glDisable(GL_DEPTH_TEST); - /* TODO(merwin): fit things like this into plates/buffers design */ - } - - glEnable(GL_BLEND); - GPU_enable_program_point_size(); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA); - immUniform1f("size", size); - - if (special_color) { - if (selstate == ACTIVE || selstate == SELECT) immUniformColor4ub(0x88, 0xFF, 0xFF, 155); - else immUniformColor4ub(0x55, 0xCC, 0xCC, 155); - } - else { - if (selstate == ACTIVE) immUniformThemeColorShadeAlpha(TH_ACTIVE, 0, -80); - else if (selstate == SELECT) immUniformThemeColorShadeAlpha(TH_SELECT, 0, -80); - else if (selstate == DESELECT) immUniformThemeColorShadeAlpha(TH_TRANSFORM, 0, -80); - } - - /* set up outline */ - float outlineColor[4]; - UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, outlineColor); - immUniform4fv("outlineColor", outlineColor); - immUniform1f("outlineWidth", outlineWidth); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, co); - immEnd(); - - immUnbindProgram(); - - GPU_disable_program_point_size(); - glDisable(GL_BLEND); - - if (v3d->zbuf) { - glEnable(GL_DEPTH_TEST); - } -} - -/* *********** text drawing for object/particles/armature ************* */ - -typedef struct ViewCachedString { - struct ViewCachedString *next; - float vec[3]; - union { - unsigned char ub[4]; - int pack; - } col; - short sco[2]; - short xoffs; - short flag; - int str_len; - - /* str is allocated past the end */ - char str[0]; -} ViewCachedString; - -/* one arena for all 3 string lists */ -static MemArena *g_v3d_strings_arena = NULL; -static ViewCachedString *g_v3d_strings[3] = {NULL, NULL, NULL}; -static int g_v3d_string_level = -1; - -void view3d_cached_text_draw_begin(void) -{ - g_v3d_string_level++; - - BLI_assert(g_v3d_string_level >= 0); - - if (g_v3d_string_level == 0) { - BLI_assert(g_v3d_strings_arena == NULL); - } -} - -void view3d_cached_text_draw_add(const float co[3], - const char *str, const size_t str_len, - short xoffs, short flag, - const unsigned char col[4]) -{ - int alloc_len = str_len + 1; - ViewCachedString *vos; - - BLI_assert(str_len == strlen(str)); - - if (g_v3d_strings_arena == NULL) { - g_v3d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__); - } - - vos = BLI_memarena_alloc(g_v3d_strings_arena, sizeof(ViewCachedString) + alloc_len); - - BLI_LINKS_PREPEND(g_v3d_strings[g_v3d_string_level], vos); - - copy_v3_v3(vos->vec, co); - copy_v4_v4_uchar(vos->col.ub, col); - vos->xoffs = xoffs; - vos->flag = flag; - vos->str_len = str_len; - - /* allocate past the end */ - memcpy(vos->str, str, alloc_len); -} - -void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write) -{ - RegionView3D *rv3d = ar->regiondata; - ViewCachedString *vos; - int tot = 0; - - BLI_assert(g_v3d_string_level >= 0 && g_v3d_string_level <= 2); - - /* project first and test */ - for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) { - if (ED_view3d_project_short_ex(ar, - (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, - (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, - vos->vec, vos->sco, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) - { - tot++; - } - else { - vos->sco[0] = IS_CLIPPED; - } - } - - if (tot) { - int col_pack_prev = 0; - - if (rv3d->rflag & RV3D_CLIPPING) { - ED_view3d_clipping_disable(); - } - - float original_proj[4][4]; - gpuGetProjectionMatrix(original_proj); - wmOrtho2_region_pixelspace(ar); - - gpuPushMatrix(); - gpuLoadIdentity(); - - if (depth_write) { - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - } - else { - glDepthMask(GL_FALSE); - } - - const int font_id = BLF_default(); - - for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) { - if (vos->sco[0] != IS_CLIPPED) { - if (col_pack_prev != vos->col.pack) { - BLF_color3ubv(font_id, vos->col.ub); - col_pack_prev = vos->col.pack; - } - - ((vos->flag & V3D_CACHE_TEXT_ASCII) ? BLF_draw_default_ascii : BLF_draw_default)( - (float)(vos->sco[0] + vos->xoffs), - (float)(vos->sco[1]), - (depth_write) ? 0.0f : 2.0f, - vos->str, - vos->str_len); - } - } - - if (depth_write) { - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - else { - glDepthMask(GL_TRUE); - } - - gpuPopMatrix(); - gpuLoadProjectionMatrix(original_proj); - - if (rv3d->rflag & RV3D_CLIPPING) { - ED_view3d_clipping_enable(); - } - } - - g_v3d_strings[g_v3d_string_level] = NULL; - - if (g_v3d_string_level == 0) { - if (g_v3d_strings_arena) { - BLI_memarena_free(g_v3d_strings_arena); - g_v3d_strings_arena = NULL; - } - } - - g_v3d_string_level--; -} - -/* ******************** primitive drawing ******************* */ - -/* draws a cube given the scaling of the cube, assuming that - * all required matrices have been set (used for drawing empties) - */ -static void drawcube_size(float size, unsigned pos) -{ - const float verts[8][3] = { - {-size, -size, -size}, - {-size, -size, size}, - {-size, size, -size}, - {-size, size, size}, - { size, -size, -size}, - { size, -size, size}, - { size, size, -size}, - { size, size, size} - }; - - const GLubyte indices[24] = {0, 1, 1, 3, 3, 2, 2, 0, 0, 4, 4, 5, 5, 7, 7, 6, 6, 4, 1, 5, 3, 7, 2, 6}; - -#if 0 - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, verts); - glDrawRangeElements(GL_LINES, 0, 7, 24, GL_UNSIGNED_BYTE, indices); - glDisableClientState(GL_VERTEX_ARRAY); -#else - immBegin(GWN_PRIM_LINES, 24); - for (int i = 0; i < 24; ++i) { - immVertex3fv(pos, verts[indices[i]]); - } - immEnd(); -#endif -} - -static void drawshadbuflimits(const Lamp *la, const float mat[4][4], unsigned pos) -{ - float sta[3], end[3], lavec[3]; - - negate_v3_v3(lavec, mat[2]); - normalize_v3(lavec); - - madd_v3_v3v3fl(sta, mat[3], lavec, la->clipsta); - madd_v3_v3v3fl(end, mat[3], lavec, la->clipend); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, sta); - immVertex3fv(pos, end); - immEnd(); - - glPointSize(3.0f); - immBegin(GWN_PRIM_POINTS, 2); - immVertex3fv(pos, sta); - immVertex3fv(pos, end); - immEnd(); -} - -static void spotvolume(float lvec[3], float vvec[3], const float inp) -{ - /* camera is at 0,0,0 */ - float temp[3], plane[3], mat1[3][3], mat2[3][3], mat3[3][3], mat4[3][3], q[4], co, si, angle; - - normalize_v3(lvec); - normalize_v3(vvec); /* is this the correct vector ? */ - - cross_v3_v3v3(temp, vvec, lvec); /* equation for a plane through vvec and lvec */ - cross_v3_v3v3(plane, lvec, temp); /* a plane perpendicular to this, parallel with lvec */ - - /* vectors are exactly aligned, use the X axis, this is arbitrary */ - if (normalize_v3(plane) == 0.0f) - plane[1] = 1.0f; - - /* now we've got two equations: one of a cone and one of a plane, but we have - * three unknowns. We remove one unknown by rotating the plane to z=0 (the plane normal) */ - - /* rotate around cross product vector of (0,0,1) and plane normal, dot product degrees */ - /* according definition, we derive cross product is (plane[1],-plane[0],0), en cos = plane[2]);*/ - - /* translating this comment to english didnt really help me understanding the math! :-) (ton) */ - - q[1] = plane[1]; - q[2] = -plane[0]; - q[3] = 0; - normalize_v3(&q[1]); - - angle = saacos(plane[2]) / 2.0f; - co = cosf(angle); - si = sqrtf(1 - co * co); - - q[0] = co; - q[1] *= si; - q[2] *= si; - q[3] = 0; - - quat_to_mat3(mat1, q); - - /* rotate lamp vector now over acos(inp) degrees */ - copy_v3_v3(vvec, lvec); - - unit_m3(mat2); - co = inp; - si = sqrtf(1.0f - inp * inp); - - mat2[0][0] = co; - mat2[1][0] = -si; - mat2[0][1] = si; - mat2[1][1] = co; - mul_m3_m3m3(mat3, mat2, mat1); - - mat2[1][0] = si; - mat2[0][1] = -si; - mul_m3_m3m3(mat4, mat2, mat1); - transpose_m3(mat1); - - mul_m3_m3m3(mat2, mat1, mat3); - mul_m3_v3(mat2, lvec); - mul_m3_m3m3(mat2, mat1, mat4); - mul_m3_v3(mat2, vvec); -} - -static void draw_spot_cone(Lamp *la, float x, float z, unsigned pos) -{ - z = fabsf(z); - - const bool square = (la->mode & LA_SQUARE); - - immBegin(GWN_PRIM_TRI_FAN, square ? 6 : 34); - immVertex3f(pos, 0.0f, 0.0f, -x); - - if (square) { - immVertex3f(pos, z, z, 0); - immVertex3f(pos, -z, z, 0); - immVertex3f(pos, -z, -z, 0); - immVertex3f(pos, z, -z, 0); - immVertex3f(pos, z, z, 0); - } - else { - for (int a = 0; a < 33; a++) { - float angle = a * M_PI * 2 / (33 - 1); - immVertex3f(pos, z * cosf(angle), z * sinf(angle), 0.0f); - } - } - - immEnd(); -} - -static void draw_transp_spot_volume(Lamp *la, float x, float z, unsigned pos) -{ - glEnable(GL_CULL_FACE); - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); - - /* draw backside darkening */ - glCullFace(GL_FRONT); - - glBlendFunc(GL_ZERO, GL_SRC_ALPHA); - immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f); - - draw_spot_cone(la, x, z, pos); - - /* draw front side lighting */ - glCullFace(GL_BACK); - - glBlendFunc(GL_ONE, GL_ONE); - immUniformColor3f(0.2f, 0.2f, 0.2f); - - draw_spot_cone(la, x, z, pos); - - /* restore state */ - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); - glDisable(GL_CULL_FACE); -} - -void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4], const bool is_obact) -{ - Object *ob = base->object; - const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]); - Lamp *la = ob->data; - float vec[3], lvec[3], vvec[3], circrad; - float imat[4][4]; - - /* cone can't be drawn for duplicated lamps, because duplilist would be freed */ - /* the moment of view3d_draw_transp() call */ - const bool is_view = (rv3d->persp == RV3D_CAMOB && v3d->camera == base->object); - const bool drawcone = ((dt > OB_WIRE) && - !(G.f & G_PICKSEL) && - (la->type == LA_SPOT) && - (la->mode & LA_SHOW_CONE) && - !(base->flag_legacy & OB_FROMDUPLI) && - !is_view); - - if (drawcone && !v3d->transp) { - /* in this case we need to draw delayed */ - ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); - return; - } - - /* we first draw only the screen aligned & fixed scale stuff */ - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); - - /* lets calculate the scale: */ - const float lampsize_px = U.obcenter_dia; - const float lampsize = pixsize * lampsize_px * 0.5f; - - /* and view aligned matrix: */ - copy_m4_m4(imat, rv3d->viewinv); - normalize_v3(imat[0]); - normalize_v3(imat[1]); - - const unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - /* lamp center */ - copy_v3_v3(vec, ob->obmat[3]); - - float curcol[4]; - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* for AA effects */ - rgb_uchar_to_float(curcol, ob_wire_col); - curcol[3] = 0.6f; - /* TODO: pay attention to GL_BLEND */ - } - - glLineWidth(1.0f); - setlinestyle(3); - - if (lampsize > 0.0f) { - const float outlineWidth = 1.5f * U.pixelsize; - const float lampdot_size = lampsize_px * U.pixelsize + outlineWidth; - - /* Inner Circle */ - if ((dflag & DRAW_CONSTCOLOR) == 0) { - const float *color = curcol; - if (ob->id.us > 1) { - if (is_obact || ((base->flag & BASE_SELECTED) != 0)) { - static const float active_color[4] = {0.533f, 1.0f, 1.0f, 1.0f}; - color = active_color; - } - else { - static const float inactive_color[4] = {0.467f, 0.8f, 0.8f, 1.0f}; - color = inactive_color; - } - } - - GPU_enable_program_point_size(); - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - immBindBuiltinProgram(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA); - immUniform1f("size", lampdot_size); - immUniform1f("outlineWidth", outlineWidth); - immUniformColor3fvAlpha(color, 0.3f); - immUniform4fv("outlineColor", color); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, vec); - immEnd(); - - immUnbindProgram(); - - glDisable(GL_BLEND); - GPU_disable_program_point_size(); - } - else { - /* CONSTCOLOR in effect */ - /* TODO: separate picking from drawing */ - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR); - /* color doesn't matter, so don't set */ - glPointSize(lampdot_size); - - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, vec); - immEnd(); - - immUnbindProgram(); - } - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - /* TODO(merwin): short term, use DEPTH_ONLY for picking - * long term, separate picking from drawing - */ - - /* restore */ - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformColor4fv(curcol); - } - - /* Outer circle */ - circrad = 3.0f * lampsize; - - imm_drawcircball(vec, circrad, imat, pos); - - /* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */ - if (la->type != LA_HEMI) { - if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) { - imm_drawcircball(vec, circrad + 3.0f * pixsize, imat, pos); - } - } - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformColor4fv(curcol); - } - circrad = 0.0f; - } - - /* draw the pretty sun rays */ - if (la->type == LA_SUN) { - float v1[3], v2[3], mat[3][3]; - short axis; - - /* setup a 45 degree rotation matrix */ - axis_angle_normalized_to_mat3_ex(mat, imat[2], M_SQRT1_2, M_SQRT1_2); - - /* vectors */ - mul_v3_v3fl(v1, imat[0], circrad * 1.2f); - mul_v3_v3fl(v2, imat[0], circrad * 2.5f); - - /* center */ - gpuPushMatrix(); - gpuTranslate3fv(vec); - - setlinestyle(3); - - immBegin(GWN_PRIM_LINES, 16); - for (axis = 0; axis < 8; axis++) { - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - mul_m3_v3(mat, v1); - mul_m3_v3(mat, v2); - } - immEnd(); - - gpuPopMatrix(); - } - - if (la->type == LA_LOCAL) { - if (la->mode & LA_SPHERE) { - imm_drawcircball(vec, la->dist, imat, pos); - } - } - - gpuPopMatrix(); /* back in object space */ - zero_v3(vec); - - if (is_view) { - /* skip drawing extra info */ - } - else if (la->type == LA_SPOT) { - float x, y, z, z_abs; - copy_v3_fl3(lvec, 0.0f, 0.0f, 1.0f); - copy_v3_fl3(vvec, rv3d->persmat[0][2], rv3d->persmat[1][2], rv3d->persmat[2][2]); - mul_transposed_mat3_m4_v3(ob->obmat, vvec); - - x = -la->dist; - y = cosf(la->spotsize * 0.5f); - z = x * sqrtf(1.0f - y * y); - - spotvolume(lvec, vvec, y); - mul_v3_fl(lvec, x); - mul_v3_fl(vvec, x); - - x *= y; - - z_abs = fabsf(z); - - if (la->mode & LA_SQUARE) { - /* draw pyramid */ - const float vertices[5][3] = { - /* 5 of vertex coords of pyramid */ - {0.0f, 0.0f, 0.0f}, - {z_abs, z_abs, x}, - {-z_abs, -z_abs, x}, - {z_abs, -z_abs, x}, - {-z_abs, z_abs, x}, - }; - - immBegin(GWN_PRIM_LINES, 16); - for (int i = 1; i <= 4; ++i) { - immVertex3fv(pos, vertices[0]); /* apex to corner */ - immVertex3fv(pos, vertices[i]); - int next_i = (i == 4) ? 1 : (i + 1); - immVertex3fv(pos, vertices[i]); /* corner to next corner */ - immVertex3fv(pos, vertices[next_i]); - } - immEnd(); - - gpuTranslate3f(0.0f, 0.0f, x); - - /* draw the square representing spotbl */ - if (la->type == LA_SPOT) { - float blend = z_abs * (1.0f - pow2f(la->spotblend)); - - /* hide line if it is zero size or overlaps with outer border, - * previously it adjusted to always to show it but that seems - * confusing because it doesn't show the actual blend size */ - if (blend != 0.0f && blend != z_abs) { - imm_draw_box_wire_3d(pos, blend, -blend, -blend, blend); - } - } - } - else { - /* draw the angled sides of the cone */ - immBegin(GWN_PRIM_LINE_STRIP, 3); - immVertex3fv(pos, vvec); - immVertex3fv(pos, vec); - immVertex3fv(pos, lvec); - immEnd(); - - /* draw the circle at the end of the cone */ - gpuTranslate3f(0.0f, 0.0f, x); - imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, z_abs, 32); - - /* draw the circle representing spotbl */ - if (la->type == LA_SPOT) { - float blend = z_abs * (1.0f - pow2f(la->spotblend)); - - /* hide line if it is zero size or overlaps with outer border, - * previously it adjusted to always to show it but that seems - * confusing because it doesn't show the actual blend size */ - if (blend != 0.0f && blend != z_abs) { - imm_draw_circle_wire_3d(pos, 0.0f, 0.0f, blend, 32); - } - } - } - - if (drawcone) - draw_transp_spot_volume(la, x, z, pos); - - /* draw clip start, useful for wide cones where its not obvious where the start is */ - gpuTranslate3f(0.0f, 0.0f, -x); /* reverse translation above */ - immBegin(GWN_PRIM_LINES, 2); - if (la->type == LA_SPOT && (la->mode & LA_SHAD_BUF)) { - float lvec_clip[3]; - float vvec_clip[3]; - float clipsta_fac = la->clipsta / -x; - - interp_v3_v3v3(lvec_clip, vec, lvec, clipsta_fac); - interp_v3_v3v3(vvec_clip, vec, vvec, clipsta_fac); - - immVertex3fv(pos, lvec_clip); - immVertex3fv(pos, vvec_clip); - } - /* Else, draw spot direction (using distance as end limit, same as for Area lamp). */ - else { - immVertex3f(pos, 0.0f, 0.0f, -circrad); - immVertex3f(pos, 0.0f, 0.0f, -la->dist); - } - immEnd(); - } - else if (ELEM(la->type, LA_HEMI, LA_SUN)) { - /* draw the line from the circle along the dist */ - immBegin(GWN_PRIM_LINES, 2); - vec[2] = -circrad; - immVertex3fv(pos, vec); - vec[2] = -la->dist; - immVertex3fv(pos, vec); - immEnd(); - - if (la->type == LA_HEMI) { - /* draw the hemisphere curves */ - short axis, steps, dir; - float outdist, zdist, mul; - zero_v3(vec); - outdist = 0.14f; mul = 1.4f; dir = 1; - - setlinestyle(4); - /* loop over the 4 compass points, and draw each arc as a LINE_STRIP */ - for (axis = 0; axis < 4; axis++) { - float v[3] = {0.0f, 0.0f, 0.0f}; - zdist = 0.02f; - - immBegin(GWN_PRIM_LINE_STRIP, 6); - - for (steps = 0; steps < 6; steps++) { - if (axis == 0 || axis == 1) { /* x axis up, x axis down */ - /* make the arcs start at the edge of the energy circle */ - if (steps == 0) v[0] = dir * circrad; - else v[0] = v[0] + dir * (steps * outdist); - } - else if (axis == 2 || axis == 3) { /* y axis up, y axis down */ - /* make the arcs start at the edge of the energy circle */ - v[1] = (steps == 0) ? (dir * circrad) : (v[1] + dir * (steps * outdist)); - } - - v[2] = v[2] - steps * zdist; - - immVertex3fv(pos, v); - - zdist = zdist * mul; - } - - immEnd(); - /* flip the direction */ - dir = -dir; - } - } - - } - else if (la->type == LA_AREA) { - setlinestyle(3); - if (la->area_shape == LA_AREA_SQUARE) - imm_draw_box_wire_3d(pos, -la->area_size * 0.5f, -la->area_size * 0.5f, la->area_size * 0.5f, la->area_size * 0.5f); - else if (la->area_shape == LA_AREA_RECT) - imm_draw_box_wire_3d(pos, -la->area_size * 0.5f, -la->area_sizey * 0.5f, la->area_size * 0.5f, la->area_sizey * 0.5f); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 0.0f, -circrad); - immVertex3f(pos, 0.0f, 0.0f, -la->dist); - immEnd(); - } - - /* and back to viewspace */ - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); - copy_v3_v3(vec, ob->obmat[3]); - - setlinestyle(0); - - if ((la->type == LA_SPOT) && (la->mode & LA_SHAD_BUF) && (is_view == false)) { - drawshadbuflimits(la, ob->obmat, pos); - } - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformThemeColor(TH_LAMP); - } - - glEnable(GL_BLEND); - - if (vec[2] > 0) vec[2] -= circrad; - else vec[2] += circrad; - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, vec); - vec[2] = 0; - immVertex3fv(pos, vec); - immEnd(); - - glPointSize(2.0f); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, vec); - immEnd(); - - glDisable(GL_BLEND); - - immUnbindProgram(); - gpuPopMatrix(); -} - -static void draw_limit_line(float sta, float end, const short dflag, const unsigned char col[3], unsigned pos) -{ - immBegin(GWN_PRIM_LINES, 2); - immVertex3f(pos, 0.0f, 0.0f, -sta); - immVertex3f(pos, 0.0f, 0.0f, -end); - immEnd(); - - if (!(dflag & DRAW_PICKING)) { - glPointSize(3.0f); - /* would like smooth round points here, but that means binding another shader... - * if it's really desired, pull these points into their own function to be called after */ - immBegin(GWN_PRIM_POINTS, 2); - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformColor3ubv(col); - } - immVertex3f(pos, 0.0f, 0.0f, -sta); - immVertex3f(pos, 0.0f, 0.0f, -end); - immEnd(); - } -} - - -/* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */ -/* qdn: now also enabled for Blender to set focus point for defocus composite node */ -static void draw_focus_cross(float dist, float size, unsigned pos) -{ - immBegin(GWN_PRIM_LINES, 4); - immVertex3f(pos, -size, 0.0f, -dist); - immVertex3f(pos, size, 0.0f, -dist); - immVertex3f(pos, 0.0f, -size, -dist); - immVertex3f(pos, 0.0f, size, -dist); - immEnd(); -} - #ifdef VIEW3D_CAMERA_BORDER_HACK unsigned char view3d_camera_border_hack_col[3]; bool view3d_camera_border_hack_test = false; #endif -/* ****************** draw clip data *************** */ - -static void draw_viewport_object_reconstruction( - Scene *scene, Base *base, const View3D *v3d, const RegionView3D *rv3d, - MovieClip *clip, MovieTrackingObject *tracking_object, - const short dflag, const unsigned char ob_wire_col[4], - int *global_track_index, bool draw_selected) -{ - MovieTracking *tracking = &clip->tracking; - MovieTrackingTrack *track; - float mat[4][4], imat[4][4]; - unsigned char col_unsel[4], col_sel[4]; - int tracknr = *global_track_index; - ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); - float camera_size[3]; - - UI_GetThemeColor4ubv(TH_TEXT, col_unsel); - UI_GetThemeColor4ubv(TH_SELECT, col_sel); - - BKE_tracking_get_camera_object_matrix(scene, base->object, mat); - - /* we're compensating camera size for bundles size, - * to make it so bundles are always displayed with the same size */ - copy_v3_v3(camera_size, base->object->size); - if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) - mul_v3_fl(camera_size, tracking_object->scale); - - gpuPushMatrix(); - - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - /* current ogl matrix is translated in camera space, bundles should - * be rendered in world space, so camera matrix should be "removed" - * from current ogl matrix */ - invert_m4_m4(imat, base->object->obmat); - - gpuMultMatrix(imat); - gpuMultMatrix(mat); - } - else { - float obmat[4][4]; - int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra); - - BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, obmat); - - invert_m4_m4(imat, obmat); - gpuMultMatrix(imat); - } - - for (track = tracksbase->first; track; track = track->next) { - bool selected = TRACK_SELECTED(track); - - if (draw_selected && !selected) - continue; - - if ((track->flag & TRACK_HAS_BUNDLE) == 0) - continue; - - if (dflag & DRAW_PICKING) - GPU_select_load_id(base->object->select_color + (tracknr << 16)); - - gpuPushMatrix(); - gpuTranslate3fv(track->bundle_pos); - gpuScale3f(v3d->bundle_size / 0.05f / camera_size[0], - v3d->bundle_size / 0.05f / camera_size[1], - v3d->bundle_size / 0.05f / camera_size[2]); - - const int v3d_drawtype = view3d_effective_drawtype(v3d); - if (v3d_drawtype == OB_WIRE) { - unsigned char color[4]; - const unsigned char *color_ptr = NULL; - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (selected && (track->flag & TRACK_CUSTOMCOLOR) == 0) { - color_ptr = ob_wire_col; - } - else { - rgba_float_to_uchar(color, track->color); - color_ptr = color; - } - } - - drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype, color_ptr); - } - else if (v3d_drawtype > OB_WIRE) { - if (v3d->bundle_drawtype == OB_EMPTY_SPHERE) { - Gwn_Batch *batch; - - gpuScaleUniform(0.05f); - - /* selection outline */ - if (selected) { - batch = GPU_batch_preset_sphere_wire(1); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4f(batch, "color", - ob_wire_col[0] / 255.f, - ob_wire_col[1] / 255.f, - ob_wire_col[2] / 255.f, 1.0f); - } - else { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_DEPTH_ONLY); - } - glLineWidth(2.0f); - - GWN_batch_draw(batch); - } - - batch = GPU_batch_preset_sphere(0); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - const float light[3] = {0.0f, 0.0f, 1.0f}; - float col[3]; - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3fv(batch, "light", light); - - if (track->flag & TRACK_CUSTOMCOLOR) copy_v3_v3(col, track->color); - else UI_GetThemeColor3fv(TH_BUNDLE_SOLID, col); - GWN_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f); - } - else { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_DEPTH_ONLY); - } - - GWN_batch_draw(batch); - } - else { - unsigned char color[4]; - const unsigned char *color_ptr = NULL; - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (selected) { - color_ptr = ob_wire_col; - } - else { - if (track->flag & TRACK_CUSTOMCOLOR) rgba_float_to_uchar(color, track->color); - else UI_GetThemeColor4ubv(TH_WIRE, color); - - color_ptr = color; - } - } - - drawaxes(rv3d->viewmatob, 0.05f, v3d->bundle_drawtype, color_ptr); - } - } - - gpuPopMatrix(); - - if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) { - float pos[3]; - - mul_v3_m4v3(pos, mat, track->bundle_pos); - view3d_cached_text_draw_add(pos, - track->name, strlen(track->name), - 10, V3D_CACHE_TEXT_GLOBALSPACE, - selected ? col_sel : col_unsel); - } - - tracknr++; - } - - if ((dflag & DRAW_PICKING) == 0) { - if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA)) { - MovieTrackingReconstruction *reconstruction; - reconstruction = BKE_tracking_object_get_reconstruction(tracking, tracking_object); - - if (reconstruction->camnr >= 2) { - MovieReconstructedCamera *camera = reconstruction->cameras; - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_CAMERA_PATH); - - glLineWidth(2.0f); - - immBegin(GWN_PRIM_LINE_STRIP, reconstruction->camnr); - for (int a = 0; a < reconstruction->camnr; a++, camera++) { - immVertex3fv(pos, camera->mat[3]); - } - immEnd(); - - immUnbindProgram(); - } - } - } - - gpuPopMatrix(); - - *global_track_index = tracknr; -} - -static void draw_viewport_reconstruction( - Scene *scene, Base *base, const View3D *v3d, const RegionView3D *rv3d, MovieClip *clip, - const short dflag, const unsigned char ob_wire_col[4], - const bool draw_selected) -{ - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object; - int global_track_index = 1; - - if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0) - return; - - if (v3d->flag2 & V3D_RENDER_OVERRIDE) - return; - - GPU_basic_shader_colors(NULL, NULL, 0, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); - - tracking_object = tracking->objects.first; - while (tracking_object) { - draw_viewport_object_reconstruction( - scene, base, v3d, rv3d, clip, tracking_object, - dflag, ob_wire_col, &global_track_index, draw_selected); - - tracking_object = tracking_object->next; - } - - /* restore */ - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - - if (dflag & DRAW_PICKING) - GPU_select_load_id(base->object->select_color); -} - -/* camera frame */ -static void drawcamera_frame(float vec[4][3], bool filled, unsigned pos) -{ - immBegin(filled ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, 4); - immVertex3fv(pos, vec[0]); - immVertex3fv(pos, vec[1]); - immVertex3fv(pos, vec[2]); - immVertex3fv(pos, vec[3]); - immEnd(); -} - -/* center point to camera frame */ -static void drawcamera_framelines(float vec[4][3], float origin[3], unsigned pos) -{ - immBegin(GWN_PRIM_LINES, 8); - immVertex3fv(pos, origin); - immVertex3fv(pos, vec[0]); - immVertex3fv(pos, origin); - immVertex3fv(pos, vec[1]); - immVertex3fv(pos, origin); - immVertex3fv(pos, vec[2]); - immVertex3fv(pos, origin); - immVertex3fv(pos, vec[3]); - immEnd(); -} - -static void drawcamera_volume(float near_plane[4][3], float far_plane[4][3], bool filled, unsigned pos) -{ - drawcamera_frame(near_plane, filled, pos); - drawcamera_frame(far_plane, filled, pos); - - if (filled) { - immBegin(GWN_PRIM_TRI_STRIP, 10); - - immVertex3fv(pos, near_plane[0]); - immVertex3fv(pos, far_plane[0]); - immVertex3fv(pos, near_plane[1]); - immVertex3fv(pos, far_plane[1]); - immVertex3fv(pos, near_plane[2]); - immVertex3fv(pos, far_plane[2]); - immVertex3fv(pos, near_plane[3]); - immVertex3fv(pos, far_plane[3]); - immVertex3fv(pos, near_plane[0]); - immVertex3fv(pos, far_plane[0]); - - immEnd(); - } - else { - immBegin(GWN_PRIM_LINES, 8); - for (int i = 0; i < 4; ++i) { - immVertex3fv(pos, near_plane[i]); - immVertex3fv(pos, far_plane[i]); - } - immEnd(); - } -} - -static bool drawcamera_is_stereo3d(Scene *scene, View3D *v3d, Object *ob) -{ - return (ob == v3d->camera) && - (scene->r.scemode & R_MULTIVIEW) != 0 && - (v3d->stereo3d_flag); -} - -static void drawcamera_stereo3d( - Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const Camera *cam, - float vec[4][3], float drawsize, const float scale[3], unsigned pos) -{ - float obmat[4][4]; - float vec_lr[2][4][3]; - const float fac = (cam->stereo.pivot == CAM_S3D_PIVOT_CENTER) ? 2.0f : 1.0f; - float origin[2][3] = {{0}}; - float tvec[3]; - const Camera *cam_lr[2]; - const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; - - const bool is_stereo3d_cameras = (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D); - const bool is_stereo3d_plane = (v3d->stereo3d_flag & V3D_S3D_DISPPLANE) && (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D); - const bool is_stereo3d_volume = (v3d->stereo3d_flag & V3D_S3D_DISPVOLUME); - - zero_v3(tvec); - - /* caller bound GPU_SHADER_3D_UNIFORM_COLOR, passed in pos attribute ID */ - - for (int i = 0; i < 2; i++) { - ob = BKE_camera_multiview_render(scene, ob, names[i]); - cam_lr[i] = ob->data; - - gpuLoadMatrix(rv3d->viewmat); - BKE_camera_multiview_model_matrix(&scene->r, ob, names[i], obmat); - gpuMultMatrix(obmat); - - copy_m3_m3(vec_lr[i], vec); - copy_v3_v3(vec_lr[i][3], vec[3]); - - if (cam->stereo.convergence_mode == CAM_S3D_OFFAXIS) { - const float shift_x = - ((BKE_camera_multiview_shift_x(&scene->r, ob, names[i]) - cam->shiftx) * - (drawsize * scale[0] * fac)); - - for (int j = 0; j < 4; j++) { - vec_lr[i][j][0] += shift_x; - } - } - - if (is_stereo3d_cameras) { - /* camera frame */ - drawcamera_frame(vec_lr[i], false, pos); - - /* center point to camera frame */ - drawcamera_framelines(vec_lr[i], tvec, pos); - } - - /* connecting line */ - mul_m4_v3(obmat, origin[i]); - - /* convergence plane */ - if (is_stereo3d_plane || is_stereo3d_volume) { - for (int j = 0; j < 4; j++) { - mul_m4_v3(obmat, vec_lr[i][j]); - } - } - } - - /* the remaining drawing takes place in the view space */ - gpuLoadMatrix(rv3d->viewmat); - - if (is_stereo3d_cameras) { - /* draw connecting lines */ - glLineStipple(2, 0xAAAA); - glEnable(GL_LINE_STIPPLE); - - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, origin[0]); - immVertex3fv(pos, origin[1]); - immEnd(); - - glDisable(GL_LINE_STIPPLE); - } - - /* draw convergence plane */ - if (is_stereo3d_plane) { - float axis_center[3], screen_center[3]; - float world_plane[4][3]; - float local_plane[4][3]; - float offset; - - mid_v3_v3v3(axis_center, origin[0], origin[1]); - - for (int i = 0; i < 4; i++) { - mid_v3_v3v3(world_plane[i], vec_lr[0][i], vec_lr[1][i]); - sub_v3_v3v3(local_plane[i], world_plane[i], axis_center); - } - - mid_v3_v3v3(screen_center, world_plane[0], world_plane[2]); - offset = cam->stereo.convergence_distance / len_v3v3(screen_center, axis_center); - - for (int i = 0; i < 4; i++) { - mul_v3_fl(local_plane[i], offset); - add_v3_v3(local_plane[i], axis_center); - } - - immUniformColor3f(0.0f, 0.0f, 0.0f); - - /* camera frame */ - drawcamera_frame(local_plane, false, pos); - - if (v3d->stereo3d_convergence_alpha > 0.0f) { - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */ - - immUniformColor4f(0.0f, 0.0f, 0.0f, v3d->stereo3d_convergence_alpha); - - drawcamera_frame(local_plane, true, pos); - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); /* restore write in zbuffer */ - } - } - - /* draw convergence plane */ - if (is_stereo3d_volume) { - float screen_center[3]; - float near_plane[4][3], far_plane[4][3]; - - for (int i = 0; i < 2; i++) { - mid_v3_v3v3(screen_center, vec_lr[i][0], vec_lr[i][2]); - - float offset = len_v3v3(screen_center, origin[i]); - - for (int j = 0; j < 4; j++) { - sub_v3_v3v3(near_plane[j], vec_lr[i][j], origin[i]); - mul_v3_fl(near_plane[j], cam_lr[i]->clipsta / offset); - add_v3_v3(near_plane[j], origin[i]); - - sub_v3_v3v3(far_plane[j], vec_lr[i][j], origin[i]); - mul_v3_fl(far_plane[j], cam_lr[i]->clipend / offset); - add_v3_v3(far_plane[j], origin[i]); - } - - /* camera frame */ - immUniformColor3f(0.0f, 0.0f, 0.0f); - - drawcamera_volume(near_plane, far_plane, false, pos); - - if (v3d->stereo3d_volume_alpha > 0.0f) { - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */ - - if (i == 0) - immUniformColor4f(0.0f, 1.0f, 1.0f, v3d->stereo3d_volume_alpha); - else - immUniformColor4f(1.0f, 0.0f, 0.0f, v3d->stereo3d_volume_alpha); - - drawcamera_volume(near_plane, far_plane, true, pos); - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); /* restore write in zbuffer */ - } - } - } -} - -/* flag similar to draw_object() */ -void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, - const short dflag, const unsigned char ob_wire_col[4]) -{ - /* a standing up pyramid with (0,0,0) as top */ - Camera *cam; - Object *ob = base->object; - float tvec[3]; - float vec[4][3], asp[2], shift[2], scale[3]; - MovieClip *clip = BKE_object_movieclip_get(scene, base->object, false); - - const bool is_active = (ob == v3d->camera); - const bool is_view = (rv3d->persp == RV3D_CAMOB && is_active); - const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0; - const bool is_stereo3d = drawcamera_is_stereo3d(scene, v3d, ob); - const bool is_stereo3d_view = (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D); - const bool is_stereo3d_cameras = (ob == scene->camera) && - is_multiview && - is_stereo3d_view && - (v3d->stereo3d_flag & V3D_S3D_DISPCAMERAS); - const bool is_selection_camera_stereo = (G.f & G_PICKSEL) && - is_view && is_multiview && - is_stereo3d_view; - - /* draw data for movie clip set as active for scene */ - if (clip) { - draw_viewport_reconstruction(scene, base, v3d, rv3d, clip, dflag, ob_wire_col, false); - draw_viewport_reconstruction(scene, base, v3d, rv3d, clip, dflag, ob_wire_col, true); - } - -#ifdef VIEW3D_CAMERA_BORDER_HACK - if (is_view && !(G.f & G_PICKSEL)) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - view3d_camera_border_hack_col[0] = ob_wire_col[0]; - view3d_camera_border_hack_col[1] = ob_wire_col[1]; - view3d_camera_border_hack_col[2] = ob_wire_col[2]; - } - else { - float col[4]; - glGetFloatv(GL_CURRENT_COLOR, col); - rgb_float_to_uchar(view3d_camera_border_hack_col, col); - } - view3d_camera_border_hack_test = true; - return; - } -#endif - - cam = ob->data; - - /* BKE_camera_multiview_model_matrix already accounts for scale, don't do it here */ - if (is_selection_camera_stereo) { - scale[0] = 1.0f; - scale[1] = 1.0f; - scale[2] = 1.0f; - } - else { - scale[0] = 1.0f / len_v3(ob->obmat[0]); - scale[1] = 1.0f / len_v3(ob->obmat[1]); - scale[2] = 1.0f / len_v3(ob->obmat[2]); - } - - float drawsize; - BKE_camera_view_frame_ex(scene, cam, cam->drawsize, is_view, scale, - asp, shift, &drawsize, vec); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) { - immUniformColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - - /* camera frame */ - if (!is_stereo3d_cameras) { - /* make sure selection uses the same matrix for camera as the one used while viewing */ - if (is_selection_camera_stereo) { - float obmat[4][4]; - bool is_left = v3d->multiview_eye == STEREO_LEFT_ID; - - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); - BKE_camera_multiview_model_matrix(&scene->r, ob, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, obmat); - gpuMultMatrix(obmat); - - drawcamera_frame(vec, false, pos); - gpuPopMatrix(); - } - else { - drawcamera_frame(vec, false, pos); - } - } - - if (is_view) { - immUnbindProgram(); - return; - } - - zero_v3(tvec); - - /* center point to camera frame */ - if (!is_stereo3d_cameras) - drawcamera_framelines(vec, tvec, pos); - - /* arrow on top */ - tvec[2] = vec[1][2]; /* copy the depth */ - - /* draw an outline arrow for inactive cameras and filled - * for active cameras. We actually draw both outline+filled - * for active cameras so the wire can be seen side-on */ - for (int i = 0; i < 2; i++) { - if (i == 0) immBegin(GWN_PRIM_LINE_LOOP, 3); - else if (i == 1 && is_active) { - glDisable(GL_CULL_FACE); /* TODO: declarative state tracking */ - immBegin(GWN_PRIM_TRIS, 3); - } - else break; - - tvec[0] = shift[0] + ((-0.7f * drawsize) * scale[0]); - tvec[1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]); - immVertex3fv(pos, tvec); /* left */ - - tvec[0] = shift[0] + ((0.7f * drawsize) * scale[0]); - immVertex3fv(pos, tvec); /* right */ - - tvec[0] = shift[0]; - tvec[1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]); - immVertex3fv(pos, tvec); /* top */ - - immEnd(); - } - - if ((dflag & DRAW_SCENESET) == 0) { - if (cam->flag & (CAM_SHOWLIMITS | CAM_SHOWMIST)) { - float nobmat[4][4]; - - /* draw in normalized object matrix space */ - copy_m4_m4(nobmat, ob->obmat); - normalize_m4(nobmat); - - gpuLoadMatrix(rv3d->viewmat); - gpuMultMatrix(nobmat); - - if (cam->flag & CAM_SHOWLIMITS) { - const unsigned char col[3] = {128, 128, 60}, col_hi[3] = {255, 255, 120}; - - draw_limit_line(cam->clipsta, cam->clipend, dflag, (is_active ? col_hi : col), pos); - /* qdn: was yafray only, now also enabled for Blender to be used with defocus composite node */ - draw_focus_cross(BKE_camera_object_dof_distance(ob), cam->drawsize, pos); - } - - if (cam->flag & CAM_SHOWMIST) { - World *world = scene->world; - const unsigned char col[3] = {128, 128, 128}, col_hi[3] = {255, 255, 255}; - - if (world) { - draw_limit_line(world->miststa, world->miststa + world->mistdist, - dflag, (is_active ? col_hi : col), pos); - } - } - } - } - - /* stereo cameras drawing */ - if (is_stereo3d) { - drawcamera_stereo3d(scene, v3d, rv3d, ob, cam, vec, drawsize, scale, pos); - } - - immUnbindProgram(); -} - -/* flag similar to draw_object() */ -void drawspeaker(const unsigned char ob_wire_col[3]) -{ - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - if (ob_wire_col) { - immUniformColor3ubv(ob_wire_col); - } - - glLineWidth(1.0f); - - const int segments = 16; - - for (int j = 0; j < 3; j++) { - float z = 0.25f * j - 0.125f; - - immBegin(GWN_PRIM_LINE_LOOP, segments); - for (int i = 0; i < segments; i++) { - float x = cosf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f); - float y = sinf((float)M_PI * i / 8.0f) * (j == 0 ? 0.5f : 0.25f); - immVertex3f(pos, x, y, z); - } - immEnd(); - } - - for (int j = 0; j < 4; j++) { - float x = (((j + 1) % 2) * (j - 1)) * 0.5f; - float y = ((j % 2) * (j - 2)) * 0.5f; - immBegin(GWN_PRIM_LINE_STRIP, 3); - for (int i = 0; i < 3; i++) { - if (i == 1) { - x *= 0.5f; - y *= 0.5f; - } - - float z = 0.25f * i - 0.125f; - immVertex3f(pos, x, y, z); - } - immEnd(); - } - - immUnbindProgram(); -} - -static void lattice_draw_verts(Lattice *lt, DispList *dl, BPoint *actbp, short sel, - unsigned int pos, unsigned int color) -{ - BPoint *bp = lt->def; - const float *co = dl ? dl->verts : NULL; - float active_color[4], draw_color[4]; - - UI_GetThemeColor4fv(sel ? TH_VERTEX_SELECT : TH_VERTEX, draw_color); - UI_GetThemeColor4fv(TH_ACTIVE_VERT, active_color); - - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - immBeginAtMost(GWN_PRIM_POINTS, lt->pntsw * lt->pntsv * lt->pntsu); - - for (int w = 0; w < lt->pntsw; w++) { - int wxt = (w == 0 || w == lt->pntsw - 1); - for (int v = 0; v < lt->pntsv; v++) { - int vxt = (v == 0 || v == lt->pntsv - 1); - for (int u = 0; u < lt->pntsu; u++, bp++, co += 3) { - int uxt = (u == 0 || u == lt->pntsu - 1); - if (!(lt->flag & LT_OUTSIDE) || uxt || vxt || wxt) { - if (bp->hide == 0) { - /* check for active BPoint and ensure selected */ - if ((bp == actbp) && (bp->f1 & SELECT)) { - immAttrib4fv(color, active_color); - immVertex3fv(pos, dl ? co : bp->vec); - } - else if ((bp->f1 & SELECT) == sel) { - immAttrib4fv(color, draw_color); - immVertex3fv(pos, dl ? co : bp->vec); - } - } - } - } - } - } - - immEnd(); -} - -static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int actdef_wcol, - unsigned int pos, unsigned int color) -{ - int index = ((w * lt->pntsv + v) * lt->pntsu) + u; - - if (actdef_wcol) { - float col[3]; - MDeformWeight *mdw = defvert_find_index(lt->dvert + index, actdef_wcol - 1); - weight_to_rgb(col, mdw ? mdw->weight : 0.0f); - immAttrib3fv(color, col); - } - - if (dl) { - immVertex3fv(pos, &dl->verts[index * 3]); - } - else { - immVertex3fv(pos, lt->def[index].vec); - } -} - -#ifdef SEQUENCER_DAG_WORKAROUND -static void ensure_curve_cache( - Depsgraph *depsgraph, Scene *scene, Object *object) -{ - bool need_recalc = object->curve_cache == NULL; - /* Render thread might have freed the curve cache if the - * object is not visible. If the object is also used for - * particles duplication, then render thread might have - * also created curve_cache with only bevel and path - * filled in. - * - * So check for curve_cache != NULL is not fully correct - * here, we also need to check whether display list is - * empty or not. - * - * The trick below tries to optimize calls to displist - * creation for cases curve is empty. Meaning, if the curve - * is empty (without splines) bevel list would also be empty. - * And the thing is, render thread always leaves bevel list - * in a proper state. So if bevel list is here and display - * list is not we need to make display list. - */ - if (need_recalc == false) { - need_recalc = object->curve_cache->disp.first == NULL && - object->curve_cache->bev.first != NULL; - } - if (need_recalc) { - switch (object->type) { - case OB_CURVE: - case OB_SURF: - case OB_FONT: - BKE_displist_make_curveTypes(depsgraph, scene, object, false); - break; - case OB_MBALL: - BKE_displist_make_mball(depsgraph, scene, object); - break; - case OB_LATTICE: - BKE_lattice_modifiers_calc(depsgraph, scene, object); - break; - } - } -} -#endif - -/* lattice color is hardcoded, now also shows weightgroup values in edit mode */ -static void drawlattice(View3D *v3d, Object *ob, const short dflag, const unsigned char ob_wire_col[4]) -{ - Lattice *lt = ob->data; - DispList *dl; - int u, v, w; - int actdef_wcol = 0; - const bool is_edit = (lt->editlatt != NULL); - - dl = BKE_displist_find(&ob->curve_cache->disp, DL_VERTS); - - if (is_edit) { - lt = lt->editlatt->latt; - - if (ob->defbase.first && lt->dvert) { - actdef_wcol = ob->actdef; - } - } - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int color, pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (actdef_wcol) { - color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_SMOOTH_COLOR); - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - if (is_edit) { - immUniformThemeColor(TH_WIRE_EDIT); - } - else { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - immUniformColor3ubv(ob_wire_col); - } - else { - immUniformColor3f(0.0f, 0.0f, 0.0f); - } - } - } - - glLineWidth(1.0f); - immBeginAtMost(GWN_PRIM_LINES, lt->pntsw * lt->pntsv * lt->pntsu * 6); - - for (w = 0; w < lt->pntsw; w++) { - int wxt = (w == 0 || w == lt->pntsw - 1); - for (v = 0; v < lt->pntsv; v++) { - int vxt = (v == 0 || v == lt->pntsv - 1); - for (u = 0; u < lt->pntsu; u++) { - int uxt = (u == 0 || u == lt->pntsu - 1); - - if (w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) { - drawlattice__point(lt, dl, u, v, w - 1, actdef_wcol, pos, color); - drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color); - } - if (v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) { - drawlattice__point(lt, dl, u, v - 1, w, actdef_wcol, pos, color); - drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color); - } - if (u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) { - drawlattice__point(lt, dl, u - 1, v, w, actdef_wcol, pos, color); - drawlattice__point(lt, dl, u, v, w, actdef_wcol, pos, color); - } - } - } - } - - immEnd(); - immUnbindProgram(); - - if (is_edit) { - BPoint *actbp = BKE_lattice_active_point_get(lt); - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - Gwn_VertFormat *v_format = immVertexFormat(); - unsigned int v_pos = GWN_vertformat_attr_add(v_format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int v_color = GWN_vertformat_attr_add(v_format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR); - - lattice_draw_verts(lt, dl, actbp, 0, v_pos, v_color); - lattice_draw_verts(lt, dl, actbp, 1, v_pos, v_color); - - immUnbindProgram(); - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } -} - -/* ***************** ******************** */ - -/* draw callback */ - -typedef struct drawDMVertSel_userData { - MVert *mvert; - int active; - unsigned char *col[3]; /* (base, sel, act) */ - char sel_prev; - unsigned int pos, color; -} drawDMVertSel_userData; - -static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - drawDMVertSel_userData *data = userData; - MVert *mv = &data->mvert[index]; - - if (!(mv->flag & ME_HIDE)) { - const char sel = (index == data->active) ? 2 : (mv->flag & SELECT); - if (sel != data->sel_prev) { - immAttrib3ubv(data->color, data->col[sel]); - data->sel_prev = sel; - } - - immVertex3fv(data->pos, co); - } -} - -static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) -{ - drawDMVertSel_userData data; - Gwn_VertFormat *format = immVertexFormat(); - - /* TODO define selected color */ - unsigned char base_col[3] = {0x0, 0x0, 0x0}; - unsigned char sel_col[3] = {0xd8, 0xb8, 0x0}; - unsigned char act_col[3] = {0xff, 0xff, 0xff}; - - data.mvert = me->mvert; - data.active = BKE_mesh_mselect_active_get(me, ME_VSEL); - data.sel_prev = 0xff; - - data.col[0] = base_col; - data.col[1] = sel_col; - data.col[2] = act_col; - - data.color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (dm->getNumVerts(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - immBeginAtMost(GWN_PRIM_POINTS, dm->getNumVerts(dm)); - dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP); - immEnd(); - - immUnbindProgram(); -} - -/* ************** DRAW MESH ****************** */ - -/* First section is all the "simple" draw routines, - * ones that just pass some sort of primitive to GL, - * with perhaps various options to control lighting, - * color, etc. - * - * These routines should not have user interface related - * logic!!! - */ - -static void calcDrawDMNormalScale(Object *ob, drawDMNormal_userData *data) -{ - float obmat[3][3]; - - copy_m3_m4(obmat, ob->obmat); - - data->uniform_scale = is_uniform_scaled_m3(obmat); - - if (!data->uniform_scale) { - /* inverted matrix */ - invert_m3_m3(data->imat, obmat); - - /* transposed inverted matrix */ - transpose_m3_m3(data->tmat, data->imat); - } -} - -static void draw_dm_face_normals__mapFunc(void *userData, int index, const float cent[3], const float no[3]) -{ - drawDMNormal_userData *data = userData; - BMFace *efa = BM_face_at_index(data->bm, index); - float n[3]; - - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - if (!data->uniform_scale) { - mul_v3_m3v3(n, data->tmat, no); - normalize_v3(n); - mul_m3_v3(data->imat, n); - } - else { - copy_v3_v3(n, no); - } - - immVertex3fv(data->pos, cent); - immVertex3f(data->pos, cent[0] + n[0] * data->normalsize, - cent[1] + n[1] * data->normalsize, - cent[2] + n[2] * data->normalsize); - } -} - -static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id) -{ - Gwn_VertFormat *format = immVertexFormat(); - drawDMNormal_userData data; - - data.bm = em->bm; - data.normalsize = scene->toolsettings->normalsize; - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - calcDrawDMNormalScale(ob, &data); - - if (dm->getNumPolys(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(theme_id); - - immBeginAtMost(GWN_PRIM_LINES, dm->getNumPolys(dm) * 2); - dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); - immEnd(); - - immUnbindProgram(); -} - -static void draw_dm_face_centers__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) -{ - drawBMSelect_userData *data = userData; - BMFace *efa = BM_face_at_index(data->bm, index); - - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && - (BM_elem_flag_test(efa, BM_ELEM_SELECT) == data->select)) - { - immVertex3fv(data->pos, cent); - } -} -static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, bool select, const unsigned char fcol[3]) -{ - Gwn_VertFormat *format = immVertexFormat(); - - drawBMSelect_userData data; - data.bm = em->bm; - data.select = select; - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (dm->getNumPolys(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(fcol); - - immBeginAtMost(GWN_PRIM_POINTS, dm->getNumPolys(dm)); - dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &data, DM_FOREACH_NOP); - immEnd(); - - immUnbindProgram(); -} - -static void draw_dm_vert_normals__mapFunc(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]) -{ - drawDMNormal_userData *data = userData; - BMVert *eve = BM_vert_at_index(data->bm, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - float no[3], n[3]; - - if (no_f) { - copy_v3_v3(no, no_f); - } - else { - normal_short_to_float_v3(no, no_s); - } - - if (!data->uniform_scale) { - mul_v3_m3v3(n, data->tmat, no); - normalize_v3(n); - mul_m3_v3(data->imat, n); - } - else { - copy_v3_v3(n, no); - } - - immVertex3fv(data->pos, co); - immVertex3f(data->pos, co[0] + n[0] * data->normalsize, - co[1] + n[1] * data->normalsize, - co[2] + n[2] * data->normalsize); - } -} - -static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id) -{ - drawDMNormal_userData data; - Gwn_VertFormat *format = immVertexFormat(); - - data.bm = em->bm; - data.normalsize = scene->toolsettings->normalsize; - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - calcDrawDMNormalScale(ob, &data); - - if (dm->getNumVerts(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(theme_id); - - immBeginAtMost(GWN_PRIM_LINES, dm->getNumVerts(dm) * 2); - dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); - immEnd(); - - immUnbindProgram(); -} - -static void draw_dm_verts_skin_root__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - drawDMVerts_userData *data = userData; - BMVert *eve = BM_vert_at_index(data->bm, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) { - /* skin nodes: draw a red circle around the root node(s) */ - const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, data->cd_vskin_offset); - if (vs->flag & MVERT_SKIN_ROOT) { - float radius = (vs->radius[0] + vs->radius[1]) * 0.5f; - imm_drawcircball(co, radius, data->imat, data->pos); - } - } -} - -/* Draw verts with color set based on selection */ -static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - drawDMVerts_userData *data = userData; - BMVert *eve = BM_vert_at_index(data->bm, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->sel) { - /* draw active in a different color - no need to stop/start point drawing for this :D */ - if (eve == data->eve_act) { - immAttrib4ubv(data->color, data->th_editmesh_active); - immVertex3fv(data->pos, co); - } - else { - immAttrib4ubv(data->color, data->sel ? data->th_vertex_select : data->th_vertex); - immVertex3fv(data->pos, co); - } - } -} - -static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVert *eve_act, - RegionView3D *rv3d, const unsigned char col[4]) -{ - Gwn_VertFormat *format = immVertexFormat(); - - drawDMVerts_userData data; - data.sel = sel; - data.eve_act = eve_act; - data.bm = em->bm; - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - data.color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - - /* Cache theme values */ - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, data.th_editmesh_active); - UI_GetThemeColor4ubv(TH_VERTEX_SELECT, data.th_vertex_select); - UI_GetThemeColor4ubv(TH_VERTEX, data.th_vertex); - UI_GetThemeColor4ubv(TH_SKIN_ROOT, data.th_skin_root); - - /* Set correct alpha */ - data.th_editmesh_active[3] = data.th_vertex_select[3] = data.th_vertex[3] = data.th_skin_root[3] = col[3]; - - /* view-aligned matrix */ - mul_m4_m4m4(data.imat, rv3d->viewmat, em->ob->obmat); - invert_m4(data.imat); - - if (dm->getNumVerts(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - immBeginAtMost(GWN_PRIM_POINTS, dm->getNumVerts(dm)); - dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP); - immEnd(); - - immUnbindProgram(); - - /* For skin root drawing */ - data.cd_vskin_offset = CustomData_get_offset(&em->bm->vdata, CD_MVERT_SKIN); - - if (data.cd_vskin_offset != -1) { - data.pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4ubv(data.th_skin_root); - - dm->foreachMappedVert(dm, draw_dm_verts_skin_root__mapFunc, &data, DM_FOREACH_NOP); - - immUnbindProgram(); - } -} - -/* Draw edges with color set based on selection */ -static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index) -{ - BMEdge *eed; - drawDMEdgesSel_userData *data = userData; - unsigned char *col; - - eed = BM_edge_at_index(data->bm, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - if (eed == data->eed_act) { - glColor4ubv(data->actCol); - } - else { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - col = data->selCol; - } - else { - col = data->baseCol; - } - /* no alpha, this is used so a transparent color can disable drawing unselected edges in editmode */ - if (col[3] == 0) - return DM_DRAW_OPTION_SKIP; - - glColor4ubv(col); - } - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - -static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, - unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act) -{ - drawDMEdgesSel_userData data; - - data.baseCol = baseCol; - data.selCol = selCol; - data.actCol = actCol; - data.bm = em->bm; - data.eed_act = eed_act; - dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, &data); -} - -/* Draw edges */ -static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index) -{ - if (BM_elem_flag_test(BM_edge_at_index(userData, index), BM_ELEM_HIDDEN)) - return DM_DRAW_OPTION_SKIP; - else - return DM_DRAW_OPTION_NORMAL; -} - -static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) -{ - dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em->bm); -} - -/* Draw edges with color interpolated based on selection */ -static DMDrawOption draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index) -{ - drawDMEdgesSelInterp_userData *data = userData; - if (BM_elem_flag_test(BM_edge_at_index(data->bm, index), BM_ELEM_HIDDEN)) - return DM_DRAW_OPTION_SKIP; - else - return DM_DRAW_OPTION_NORMAL; -} -static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t) -{ - drawDMEdgesSelInterp_userData *data = userData; - BMEdge *eed = BM_edge_at_index(data->bm, index); - unsigned char **cols = userData; - unsigned int col0_id = (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT)) ? 2 : 1; - unsigned int col1_id = (BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)) ? 2 : 1; - unsigned char *col0 = cols[col0_id]; - unsigned char *col1 = cols[col1_id]; - unsigned char *col_pt; - - if (col0_id == col1_id) { - col_pt = col0; - } - else if (t == 0.0f) { - col_pt = col0; - } - else if (t == 1.0f) { - col_pt = col1; - } - else { - unsigned char col_blend[4]; - interp_v4_v4v4_uchar(col_blend, col0, col1, t); - glColor4ubv(col_blend); - data->lastCol = NULL; - return; - } - - if (data->lastCol != col_pt) { - data->lastCol = col_pt; - glColor4ubv(col_pt); - } -} - -static void draw_dm_edges_sel_interp(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol) -{ - drawDMEdgesSelInterp_userData data; - data.bm = em->bm; - data.baseCol = baseCol; - data.selCol = selCol; - data.lastCol = NULL; - - dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, &data); -} - -static void bm_color_from_weight(float col[3], BMVert *vert, drawDMEdgesWeightInterp_userData *data) -{ - MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(vert, data->cd_dvert_offset); - float weight = defvert_find_weight(dvert, data->vgroup_index); - - if ((weight == 0.0f) && - ((data->weight_user == OB_DRAW_GROUPUSER_ACTIVE) || - ((data->weight_user == OB_DRAW_GROUPUSER_ALL) && defvert_is_weight_zero(dvert, data->defgroup_tot)))) - { - copy_v3_v3(col, data->alert_color); - } - else { - weight_to_rgb(col, weight); - } -} - -static void draw_dm_edges_nop_interp__setDrawInterpOptions(void *UNUSED(userData), int UNUSED(index), float UNUSED(t)) -{ - /* pass */ -} - -static void draw_dm_edges_weight_interp__setDrawInterpOptions(void *userData, int index, float t) -{ - drawDMEdgesWeightInterp_userData *data = userData; - BMEdge *eed = BM_edge_at_index(data->bm, index); - float col[3]; - - if (t == 0.0f) { - bm_color_from_weight(col, eed->v1, data); - } - else if (t == 1.0f) { - bm_color_from_weight(col, eed->v2, data); - } - else { - float col_v1[3]; - float col_v2[3]; - - bm_color_from_weight(col_v1, eed->v1, data); - bm_color_from_weight(col_v2, eed->v2, data); - interp_v3_v3v3(col, col_v1, col_v2, t); - } - - glColor3fv(col); -} - -static void draw_dm_edges_weight_interp(BMEditMesh *em, DerivedMesh *dm, const char weight_user) -{ - drawDMEdgesWeightInterp_userData data; - Object *ob = em->ob; - - data.bm = em->bm; - data.cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); - data.defgroup_tot = BLI_listbase_count(&ob->defbase); - data.vgroup_index = ob->actdef - 1; - data.weight_user = weight_user; - UI_GetThemeColor3fv(TH_VERTEX_UNREFERENCED, data.alert_color); - - if ((data.vgroup_index != -1) && (data.cd_dvert_offset != -1)) { - glEnable(GL_BLEND); - dm->drawMappedEdgesInterp( - dm, - draw_dm_edges_sel_interp__setDrawOptions, - draw_dm_edges_weight_interp__setDrawInterpOptions, - &data); - glDisable(GL_BLEND); - } - else { - float col[3]; - - if (data.weight_user == OB_DRAW_GROUPUSER_NONE) { - weight_to_rgb(col, 0.0f); - } - else { - copy_v3_v3(col, data.alert_color); - } - glColor3fv(col); - - dm->drawMappedEdgesInterp( - dm, - draw_dm_edges_sel_interp__setDrawOptions, - draw_dm_edges_nop_interp__setDrawInterpOptions, - &data); - } - -} - -static bool draw_dm_edges_weight_check(Mesh *me, View3D *v3d) -{ - if (me->drawflag & ME_DRAWEIGHT) { - if ((v3d->drawtype == OB_WIRE) || - (v3d->flag2 & V3D_SOLID_MATCAP) || - ((v3d->flag2 & V3D_OCCLUDE_WIRE) && (v3d->drawtype > OB_WIRE))) - { - return true; - } - } - - return false; -} - -/* Draw only seam edges */ -static DMDrawOption draw_dm_edges_seams__setDrawOptions(void *userData, int index) -{ - BMEdge *eed = BM_edge_at_index(userData, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_SEAM)) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; -} - -static void draw_dm_edges_seams(BMEditMesh *em, DerivedMesh *dm) -{ - dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, em->bm); -} - -/* Draw only sharp edges */ -static DMDrawOption draw_dm_edges_sharp__setDrawOptions(void *userData, int index) -{ - BMEdge *eed = BM_edge_at_index(userData, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && !BM_elem_flag_test(eed, BM_ELEM_SMOOTH)) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; -} - -static void draw_dm_edges_sharp(BMEditMesh *em, DerivedMesh *dm) -{ - dm->drawMappedEdges(dm, draw_dm_edges_sharp__setDrawOptions, em->bm); -} - -#ifdef WITH_FREESTYLE - -static bool draw_dm_test_freestyle_edge_mark(BMesh *bm, BMEdge *eed) -{ - FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, eed->head.data, CD_FREESTYLE_EDGE); - if (!fed) - return false; - return (fed->flag & FREESTYLE_EDGE_MARK) != 0; -} - -/* Draw only Freestyle feature edges */ -static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int index) -{ - BMEdge *eed = BM_edge_at_index(userData, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_edge_mark(userData, eed)) - return DM_DRAW_OPTION_NORMAL; - else - return DM_DRAW_OPTION_SKIP; -} - -static void draw_dm_edges_freestyle(BMEditMesh *em, DerivedMesh *dm) -{ - dm->drawMappedEdges(dm, draw_dm_edges_freestyle__setDrawOptions, em->bm); -} - -static bool draw_dm_test_freestyle_face_mark(BMesh *bm, BMFace *efa) -{ - FreestyleFace *ffa = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_FREESTYLE_FACE); - if (!ffa) - return false; - return (ffa->flag & FREESTYLE_FACE_MARK) != 0; -} - -#endif - -/* Draw loop normals. */ -static void draw_dm_loop_normals__mapFunc(void *userData, int vertex_index, int face_index, - const float co[3], const float no[3]) -{ - if (no) { - const drawDMNormal_userData *data = userData; - const BMVert *eve = BM_vert_at_index(data->bm, vertex_index); - const BMFace *efa = BM_face_at_index(data->bm, face_index); - float vec[3]; - - if (!(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) || BM_elem_flag_test(efa, BM_ELEM_HIDDEN))) { - if (!data->uniform_scale) { - mul_v3_m3v3(vec, (float(*)[3])data->tmat, no); - normalize_v3(vec); - mul_m3_v3((float(*)[3])data->imat, vec); - } - else { - copy_v3_v3(vec, no); - } - mul_v3_fl(vec, data->normalsize); - add_v3_v3(vec, co); - immVertex3fv(data->pos, co); - immVertex3fv(data->pos, vec); - } - } -} - -static void draw_dm_loop_normals(BMEditMesh *em, Scene *scene, Object *ob, DerivedMesh *dm, int theme_id) -{ - drawDMNormal_userData data; - - data.bm = em->bm; - data.normalsize = scene->toolsettings->normalsize; - data.pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (dm->getNumLoops(dm) == 0) return; - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(theme_id); - - calcDrawDMNormalScale(ob, &data); - - immBeginAtMost(GWN_PRIM_LINES, dm->getNumLoops(dm) * 2); - dm->foreachMappedLoop(dm, draw_dm_loop_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); - immEnd(); - - immUnbindProgram(); -} - -/* Draw faces with color set based on selection - * return 2 for the active face so it renders with stipple enabled */ -static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index) -{ - drawDMFacesSel_userData *data = userData; - BMFace *efa = BM_face_at_index(data->bm, index); - unsigned char *col; - - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - if (efa == data->efa_act) { - glColor4ubv(data->cols[2]); - return DM_DRAW_OPTION_STIPPLE; - } - else { -#ifdef WITH_FREESTYLE - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; -#else - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; -#endif - if (col[3] == 0) - return DM_DRAW_OPTION_SKIP; - glColor4ubv(col); - return DM_DRAW_OPTION_NORMAL; - } - } - return DM_DRAW_OPTION_SKIP; -} - -static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index) -{ - - drawDMFacesSel_userData *data = userData; - int i; - BMFace *efa; - BMFace *next_efa; - - unsigned char *col, *next_col; - - i = data->orig_index_mp_to_orig ? data->orig_index_mp_to_orig[index] : index; - efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL; - i = data->orig_index_mp_to_orig ? data->orig_index_mp_to_orig[next_index] : next_index; - next_efa = (i != ORIGINDEX_NONE) ? BM_face_at_index(data->bm, i) : NULL; - - if (ELEM(NULL, efa, next_efa)) - return 0; - - if (efa == next_efa) - return 1; - - if (efa == data->efa_act || next_efa == data->efa_act) - return 0; - -#ifdef WITH_FREESTYLE - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; - next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : draw_dm_test_freestyle_face_mark(data->bm, efa) ? 3 : 0]; -#else - col = data->cols[BM_elem_flag_test(efa, BM_ELEM_SELECT) ? 1 : 0]; - next_col = data->cols[BM_elem_flag_test(next_efa, BM_ELEM_SELECT) ? 1 : 0]; -#endif - - if (col[3] == 0 || next_col[3] == 0) - return 0; - - return col == next_col; -} - -/* also draws the active face */ -#ifdef WITH_FREESTYLE -static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, - unsigned char *selCol, unsigned char *actCol, unsigned char *markCol, BMFace *efa_act) -#else -static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, - unsigned char *selCol, unsigned char *actCol, BMFace *efa_act) -#endif -{ - drawDMFacesSel_userData data; - data.dm = dm; - data.cols[0] = baseCol; - data.bm = em->bm; - data.cols[1] = selCol; - data.cols[2] = actCol; -#ifdef WITH_FREESTYLE - data.cols[3] = markCol; -#endif - data.efa_act = efa_act; - /* double lookup */ - data.orig_index_mp_to_orig = DM_get_poly_data_layer(dm, CD_ORIGINDEX); - - dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, NULL, draw_dm_faces_sel__compareDrawOptions, &data, DM_DRAW_SKIP_HIDDEN); -} - -static DMDrawOption draw_dm_creases__setDrawOptions(void *userData, int index) -{ - drawDMLayer_userData *data = userData; - BMesh *bm = data->bm; - BMEdge *eed = BM_edge_at_index(bm, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - const float crease = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset); - if (crease != 0.0f) { - UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_CREASE, crease); - return DM_DRAW_OPTION_NORMAL; - } - } - return DM_DRAW_OPTION_SKIP; -} -static void draw_dm_creases(BMEditMesh *em, DerivedMesh *dm) -{ - drawDMLayer_userData data; - - data.bm = em->bm; - data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE); - - if (data.cd_layer_offset != -1) { - glLineWidth(3.0f); - dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, &data); - } -} - -static DMDrawOption draw_dm_bweights__setDrawOptions(void *userData, int index) -{ - drawDMLayer_userData *data = userData; - BMesh *bm = data->bm; - BMEdge *eed = BM_edge_at_index(bm, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - const float bweight = BM_ELEM_CD_GET_FLOAT(eed, data->cd_layer_offset); - if (bweight != 0.0f) { - UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_BEVEL, bweight); - return DM_DRAW_OPTION_NORMAL; - } - } - return DM_DRAW_OPTION_SKIP; -} -static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - drawDMLayer_userData *data = userData; - BMesh *bm = data->bm; - BMVert *eve = BM_vert_at_index(bm, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - const float bweight = BM_ELEM_CD_GET_FLOAT(eve, data->cd_layer_offset); - if (bweight != 0.0f) { - unsigned char col[3]; - UI_GetThemeColorBlend3ubv(TH_VERTEX, TH_VERTEX_BEVEL, bweight, col); - immAttrib3ubv(data->col, col); - immVertex3fv(data->pos, co); - } - } -} -static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) -{ - ToolSettings *ts = scene->toolsettings; - - if (ts->selectmode & SCE_SELECT_VERTEX) { - drawDMLayer_userData data; - - data.bm = em->bm; - data.cd_layer_offset = CustomData_get_offset(&em->bm->vdata, CD_BWEIGHT); - - /* is that ever true? */ - if (data.cd_layer_offset != -1) { - Gwn_VertFormat *format = immVertexFormat(); - data.pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - data.col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2.0f); - - immBeginAtMost(GWN_PRIM_POINTS, dm->getNumVerts(dm)); - dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data, DM_FOREACH_NOP); - immEnd(); - - immUnbindProgram(); - } - } - else { - drawDMLayer_userData data; - - data.bm = em->bm; - data.cd_layer_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT); - - if (data.cd_layer_offset != -1) { - glLineWidth(3.0f); - dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, &data); - } - } -} - -/* Second section of routines: Combine first sets to form fancy - * drawing routines (for example rendering twice to get overlays). - * - * Also includes routines that are basic drawing but are too - * specialized to be split out (like drawing creases or measurements). - */ - -/* EditMesh drawing routines */ - -static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, - BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act, - RegionView3D *rv3d) -{ - ToolSettings *ts = scene->toolsettings; - - if (v3d->zbuf) glDepthMask(GL_FALSE); /* disable write in zbuffer, zbuf select */ - - for (int sel = 0; sel < 2; sel++) { - unsigned char col[4], fcol[4]; - - UI_GetThemeColor3ubv(sel ? TH_VERTEX_SELECT : TH_VERTEX, col); - UI_GetThemeColor3ubv(sel ? TH_FACE_DOT : TH_WIRE_EDIT, fcol); - - for (int pass = 0; pass < 2; pass++) { - float size = UI_GetThemeValuef(TH_VERTEX_SIZE); - float fsize = UI_GetThemeValuef(TH_FACEDOT_SIZE); - - if (pass == 0) { - if (v3d->zbuf && !(v3d->flag & V3D_ZBUF_SELECT)) { - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - } - else { - continue; - } - - size = (size > 2.1f ? size / 2.0f : size); - fsize = (fsize > 2.1f ? fsize / 2.0f : fsize); - col[3] = fcol[3] = 100; - } - else { - col[3] = fcol[3] = 255; - } - - if (ts->selectmode & SCE_SELECT_VERTEX) { - draw_dm_verts(em, cageDM, sel, eve_act, rv3d, col); - } - - if (check_ob_drawface_dot(scene, v3d, obedit->dt)) { - glPointSize(fsize); - draw_dm_face_centers(em, cageDM, sel, fcol); - } - - if (pass == 0) { - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); - } - } - } - - if (v3d->zbuf) glDepthMask(GL_TRUE); -} - -static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d, - Mesh *me, DerivedMesh *cageDM, short sel_only, - BMEdge *eed_act) -{ - ToolSettings *ts = scene->toolsettings; - unsigned char wireCol[4], selCol[4], actCol[4]; - - /* since this function does transparent... */ - UI_GetThemeColor4ubv(TH_EDGE_SELECT, selCol); - UI_GetThemeColor4ubv(TH_WIRE_EDIT, wireCol); - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, actCol); - - /* when sel only is used, don't render wire, only selected, this is used for - * textured draw mode when the 'edges' option is disabled */ - if (sel_only) - wireCol[3] = 0; - - for (int pass = 0; pass < 2; pass++) { - /* show wires in transparent when no zbuf clipping for select */ - if (pass == 0) { - if (v3d->zbuf && (v3d->flag & V3D_ZBUF_SELECT) == 0) { - glEnable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - selCol[3] = 85; - if (!sel_only) wireCol[3] = 85; - } - else { - continue; - } - } - else { - selCol[3] = 255; - if (!sel_only) wireCol[3] = 255; - } - - if ((me->drawflag & ME_DRAWEDGES) || (ts->selectmode & SCE_SELECT_EDGE)) { - if (cageDM->drawMappedEdgesInterp && - ((ts->selectmode & SCE_SELECT_VERTEX) || (me->drawflag & ME_DRAWEIGHT))) - { - if (draw_dm_edges_weight_check(me, v3d)) { - // Interpolate vertex weights - draw_dm_edges_weight_interp(em, cageDM, ts->weightuser); - } - else if (ts->selectmode == SCE_SELECT_FACE) { - draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act); - } - else { - // Interpolate vertex selection - draw_dm_edges_sel_interp(em, cageDM, wireCol, selCol); - } - } - else { - draw_dm_edges_sel(em, cageDM, wireCol, selCol, actCol, eed_act); - } - } - else { - if (!sel_only) { - glColor4ubv(wireCol); - draw_dm_edges(em, cageDM); - } - } - - if (pass == 0) { - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); - } - } -} - -static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMesh *em, UnitSettings *unit) -{ - /* Do not use ascii when using non-default unit system, some unit chars are utf8 (micro, square, etc.). - * See bug #36090. - */ - const short txt_flag = V3D_CACHE_TEXT_LOCALCLIP | (unit->system ? 0 : V3D_CACHE_TEXT_ASCII); - Mesh *me = ob->data; - float v1[3], v2[3], v3[3], vmid[3], fvec[3]; - char numstr[32]; /* Stores the measurement display text here */ - size_t numstr_len; - const char *conv_float; /* Use a float conversion matching the grid size */ - unsigned char col[4] = {0, 0, 0, 255}; /* color of the text to draw */ - float area; /* area of the face */ - float grid = unit->system ? unit->scale_length : v3d->grid; - const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; - const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0; - const bool do_moving = (G.moving & G_TRANSFORM_EDIT) != 0; - /* when 2 edge-info options are enabled, space apart */ - const bool do_edge_textpair = (me->drawflag & ME_DRAWEXTRA_EDGELEN) && (me->drawflag & ME_DRAWEXTRA_EDGEANG); - const float edge_texpair_sep = 0.4f; - float clip_planes[4][4]; - /* allow for displaying shape keys and deform mods */ - DerivedMesh *dm = EDBM_mesh_deform_dm_get(em); - BMIter iter; - - /* make the precision of the display value proportionate to the gridsize */ - - if (grid <= 0.01f) conv_float = "%.6g"; - else if (grid <= 0.1f) conv_float = "%.5g"; - else if (grid <= 1.0f) conv_float = "%.4g"; - else if (grid <= 10.0f) conv_float = "%.3g"; - else conv_float = "%.2g"; - - if (me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_EDGEANG)) { - BoundBox bb; - const rcti rect = {0, ar->winx, 0, ar->winy}; - - ED_view3d_clipping_calc(&bb, clip_planes, ar, em->ob, &rect); - } - - if (me->drawflag & ME_DRAWEXTRA_EDGELEN) { - BMEdge *eed; - - UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); - - if (dm) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT); - } - - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - /* draw selected edges, or edges next to selected verts while dragging */ - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) || - (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)))) - { - float v1_clip[3], v2_clip[3]; - - if (dm) { - dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1); - dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2); - } - else { - copy_v3_v3(v1, eed->v1->co); - copy_v3_v3(v2, eed->v2->co); - } - - if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) { - - if (do_edge_textpair) { - interp_v3_v3v3(vmid, v1, v2, edge_texpair_sep); - } - else { - mid_v3_v3v3(vmid, v1_clip, v2_clip); - } - - if (do_global) { - mul_mat3_m4_v3(ob->obmat, v1); - mul_mat3_m4_v3(ob->obmat, v2); - } - - if (unit->system) { - numstr_len = bUnit_AsString(numstr, sizeof(numstr), len_v3v3(v1, v2) * unit->scale_length, 3, - unit->system, B_UNIT_LENGTH, do_split, false); - } - else { - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2)); - } - - view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); - } - } - } - } - - if (me->drawflag & ME_DRAWEXTRA_EDGEANG) { - const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS); - BMEdge *eed; - - UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col); - - if (dm) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); - } - - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - BMLoop *l_a, *l_b; - if (BM_edge_loop_pair(eed, &l_a, &l_b)) { - /* draw selected edges, or edges next to selected verts while dragging */ - if (BM_elem_flag_test(eed, BM_ELEM_SELECT) || - (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT) || - /* special case, this is useful to show when verts connected to - * this edge via a face are being transformed */ - BM_elem_flag_test(l_a->next->next->v, BM_ELEM_SELECT) || - BM_elem_flag_test(l_a->prev->v, BM_ELEM_SELECT) || - BM_elem_flag_test(l_b->next->next->v, BM_ELEM_SELECT) || - BM_elem_flag_test(l_b->prev->v, BM_ELEM_SELECT) - ))) - { - float v1_clip[3], v2_clip[3]; - - if (dm) { - dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1); - dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2); - } - else { - copy_v3_v3(v1, eed->v1->co); - copy_v3_v3(v2, eed->v2->co); - } - - if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4, v1_clip, v2_clip)) { - float no_a[3], no_b[3]; - float angle; - - if (do_edge_textpair) { - interp_v3_v3v3(vmid, v2_clip, v1_clip, edge_texpair_sep); - } - else { - mid_v3_v3v3(vmid, v1_clip, v2_clip); - } - - if (dm) { - dm->getPolyNo(dm, BM_elem_index_get(l_a->f), no_a); - dm->getPolyNo(dm, BM_elem_index_get(l_b->f), no_b); - } - else { - copy_v3_v3(no_a, l_a->f->no); - copy_v3_v3(no_b, l_b->f->no); - } - - if (do_global) { - mul_mat3_m4_v3(ob->imat, no_a); - mul_mat3_m4_v3(ob->imat, no_b); - normalize_v3(no_a); - normalize_v3(no_b); - } - - angle = angle_normalized_v3v3(no_a, no_b); - - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); - - view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); - } - } - } - } - } - - if (me->drawflag & ME_DRAWEXTRA_FACEAREA) { - /* would be nice to use BM_face_calc_area, but that is for 2d faces - * so instead add up tessellation triangle areas */ - BMFace *f = NULL; - -#define DRAW_EM_MEASURE_STATS_FACEAREA() \ - if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { \ - mul_v3_fl(vmid, 1.0f / (float)n); \ - if (unit->system) { \ - numstr_len = bUnit_AsString( \ - numstr, sizeof(numstr), \ - (double)(area * unit->scale_length * unit->scale_length), \ - 3, unit->system, B_UNIT_AREA, do_split, false); \ - } \ - else { \ - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), conv_float, area); \ - } \ - view3d_cached_text_draw_add(vmid, numstr, numstr_len, 0, txt_flag, col); \ - } (void)0 - - UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); - - if (dm) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT); - } - - area = 0.0; - zero_v3(vmid); - int n = 0; - for (int i = 0; i < em->tottri; i++) { - BMLoop **l = em->looptris[i]; - if (f && l[0]->f != f) { - DRAW_EM_MEASURE_STATS_FACEAREA(); - zero_v3(vmid); - area = 0.0; - n = 0; - } - - f = l[0]->f; - - if (dm) { - dm->getVertCo(dm, BM_elem_index_get(l[0]->v), v1); - dm->getVertCo(dm, BM_elem_index_get(l[1]->v), v2); - dm->getVertCo(dm, BM_elem_index_get(l[2]->v), v3); - } - else { - copy_v3_v3(v1, l[0]->v->co); - copy_v3_v3(v2, l[1]->v->co); - copy_v3_v3(v3, l[2]->v->co); - } - - add_v3_v3(vmid, v1); - add_v3_v3(vmid, v2); - add_v3_v3(vmid, v3); - n += 3; - if (do_global) { - mul_mat3_m4_v3(ob->obmat, v1); - mul_mat3_m4_v3(ob->obmat, v2); - mul_mat3_m4_v3(ob->obmat, v3); - } - area += area_tri_v3(v1, v2, v3); - } - - if (f) { - DRAW_EM_MEASURE_STATS_FACEAREA(); - } -#undef DRAW_EM_MEASURE_STATS_FACEAREA - } - - if (me->drawflag & ME_DRAWEXTRA_FACEANG) { - BMFace *efa; - const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS); - - UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); - - if (dm) { - BM_mesh_elem_index_ensure(em->bm, BM_VERT); - } - - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - const bool is_face_sel = BM_elem_flag_test_bool(efa, BM_ELEM_SELECT); - - if (is_face_sel || do_moving) { - BMIter liter; - BMLoop *loop; - bool is_first = true; - - BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) { - if (is_face_sel || - (do_moving && - (BM_elem_flag_test(loop->v, BM_ELEM_SELECT) || - BM_elem_flag_test(loop->prev->v, BM_ELEM_SELECT) || - BM_elem_flag_test(loop->next->v, BM_ELEM_SELECT)))) - { - float v2_local[3]; - - /* lazy init center calc */ - if (is_first) { - if (dm) { - BMLoop *l_iter, *l_first; - float tvec[3]; - zero_v3(vmid); - l_iter = l_first = BM_FACE_FIRST_LOOP(efa); - do { - dm->getVertCo(dm, BM_elem_index_get(l_iter->v), tvec); - add_v3_v3(vmid, tvec); - } while ((l_iter = l_iter->next) != l_first); - mul_v3_fl(vmid, 1.0f / (float)efa->len); - } - else { - BM_face_calc_center_bounds(efa, vmid); - } - is_first = false; - } - - if (dm) { - dm->getVertCo(dm, BM_elem_index_get(loop->prev->v), v1); - dm->getVertCo(dm, BM_elem_index_get(loop->v), v2); - dm->getVertCo(dm, BM_elem_index_get(loop->next->v), v3); - } - else { - copy_v3_v3(v1, loop->prev->v->co); - copy_v3_v3(v2, loop->v->co); - copy_v3_v3(v3, loop->next->v->co); - } - - copy_v3_v3(v2_local, v2); - - if (do_global) { - mul_mat3_m4_v3(ob->obmat, v1); - mul_mat3_m4_v3(ob->obmat, v2); - mul_mat3_m4_v3(ob->obmat, v3); - } - - float angle = angle_v3v3v3(v1, v2, v3); - - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); - interp_v3_v3v3(fvec, vmid, v2_local, 0.8f); - view3d_cached_text_draw_add(fvec, numstr, numstr_len, 0, txt_flag, col); - } - } - } - } - } -} - -static void draw_em_indices(BMEditMesh *em) -{ - const short txt_flag = V3D_CACHE_TEXT_ASCII | V3D_CACHE_TEXT_LOCALCLIP; - BMEdge *e; - BMFace *f; - BMVert *v; - char numstr[32]; - size_t numstr_len; - float pos[3]; - unsigned char col[4]; - - BMIter iter; - BMesh *bm = em->bm; - - /* For now, reuse appropriate theme colors from stats text colors */ - int i = 0; - if (em->selectmode & SCE_SELECT_VERTEX) { - UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i); - view3d_cached_text_draw_add(v->co, numstr, numstr_len, 0, txt_flag, col); - } - i++; - } - } - - if (em->selectmode & SCE_SELECT_EDGE) { - i = 0; - UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i); - mid_v3_v3v3(pos, e->v1->co, e->v2->co); - view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col); - } - i++; - } - } - - if (em->selectmode & SCE_SELECT_FACE) { - i = 0; - UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { - BM_face_calc_center_mean(f, pos); - numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", i); - view3d_cached_text_draw_add(pos, numstr, numstr_len, 0, txt_flag, col); - } - i++; - } - } -} - -static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index) -{ - BMEditMesh *em = userData; - - if (UNLIKELY(index >= em->bm->totface)) - return DM_DRAW_OPTION_NORMAL; - - BMFace *efa = BM_face_at_index(em->bm, index); - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - -static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index) -{ - BMEditMesh *em = userData; - - if (UNLIKELY(index >= em->bm->totface)) - return DM_DRAW_OPTION_NORMAL; - - BMFace *efa = BM_face_at_index(em->bm, index); - - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - -static void draw_em_fancy(Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, - Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const char dt) - -{ - RegionView3D *rv3d = ar->regiondata; - Mesh *me = ob->data; - const bool use_occlude_wire = (dt > OB_WIRE) && (v3d->flag2 & V3D_OCCLUDE_WIRE); - bool use_depth_offset = false; - - glLineWidth(1.0f); - - BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); - - if (check_object_draw_editweight(me, finalDM)) { - if (dt > OB_WIRE) { - draw_mesh_paint_weight_faces(finalDM, true, draw_em_fancy__setFaceOpts, me->edit_btmesh); - - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(GL_FALSE); - use_depth_offset = true; - } - else { - glEnable(GL_DEPTH_TEST); - draw_mesh_paint_weight_faces(finalDM, false, draw_em_fancy__setFaceOpts, me->edit_btmesh); - draw_mesh_paint_weight_edges(rv3d, finalDM, true, true, draw_dm_edges__setDrawOptions, me->edit_btmesh->bm); - glDisable(GL_DEPTH_TEST); - } - } - else if (dt > OB_WIRE) { - if (use_occlude_wire) { - /* use the cageDM since it always overlaps the editmesh faces */ - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - cageDM->drawMappedFaces(cageDM, draw_em_fancy__setFaceOpts, - GPU_object_material_bind, NULL, me->edit_btmesh, DM_DRAW_SKIP_HIDDEN | DM_DRAW_NEED_NORMALS); - GPU_object_material_unbind(); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } - else if (check_object_draw_texture(scene, v3d, dt)) { - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - finalDM->drawMappedFacesGLSL(finalDM, GPU_object_material_bind, - draw_em_fancy__setGLSLFaceOpts, em); - GPU_object_material_unbind(); - - glFrontFace(GL_CCW); - } - else { - draw_mesh_textured(scene, view_layer, v3d, rv3d, ob, finalDM, 0); - } - } - else { - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, GPU_object_material_bind, NULL, me->edit_btmesh, DM_DRAW_SKIP_HIDDEN | DM_DRAW_NEED_NORMALS); - - glFrontFace(GL_CCW); - - GPU_object_material_unbind(); - } - - /* Setup for drawing wire over, disable zbuffer - * write to show selected edge wires better */ - UI_ThemeColor(TH_WIRE_EDIT); - - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(GL_FALSE); - use_depth_offset = true; - } - else { - if (cageDM != finalDM) { - UI_ThemeColorBlend(TH_WIRE_EDIT, TH_BACK, 0.7); - finalDM->drawEdges(finalDM, 1, 0); - } - } - - if ((dt > OB_WIRE) && (v3d->flag2 & V3D_RENDER_SHADOW)) { - /* pass */ - } - else { - /* annoying but active faces is stored differently */ - BMFace *efa_act = BM_mesh_active_face_get(em->bm, false, true); - BMEdge *eed_act = NULL; - BMVert *eve_act = NULL; - - if (em->bm->selected.last) { - BMEditSelection *ese = em->bm->selected.last; - /* face is handled above */ -#if 0 - if (ese->type == BM_FACE) { - efa_act = (BMFace *)ese->data; - } - else -#endif - if (ese->htype == BM_EDGE) { - eed_act = (BMEdge *)ese->ele; - } - else if (ese->htype == BM_VERT) { - eve_act = (BMVert *)ese->ele; - } - } - - if ((me->drawflag & ME_DRAWFACES) && (use_occlude_wire == false)) { /* transp faces */ - unsigned char col1[4], col2[4], col3[4]; -#ifdef WITH_FREESTYLE - unsigned char col4[4]; -#endif - - UI_GetThemeColor4ubv(TH_FACE, col1); - UI_GetThemeColor4ubv(TH_FACE_SELECT, col2); - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); -#ifdef WITH_FREESTYLE - UI_GetThemeColor4ubv(TH_FREESTYLE_FACE_MARK, col4); -#endif - - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */ - - /* don't draw unselected faces, only selected, this is MUCH nicer when texturing */ - if (check_object_draw_texture(scene, v3d, dt)) - col1[3] = 0; - -#ifdef WITH_FREESTYLE - if (!(me->drawflag & ME_DRAW_FREESTYLE_FACE) || !CustomData_has_layer(&em->bm->pdata, CD_FREESTYLE_FACE)) - col4[3] = 0; - - draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); -#else - draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); -#endif - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); /* restore write in zbuffer */ - } - else if (efa_act) { - /* even if draw faces is off it would be nice to draw the stipple face - * Make all other faces zero alpha except for the active */ - unsigned char col1[4], col2[4], col3[4]; -#ifdef WITH_FREESTYLE - unsigned char col4[4]; - col4[3] = 0; /* don't draw */ -#endif - col1[3] = col2[3] = 0; /* don't draw */ - - UI_GetThemeColor4ubv(TH_EDITMESH_ACTIVE, col3); - - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); /* disable write in zbuffer, needed for nice transp */ - -#ifdef WITH_FREESTYLE - draw_dm_faces_sel(em, cageDM, col1, col2, col3, col4, efa_act); -#else - draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act); -#endif - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); /* restore write in zbuffer */ - } - - /* here starts all fancy draw-extra over */ - if ((me->drawflag & ME_DRAWEDGES) == 0 && check_object_draw_texture(scene, v3d, dt)) { - /* we are drawing textures and 'ME_DRAWEDGES' is disabled, don't draw any edges */ - - /* only draw selected edges otherwise there is no way of telling if a face is selected */ - draw_em_fancy_edges(em, scene, v3d, me, cageDM, 1, eed_act); - - } - else { - if (me->drawflag & ME_DRAWSEAMS) { - UI_ThemeColor(TH_EDGE_SEAM); - glLineWidth(2.0f); - - draw_dm_edges_seams(em, cageDM); - - glColor3ub(0, 0, 0); - } - - if (me->drawflag & ME_DRAWSHARP) { - UI_ThemeColor(TH_EDGE_SHARP); - glLineWidth(2.0f); - - draw_dm_edges_sharp(em, cageDM); - - glColor3ub(0, 0, 0); - } - -#ifdef WITH_FREESTYLE - if (me->drawflag & ME_DRAW_FREESTYLE_EDGE && CustomData_has_layer(&em->bm->edata, CD_FREESTYLE_EDGE)) { - UI_ThemeColor(TH_FREESTYLE_EDGE_MARK); - glLineWidth(2.0f); - - draw_dm_edges_freestyle(em, cageDM); - - glColor3ub(0, 0, 0); - } -#endif - - if (me->drawflag & ME_DRAWCREASES) { - draw_dm_creases(em, cageDM); - } - if (me->drawflag & ME_DRAWBWEIGHTS) { - draw_dm_bweights(em, scene, cageDM); - } - - glLineWidth(1.0f); - draw_em_fancy_edges(em, scene, v3d, me, cageDM, 0, eed_act); - } - - { - draw_em_fancy_verts(scene, v3d, ob, em, cageDM, eve_act, rv3d); - - if (me->drawflag & ME_DRAWNORMALS) { - draw_dm_face_normals(em, scene, ob, cageDM, TH_NORMAL); - } - if (me->drawflag & ME_DRAW_VNORMALS) { - draw_dm_vert_normals(em, scene, ob, cageDM, TH_VNORMAL); - } - if (me->drawflag & ME_DRAW_LNORMALS) { - draw_dm_loop_normals(em, scene, ob, cageDM, TH_LNORMAL); - } - - if ((me->drawflag & (ME_DRAWEXTRA_EDGELEN | - ME_DRAWEXTRA_FACEAREA | - ME_DRAWEXTRA_FACEANG | - ME_DRAWEXTRA_EDGEANG)) && - !(v3d->flag2 & V3D_RENDER_OVERRIDE)) - { - draw_em_measure_stats(ar, v3d, ob, em, &scene->unit); - } - - if ((G.debug & G_DEBUG) && (me->drawflag & ME_DRAWEXTRA_INDICES) && - !(v3d->flag2 & V3D_RENDER_OVERRIDE)) - { - draw_em_indices(em); - } - } - } - - if (use_depth_offset) { - glDepthMask(GL_TRUE); - ED_view3d_polygon_offset(rv3d, 0.0); - GPU_object_material_unbind(); - } -#if 0 /* currently not needed */ - else if (use_occlude_wire) { - ED_view3d_polygon_offset(rv3d, 0.0); - } -#endif -} - -static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D *UNUSED(v3d), - Object *UNUSED(ob), Mesh *me, BMEditMesh *UNUSED(em), DerivedMesh *UNUSED(cageDM), DerivedMesh *UNUSED(finalDM), const char UNUSED(dt)) -{ - /* for now... something simple! */ - Gwn_Batch *surface = DRW_mesh_batch_cache_get_all_triangles(me); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - - glEnable(GL_BLEND); - - /* disable depth writes for transparent surface, so it doesn't interfere with itself */ - glDepthMask(GL_FALSE); - - GWN_batch_program_set_builtin(surface, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4f(surface, "color", 1.0f, 0.5f, 0.0f, 0.5f); - GWN_batch_draw(surface); - -#if 0 /* until I understand finalDM better */ - if (finalDM != cageDM) { - puts("finalDM != cageDM"); - Gwn_Batch *finalSurface = MBC_get_all_triangles(finalDM); - GWN_batch_program_set_builtin(finalSurface, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4f(finalSurface, "color", 0.0f, 0.0f, 0.0f, 0.05f); - GWN_batch_draw(finalSurface); - } -#endif - - glDepthMask(GL_TRUE); - - /* now write surface depth so other objects won't poke through - * NOTE: does not help as much as desired - * TODO: draw edit object last to avoid this mess - */ - GWN_batch_program_set_builtin(surface, GPU_SHADER_3D_DEPTH_ONLY); - GWN_batch_draw(surface); - - if (GLEW_VERSION_3_2) { -#if 0 - Gwn_Batch *overlay = DRW_mesh_batch_cache_get_overlay_edges(me); - GWN_batch_program_set_builtin(overlay, GPU_SHADER_EDGES_OVERLAY); - GWN_batch_uniform_2f(overlay, "viewportSize", ar->winx, ar->winy); - GWN_batch_draw(overlay); -#endif - -#if 0 /* TODO: use this SIMPLE variant for pure triangle meshes */ - GWN_batch_program_set_builtin(surface, GPU_SHADER_EDGES_OVERLAY_SIMPLE); - /* use these defaults: - * const float edgeColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - * GWN_batch_uniform_4f(surface, "fillColor", edgeColor[0], edgeColor[1], edgeColor[2], 0.0f); - * GWN_batch_uniform_4fv(surface, "outlineColor", edgeColor); - * GWN_batch_uniform_1f(surface, "outlineWidth", 1.0f); - */ - GWN_batch_uniform_2f(surface, "viewportSize", ar->winx, ar->winy); - GWN_batch_draw(surface); -#endif - } - else { - Gwn_Batch *edges = DRW_mesh_batch_cache_get_all_edges(me); - GWN_batch_program_set_builtin(edges, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4f(edges, "color", 0.0f, 0.0f, 0.0f, 1.0f); - glEnable(GL_LINE_SMOOTH); - glLineWidth(1.5f); - GWN_batch_draw(edges); - glDisable(GL_LINE_SMOOTH); - } - -#if 0 /* looks good even without points */ - Gwn_Batch *verts = MBC_get_all_verts(me); - glEnable(GL_BLEND); - - GWN_batch_program_set_builtin(verts, GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA); - GWN_batch_uniform_4f(verts, "color", 0.0f, 0.0f, 0.0f, 1.0f); - GWN_batch_uniform_1f(verts, "size", UI_GetThemeValuef(TH_VERTEX_SIZE) * 1.5f); - GWN_batch_draw(verts); - - glDisable(GL_BLEND); -#endif -} - -/* Mesh drawing routines */ - -void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm, const unsigned char ob_wire_col[4]) /* LEGACY */ -{ - if ((v3d->transp == false) && /* not when we draw the transparent pass */ - (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ - { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - glDepthMask(GL_FALSE); - - if (ob_wire_col) glColor4ubv(ob_wire_col); - - /* if transparent, we cannot draw the edges for solid select... edges - * have no material info. GPU_object_material_visible will skip the - * transparent faces */ - if (ob->dtx & OB_DRAWTRANSP) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_visible); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - else { - dm->drawEdges(dm, 0, 1); - } - - glDepthMask(GL_TRUE); - } -} - -static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object *ob, Mesh *me, const bool is_active) -{ - if ((v3d->transp == false) && /* not when we draw the transparent pass */ - (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ - { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - glDepthMask(GL_FALSE); - - float outline_color[4]; - UI_GetThemeColor4fv((is_active ? TH_ACTIVE : TH_SELECT), outline_color); - -#if 1 /* new version that draws only silhouette edges */ - Gwn_Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me); - - if (rv3d->persp == RV3D_ORTHO) { - GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO); - /* set eye vector, transformed to object coords */ - float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */ - mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye); - GWN_batch_uniform_3fv(fancy_edges, "eye", eye); - } - else { - GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP); - } - - GWN_batch_uniform_1b(fancy_edges, "drawFront", false); - GWN_batch_uniform_1b(fancy_edges, "drawBack", false); - GWN_batch_uniform_1b(fancy_edges, "drawSilhouette", true); - GWN_batch_uniform_4fv(fancy_edges, "silhouetteColor", outline_color); - - GWN_batch_draw(fancy_edges); -#else /* alternate version that matches look of old viewport (but more efficient) */ - Gwn_Batch *batch = MBC_get_all_edges(dm); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - GWN_batch_uniform_4fv(batch, "color", outline_color); - GWN_batch_draw(batch); -#endif - - glDepthMask(GL_TRUE); - } -} - -static bool object_is_halo(Scene *scene, Object *ob) -{ - const Material *ma = give_current_material(ob, 1); - return (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene)); -} - -static void draw_mesh_fancy( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag) -{ - Object *ob = base->object; - Mesh *me = ob->data; - eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; - bool /* no_verts,*/ no_edges, no_faces; - DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, scene->customdata_mask); - const bool is_obact = (ob == OBACT(view_layer)); - int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0; - - if (!dm) - return; - - DM_update_materials(dm, ob); - - /* Check to draw dynamic paint colors (or weights from WeightVG modifiers). - * Note: Last "preview-active" modifier in stack will win! */ - if (DM_get_loop_data_layer(dm, CD_PREVIEW_MLOOPCOL) && modifiers_isPreview(ob)) - draw_flags |= DRAW_MODIFIERS_PREVIEW; - - /* Unwanted combination */ - if (draw_flags & DRAW_FACE_SELECT) { - draw_wire = OBDRAW_WIRE_OFF; - } - else if (ob->dtx & OB_DRAWWIRE) { - draw_wire = OBDRAW_WIRE_ON_DEPTH; /* draw wire after solid using zoffset and depth buffer adjusment */ - } - - /* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */ - if (dm->type == DM_TYPE_CCGDM) { - no_edges = !subsurf_has_edges(dm); - no_faces = !subsurf_has_faces(dm); - } - else { - no_edges = (dm->getNumEdges(dm) == 0); - no_faces = (dm->getNumPolys(dm) == 0); - } - - /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */ - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (dt == OB_BOUNDBOX) { - if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0) - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - else if ((no_faces && no_edges) || - ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob))) - { - glPointSize(1.5f); - dm->drawVerts(dm); - } - else if ((dt == OB_WIRE) || no_faces) { - draw_wire = OBDRAW_WIRE_ON; /* draw wire only, no depth buffer stuff */ - } - else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) || - check_object_draw_texture(scene, v3d, dt)) - { - bool draw_loose = true; - - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) && - (draw_wire == OBDRAW_WIRE_OFF)) - { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); - } - - if (draw_glsl_material(scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) { - Paint *p; - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { - GPUVertexAttribs gattribs; - float planes[4][4]; - float (*fpl)[4] = NULL; - const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); - - if (ob->sculpt->partial_redraw) { - if (ar->do_draw & RGN_DRAW_PARTIAL) { - ED_sculpt_redraw_planes_get(planes, ar, ob); - fpl = planes; - ob->sculpt->partial_redraw = 0; - } - } - - GPU_object_material_bind(1, &gattribs); - dm->drawFacesSolid(dm, fpl, fast, NULL); - draw_loose = false; - } - else - dm->drawFacesGLSL(dm, GPU_object_material_bind); - -#if 0 /* XXX */ - if (BKE_bproperty_object_get(ob, "Text")) - draw_mesh_text(ob, 1); -#endif - GPU_object_material_unbind(); - - glFrontFace(GL_CCW); - - if (draw_flags & DRAW_FACE_SELECT) - draw_mesh_face_select(rv3d, me, dm, false); - } - else { - draw_mesh_textured(scene, view_layer, v3d, rv3d, ob, dm, draw_flags); - } - - if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) { - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - dm->drawLooseEdges(dm); - } - } - } - else if (dt == OB_SOLID) { - if (draw_flags & DRAW_MODIFIERS_PREVIEW) { - /* for object selection draws no shade */ - if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - GPU_object_material_unbind(); - } - else { - const float specular[3] = {0.47f, 0.47f, 0.47f}; - - /* draw outline */ - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - (draw_wire == OBDRAW_WIRE_OFF) && - (ob->sculpt == NULL)) - { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); - } - - /* materials arent compatible with vertex colors */ - GPU_end_object_materials(); - - /* set default specular */ - GPU_basic_shader_colors(NULL, specular, 35, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); - - dm->drawMappedFaces(dm, NULL, NULL, NULL, NULL, DM_DRAW_USE_COLORS | DM_DRAW_NEED_NORMALS); - - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - } - else { - Paint *p; - - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - (draw_wire == OBDRAW_WIRE_OFF) && - (ob->sculpt == NULL)) - { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); - } - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { - float planes[4][4]; - float (*fpl)[4] = NULL; - const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); - - if (ob->sculpt->partial_redraw) { - if (ar->do_draw & RGN_DRAW_PARTIAL) { - ED_sculpt_redraw_planes_get(planes, ar, ob); - fpl = planes; - ob->sculpt->partial_redraw = 0; - } - } - - dm->drawFacesSolid(dm, fpl, fast, GPU_object_material_bind); - } - else - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - - glFrontFace(GL_CCW); - - GPU_object_material_unbind(); - - if (!ob->sculpt && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - dm->drawLooseEdges(dm); - } - } - } - else if (dt == OB_PAINT) { - draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags); - - /* since we already draw wire as wp guide, don't draw over the top */ - draw_wire = OBDRAW_WIRE_OFF; - } - - if ((draw_wire != OBDRAW_WIRE_OFF) && /* draw extra wire */ - /* when overriding with render only, don't bother */ - (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0)) - { - /* When using wireframe object draw in particle edit mode - * the mesh gets in the way of seeing the particles, fade the wire color - * with the background. */ - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (is_obact && (ob->mode & OB_MODE_PARTICLE_EDIT)) { - float color[3]; - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.15f, color); - glColor3fv(color); - } - else { - glColor3ubv(ob_wire_col); - } - } - - /* If drawing wire and drawtype is not OB_WIRE then we are - * overlaying the wires. - * - * UPDATE bug #10290 - With this wire-only objects can draw - * behind other objects depending on their order in the scene. 2x if 0's below. undo'ing zr's commit: r4059 - * - * if draw wire is 1 then just drawing wire, no need for depth buffer stuff, - * otherwise this wire is to overlay solid mode faces so do some depth buffer tricks. - */ - if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) { - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */ - } - - glLineWidth(1.0f); - dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0); - - if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) { - glDepthMask(GL_TRUE); - ED_view3d_polygon_offset(rv3d, 0.0); - } - } - - if (is_obact && BKE_paint_select_vert_test(ob)) { - const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0; - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - if (!use_depth) glDisable(GL_DEPTH_TEST); - else ED_view3d_polygon_offset(rv3d, 1.0); - drawSelectedVertices(dm, ob->data); - if (!use_depth) glEnable(GL_DEPTH_TEST); - else ED_view3d_polygon_offset(rv3d, 0.0); - } - dm->release(dm); -} - -/* returns true if nothing was drawn, for detecting to draw an object center */ -static bool draw_mesh_object( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag) -{ - Object *ob = base->object; - Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); - Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; - bool do_alpha_after = false, drawlinked = false, retval = false; - - /* If we are drawing shadows and any of the materials don't cast a shadow, - * then don't draw the object */ - if (v3d->flag2 & V3D_RENDER_SHADOW) { - for (int i = 0; i < ob->totcol; ++i) { - Material *ma = give_current_material(ob, i); - if (ma && !(ma->mode2 & MA_CASTSHADOW)) { - return true; - } - } - } - - if (obedit && ob != obedit && ob->data == obedit->data) { - if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {} - else if (ob->modifiers.first || obedit->modifiers.first) {} - else drawlinked = true; - } - - /* backface culling */ - if (v3d->flag2 & V3D_BACKFACE_CULLING) { - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - } - - if (ob == obedit || drawlinked) { - DerivedMesh *finalDM, *cageDM; - - if (obedit != ob) { - finalDM = cageDM = editbmesh_get_derived_base( - ob, em, scene->customdata_mask); - } - else { - cageDM = editbmesh_get_derived_cage_and_final( - depsgraph, scene, ob, em, scene->customdata_mask, - &finalDM); - } - - const bool use_material = ((me->drawflag & ME_DRAWEIGHT) == 0); - - DM_update_materials(finalDM, ob); - if (cageDM != finalDM) { - DM_update_materials(cageDM, ob); - } - - if (use_material) { - if (dt > OB_WIRE) { - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); - } - } - - draw_em_fancy(scene, view_layer, ar, v3d, ob, em, cageDM, finalDM, dt); - - if (use_material) { - GPU_end_object_materials(); - } - - if (obedit != ob) - finalDM->release(finalDM); - } - else { - /* ob->bb was set by derived mesh system, do NULL check just to be sure */ - if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) { - if (dt > OB_WIRE) { - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - - if (dt == OB_SOLID || glsl) { - const bool check_alpha = check_alpha_pass(base); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, - (check_alpha) ? &do_alpha_after : NULL); - } - } - - draw_mesh_fancy(depsgraph, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); - - GPU_end_object_materials(); - - if (me->totvert == 0) retval = true; - } - } - - if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { - /* GPU_begin_object_materials checked if this is needed */ - if (do_alpha_after) { - if (ob->dtx & OB_DRAWXRAY) { - ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag); - } - else { - ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); - } - } - else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) { - /* special case xray+transp when alpha is 1.0, without this the object vanishes */ - if (v3d->xray == 0 && v3d->transp == 0) { - ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); - } - } - } - - if (v3d->flag2 & V3D_BACKFACE_CULLING) - glDisable(GL_CULL_FACE); - - return retval; -} - -static void make_color_variations(const unsigned char base_ubyte[4], float low[4], float med[4], float high[4], const bool other_obedit) -{ - /* original idea: nice variations (lighter & darker shades) of base color - * current implementation uses input color as high; med & low get closer to background color - */ - - float bg[3]; - UI_GetThemeColor3fv(TH_BACK, bg); - - float base[4]; - rgba_uchar_to_float(base, base_ubyte); - - if (other_obedit) { - /* this object should fade away so user can focus on the object being edited */ - interp_v3_v3v3(low, bg, base, 0.1f); - interp_v3_v3v3(med, bg, base, 0.2f); - interp_v3_v3v3(high, bg, base, 0.25f); - } - else { - interp_v3_v3v3(low, bg, base, 0.333f); - interp_v3_v3v3(med, bg, base, 0.667f); - copy_v3_v3(high, base); - } - - /* use original alpha */ - low[3] = base[3]; - med[3] = base[3]; - high[3] = base[3]; -} - -static void draw_mesh_fancy_new( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, - ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag, const bool other_obedit) -{ - if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { - /* too complicated! use existing methods */ - /* TODO: move this into a separate depth pre-pass */ - draw_mesh_fancy(depsgraph, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); - return; - } - - Object *ob = base->object; - Mesh *me = ob->data; - eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; /* could be bool draw_wire_overlay */ - bool no_edges, no_faces; - DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, scene->customdata_mask); - const bool is_obact = (ob == OBACT(view_layer)); - int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0; - - if (!dm) - return; - - const bool solid = dt >= OB_SOLID; - if (solid) { - DM_update_materials(dm, ob); - } - - /* Check to draw dynamic paint colors (or weights from WeightVG modifiers). - * Note: Last "preview-active" modifier in stack will win! */ - if (DM_get_loop_data_layer(dm, CD_PREVIEW_MLOOPCOL) && modifiers_isPreview(ob)) - draw_flags |= DRAW_MODIFIERS_PREVIEW; - - /* Unwanted combination */ - if (draw_flags & DRAW_FACE_SELECT) { - draw_wire = OBDRAW_WIRE_OFF; - } - else if (ob->dtx & OB_DRAWWIRE) { - draw_wire = OBDRAW_WIRE_ON; - } - - /* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */ - if (dm->type == DM_TYPE_CCGDM) { - no_edges = !subsurf_has_edges(dm); - no_faces = !subsurf_has_faces(dm); - } - else { - no_edges = (dm->getNumEdges(dm) == 0); - no_faces = (dm->getNumPolys(dm) == 0); - } - - if (solid) { - /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */ - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - } - - if (dt == OB_BOUNDBOX) { - if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_WIRE) == 0) - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - else if ((no_faces && no_edges) || - ((!is_obact || (ob->mode == OB_MODE_OBJECT)) && object_is_halo(scene, ob))) - { - glPointSize(1.5f); - // dm->drawVerts(dm); - // TODO: draw smooth round points as a batch - } - else if ((dt == OB_WIRE) || no_faces) { - draw_wire = OBDRAW_WIRE_ON; - - /* enable depth for wireframes */ - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - - glLineWidth(1.0f); - -#if 1 /* fancy wireframes */ - - Gwn_Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me); - - if (rv3d->persp == RV3D_ORTHO) { - GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO); - /* set eye vector, transformed to object coords */ - float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */ - mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye); - GWN_batch_uniform_3fv(fancy_edges, "eye", eye); - } - else { - GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP); - } - - float frontColor[4]; - float backColor[4]; - float outlineColor[4]; - make_color_variations(ob_wire_col, backColor, frontColor, outlineColor, other_obedit); - - GWN_batch_uniform_4fv(fancy_edges, "frontColor", frontColor); - GWN_batch_uniform_4fv(fancy_edges, "backColor", backColor); - GWN_batch_uniform_1b(fancy_edges, "drawFront", true); - GWN_batch_uniform_1b(fancy_edges, "drawBack", true); /* false here = backface cull */ - GWN_batch_uniform_1b(fancy_edges, "drawSilhouette", false); - - GWN_batch_draw(fancy_edges); - - /* extra oomph for the silhouette contours */ - glLineWidth(2.0f); - GWN_batch_program_use_begin(fancy_edges); /* hack to make the following uniforms stick */ - GWN_batch_uniform_1b(fancy_edges, "drawFront", false); - GWN_batch_uniform_1b(fancy_edges, "drawBack", false); - GWN_batch_uniform_1b(fancy_edges, "drawSilhouette", true); - GWN_batch_uniform_4fv(fancy_edges, "silhouetteColor", outlineColor); - - GWN_batch_draw(fancy_edges); - -#else /* simple wireframes */ - - Gwn_Batch *batch = MBC_get_all_edges(dm); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - - float color[4]; - rgba_uchar_to_float(color, ob_wire_col); - - GWN_batch_uniform_4fv(batch, "color", color); - - GWN_batch_draw(batch); -#endif - } - else if (((is_obact && ob->mode & OB_MODE_TEXTURE_PAINT)) || - check_object_draw_texture(scene, v3d, dt)) - { - bool draw_loose = true; - - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - !(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) && - (draw_wire == OBDRAW_WIRE_OFF)) - { - draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer))); - } - - if (draw_glsl_material(scene, view_layer, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) { - Paint *p; - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if ((v3d->flag2 & V3D_SHOW_SOLID_MATCAP) && ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { - GPUVertexAttribs gattribs; - float planes[4][4]; - float (*fpl)[4] = NULL; - const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); - - if (ob->sculpt->partial_redraw) { - if (ar->do_draw & RGN_DRAW_PARTIAL) { - ED_sculpt_redraw_planes_get(planes, ar, ob); - fpl = planes; - ob->sculpt->partial_redraw = 0; - } - } - - GPU_object_material_bind(1, &gattribs); - dm->drawFacesSolid(dm, fpl, fast, NULL); - draw_loose = false; - } - else - dm->drawFacesGLSL(dm, GPU_object_material_bind); - - GPU_object_material_unbind(); - - glFrontFace(GL_CCW); - - if (draw_flags & DRAW_FACE_SELECT) - draw_mesh_face_select(rv3d, me, dm, false); - } - else { - draw_mesh_textured(scene, view_layer, v3d, rv3d, ob, dm, draw_flags); - } - - if (draw_loose && !(draw_flags & DRAW_FACE_SELECT)) { - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - dm->drawLooseEdges(dm); - } - } - } - else if (dt == OB_SOLID) { - if (draw_flags & DRAW_MODIFIERS_PREVIEW) { - /* for object selection draws no shade */ - if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { - /* TODO: draw basic faces with GPU_SHADER_3D_DEPTH_ONLY */ - } - else { - const float specular[3] = {0.47f, 0.47f, 0.47f}; - - /* draw outline */ - /* TODO: move this into a separate pass */ - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - (draw_wire == OBDRAW_WIRE_OFF) && - (ob->sculpt == NULL)) - { - draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer))); - } - - /* materials arent compatible with vertex colors */ - GPU_end_object_materials(); - - /* set default specular */ - GPU_basic_shader_colors(NULL, specular, 35, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); - - dm->drawMappedFaces(dm, NULL, NULL, NULL, NULL, DM_DRAW_USE_COLORS | DM_DRAW_NEED_NORMALS); - - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - } - else { - Paint *p; - - if ((v3d->flag & V3D_SELECT_OUTLINE) && - ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && - (base->flag & BASE_SELECTED) && - (draw_wire == OBDRAW_WIRE_OFF) && - (ob->sculpt == NULL)) - { - /* TODO: move this into a separate pass */ - draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT(view_layer))); - } - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (ob->sculpt && (p = BKE_paint_get_active(scene, view_layer))) { - float planes[4][4]; - float (*fpl)[4] = NULL; - const bool fast = (p->flags & PAINT_FAST_NAVIGATE) && (rv3d->rflag & RV3D_NAVIGATING); - - if (ob->sculpt->partial_redraw) { - if (ar->do_draw & RGN_DRAW_PARTIAL) { - ED_sculpt_redraw_planes_get(planes, ar, ob); - fpl = planes; - ob->sculpt->partial_redraw = 0; - } - } - - dm->drawFacesSolid(dm, fpl, fast, GPU_object_material_bind); - } - else - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - - glFrontFace(GL_CCW); - - GPU_object_material_unbind(); - - if (!ob->sculpt && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - glLineWidth(1.0f); - dm->drawLooseEdges(dm); - } - } - } - else if (dt == OB_PAINT) { - draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags); - - /* since we already draw wire as wp guide, don't draw over the top */ - draw_wire = OBDRAW_WIRE_OFF; - } - - if ((draw_wire != OBDRAW_WIRE_OFF) && /* draw extra wire */ - /* when overriding with render only, don't bother */ - (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0)) // <-- is this "== 0" in the right spot??? - { - /* When using wireframe object draw in particle edit mode - * the mesh gets in the way of seeing the particles, fade the wire color - * with the background. */ - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* TODO: - * Batch_UniformColor4ubv(ob_wire_col); - */ - } - - /* If drawing wire and drawtype is not OB_WIRE then we are - * overlaying the wires. - * - * No need for polygon offset because new technique is AWESOME. - */ -#if 0 - glLineWidth(1.0f); - dm->drawEdges(dm, ((dt == OB_WIRE) || no_faces), (ob->dtx & OB_DRAW_ALL_EDGES) != 0); -#else - /* something */ -#endif - } - -#if 0 // (merwin) what is this for? - if (is_obact && BKE_paint_select_vert_test(ob)) { - const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) != 0; - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - if (!use_depth) glDisable(GL_DEPTH_TEST); - else ED_view3d_polygon_offset(rv3d, 1.0); - drawSelectedVertices(dm, ob->data); - if (!use_depth) glEnable(GL_DEPTH_TEST); - else ED_view3d_polygon_offset(rv3d, 0.0); - } -#endif - - dm->release(dm); -} - -static bool UNUSED_FUNCTION(draw_mesh_object_new)( - Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const unsigned char ob_wire_col[4], const short dflag) -{ - ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - Object *ob = base->object; - Mesh *me = ob->data; - BMEditMesh *em = me->edit_btmesh; - bool do_alpha_after = false, drawlinked = false, retval = false; - - if (v3d->flag2 & V3D_RENDER_SHADOW) { - /* TODO: handle shadow pass separately */ - return true; - } - Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); - - if (obedit && ob != obedit && ob->data == obedit->data) { - if (BKE_key_from_object(ob) || BKE_key_from_object(obedit)) {} - else if (ob->modifiers.first || obedit->modifiers.first) {} - else drawlinked = true; - } - - /* backface culling */ - const bool solid = dt > OB_WIRE; - const bool cullBackface = solid && (v3d->flag2 & V3D_BACKFACE_CULLING); - if (cullBackface) { - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - } - - if (ob == obedit || drawlinked) { - DerivedMesh *finalDM, *cageDM; - - if (obedit != ob) { - /* linked to the edit object */ - finalDM = cageDM = editbmesh_get_derived_base( - ob, em, scene->customdata_mask); - } - else { - cageDM = editbmesh_get_derived_cage_and_final( - depsgraph, scene, ob, em, scene->customdata_mask, - &finalDM); - } - - const bool use_material = solid && ((me->drawflag & ME_DRAWEIGHT) == 0); - -#if 0 // why update if not being used? - DM_update_materials(finalDM, ob); - if (cageDM != finalDM) { - DM_update_materials(cageDM, ob); - } -#endif // moved to below - - if (use_material) { - DM_update_materials(finalDM, ob); - if (cageDM != finalDM) { - DM_update_materials(cageDM, ob); - } - - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); - } - - draw_em_fancy_new(scene, ar, v3d, ob, me, em, cageDM, finalDM, dt); - - if (use_material) { - GPU_end_object_materials(); - } - - if (obedit != ob) - finalDM->release(finalDM); - } - else { - /* ob->bb was set by derived mesh system, do NULL check just to be sure */ - if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->bb))) { - if (solid) { - const bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - - if (dt == OB_SOLID || glsl) { - const bool check_alpha = check_alpha_pass(base); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, - (check_alpha) ? &do_alpha_after : NULL); - } - } - - const bool other_obedit = obedit && (obedit != ob); - - draw_mesh_fancy_new(depsgraph, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag, other_obedit); - - GPU_end_object_materials(); - - if (me->totvert == 0) retval = true; - } - } - - if (cullBackface) - glDisable(GL_CULL_FACE); - - return retval; -} - -/* ************** DRAW DISPLIST ****************** */ - -static void drawDispListVerts(Gwn_PrimType prim_type, const void *data, unsigned int vert_ct, const unsigned char wire_col[3]) -{ - Gwn_VertFormat format = {0}; - unsigned int pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vert_ct); - - GWN_vertbuf_attr_fill(vbo, pos_id, data); - - Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - if (wire_col) { - GWN_batch_uniform_4f(batch, "color", wire_col[0] / 255.0f, wire_col[1] / 255.0f, wire_col[2] / 255.0f, 1.0f); - } - GWN_batch_draw(batch); - GWN_batch_discard(batch); -} - -/* convert dispList with elem indices to batch, only support triangles and quads - * XXX : This is a huge perf issue. We should cache the resulting batches inside the object instead. - * But new viewport will do it anyway - * TODO implement flat drawing */ -static void drawDispListElem( - bool quads, bool UNUSED(smooth), bool ndata_is_single, - const float *data, const float *ndata, unsigned int data_len, - const int *elem, unsigned int elem_len, const unsigned char wire_col[3]) -{ - Gwn_VertFormat format = {0}; - int i; - const int *idx = elem; - unsigned int pos_id, nor_id; - - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - if (ndata) { - if (ndata_is_single) { - /* pass */ - } - else { - nor_id = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - } - } - - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, (quads) ? elem_len * 2 : elem_len, 0xffffffff); - - if (quads) { - for (i = elem_len; i; --i, idx += 4) { - GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]); - GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[2], idx[3]); - } - } - else { - for (i = elem_len; i; --i, idx += 3) { - GWN_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]); - } - } - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, data_len); - - GWN_vertbuf_attr_fill(vbo, pos_id, data); - - if (ndata) { - if (ndata_is_single) { - /* TODO: something like glNormal for a single value */ - } - else { - GWN_vertbuf_attr_fill(vbo, nor_id, ndata); - } - } - - Gwn_Batch *batch = GWN_batch_create_ex( - GWN_PRIM_TRIS, vbo, GWN_indexbuf_build(&elb), GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX); - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING); - if (wire_col) { - GWN_batch_uniform_4f(batch, "color", wire_col[0] / 255.0f, wire_col[1] / 255.0f, wire_col[2] / 255.0f, 1.0f); - } - GWN_batch_uniform_4f(batch, "color", 0.8f, 0.8f, 0.8f, 1.0f); - GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f); - GWN_batch_draw(batch); - GWN_batch_discard(batch); -} - -/** - * \param dl_type_mask Only draw types matching this mask. - * \return true when nothing was drawn - */ -static bool drawDispListwire_ex(ListBase *dlbase, unsigned int dl_type_mask, const unsigned char wire_col[3]) -{ - if (dlbase == NULL) return true; - - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - for (DispList *dl = dlbase->first; dl; dl = dl->next) { - if (dl->parts == 0 || dl->nr == 0) { - continue; - } - - if ((dl_type_mask & (1 << dl->type)) == 0) { - continue; - } - - const float *data = dl->verts; - int parts; - - switch (dl->type) { - case DL_SEGM: - for (parts = 0; parts < dl->parts; parts++) - drawDispListVerts(GWN_PRIM_LINE_STRIP, data + (parts * dl->nr * 3), dl->nr, wire_col); - break; - - case DL_POLY: - for (parts = 0; parts < dl->parts; parts++) - drawDispListVerts(GWN_PRIM_LINE_LOOP, data + (parts * dl->nr * 3), dl->nr, wire_col); - break; - - case DL_SURF: - for (parts = 0; parts < dl->parts; parts++) { - if (dl->flag & DL_CYCL_U) - drawDispListVerts(GWN_PRIM_LINE_LOOP, data + (parts * dl->nr * 3), dl->nr, wire_col); - else - drawDispListVerts(GWN_PRIM_LINE_STRIP, data + (parts * dl->nr * 3), dl->nr, wire_col); - } - - float *data_aligned = MEM_mallocN(sizeof(float) * 3 * dl->parts, "aligned data"); - for (int nr = 0; nr < dl->nr; nr++) { - int ofs = 3 * dl->nr; - int idx = 0; - - data = (dl->verts) + 3 * nr; - parts = dl->parts; - - while (parts--) { - copy_v3_v3(data_aligned + idx, data); - data += ofs; - idx += 3; - } - - if (dl->flag & DL_CYCL_V) - drawDispListVerts(GWN_PRIM_LINE_LOOP, data_aligned, dl->parts, wire_col); - else - drawDispListVerts(GWN_PRIM_LINE_STRIP, data_aligned, dl->parts, wire_col); - } - - if (data_aligned) - MEM_freeN(data_aligned); - - break; - - case DL_INDEX3: - drawDispListElem( - false, true, false, - dl->verts, NULL, dl->nr, - dl->index, dl->parts, wire_col); - break; - - case DL_INDEX4: - drawDispListElem( - true, true, false, - dl->verts, NULL, dl->nr, - dl->index, dl->parts, wire_col); - break; - } - } - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - return false; -} - -static bool drawDispListwire(ListBase *dlbase, const short ob_type, const unsigned char wire_col[3]) -{ - unsigned int dl_mask = 0xffffffff; - - /* skip fill-faces for curves & fonts */ - if (ELEM(ob_type, OB_FONT, OB_CURVE)) { - dl_mask &= ~((1 << DL_INDEX3) | (1 << DL_INDEX4)); - } - - return drawDispListwire_ex(dlbase, dl_mask, wire_col); -} - -static bool index3_nors_incr = true; - -static void drawDispListsolid(ListBase *lb, Object *ob, const short UNUSED(dflag), - const unsigned char ob_wire_col[4], const bool use_glsl) -{ - GPUVertexAttribs gattribs; - - if (lb == NULL) return; - - /* track current material, -1 for none (needed for lines) */ - short col = -1; - - DispList *dl = lb->first; - while (dl) { - const float *data = dl->verts; - //const float *ndata = dl->nors; - - switch (dl->type) { - case DL_SEGM: - if (ob->type == OB_SURF) { - if (col != -1) { - GPU_object_material_unbind(); - col = -1; - } - - drawDispListVerts(GWN_PRIM_LINE_STRIP, data, dl->nr, ob_wire_col); - } - break; - case DL_POLY: - if (ob->type == OB_SURF) { - if (col != -1) { - GPU_object_material_unbind(); - col = -1; - } - - drawDispListVerts(GWN_PRIM_LINE_LOOP, data, dl->nr, ob_wire_col); - } - break; - case DL_SURF: - - if (dl->index) { - if (col != dl->col) { - GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); - col = dl->col; - } - const unsigned int verts_len = dl->nr * dl->parts; - - drawDispListElem( - true, (dl->rt & CU_SMOOTH) != 0, false, - dl->verts, dl->nors, verts_len, - dl->index, dl->totindex, ob_wire_col); - } - break; - - case DL_INDEX3: - if (col != dl->col) { - GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); - col = dl->col; - } - -#if 0 - /* for polys only one normal needed */ - if (index3_nors_incr) { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, dl->nors); - } - else - glNormal3fv(ndata); -#endif - /* special case, 'nors' is a single value */ - drawDispListElem( - false, (dl->rt & CU_SMOOTH) != 0, true, - dl->verts, dl->nors, dl->nr, - dl->index, dl->parts, ob_wire_col); - -#if 0 - if (index3_nors_incr) - glDisableClientState(GL_NORMAL_ARRAY); -#endif - - break; - - case DL_INDEX4: - if (col != dl->col) { - GPU_object_material_bind(dl->col + 1, use_glsl ? &gattribs : NULL); - col = dl->col; - } - - drawDispListElem( - true, true, false, - dl->verts, dl->nors, dl->nr, - dl->index, dl->parts, ob_wire_col); - - break; - } - dl = dl->next; - } - - glFrontFace(GL_CCW); - - if (col != -1) { - GPU_object_material_unbind(); - } -} - -static void drawCurveDMWired(Object *ob) -{ - DerivedMesh *dm = ob->derivedFinal; - dm->drawEdges(dm, 1, 0); -} - -/* return true when nothing was drawn */ -static bool drawCurveDerivedMesh(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, const char dt) -{ - Object *ob = base->object; - DerivedMesh *dm = ob->derivedFinal; - - if (!dm) { - return true; - } - - DM_update_materials(dm, ob); - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (dt > OB_WIRE && dm->getNumPolys(dm)) { - bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); - - if (!glsl) - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - else - dm->drawFacesGLSL(dm, GPU_object_material_bind); - - GPU_end_object_materials(); - } - else { - if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && v3d->drawtype >= OB_SOLID) == 0) - drawCurveDMWired(ob); - } - - return false; -} - -/** - * Only called by #drawDispList - * \return true when nothing was drawn - */ -static bool drawDispList_nobackface(Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4]) -{ - Object *ob = base->object; - ListBase *lb = NULL; - DispList *dl; - Curve *cu; - const bool render_only = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0; - const bool solid = (dt > OB_WIRE); - - switch (ob->type) { - case OB_FONT: - case OB_CURVE: - cu = ob->data; - - lb = &ob->curve_cache->disp; - - if (solid) { - const bool has_faces = BKE_displist_has_faces(lb); - dl = lb->first; - if (dl == NULL) { - return true; - } - - if (dl->nors == NULL) BKE_displist_normals_add(lb); - index3_nors_incr = false; - - if (!render_only) { - /* when we have faces, only draw loose-wire */ - if (has_faces) { - drawDispListwire_ex(lb, (1 << DL_SEGM), ob_wire_col); - } - else { - drawDispListwire(lb, ob->type, ob_wire_col); - } - } - - if (has_faces == false) { - /* pass */ - } - else { - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, true); - GPU_end_object_materials(); - } - else { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, false); - GPU_end_object_materials(); - } - if (cu->editnurb && cu->bevobj == NULL && cu->taperobj == NULL && cu->ext1 == 0.0f && cu->ext2 == 0.0f) { - unsigned char col[4] = {0, 0, 0, 0}; - drawDispListwire(lb, ob->type, col); - } - } - index3_nors_incr = true; - } - else { - if (!render_only || BKE_displist_has_faces(lb)) { - return drawDispListwire(lb, ob->type, ob_wire_col); - } - } - break; - case OB_SURF: - - lb = &ob->curve_cache->disp; - - if (solid) { - dl = lb->first; - if (dl == NULL) { - return true; - } - - if (dl->nors == NULL) BKE_displist_normals_add(lb); - - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, true); - GPU_end_object_materials(); - } - else { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, false); - GPU_end_object_materials(); - } - } - else { - return drawDispListwire(lb, ob->type, ob_wire_col); - } - break; - case OB_MBALL: - - if (BKE_mball_is_basis(ob)) { - lb = &ob->curve_cache->disp; - if (BLI_listbase_is_empty(lb)) { - return true; - } - - if (solid) { - - if (draw_glsl_material(scene, view_layer, ob, v3d, dt)) { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 1, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, true); - GPU_end_object_materials(); - } - else { - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, 0, NULL); - drawDispListsolid(lb, ob, dflag, ob_wire_col, false); - GPU_end_object_materials(); - } - } - else { - return drawDispListwire(lb, ob->type, ob_wire_col); - } - } - break; - } - - return false; -} -static bool drawDispList( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4]) -{ - bool retval; - - /* backface culling */ - if (v3d->flag2 & V3D_BACKFACE_CULLING) { - /* not all displists use same in/out normal direction convention */ - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - } - -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, base->object); -#endif - - if (drawCurveDerivedMesh(scene, view_layer, v3d, rv3d, base, dt) == false) { - retval = false; - } - else { - Object *ob = base->object; - GLenum mode; - - if (ob->type == OB_MBALL) { - mode = (ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW; - } - else { - mode = (ob->transflag & OB_NEG_SCALE) ? GL_CCW : GL_CW; - } - - glFrontFace(mode); - - retval = drawDispList_nobackface(scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - - if (mode != GL_CCW) { - glFrontFace(GL_CCW); - } - } - - if (v3d->flag2 & V3D_BACKFACE_CULLING) { - glDisable(GL_CULL_FACE); - } - - return retval; -} - -/* *********** drawing for particles ************* */ -/* stride : offset size in bytes - * col[4] : the color to use when *color is NULL, can be also NULL */ -static void draw_vertex_array(Gwn_PrimType prim_type, const float *vert, const float *nor, const float *color, int stride, int vert_ct, float col[4]) -{ - Gwn_VertFormat format = {0}; - unsigned int pos_id, nor_id, col_id; - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - if (nor) nor_id = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - if (color) col_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, vert_ct); - - if (stride == 0) { - GWN_vertbuf_attr_fill(vbo, pos_id, vert); - if (nor) GWN_vertbuf_attr_fill(vbo, nor_id, nor); - if (color) GWN_vertbuf_attr_fill(vbo, col_id, color); - } - else { - GWN_vertbuf_attr_fill_stride(vbo, pos_id, stride, vert); - if (nor) GWN_vertbuf_attr_fill_stride(vbo, nor_id, stride, nor); - if (color) GWN_vertbuf_attr_fill_stride(vbo, col_id, stride, color); - } - - Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO); - if (nor && color) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR); - GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f); - } - else if (nor) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING); - GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f); - if (col) GWN_batch_uniform_4fv(batch, "color", col); - } - else if (color) { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR); - } - else { - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); - if (col) GWN_batch_uniform_4fv(batch, "color", col); - } - GWN_batch_draw(batch); - GWN_batch_discard(batch); -} - -static void draw_particle_arrays_new(int draw_as, int ob_dt, int select, - const float *vert, const float *nor, const float *color, - int totpoint, float col[4]) -{ - /* draw created data arrays */ - switch (draw_as) { - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - draw_vertex_array(GWN_PRIM_LINES, vert, nor, color, 0, 6 * totpoint, col); - break; - case PART_DRAW_LINE: - draw_vertex_array(GWN_PRIM_LINES, vert, nor, color, 0, 2 * totpoint, col); - break; - case PART_DRAW_BB: - if (ob_dt <= OB_WIRE || select) - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - else - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - - draw_vertex_array(GWN_PRIM_TRIS, vert, nor, color, 0, 6 * totpoint, col); - break; - default: - draw_vertex_array(GWN_PRIM_POINTS, vert, nor, color, 0, totpoint, col); - break; - } -} -static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, - float imat[4][4], const float draw_line[2], ParticleBillboardData *bb, ParticleDrawData *pdd, - unsigned int pos) -{ - float vec[3], vec2[3]; - float *vd = NULL; - float *cd = NULL; - float ma_col[3] = {0.0f, 0.0f, 0.0f}; - - /* null only for PART_DRAW_CIRC */ - if (pdd) { - vd = pdd->vd; - cd = pdd->cd; - - if (pdd->ma_col) { - copy_v3_v3(ma_col, pdd->ma_col); - } - } - - switch (draw_as) { - case PART_DRAW_DOT: - { - if (vd) { - copy_v3_v3(vd, state->co); pdd->vd += 3; - } - if (cd) { - copy_v3_v3(cd, pdd->ma_col); - pdd->cd += 3; - } - break; - } - case PART_DRAW_CROSS: - case PART_DRAW_AXIS: - { - vec[0] = 2.0f * pixsize; - vec[1] = vec[2] = 0.0; - mul_qt_v3(state->rot, vec); - if (draw_as == PART_DRAW_AXIS) { - if (cd) { - cd[1] = cd[2] = cd[4] = cd[5] = 0.0; - cd[0] = cd[3] = 1.0; - cd[6] = cd[8] = cd[9] = cd[11] = 0.0; - cd[7] = cd[10] = 1.0; - cd[13] = cd[12] = cd[15] = cd[16] = 0.0; - cd[14] = cd[17] = 1.0; - pdd->cd += 18; - } - - copy_v3_v3(vec2, state->co); - } - else { - if (cd) { - cd[0] = cd[3] = cd[6] = cd[9] = cd[12] = cd[15] = ma_col[0]; - cd[1] = cd[4] = cd[7] = cd[10] = cd[13] = cd[16] = ma_col[1]; - cd[2] = cd[5] = cd[8] = cd[11] = cd[14] = cd[17] = ma_col[2]; - pdd->cd += 18; - } - sub_v3_v3v3(vec2, state->co, vec); - } - - add_v3_v3(vec, state->co); - copy_v3_v3(pdd->vd, vec); pdd->vd += 3; - copy_v3_v3(pdd->vd, vec2); pdd->vd += 3; - - vec[1] = 2.0f * pixsize; - vec[0] = vec[2] = 0.0; - mul_qt_v3(state->rot, vec); - if (draw_as == PART_DRAW_AXIS) { - copy_v3_v3(vec2, state->co); - } - else { - sub_v3_v3v3(vec2, state->co, vec); - } - - add_v3_v3(vec, state->co); - copy_v3_v3(pdd->vd, vec); pdd->vd += 3; - copy_v3_v3(pdd->vd, vec2); pdd->vd += 3; - - vec[2] = 2.0f * pixsize; - vec[0] = vec[1] = 0.0f; - mul_qt_v3(state->rot, vec); - if (draw_as == PART_DRAW_AXIS) { - copy_v3_v3(vec2, state->co); - } - else { - sub_v3_v3v3(vec2, state->co, vec); - } - - add_v3_v3(vec, state->co); - - copy_v3_v3(pdd->vd, vec); pdd->vd += 3; - copy_v3_v3(pdd->vd, vec2); pdd->vd += 3; - break; - } - case PART_DRAW_LINE: - { - copy_v3_v3(vec, state->vel); - normalize_v3(vec); - if (draw & PART_DRAW_VEL_LENGTH) - mul_v3_fl(vec, len_v3(state->vel)); - madd_v3_v3v3fl(pdd->vd, state->co, vec, -draw_line[0]); pdd->vd += 3; - madd_v3_v3v3fl(pdd->vd, state->co, vec, draw_line[1]); pdd->vd += 3; - if (cd) { - cd[0] = cd[3] = ma_col[0]; - cd[1] = cd[4] = ma_col[1]; - cd[2] = cd[5] = ma_col[2]; - pdd->cd += 6; - } - break; - } - case PART_DRAW_CIRC: - { - imm_drawcircball(state->co, pixsize, imat, pos); - break; - } - case PART_DRAW_BB: - { - float xvec[3], yvec[3], zvec[3], bb_center[3]; - - copy_v3_v3(bb->vec, state->co); - copy_v3_v3(bb->vel, state->vel); - - psys_make_billboard(bb, xvec, yvec, zvec, bb_center); - - /* First tri */ - add_v3_v3v3(pdd->vd, bb_center, xvec); - add_v3_v3(pdd->vd, yvec); pdd->vd += 3; - - sub_v3_v3v3(pdd->vd, bb_center, xvec); - add_v3_v3(pdd->vd, yvec); pdd->vd += 3; - - sub_v3_v3v3(pdd->vd, bb_center, xvec); - sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3; - - /* Second tri */ - add_v3_v3v3(pdd->vd, bb_center, xvec); - add_v3_v3(pdd->vd, yvec); pdd->vd += 3; - - sub_v3_v3v3(pdd->vd, bb_center, xvec); - sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3; - - add_v3_v3v3(pdd->vd, bb_center, xvec); - sub_v3_v3v3(pdd->vd, pdd->vd, yvec); pdd->vd += 3; - - if (cd) { - for (int i = 0; i < 6; i++, cd += 3, pdd->cd += 3) { - copy_v3_v3(cd, ma_col); - } - } - for (int i = 0; i < 6; i++, pdd->nd += 3) { - copy_v3_v3(pdd->nd, zvec); - } - break; - } - } -} -static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d, - ParticleKey *state, int draw_as, - float imat[4][4], ParticleBillboardData *bb, ParticleDrawData *pdd, - const float ct, const float pa_size, const float r_tilt, const float pixsize_scale, - unsigned int pos) -{ - ParticleSettings *part = psys->part; - float pixsize; - - if (psys->parent) - mul_m4_v3(psys->parent->obmat, state->co); - - /* create actual particle data */ - if (draw_as == PART_DRAW_BB) { - bb->offset[0] = part->bb_offset[0]; - bb->offset[1] = part->bb_offset[1]; - bb->size[0] = part->bb_size[0] * pa_size; - if (part->bb_align == PART_BB_VEL) { - float pa_vel = len_v3(state->vel); - float head = part->bb_vel_head * pa_vel; - float tail = part->bb_vel_tail * pa_vel; - bb->size[1] = part->bb_size[1] * pa_size + head + tail; - /* use offset to adjust the particle center. this is relative to size, so need to divide! */ - if (bb->size[1] > 0.0f) - bb->offset[1] += (head - tail) / bb->size[1]; - } - else { - bb->size[1] = part->bb_size[1] * pa_size; - } - bb->tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); - bb->time = ct; - } - - pixsize = ED_view3d_pixel_size(rv3d, state->co) * pixsize_scale; - - draw_particle(state, draw_as, part->draw, pixsize, imat, part->draw_line, bb, pdd, pos); -} -/* unified drawing of all new particle systems draw types except dupli ob & group - * mostly tries to use vertex arrays for speed - * - * 1. check that everything is ok & updated - * 2. start initializing things - * 3. initialize according to draw type - * 4. allocate drawing data arrays - * 5. start filling the arrays - * 6. draw the arrays - * 7. clean up - */ -static void draw_new_particle_system( - Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, - Base *base, ParticleSystem *psys, - const char ob_dt, const short dflag) -{ - Object *ob = base->object; - ParticleEditSettings *pset = PE_settings(scene); - ParticleSettings *part = psys->part; - ParticleData *pars = psys->particles; - ParticleData *pa; - ParticleKey state, *states = NULL; - ParticleBillboardData bb; - ParticleSimulationData sim = {NULL}; - ParticleDrawData *pdd = psys->pdd; - Material *ma; - float vel[3], imat[4][4]; - float timestep, pixsize_scale = 1.0f, pa_size, r_tilt, r_length; - float pa_time, pa_birthtime, pa_dietime, pa_health, intensity; - float cfra; - float ma_col[3] = {0.0f, 0.0f, 0.0f}; - int a, totpart, totpoint = 0, totve = 0, drawn, draw_as, totchild = 0; - bool select = (base->flag & BASE_SELECTED) != 0, create_cdata = false, need_v = false; - GLint polygonmode[2]; - char numstr[32]; - unsigned char tcol[4] = {0, 0, 0, 255}; - unsigned int pos; - -/* 1. */ - if (part == NULL || !psys_check_enabled(ob, psys, G.is_rendering)) - return; - - if (pars == NULL) return; - - /* don't draw normal paths in edit mode */ - if (psys_in_edit_mode(depsgraph, psys) && (pset->flag & PE_DRAW_PART) == 0) - return; - - if (part->draw_as == PART_DRAW_REND) - draw_as = part->ren_as; - else - draw_as = part->draw_as; - - if (draw_as == PART_DRAW_NOT) - return; - - /* prepare curvemapping tables */ - if ((psys->part->child_flag & PART_CHILD_USE_CLUMP_CURVE) && psys->part->clumpcurve) - curvemapping_changed_all(psys->part->clumpcurve); - if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve) - curvemapping_changed_all(psys->part->roughcurve); - if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve) - curvemapping_changed_all(psys->part->twistcurve); - -/* 2. */ - sim.depsgraph = depsgraph; - sim.scene = scene; - sim.ob = ob; - sim.psys = psys; - sim.psmd = psys_get_modifier(ob, psys); - - if (part->phystype == PART_PHYS_KEYED) { - if (psys->flag & PSYS_KEYED) { - psys_count_keyed_targets(&sim); - if (psys->totkeyed == 0) - return; - } - } - - if (select) { - select = false; - if (psys_get_current(ob) == psys) - select = true; - } - - psys->flag |= PSYS_DRAWING; - - if (part->type == PART_HAIR && !psys->childcache) - totchild = 0; - else - totchild = psys->totchild * part->disp / 100; - - ma = give_current_material(ob, part->omat); - - if (v3d->zbuf) glDepthMask(1); - - if ((ma) && (part->draw_col == PART_DRAW_COL_MAT)) { - rgb_float_to_uchar(tcol, &(ma->r)); - copy_v3_v3(ma_col, &ma->r); - } - - timestep = psys_get_timestep(&sim); - - if ((ob->flag & OB_FROMGROUP) != 0) { - float mat[4][4]; - mul_m4_m4m4(mat, ob->obmat, psys->imat); - gpuMultMatrix(mat); - } - - /* needed for text display */ - invert_m4_m4(ob->imat, ob->obmat); - - totpart = psys->totpart; - - cfra = BKE_scene_frame_get(scene); - - if (draw_as == PART_DRAW_PATH && psys->pathcache == NULL && psys->childcache == NULL) - draw_as = PART_DRAW_DOT; - -/* 3. */ - glLineWidth(1.0f); - - switch (draw_as) { - case PART_DRAW_DOT: - if (part->draw_size) - glPointSize(part->draw_size); - else - glPointSize(2.0); /* default dot size */ - break; - case PART_DRAW_CIRC: - /* calculate view aligned matrix: */ - copy_m4_m4(imat, rv3d->viewinv); - normalize_v3(imat[0]); - normalize_v3(imat[1]); - ATTR_FALLTHROUGH; - case PART_DRAW_CROSS: - case PART_DRAW_AXIS: - /* lets calculate the scale: */ - - if (part->draw_size == 0.0) - pixsize_scale = 2.0f; - else - pixsize_scale = part->draw_size; - - if (draw_as == PART_DRAW_AXIS) - create_cdata = 1; - break; - case PART_DRAW_OB: - if (part->dup_ob == NULL) - draw_as = PART_DRAW_DOT; - else - draw_as = 0; - break; - case PART_DRAW_GR: - if (part->dup_group == NULL) - draw_as = PART_DRAW_DOT; - else - draw_as = 0; - break; - case PART_DRAW_BB: - if (v3d->camera == NULL && part->bb_ob == NULL) { - printf("Billboards need an active camera or a target object!\n"); - - draw_as = part->draw_as = PART_DRAW_DOT; - - if (part->draw_size) - glPointSize(part->draw_size); - else - glPointSize(2.0); /* default dot size */ - } - else if (part->bb_ob) - bb.ob = part->bb_ob; - else - bb.ob = v3d->camera; - - bb.align = part->bb_align; - bb.anim = part->bb_anim; - bb.lock = part->draw & PART_DRAW_BB_LOCK; - break; - case PART_DRAW_PATH: - break; - case PART_DRAW_LINE: - need_v = 1; - break; - } - if (part->draw & PART_DRAW_SIZE && part->draw_as != PART_DRAW_CIRC) { - copy_m4_m4(imat, rv3d->viewinv); - normalize_v3(imat[0]); - normalize_v3(imat[1]); - } - - if (ELEM(draw_as, PART_DRAW_DOT, PART_DRAW_CROSS, PART_DRAW_LINE) && - (part->draw_col > PART_DRAW_COL_MAT)) - { - create_cdata = 1; - } - - if (!create_cdata && pdd && pdd->cdata) { - MEM_freeN(pdd->cdata); - pdd->cdata = pdd->cd = NULL; - } - -/* 4. */ - if (draw_as && ELEM(draw_as, PART_DRAW_PATH, PART_DRAW_CIRC) == 0) { - int partsize = 3 * sizeof(float); - int create_ndata = 0; - - if (!pdd) - pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticleDrawData"); - - if (part->draw_as == PART_DRAW_REND && part->trail_count > 1) { - partsize *= part->trail_count; - psys_make_temp_pointcache(ob, psys); - } - - switch (draw_as) { - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - partsize *= 6; - if (draw_as != PART_DRAW_CROSS) - create_cdata = 1; - break; - case PART_DRAW_LINE: - partsize *= 2; - break; - case PART_DRAW_BB: - partsize *= 6; /* New OGL only understands tris, no choice here. */ - create_ndata = 1; - break; - } - - if (pdd->totpart != totpart + totchild || pdd->partsize != partsize) - psys_free_pdd(psys); - - if (!pdd->vdata) - pdd->vdata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_vdata"); - if (create_cdata && !pdd->cdata) - pdd->cdata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_cdata"); - if (create_ndata && !pdd->ndata) - pdd->ndata = MEM_calloc_arrayN(totpart + totchild, partsize, "particle_ndata"); - - if (part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) { - if (!pdd->vedata) - pdd->vedata = MEM_calloc_arrayN(totpart + totchild, 2 * 3 * sizeof(float), "particle_vedata"); - - need_v = 1; - } - else if (pdd->vedata) { - /* velocity data not needed, so free it */ - MEM_freeN(pdd->vedata); - pdd->vedata = NULL; - } - - pdd->vd = pdd->vdata; - pdd->ved = pdd->vedata; - pdd->cd = pdd->cdata; - pdd->nd = pdd->ndata; - pdd->totpart = totpart + totchild; - pdd->partsize = partsize; - } - else if (psys->pdd) { - psys_free_pdd(psys); - MEM_freeN(psys->pdd); - pdd = psys->pdd = NULL; - } - - if (pdd) { - pdd->ma_col = ma_col; - } - - psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); - - /* circles don't use drawdata, so have to add a special case here */ - if ((pdd || draw_as == PART_DRAW_CIRC) && draw_as != PART_DRAW_PATH) { - /* 5. */ - if (pdd && (pdd->flag & PARTICLE_DRAW_DATA_UPDATED) && - (pdd->vedata || part->draw & (PART_DRAW_SIZE | PART_DRAW_NUM | PART_DRAW_HEALTH)) == 0) - { - totpoint = pdd->totpoint; /* draw data is up to date */ - } - else { - if ((draw_as == PART_DRAW_CIRC) || (part->draw & PART_DRAW_SIZE)) { - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - imm_cpack(0xFFFFFF); - } - for (a = 0, pa = pars; a < totpart + totchild; a++, pa++) { - /* setup per particle individual stuff */ - if (a < totpart) { - if (totchild && (part->draw & PART_DRAW_PARENT) == 0) continue; - if (pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue; - - pa_time = (cfra - pa->time) / pa->lifetime; - pa_birthtime = pa->time; - pa_dietime = pa->dietime; - pa_size = pa->size; - if (part->phystype == PART_PHYS_BOIDS) - pa_health = pa->boid->data.health; - else - pa_health = -1.0; - - r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f); - r_length = psys_frand(psys, a + 22); - - if (part->draw_col > PART_DRAW_COL_MAT) { - switch (part->draw_col) { - case PART_DRAW_COL_VEL: - intensity = len_v3(pa->state.vel) / part->color_vec_max; - break; - case PART_DRAW_COL_ACC: - intensity = len_v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * part->color_vec_max); - break; - default: - intensity = 1.0f; /* should never happen */ - BLI_assert(0); - break; - } - CLAMP(intensity, 0.0f, 1.0f); - weight_to_rgb(ma_col, intensity); - } - } - else { - ChildParticle *cpa = &psys->child[a - totpart]; - - pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime); - pa_size = psys_get_child_size(psys, cpa, cfra, NULL); - - pa_health = -1.0; - - r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f); - r_length = psys_frand(psys, a + 22); - } - - drawn = 0; - if (part->draw_as == PART_DRAW_REND && part->trail_count > 1) { - float length = part->path_end * (1.0f - part->randlength * r_length); - int trail_count = part->trail_count * (1.0f - part->randlength * r_length); - float ct = ((part->draw & PART_ABS_PATH_TIME) ? cfra : pa_time) - length; - float dt = length / (trail_count ? (float)trail_count : 1.0f); - int i = 0; - - ct += dt; - for (i = 0; i < trail_count; i++, ct += dt) { - - if (part->draw & PART_ABS_PATH_TIME) { - if (ct < pa_birthtime || ct > pa_dietime) - continue; - } - else if (ct < 0.0f || ct > 1.0f) - continue; - - state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime)); - psys_get_particle_on_path(&sim, a, &state, need_v); - - draw_particle_data(psys, rv3d, - &state, draw_as, imat, &bb, psys->pdd, - ct, pa_size, r_tilt, pixsize_scale, pos); - - totpoint++; - drawn = 1; - } - } - else { - state.time = cfra; - if (psys_get_particle_state(&sim, a, &state, 0)) { - - draw_particle_data(psys, rv3d, - &state, draw_as, imat, &bb, psys->pdd, - pa_time, pa_size, r_tilt, pixsize_scale, pos); - - totpoint++; - drawn = 1; - } - } - - if (drawn) { - /* additional things to draw for each particle - * (velocity, size and number) */ - if ((part->draw & PART_DRAW_VEL) && pdd && pdd->vedata) { - copy_v3_v3(pdd->ved, state.co); - pdd->ved += 3; - mul_v3_v3fl(vel, state.vel, timestep); - add_v3_v3v3(pdd->ved, state.co, vel); - pdd->ved += 3; - - totve++; - } - - if (part->draw & PART_DRAW_SIZE) { - setlinestyle(3); - imm_drawcircball(state.co, pa_size, imat, pos); - setlinestyle(0); - } - - - if ((part->draw & PART_DRAW_NUM || part->draw & PART_DRAW_HEALTH) && - (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) - { - size_t numstr_len; - float vec_txt[3]; - char *val_pos = numstr; - numstr[0] = '\0'; - - if (part->draw & PART_DRAW_NUM) { - if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { - numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health); - } - else { - numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%d", a); - } - } - else { - if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { - numstr_len = BLI_snprintf_rlen(val_pos, sizeof(numstr), "%.2f", pa_health); - } - } - - if (numstr[0]) { - /* in path drawing state.co is the end point - * use worldspace because object matrix is already applied */ - mul_v3_m4v3(vec_txt, ob->imat, state.co); - view3d_cached_text_draw_add(vec_txt, numstr, numstr_len, - 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol); - } - } - } - } - if ((draw_as == PART_DRAW_CIRC) || (part->draw & PART_DRAW_SIZE)) { - immUnbindProgram(); - } - } - } -/* 6. */ - - glGetIntegerv(GL_POLYGON_MODE, polygonmode); - - if (draw_as == PART_DRAW_PATH) { - ParticleCacheKey **cache, *path; - float *cdata2 = NULL; - - if (totchild && (part->draw & PART_DRAW_PARENT) == 0) - totpart = 0; - else if (psys->pathcache == NULL) - totpart = 0; - - /* draw actual/parent particles */ - cache = psys->pathcache; - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - path = cache[a]; - if (path->segments > 0) { - if (((dflag & DRAW_CONSTCOLOR) == 0) && (part->draw_col == PART_DRAW_COL_MAT)) { - draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, path->col, sizeof(ParticleCacheKey), path->segments + 1, NULL); - } - else { - float color[4]; - rgba_uchar_to_float(color, tcol); - draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, NULL, sizeof(ParticleCacheKey), path->segments + 1, color); - } - } - } - - if (part->type == PART_HAIR) { - if (part->draw & PART_DRAW_GUIDE_HAIRS) { - DerivedMesh *hair_dm = psys->hair_out_dm; - - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - if (pa->totkey > 1) { - HairKey *hkey = pa->hair; - - /* XXX use proper theme color here */ - float color[4] = {0.58f, 0.67f, 1.0f, 1.0f}; - draw_vertex_array(GWN_PRIM_LINE_STRIP, hkey->world_co, NULL, NULL, sizeof(HairKey), pa->totkey, color); - } - } - - if (hair_dm) { - MVert *mvert = hair_dm->getVertArray(hair_dm); - int i; - - unsigned int pos_id = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3f(0.9f, 0.4f, 0.4f); - - unsigned int count = 0; - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - count += MAX2(pa->totkey - 1, 0); - } - - if (count > 0) { - immBegin(GWN_PRIM_LINES, count * 2); - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - for (i = 1; i < pa->totkey; ++i) { - float v1[3], v2[3]; - - copy_v3_v3(v1, mvert[pa->hair_index + i - 1].co); - copy_v3_v3(v2, mvert[pa->hair_index + i].co); - - mul_m4_v3(ob->obmat, v1); - mul_m4_v3(ob->obmat, v2); - - immVertex3fv(pos_id, v1); - immVertex3fv(pos_id, v2); - } - } - immEnd(); - } - - immUnbindProgram(); - } - } - - if (part->draw & PART_DRAW_HAIR_GRID) { - ClothModifierData *clmd = psys->clmd; - if (clmd) { - float *gmin = clmd->hair_grid_min; - float *gmax = clmd->hair_grid_max; - int *res = clmd->hair_grid_res; - int i; - - unsigned int pos_id = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (select) - immUniformThemeColor(TH_ACTIVE); - else - immUniformThemeColor(TH_WIRE); - - immBegin(GWN_PRIM_LINES, 24); - immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); - immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); - immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); - immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); - - immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]); - immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]); - immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]); - immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]); - - immVertex3f(pos_id, gmin[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmin[1], gmax[2]); - immVertex3f(pos_id, gmax[0], gmin[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmin[1], gmax[2]); - immVertex3f(pos_id, gmin[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmin[0], gmax[1], gmax[2]); - immVertex3f(pos_id, gmax[0], gmax[1], gmin[2]); immVertex3f(pos_id, gmax[0], gmax[1], gmax[2]); - immEnd(); - - if (select) - immUniformThemeColorShadeAlpha(TH_ACTIVE, 0, -100); - else - immUniformThemeColorShadeAlpha(TH_WIRE, 0, -100); - - int count = 0; - count += MAX2(0, res[0] - 2) * 8; - count += MAX2(0, res[1] - 2) * 8; - count += MAX2(0, res[2] - 2) * 8; - - if (count >= 2) { - glEnable(GL_BLEND); - immBegin(GWN_PRIM_LINES, count); - for (i = 1; i < res[0] - 1; ++i) { - float f = interpf(gmax[0], gmin[0], (float)i / (float)(res[0] - 1)); - immVertex3f(pos_id, f, gmin[1], gmin[2]); immVertex3f(pos_id, f, gmax[1], gmin[2]); - immVertex3f(pos_id, f, gmax[1], gmin[2]); immVertex3f(pos_id, f, gmax[1], gmax[2]); - immVertex3f(pos_id, f, gmax[1], gmax[2]); immVertex3f(pos_id, f, gmin[1], gmax[2]); - immVertex3f(pos_id, f, gmin[1], gmax[2]); immVertex3f(pos_id, f, gmin[1], gmin[2]); - } - for (i = 1; i < res[1] - 1; ++i) { - float f = interpf(gmax[1], gmin[1], (float)i / (float)(res[1] - 1)); - immVertex3f(pos_id, gmin[0], f, gmin[2]); immVertex3f(pos_id, gmax[0], f, gmin[2]); - immVertex3f(pos_id, gmax[0], f, gmin[2]); immVertex3f(pos_id, gmax[0], f, gmax[2]); - immVertex3f(pos_id, gmax[0], f, gmax[2]); immVertex3f(pos_id, gmin[0], f, gmax[2]); - immVertex3f(pos_id, gmin[0], f, gmax[2]); immVertex3f(pos_id, gmin[0], f, gmin[2]); - } - for (i = 1; i < res[2] - 1; ++i) { - float f = interpf(gmax[2], gmin[2], (float)i / (float)(res[2] - 1)); - immVertex3f(pos_id, gmin[0], gmin[1], f); immVertex3f(pos_id, gmax[0], gmin[1], f); - immVertex3f(pos_id, gmax[0], gmin[1], f); immVertex3f(pos_id, gmax[0], gmax[1], f); - immVertex3f(pos_id, gmax[0], gmax[1], f); immVertex3f(pos_id, gmin[0], gmax[1], f); - immVertex3f(pos_id, gmin[0], gmax[1], f); immVertex3f(pos_id, gmin[0], gmin[1], f); - } - immEnd(); - glDisable(GL_BLEND); - } - - immUnbindProgram(); - } - } - } - - /* draw child particles */ - cache = psys->childcache; - for (a = 0; a < totchild; a++) { - path = cache[a]; - - if (((dflag & DRAW_CONSTCOLOR) == 0) && (part->draw_col == PART_DRAW_COL_MAT)) { - draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, path->col, sizeof(ParticleCacheKey), path->segments + 1, NULL); - } - else { - float color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - draw_vertex_array(GWN_PRIM_LINE_STRIP, path->co, path->vel, NULL, sizeof(ParticleCacheKey), path->segments + 1, color); - } - } - - /* restore & clean up */ - if (cdata2) { - MEM_freeN(cdata2); - cdata2 = NULL; - } - - if ((part->draw & PART_DRAW_NUM) && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - cache = psys->pathcache; - - for (a = 0, pa = psys->particles; a < totpart; a++, pa++) { - float vec_txt[3]; - size_t numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%i", a); - /* use worldspace because object matrix is already applied */ - mul_v3_m4v3(vec_txt, ob->imat, cache[a]->co); - view3d_cached_text_draw_add(vec_txt, numstr, numstr_len, - 10, V3D_CACHE_TEXT_WORLDSPACE | V3D_CACHE_TEXT_ASCII, tcol); - } - } - } - else if (pdd && ELEM(draw_as, 0, PART_DRAW_CIRC) == 0) { - - if (pdd->vdata) { - if (select) { - float color[4]; - UI_GetThemeColor4fv(TH_ACTIVE, color); - - if (part->draw_size) - glPointSize(part->draw_size + 2); - else - glPointSize(4.0); - - glLineWidth(3.0); - - draw_particle_arrays_new(draw_as, ob_dt, 1, pdd->vdata, NULL, NULL, totpoint, color); - } - - glPointSize(part->draw_size ? part->draw_size : 2.0); - glLineWidth(1.0); - - -#if 0 - /* enable other data arrays */ - /* billboards are drawn this way */ - if (pdd->ndata && ob_dt > OB_WIRE) { - GPU_basic_shader_colors(NULL, NULL, 0.0f, 1.0f); - GPU_basic_shader_bind(GPU_SHADER_LIGHTING | GPU_SHADER_USE_COLOR); - } - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if (pdd->cdata) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, pdd->cdata); - } - } -#endif - - draw_particle_arrays_new(draw_as, ob_dt, 0, pdd->vdata, pdd->ndata, pdd->cdata, totpoint, NULL); - } - - - pdd->flag |= PARTICLE_DRAW_DATA_UPDATED; - pdd->totpoint = totpoint; - } - - if (pdd && pdd->vedata) { - float color[4] = {0.75f, 0.75f, 0.75f, 1.0f}; - draw_vertex_array(GWN_PRIM_LINES, pdd->vedata, NULL, NULL, 0, 2 * totve, color); - } - - glPolygonMode(GL_FRONT, polygonmode[0]); - glPolygonMode(GL_BACK, polygonmode[1]); - -/* 7. */ - - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - - if (states) - MEM_freeN(states); - - psys->flag &= ~PSYS_DRAWING; - - /* draw data can't be saved for billboards as they must update to target changes */ - if (draw_as == PART_DRAW_BB) { - psys_free_pdd(psys); - pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED; - } - - if (psys->lattice_deform_data) { - end_latt_deform(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; - } - - if (pdd) { - /* drop references to stack memory */ - pdd->ma_col = NULL; - } - - if ((ob->flag & OB_FROMGROUP) != 0) { - gpuLoadMatrix(rv3d->viewmat); - } -} - -static void draw_update_ptcache_edit( - Depsgraph *depsgraph, Scene *scene, Object *ob, PTCacheEdit *edit) -{ - if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) - PE_update_object(depsgraph, scene, ob, 0); - - /* create path and child path cache if it doesn't exist already */ - if (edit->pathcache == NULL) { - psys_cache_edit_paths(depsgraph, scene, ob, edit, CFRA, G.is_rendering); - } -} - -static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit) -{ - ParticleEditSettings *pset = PE_settings(scene); - const int totpoint = edit->totpoint; - const bool timed = (pset->flag & PE_FADE_TIME) ? pset->fade_frames : false; - - if (edit->pathcache == NULL) - return; - - PE_hide_keys_time(scene, edit, CFRA); - - /* opengl setup */ - if ((v3d->flag & V3D_ZBUF_SELECT) == 0) - glDisable(GL_DEPTH_TEST); - - /* get selection theme colors */ - float sel_col[3], nosel_col[3]; - UI_GetThemeColor3fv(TH_VERTEX_SELECT, sel_col); - UI_GetThemeColor3fv(TH_VERTEX, nosel_col); - - /* draw paths */ - const int totkeys = (*edit->pathcache)->segments + 1; - - glEnable(GL_BLEND); - float *pathcol = MEM_calloc_arrayN(totkeys, 4 * sizeof(float), "particle path color data"); - - if (pset->brushtype == PE_BRUSH_WEIGHT) - glLineWidth(2.0f); - - ParticleCacheKey **cache = edit->pathcache; - PTCacheEditPoint *point; - int i; - - for (i = 0, point = edit->points; i < totpoint; i++, point++) { - ParticleCacheKey *path = cache[i]; - - Gwn_VertFormat format = {0}; - unsigned int pos_id, col_id, col_comp; - - col_comp = ((point->flag & PEP_HIDE) || timed) ? 4 : 3; - - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - col_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, col_comp, GWN_FETCH_FLOAT); - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, path->segments + 1); - - GWN_vertbuf_attr_fill_stride(vbo, pos_id, sizeof(ParticleCacheKey), path->co); - - float *pcol = pathcol; - - if (point->flag & PEP_HIDE) { - for (int k = 0; k < totkeys; k++, pcol += 4) { - copy_v3_v3(pcol, path->col); - pcol[3] = 0.25f; - } - - GWN_vertbuf_attr_fill(vbo, col_id, pathcol); - } - else if (timed) { - ParticleCacheKey *pkey = path; - for (int k = 0; k < totkeys; k++, pkey++, pcol += 4) { - copy_v3_v3(pcol, pkey->col); - pcol[3] = 1.0f - fabsf((float)(CFRA) -pkey->time) / (float)pset->fade_frames; - } - - GWN_vertbuf_attr_fill(vbo, col_id, pathcol); - } - else { - /* FIXME: shader wants 4 color components but the cache only contains ParticleCacheKey - * So alpha is random */ - GWN_vertbuf_attr_fill_stride(vbo, col_id, sizeof(ParticleCacheKey), path->col); - } - - Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR); - GWN_batch_draw(batch); - GWN_batch_discard(batch); - } - - if (pathcol) { MEM_freeN(pathcol); pathcol = NULL; } - - /* draw edit vertices */ - if (pset->selectmode != SCE_SELECT_PATH) { - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - if (pset->selectmode == SCE_SELECT_POINT) { - float *pd = NULL, *pdata = NULL; - float *cd = NULL, *cdata = NULL; - int totkeys_visible = 0; - - Gwn_VertFormat format = {0}; - unsigned int pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int col_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, (timed ? 4 : 3), GWN_FETCH_FLOAT); - - for (i = 0, point = edit->points; i < totpoint; i++, point++) - if (!(point->flag & PEP_HIDE)) - totkeys_visible += point->totkey; - - if (totkeys_visible) { - if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO)) - pd = pdata = MEM_calloc_arrayN(totkeys_visible, 3 * sizeof(float), "particle edit point data"); - cd = cdata = MEM_calloc_arrayN(totkeys_visible, (timed ? 4 : 3) * sizeof(float), "particle edit color data"); - } - - for (i = 0, point = edit->points; i < totpoint; i++, point++) { - if (point->flag & PEP_HIDE) - continue; - - PTCacheEditKey *key = point->keys; - for (int k = 0; k < point->totkey; k++, key++) { - if (pd) { - copy_v3_v3(pd, key->co); - pd += 3; - } - - if (key->flag & PEK_SELECT) { - copy_v3_v3(cd, sel_col); - } - else { - copy_v3_v3(cd, nosel_col); - } - - if (timed) - *(cd + 3) = 1.0f - fabsf((float)CFRA - *key->time) / (float)pset->fade_frames; - - cd += (timed ? 4 : 3); - } - } - cd = cdata; - pd = pdata; - for (i = 0, point = edit->points; i < totpoint; i++, point++) { - if (point->flag & PEP_HIDE || point->totkey == 0) - continue; - - Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(vbo, point->totkey); - - if (point->keys->flag & PEK_USE_WCO) - GWN_vertbuf_attr_fill_stride(vbo, pos_id, sizeof(PTCacheEditKey), point->keys->world_co); - else - GWN_vertbuf_attr_fill(vbo, pos_id, pd); - - GWN_vertbuf_attr_fill(vbo, col_id, cd); - - Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO); - GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR); - GWN_batch_draw(batch); - GWN_batch_discard(batch); - - pd += pd ? 3 * point->totkey : 0; - cd += (timed ? 4 : 3) * point->totkey; - } - if (pdata) { MEM_freeN(pdata); pd = pdata = NULL; } - if (cdata) { MEM_freeN(cdata); cd = cdata = NULL; } - } - else if (pset->selectmode == SCE_SELECT_END) { - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos_id = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int col_id = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - immBeginAtMost(GWN_PRIM_POINTS, totpoint); - for (i = 0, point = edit->points; i < totpoint; i++, point++) { - if ((point->flag & PEP_HIDE) == 0 && point->totkey) { - PTCacheEditKey *key = point->keys + point->totkey - 1; - if ((key->flag & PEK_SELECT) != 0) { - immAttrib3fv(col_id, sel_col); - } - else { - immAttrib3fv(col_id, nosel_col); - } - /* has to be like this.. otherwise selection won't work, have try glArrayElement later..*/ - immVertex3fv(pos_id, (key->flag & PEK_USE_WCO) ? key->world_co : key->co); - } - } - immEnd(); - immUnbindProgram(); - } - } - - glDisable(GL_BLEND); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); -} - -static void ob_draw_RE_motion(float com[3], float rotscale[3][3], float itw, float ith, float drw_size) -{ - float tr[3][3]; - float root[3], tip[3]; - /* take a copy for not spoiling original */ - copy_m3_m3(tr, rotscale); - float tw = itw * drw_size; - float th = ith * drw_size; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 4, GWN_FETCH_INT_TO_FLOAT_UNIT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - immBegin(GWN_PRIM_LINES, 30); - - immAttrib4ub(col, 0x7F, 0x00, 0x00, 155); - root[1] = root[2] = 0.0f; - root[0] = -drw_size; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - tip[1] = tip[2] = 0.0f; - tip[0] = drw_size; - mul_m3_v3(tr, tip); - add_v3_v3(tip, com); - immVertex3fv(pos, tip); - - root[1] = 0.0f; root[2] = tw; - root[0] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[1] = 0.0f; root[2] = -tw; - root[0] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[1] = tw; root[2] = 0.0f; - root[0] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[1] = -tw; root[2] = 0.0f; - root[0] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - immAttrib4ub(col, 0x00, 0x7F, 0x00, 155); - - root[0] = root[2] = 0.0f; - root[1] = -drw_size; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - tip[0] = tip[2] = 0.0f; - tip[1] = drw_size; - mul_m3_v3(tr, tip); - add_v3_v3(tip, com); - immVertex3fv(pos, tip); - - root[0] = 0.0f; root[2] = tw; - root[1] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = 0.0f; root[2] = -tw; - root[1] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = tw; root[2] = 0.0f; - root[1] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = -tw; root[2] = 0.0f; - root[1] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - immAttrib4ub(col, 0x00, 0x00, 0x7F, 155); - root[0] = root[1] = 0.0f; - root[2] = -drw_size; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - tip[0] = tip[1] = 0.0f; - tip[2] = drw_size; - mul_m3_v3(tr, tip); - add_v3_v3(tip, com); - immVertex3fv(pos, tip); - - root[0] = 0.0f; root[1] = tw; - root[2] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = 0.0f; root[1] = -tw; - root[2] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = tw; root[1] = 0.0f; - root[2] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - root[0] = -tw; root[1] = 0.0f; - root[2] = th; - mul_m3_v3(tr, root); - add_v3_v3(root, com); - immVertex3fv(pos, root); - immVertex3fv(pos, tip); - - immEnd(); - - immUnbindProgram(); -} - -/* place to add drawers */ - -static void drawhandlesN(Nurb *nu, const char sel, const bool hide_handles) -{ - if (nu->hide || hide_handles) return; - - if (nu->type == CU_BEZIER && nu->pntsu > 0) { - - const float *fp; - -#define TH_HANDLE_COL_TOT ((TH_HANDLE_SEL_FREE - TH_HANDLE_FREE) + 1) - /* use MIN2 when indexing to ensure newer files don't read outside the array */ - unsigned char handle_cols[TH_HANDLE_COL_TOT][3]; - const int basecol = sel ? TH_HANDLE_SEL_FREE : TH_HANDLE_FREE; - - for (int a = 0; a < TH_HANDLE_COL_TOT; a++) { - UI_GetThemeColor3ubv(basecol + a, handle_cols[a]); - } - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - glLineWidth(1.0f); - - immBeginAtMost(GWN_PRIM_LINES, nu->pntsu * 4); - - BezTriple *bezt = nu->bezt; - int a = nu->pntsu; - while (a--) { - if (bezt->hide == 0) { - if ((bezt->f2 & SELECT) == sel) { - fp = bezt->vec[0]; - - immAttrib3ubv(col, handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]); - immVertex3fv(pos, fp); - immVertex3fv(pos, fp + 3); - - immAttrib3ubv(col, handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]); - immVertex3fv(pos, fp + 3); - immVertex3fv(pos, fp + 6); - } - else if ((bezt->f1 & SELECT) == sel) { - fp = bezt->vec[0]; - - immAttrib3ubv(col, handle_cols[MIN2(bezt->h1, TH_HANDLE_COL_TOT - 1)]); - immVertex3fv(pos, fp); - immVertex3fv(pos, fp + 3); - } - else if ((bezt->f3 & SELECT) == sel) { - fp = bezt->vec[1]; - - immAttrib3ubv(col, handle_cols[MIN2(bezt->h2, TH_HANDLE_COL_TOT - 1)]); - immVertex3fv(pos, fp); - immVertex3fv(pos, fp + 3); - } - } - bezt++; - } - - immEnd(); - - immUnbindProgram(); - -#undef TH_HANDLE_COL_TOT - - } -} - -static void drawhandlesN_active(Nurb *nu) -{ - if (nu->hide) return; - - if (nu->type == CU_BEZIER && nu->pntsu > 0) { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_ACTIVE_SPLINE); - glLineWidth(2.0f); - - immBeginAtMost(GWN_PRIM_LINES, nu->pntsu * 4); - BezTriple *bezt = nu->bezt; - int a = nu->pntsu; - while (a--) { - if (bezt->hide == 0) { - const float *fp = bezt->vec[0]; - - immVertex3fv(pos, fp); - immVertex3fv(pos, fp + 3); - - immVertex3fv(pos, fp + 3); - immVertex3fv(pos, fp + 6); - } - bezt++; - } - immEnd(); - immUnbindProgram(); - } -} - -static void drawvertsN(const Nurb *nurb, const bool hide_handles, const void *vert) -{ - const Nurb *nu; - - // just quick guesstimate of how many verts to draw - int count = 0; - for (nu = nurb; nu; nu = nu->next) { - if (!nu->hide) { - if (nu->type == CU_BEZIER) { - count += nu->pntsu * 3; - } - else { - count += nu->pntsu * nu->pntsv; - } - } - } - if (count == 0) return; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - unsigned char vert_color[3]; - unsigned char vert_color_select[3]; - unsigned char vert_color_active[3]; - UI_GetThemeColor3ubv(TH_VERTEX, vert_color); - UI_GetThemeColor3ubv(TH_VERTEX_SELECT, vert_color_select); - UI_GetThemeColor3ubv(TH_ACTIVE_VERT, vert_color_active); - - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - - immBeginAtMost(GWN_PRIM_POINTS, count); - - for (nu = nurb; nu; nu = nu->next) { - - if (nu->hide) continue; - - if (nu->type == CU_BEZIER) { - - const BezTriple *bezt = nu->bezt; - int a = nu->pntsu; - while (a--) { - if (bezt->hide == 0) { - if (bezt == vert) { - immAttrib3ubv(color, bezt->f2 & SELECT ? vert_color_active : vert_color); - immVertex3fv(pos, bezt->vec[1]); - if (!hide_handles) { - immAttrib3ubv(color, bezt->f1 & SELECT ? vert_color_active : vert_color); - immVertex3fv(pos, bezt->vec[0]); - immAttrib3ubv(color, bezt->f3 & SELECT ? vert_color_active : vert_color); - immVertex3fv(pos, bezt->vec[2]); - } - } - else { - immAttrib3ubv(color, bezt->f2 & SELECT ? vert_color_select : vert_color); - immVertex3fv(pos, bezt->vec[1]); - if (!hide_handles) { - immAttrib3ubv(color, bezt->f1 & SELECT ? vert_color_select : vert_color); - immVertex3fv(pos, bezt->vec[0]); - immAttrib3ubv(color, bezt->f3 & SELECT ? vert_color_select : vert_color); - immVertex3fv(pos, bezt->vec[2]); - } - } - } - bezt++; - } - } - else { - const BPoint *bp = nu->bp; - int a = nu->pntsu * nu->pntsv; - while (a--) { - if (bp->hide == 0) { - if (bp == vert) { - immAttrib3ubv(color, vert_color_active); - } - else { - immAttrib3ubv(color, bp->f1 & SELECT ? vert_color_select : vert_color); - } - immVertex3fv(pos, bp->vec); - } - bp++; - } - } - } - - immEnd(); - immUnbindProgram(); -} - -static void editnurb_draw_active_poly(Nurb *nu) -{ - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_ACTIVE_SPLINE); - - glLineWidth(2.0f); - - BPoint *bp = nu->bp; - for (int b = 0; b < nu->pntsv; b++) { - if (nu->pntsu >= 2) { - if (nu->flagu & 1) immBegin(GWN_PRIM_LINE_LOOP, nu->pntsu); - else immBegin(GWN_PRIM_LINE_STRIP, nu->pntsu); - - for (int a = 0; a < nu->pntsu; a++, bp++) { - immVertex3fv(pos, bp->vec); - } - - immEnd(); - } - } - - immUnbindProgram(); -} - -static void editnurb_draw_active_nurbs(Nurb *nu) -{ - if (nu->pntsv > 0) { - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_ACTIVE_SPLINE); - - glLineWidth(2.0f); - // just quick guesstimate of how many verts to draw - int count = (nu->pntsu - 1) * nu->pntsv * 2; - if (nu->pntsv > 1) count += (nu->pntsv - 1) * nu->pntsu * 2; - if (count < 2) return; - - immBeginAtMost(GWN_PRIM_LINES, count); - BPoint *bp = nu->bp; - for (int b = 0; b < nu->pntsv; b++) { - BPoint *bp1 = bp; - bp++; - - for (int a = nu->pntsu - 1; a > 0; a--, bp++) { - if (bp->hide == 0 && bp1->hide == 0) { - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - bp1 = bp; - } - } - - if (nu->pntsv > 1) { /* surface */ - int ofs = nu->pntsu; - for (int b = 0; b < nu->pntsu; b++) { - BPoint *bp1 = nu->bp + b; - bp = bp1 + ofs; - for (int a = nu->pntsv - 1; a > 0; a--, bp += ofs) { - if (bp->hide == 0 && bp1->hide == 0) { - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - bp1 = bp; - } - } - } - - immEnd(); - - immUnbindProgram(); - } -} - -static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel) -{ - BPoint *bp, *bp1; - int a, b; - Curve *cu = ob->data; - Gwn_VertFormat *format; - unsigned int pos, col; - unsigned char color[3]; - - int index = 0; - Nurb *nu = nurb; - while (nu) { - if (nu->hide == 0) { - switch (nu->type) { - case CU_POLY: - { - if (!sel && index == cu->actnu) { - /* we should draw active spline highlight below everything */ - editnurb_draw_active_poly(nu); - } - - format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - glLineWidth(1.0f); - - immUniformThemeColor(TH_NURB_ULINE); - bp = nu->bp; - for (b = 0; b < nu->pntsv; b++) { - if (nu->pntsu >= 2) { - if (nu->flagu & 1) immBegin(GWN_PRIM_LINE_LOOP, nu->pntsu); - else immBegin(GWN_PRIM_LINE_STRIP, nu->pntsu); - - for (a = 0; a < nu->pntsu; a++, bp++) { - immVertex3fv(pos, bp->vec); - } - - immEnd(); - } - } - immUnbindProgram(); - break; - } - case CU_NURBS: - { - if (!sel && index == cu->actnu) { - /* we should draw active spline highlight below everything */ - editnurb_draw_active_nurbs(nu); - } - - format = immVertexFormat(); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - col = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - // just quick guesstimate of how many verts to draw - int count = (nu->pntsu - 1) * nu->pntsv * 2; - if (nu->pntsv > 1) count += (nu->pntsv - 1) * nu->pntsu * 2; - if (count < 2) return; - - glLineWidth(1.0f); - - immBeginAtMost(GWN_PRIM_LINES, count); - - bp = nu->bp; - for (b = 0; b < nu->pntsv; b++) { - bp1 = bp; - bp++; - for (a = nu->pntsu - 1; a > 0; a--, bp++) { - if (bp->hide == 0 && bp1->hide == 0) { - if (sel) { - if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { - UI_GetThemeColor3ubv(TH_NURB_SEL_ULINE, color); - immAttrib3ubv(col, color); - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - } - else { - if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { - /* pass */ - } - else { - UI_GetThemeColor3ubv(TH_NURB_ULINE, color); - immAttrib3ubv(col, color); - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - } - } - bp1 = bp; - } - } - - if (nu->pntsv > 1) { /* surface */ - int ofs = nu->pntsu; - for (b = 0; b < nu->pntsu; b++) { - bp1 = nu->bp + b; - bp = bp1 + ofs; - for (a = nu->pntsv - 1; a > 0; a--, bp += ofs) { - if (bp->hide == 0 && bp1->hide == 0) { - if (sel) { - if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { - UI_GetThemeColor3ubv(TH_NURB_SEL_VLINE, color); - immAttrib3ubv(col, color); - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - } - else { - if ((bp->f1 & SELECT) && (bp1->f1 & SELECT)) { - /* pass */ - } - else { - UI_GetThemeColor3ubv(TH_NURB_VLINE, color); - immAttrib3ubv(col, color); - immVertex3fv(pos, bp->vec); - immVertex3fv(pos, bp1->vec); - } - } - } - bp1 = bp; - } - } - } - immEnd(); - immUnbindProgram(); - break; - } - } - } - - index++; - nu = nu->next; - } -} - -static void draw_editnurb( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, - View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, - const char dt, const short dflag, const unsigned char UNUSED(ob_wire_col[4])) -{ - ToolSettings *ts = scene->toolsettings; - Object *ob = base->object; - Curve *cu = ob->data; - Nurb *nu; - const void *vert = BKE_curve_vert_active_get(cu); - const bool hide_handles = (cu->drawflag & CU_HIDE_HANDLES) != 0; - unsigned char wire_col[3]; - - /* DispList */ - UI_GetThemeColor3ubv(TH_WIRE_EDIT, wire_col); - - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, wire_col); - - /* for shadows only show solid faces */ - if (v3d->flag2 & V3D_RENDER_SHADOW) - return; - - if (v3d->zbuf) glDepthFunc(GL_ALWAYS); - - /* first non-selected and active handles */ - int index = 0; - for (nu = nurb; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - if (index == cu->actnu && !hide_handles) - drawhandlesN_active(nu); - drawhandlesN(nu, 0, hide_handles); - } - index++; - } - draw_editnurb_splines(ob, nurb, false); - draw_editnurb_splines(ob, nurb, true); - /* selected handles */ - for (nu = nurb; nu; nu = nu->next) { - if (nu->type == CU_BEZIER && (cu->drawflag & CU_HIDE_HANDLES) == 0) - drawhandlesN(nu, 1, hide_handles); - } - - if (v3d->zbuf) glDepthFunc(GL_LEQUAL); - - /* direction vectors for 3d curve paths - * when at its lowest, don't render normals */ - if ((cu->flag & CU_3D) && (ts->normalsize > 0.0015f) && (cu->drawflag & CU_HIDE_NORMALS) == 0) { - BevList *bl; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(TH_WIRE_EDIT); - - glLineWidth(1.0f); - - int count = 0; - int count_used = 0; - for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) { - int nr = bl->nr; - int skip = nu->resolu / 16; - -#if 0 - while (nr-- > 0) { /* accounts for empty bevel lists */ - count += 4; - nr -= skip; - } -#else - /* Same as loop above */ - count += 4 * ((nr / (skip + 1)) + ((nr % (skip + 1)) != 0)); -#endif - } - - if (count > 2) { - immBegin(GWN_PRIM_LINES, count); - for (bl = ob->curve_cache->bev.first, nu = nurb; nu && bl; bl = bl->next, nu = nu->next) { - BevPoint *bevp = bl->bevpoints; - int nr = bl->nr; - int skip = nu->resolu / 16; - - while (nr-- > 0) { /* accounts for empty bevel lists */ - const float fac = bevp->radius * ts->normalsize; - float vec_a[3]; /* Offset perpendicular to the curve */ - float vec_b[3]; /* Delta along the curve */ - - vec_a[0] = fac; - vec_a[1] = 0.0f; - vec_a[2] = 0.0f; - - mul_qt_v3(bevp->quat, vec_a); - madd_v3_v3fl(vec_a, bevp->dir, -fac); - - reflect_v3_v3v3(vec_b, vec_a, bevp->dir); - negate_v3(vec_b); - - add_v3_v3(vec_a, bevp->vec); - add_v3_v3(vec_b, bevp->vec); - - immVertex3fv(pos, vec_a); - immVertex3fv(pos, bevp->vec); - immVertex3fv(pos, bevp->vec); - immVertex3fv(pos, vec_b); - - bevp += skip + 1; - nr -= skip; - count_used += 4; - } - } - BLI_assert(count == count_used); - UNUSED_VARS_NDEBUG(count_used); - - immEnd(); - } - immUnbindProgram(); - } - - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - - drawvertsN(nurb, hide_handles, vert); - - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); -} - -static void draw_editfont_textcurs(RegionView3D *rv3d, float textcurs[4][2]) -{ - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - ED_view3d_polygon_offset(rv3d, -1.0); - set_inverted_drawing(1); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - imm_cpack(0); - immBegin(GWN_PRIM_TRI_FAN, 4); - immVertex2fv(pos, textcurs[0]); - immVertex2fv(pos, textcurs[1]); - immVertex2fv(pos, textcurs[2]); - immVertex2fv(pos, textcurs[3]); - immEnd(); - set_inverted_drawing(0); - ED_view3d_polygon_offset(rv3d, 0.0); - immUnbindProgram(); -} - -static void draw_editfont( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4]) -{ - Object *ob = base->object; - Curve *cu = ob->data; - EditFont *ef = cu->editfont; - float vec1[3], vec2[3]; - - draw_editfont_textcurs(rv3d, ef->textcurs); - - if (cu->flag & CU_FAST) { - imm_cpack(0xFFFFFF); - set_inverted_drawing(1); - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col); - set_inverted_drawing(0); - } - else { - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - - if (cu->linewidth != 0.0f) { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformThemeColor(TH_WIRE_EDIT); - copy_v3_v3(vec1, ob->orig); - copy_v3_v3(vec2, ob->orig); - vec1[0] += cu->linewidth; - vec2[0] += cu->linewidth; - vec1[1] += cu->linedist * cu->fsize; - vec2[1] -= cu->lines * cu->linedist * cu->fsize; - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex2fv(pos, vec1); - immVertex2fv(pos, vec2); - immEnd(); - setlinestyle(0); - immUnbindProgram(); - } - - setlinestyle(3); - for (int i = 0; i < cu->totbox; i++) { - if (cu->tb[i].w != 0.0f) { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformThemeColor(i == (cu->actbox - 1) ? TH_ACTIVE : TH_WIRE); - vec1[0] = cu->xof + cu->tb[i].x; - vec1[1] = cu->yof + cu->tb[i].y + cu->fsize; - vec1[2] = 0.001; - immBegin(GWN_PRIM_LINE_STRIP, 5); - immVertex3fv(pos, vec1); - vec1[0] += cu->tb[i].w; - immVertex3fv(pos, vec1); - vec1[1] -= cu->tb[i].h; - immVertex3fv(pos, vec1); - vec1[0] -= cu->tb[i].w; - immVertex3fv(pos, vec1); - vec1[1] += cu->tb[i].h; - immVertex3fv(pos, vec1); - immEnd(); - immUnbindProgram(); - } - } - setlinestyle(0); - - - if (ef->selboxes && ef->selboxes_len) { - float selboxw; - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - imm_cpack(0xffffff); - set_inverted_drawing(1); - for (int i = 0; i < ef->selboxes_len; i++) { - EditFontSelBox *sb = &ef->selboxes[i]; - float tvec[3]; - - if (i + 1 != ef->selboxes_len) { - if (ef->selboxes[i + 1].y == sb->y) - selboxw = ef->selboxes[i + 1].x - sb->x; - else - selboxw = sb->w; - } - else { - selboxw = sb->w; - } - - /* fill in xy below */ - tvec[2] = 0.001; - - immBegin(GWN_PRIM_TRI_FAN, 4); - - if (sb->rot == 0.0f) { - copy_v2_fl2(tvec, sb->x, sb->y); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, sb->x + selboxw, sb->y); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, sb->x + selboxw, sb->y + sb->h); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, sb->x, sb->y + sb->h); - immVertex3fv(pos, tvec); - } - else { - float mat[2][2]; - - angle_to_mat2(mat, sb->rot); - - copy_v2_fl2(tvec, sb->x, sb->y); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, selboxw, 0.0f); - mul_m2v2(mat, tvec); - add_v2_v2(tvec, &sb->x); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, selboxw, sb->h); - mul_m2v2(mat, tvec); - add_v2_v2(tvec, &sb->x); - immVertex3fv(pos, tvec); - - copy_v2_fl2(tvec, 0.0f, sb->h); - mul_m2v2(mat, tvec); - add_v2_v2(tvec, &sb->x); - immVertex3fv(pos, tvec); - } - - immEnd(); - } - set_inverted_drawing(0); - immUnbindProgram(); - } -} - -/* draw a sphere for use as an empty drawtype */ -static void draw_empty_sphere(float size, unsigned pos) -{ -#define NSEGMENTS 16 - /* a single ring of vertices */ - float p[NSEGMENTS][2]; - for (int i = 0; i < NSEGMENTS; ++i) { - float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS); - p[i][0] = size * cosf(angle); - p[i][1] = size * sinf(angle); - } - - immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS); - for (int i = 0; i < NSEGMENTS; ++i) - immVertex3f(pos, p[i][0], p[i][1], 0.0f); - immEnd(); - immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS); - for (int i = 0; i < NSEGMENTS; ++i) - immVertex3f(pos, p[i][0], 0.0f, p[i][1]); - immEnd(); - immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS); - for (int i = 0; i < NSEGMENTS; ++i) - immVertex3f(pos, 0.0f, p[i][0], p[i][1]); - immEnd(); -#undef NSEGMENTS -} - -/* draw a cone for use as an empty drawtype */ -static void draw_empty_cone(float size, unsigned pos) -{ -#define NSEGMENTS 8 - /* a single ring of vertices */ - float p[NSEGMENTS][2]; - for (int i = 0; i < NSEGMENTS; ++i) { - float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS); - p[i][0] = size * cosf(angle); - p[i][1] = size * sinf(angle); - } - - /* cone sides */ - immBegin(GWN_PRIM_LINES, NSEGMENTS * 2); - for (int i = 0; i < NSEGMENTS; ++i) { - immVertex3f(pos, 0.0f, 2.0f * size, 0.0f); - immVertex3f(pos, p[i][0], 0.0f, p[i][1]); - } - immEnd(); - - /* end ring */ - immBegin(GWN_PRIM_LINE_LOOP, NSEGMENTS); - for (int i = 0; i < NSEGMENTS; ++i) - immVertex3f(pos, p[i][0], 0.0f, p[i][1]); - immEnd(); -#undef NSEGMENTS -} - -static void drawspiral(unsigned int pos, const float cent[3], float rad, float tmat[4][4], int start) -{ - float vec[3], vx[3], vy[3]; - const float tot_inv = 1.0f / (float)CIRCLE_RESOL; - int a; - bool inverse = false; - float x, y, fac; - - if (start < 0) { - inverse = true; - start = -start; - } - - mul_v3_v3fl(vx, tmat[0], rad); - mul_v3_v3fl(vy, tmat[1], rad); - - immBegin(GWN_PRIM_LINE_STRIP, CIRCLE_RESOL + 1); - - if (inverse == 0) { - copy_v3_v3(vec, cent); - immVertex3fv(pos, vec); - - for (a = 0; a < CIRCLE_RESOL; a++) { - if (a + start >= CIRCLE_RESOL) - start = -a + 1; - - fac = (float)a * tot_inv; - x = sinval[a + start] * fac; - y = cosval[a + start] * fac; - - vec[0] = cent[0] + (x * vx[0] + y * vy[0]); - vec[1] = cent[1] + (x * vx[1] + y * vy[1]); - vec[2] = cent[2] + (x * vx[2] + y * vy[2]); - - immVertex3fv(pos, vec); - } - } - else { - fac = (float)(CIRCLE_RESOL - 1) * tot_inv; - x = sinval[start] * fac; - y = cosval[start] * fac; - - vec[0] = cent[0] + (x * vx[0] + y * vy[0]); - vec[1] = cent[1] + (x * vx[1] + y * vy[1]); - vec[2] = cent[2] + (x * vx[2] + y * vy[2]); - - immVertex3fv(pos, vec); - - for (a = 0; a < CIRCLE_RESOL; a++) { - if (a + start >= CIRCLE_RESOL) - start = -a + 1; - - fac = (float)(-a + (CIRCLE_RESOL - 1)) * tot_inv; - x = sinval[a + start] * fac; - y = cosval[a + start] * fac; - - vec[0] = cent[0] + (x * vx[0] + y * vy[0]); - vec[1] = cent[1] + (x * vx[1] + y * vy[1]); - vec[2] = cent[2] + (x * vx[2] + y * vy[2]); - immVertex3fv(pos, vec); - } - } - - immEnd(); -} - -/* draws a circle on x-z plane given the scaling of the circle, assuming that - * all required matrices have been set (used for drawing empties) */ -static void drawcircle_size(float size, unsigned pos) -{ - immBegin(GWN_PRIM_LINE_LOOP, CIRCLE_RESOL); - - /* coordinates are: cos(degrees * 11.25) = x, sin(degrees * 11.25) = y, 0.0f = z */ - for (short degrees = 0; degrees < CIRCLE_RESOL; degrees++) { - float x = cosval[degrees]; - float y = sinval[degrees]; - - immVertex3f(pos, x * size, 0.0f, y * size); - } - - immEnd(); -} - -/* needs fixing if non-identity matrix used */ -static void imm_drawtube(const float vec[3], float radius, float height, float tmat[4][4], unsigned pos) -{ - float cur[3]; - imm_drawcircball(vec, radius, tmat, pos); - - copy_v3_v3(cur, vec); - cur[2] += height; - - imm_drawcircball(cur, radius, tmat, pos); - - immBegin(GWN_PRIM_LINES, 8); - immVertex3f(pos, vec[0] + radius, vec[1], vec[2]); - immVertex3f(pos, cur[0] + radius, cur[1], cur[2]); - immVertex3f(pos, vec[0] - radius, vec[1], vec[2]); - immVertex3f(pos, cur[0] - radius, cur[1], cur[2]); - immVertex3f(pos, vec[0], vec[1] + radius, vec[2]); - immVertex3f(pos, cur[0], cur[1] + radius, cur[2]); - immVertex3f(pos, vec[0], vec[1] - radius, vec[2]); - immVertex3f(pos, cur[0], cur[1] - radius, cur[2]); - immEnd(); -} - -/* needs fixing if non-identity matrix used */ -static void imm_drawcone(const float vec[3], float radius, float height, float tmat[4][4], unsigned pos) -{ - float cur[3]; - - copy_v3_v3(cur, vec); - cur[2] += height; - - imm_drawcircball(cur, radius, tmat, pos); - - immBegin(GWN_PRIM_LINES, 8); - immVertex3f(pos, vec[0], vec[1], vec[2]); - immVertex3f(pos, cur[0] + radius, cur[1], cur[2]); - immVertex3f(pos, vec[0], vec[1], vec[2]); - immVertex3f(pos, cur[0] - radius, cur[1], cur[2]); - immVertex3f(pos, vec[0], vec[1], vec[2]); - immVertex3f(pos, cur[0], cur[1] + radius, cur[2]); - immVertex3f(pos, vec[0], vec[1], vec[2]); - immVertex3f(pos, cur[0], cur[1] - radius, cur[2]); - immEnd(); -} - -/* return true if nothing was drawn */ -static bool drawmball( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4]) -{ - Object *ob = base->object; - MetaElem *ml; - float imat[4][4]; - int code = 1; - - MetaBall *mb = ob->data; - - if (mb->editelems) { - if ((G.f & G_PICKSEL) == 0) { - unsigned char wire_col[4]; - UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_col); - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, wire_col); - } - ml = mb->editelems->first; - } - else { - if ((base->flag_legacy & OB_FROMDUPLI) == 0) { - drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - ml = mb->elems.first; - } - - if (ml == NULL) { - return true; - } - - if (v3d->flag2 & V3D_RENDER_OVERRIDE) { - return false; - } - - invert_m4_m4(imat, rv3d->viewmatob); - normalize_v3(imat[0]); - normalize_v3(imat[1]); - -#if 0 /* no purpose? */ - if (mb->editelems == NULL) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(ob_wire_col); - } - } -#endif - - glLineWidth(1.0f); - - const unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - while (ml) { - /* draw radius */ - if (mb->editelems) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) imm_cpack(0xA0A0F0); - else imm_cpack(0x3030A0); - } - - if (G.f & G_PICKSEL) { - ml->selcol1 = code; - GPU_select_load_id(code++); - } - } - imm_drawcircball(&(ml->x), ml->rad, imat, pos); - - /* draw stiffness */ - if (mb->editelems) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) imm_cpack(0xA0F0A0); - else imm_cpack(0x30A030); - } - - if (G.f & G_PICKSEL) { - ml->selcol2 = code; - GPU_select_load_id(code++); - } - imm_drawcircball(&(ml->x), ml->rad * atanf(ml->s) / (float)M_PI_2, imat, pos); - } - - ml = ml->next; - } - - immUnbindProgram(); - return false; -} - -static void draw_forcefield(Object *ob, RegionView3D *rv3d, - const short dflag, const unsigned char ob_wire_col[4]) -{ - PartDeflect *pd = ob->pd; - float imat[4][4], tmat[4][4]; - float vec[3] = {0.0, 0.0, 0.0}; - float draw_color[3] = {0.0f, 0.0f, 0.0f}; - /* scale size of circle etc with the empty drawsize */ - const float size = (ob->type == OB_EMPTY) ? ob->empty_drawsize : 1.0f; - - /* calculus here, is reused in PFIELD_FORCE */ - invert_m4_m4(imat, rv3d->viewmatob); -#if 0 - normalize_v3(imat[0]); /* we don't do this because field doesnt scale either... apart from wind! */ - normalize_v3(imat[1]); -#endif - - const unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3fv(draw_color); - - if (pd->forcefield == PFIELD_WIND) { - float force_val = pd->f_strength; - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color); - immUniformColor3fv(draw_color); - } - - unit_m4(tmat); - force_val *= 0.1f; - imm_drawcircball(vec, size, tmat, pos); - vec[2] = 0.5f * force_val; - imm_drawcircball(vec, size, tmat, pos); - vec[2] = 1.0f * force_val; - imm_drawcircball(vec, size, tmat, pos); - vec[2] = 1.5f * force_val; - imm_drawcircball(vec, size, tmat, pos); - vec[2] = 0.0f; /* reset vec for max dist circle */ - } - else if (pd->forcefield == PFIELD_FORCE) { - float ffall_val = pd->f_power; - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color); - immUniformColor3fv(draw_color); - } - - imm_drawcircball(vec, size, imat, pos); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(1.5f, ffall_val), draw_color); - immUniformColor3fv(draw_color); - } - - imm_drawcircball(vec, size * 1.5f, imat, pos); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.9f - 0.4f / powf(2.0f, ffall_val), draw_color); - immUniformColor3fv(draw_color); - } - - imm_drawcircball(vec, size * 2.0f, imat, pos); - } - else if (pd->forcefield == PFIELD_VORTEX) { - float force_val = pd->f_strength; - - unit_m4(tmat); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.7f, draw_color); - immUniformColor3fv(draw_color); - } - - if (force_val < 0) { - drawspiral(pos, vec, size, tmat, 1); - drawspiral(pos, vec, size, tmat, 16); - } - else { - drawspiral(pos, vec, size, tmat, -1); - drawspiral(pos, vec, size, tmat, -16); - } - } - else if (pd->forcefield == PFIELD_GUIDE && ob->type == OB_CURVE) { - Curve *cu = ob->data; - if ((cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) { - float guidevec1[4], guidevec2[3]; - float mindist = pd->f_strength; - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color); - immUniformColor3fv(draw_color); - } - - /* path end */ - setlinestyle(3); - where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL, NULL); - imm_drawcircball(guidevec1, mindist, imat, pos); - - /* path beginning */ - setlinestyle(0); - where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL, NULL); - imm_drawcircball(guidevec1, mindist, imat, pos); - - copy_v3_v3(vec, guidevec1); /* max center */ - } - } - - setlinestyle(3); - - if ((dflag & DRAW_CONSTCOLOR) == 0) { - ob_wire_color_blend_theme_id(ob_wire_col, TH_BACK, 0.5f, draw_color); - immUniformColor3fv(draw_color); - } - - if (pd->falloff == PFIELD_FALL_SPHERE) { - /* as last, guide curve alters it */ - if ((pd->flag & PFIELD_USEMAX) != 0) { - imm_drawcircball(vec, pd->maxdist, imat, pos); - } - - if ((pd->flag & PFIELD_USEMIN) != 0) { - imm_drawcircball(vec, pd->mindist, imat, pos); - } - } - else if (pd->falloff == PFIELD_FALL_TUBE) { - float radius, distance; - - unit_m4(tmat); - - vec[0] = vec[1] = 0.0f; - radius = (pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f; - distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f; - vec[2] = distance; - distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distance; - - if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) { - imm_drawtube(vec, radius, distance, tmat, pos); - } - - radius = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f; - distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f; - vec[2] = distance; - distance = (pd->flag & PFIELD_POSZ) ? -distance : -2.0f * distance; - - if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) { - imm_drawtube(vec, radius, distance, tmat, pos); - } - } - else if (pd->falloff == PFIELD_FALL_CONE) { - float radius, distance; - - unit_m4(tmat); - - radius = DEG2RADF((pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f); - distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f; - - if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) { - imm_drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat, pos); - if ((pd->flag & PFIELD_POSZ) == 0) - imm_drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat, pos); - } - - radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f); - distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f; - - if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) { - imm_drawcone(vec, distance * sinf(radius), distance * cosf(radius), tmat, pos); - if ((pd->flag & PFIELD_POSZ) == 0) - imm_drawcone(vec, distance * sinf(radius), -distance * cosf(radius), tmat, pos); - } - } - setlinestyle(0); - - immUnbindProgram(); -} - -static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos) -{ - if (solid) { - /* Adpated from "Optimizing Triangle Strips for Fast Rendering" by F. Evans, S. Skiena and A. Varshney - * (http://www.cs.umd.edu/gvil/papers/av_ts.pdf). */ - static const GLubyte tris_strip_indices[14] = {0, 1, 3, 2, 6, 1, 5, 0, 4, 3, 7, 6, 4, 5}; - immBegin(GWN_PRIM_TRI_STRIP, 14); - for (int i = 0; i < 14; ++i) { - immVertex3fv(pos, vec[tris_strip_indices[i]]); - } - immEnd(); - } - else { - static const GLubyte line_indices[24] = - {0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 4, 5, 5, 6, 6, 7, 7, 4, 1, 5, 2, 6, 3, 7}; - immBegin(GWN_PRIM_LINES, 24); - for (int i = 0; i < 24; ++i) { - immVertex3fv(pos, vec[line_indices[i]]); - } - immEnd(); - } - -} - -static void imm_draw_bb(BoundBox *bb, char type, bool around_origin, const unsigned char ob_wire_col[4]) -{ - float size[3], cent[3]; - Gwn_Batch *sphere = GPU_batch_preset_sphere_wire(0); - GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) GWN_batch_uniform_4f(sphere, "color", ob_wire_col[0] / 255.0f, ob_wire_col[1] / 255.0f, ob_wire_col[2] / 255.0f, 1.0f); - - BKE_boundbox_calc_size_aabb(bb, size); - - if (around_origin) { - zero_v3(cent); - } - else { - BKE_boundbox_calc_center_aabb(bb, cent); - } - - gpuPushMatrix(); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) immUniformColor3ubv(ob_wire_col); - - if (type == OB_BOUND_SPHERE) { - float scale = MAX3(size[0], size[1], size[2]); - gpuTranslate3fv(cent); - gpuRotateAxis(90, 'X'); - gpuScaleUniform(scale); - GWN_batch_draw(sphere); - } - else if (type == OB_BOUND_CYLINDER) { - float radius = size[0] > size[1] ? size[0] : size[1]; - gpuTranslate3f(cent[0], cent[1], cent[2] - size[2]); - gpuScale3f(radius, radius, 2.0f * size[2]); - imm_draw_cylinder_wire_3d(pos, 1.0f, 1.0f, 1.0f, 8, 1); - } - else if (type == OB_BOUND_CONE) { - float radius = size[0] > size[1] ? size[0] : size[1]; - gpuTranslate3f(cent[0], cent[1], cent[2] - size[2]); - gpuScale3f(radius, radius, 2.0f * size[2]); - imm_draw_cylinder_wire_3d(pos, 1.0f, 0.0f, 1.0f, 8, 1); - - } - else if (type == OB_BOUND_CAPSULE) { - float radius = size[0] > size[1] ? size[0] : size[1]; - float length = size[2] > radius ? 2.0f * (size[2] - radius) : 0.0f; - gpuTranslate3f(cent[0], cent[1], cent[2] - length * 0.5f); - imm_draw_cylinder_wire_3d(pos, radius, radius, length, 8, 1); - - gpuRotateAxis(90, 'X'); - gpuScaleUniform(radius); - GWN_batch_draw(sphere); - - gpuTranslate3f(0.0f, length / radius, 0.0f); - GWN_batch_draw(sphere); - } - - gpuPopMatrix(); - immUnbindProgram(); -} - -void draw_bounding_volume(Object *ob, char type, const unsigned char ob_wire_col[4]) -{ - BoundBox bb_local; - BoundBox *bb = NULL; - - if (ob->type == OB_MESH) { - bb = BKE_mesh_boundbox_get(ob); - } - else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { - bb = BKE_curve_boundbox_get(ob); - } - else if (ob->type == OB_MBALL) { - if (BKE_mball_is_basis(ob)) { - bb = ob->bb; - } - } - else if (ob->type == OB_ARMATURE) { - bb = BKE_armature_boundbox_get(ob); - } - else if (ob->type == OB_LATTICE) { - bb = BKE_lattice_boundbox_get(ob); - } - else { - const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f, 1.0f}; - bb = &bb_local; - BKE_boundbox_init_from_minmax(bb, min, max); - } - - if (bb == NULL) - return; - - { - if (type == OB_BOUND_BOX) { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) immUniformColor3ubv(ob_wire_col); - - imm_draw_box(bb->vec, false, pos); - - immUnbindProgram(); - } - else - imm_draw_bb(bb, type, false, ob_wire_col); - } - -} - -static void drawtexspace(Object *ob, const unsigned char ob_wire_col[3]) -{ - float vec[8][3], loc[3], size[3]; - - if (ob->type == OB_MESH) { - BKE_mesh_texspace_get(ob->data, loc, NULL, size); - } - else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { - BKE_curve_texspace_get(ob->data, loc, NULL, size); - } - else if (ob->type == OB_MBALL) { - MetaBall *mb = ob->data; - copy_v3_v3(size, mb->size); - copy_v3_v3(loc, mb->loc); - } - else { - return; - } - - vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = loc[0] - size[0]; - vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = loc[0] + size[0]; - - vec[0][1] = vec[1][1] = vec[4][1] = vec[5][1] = loc[1] - size[1]; - vec[2][1] = vec[3][1] = vec[6][1] = vec[7][1] = loc[1] + size[1]; - - vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = loc[2] - size[2]; - vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = loc[2] + size[2]; - - setlinestyle(2); - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - if (ob_wire_col) { - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(ob_wire_col); - } - else { - immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY); - } - - imm_draw_box(vec, false, pos); - - immUnbindProgram(); - - setlinestyle(0); -} - -/* draws wire outline */ -static void draw_object_selected_outline( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base, - const unsigned char ob_wire_col[4]) -{ - RegionView3D *rv3d = ar->regiondata; - Object *ob = base->object; - - glDepthMask(GL_FALSE); - - if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { - bool has_faces = false; - -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, ob); -#endif - - DerivedMesh *dm = ob->derivedFinal; - if (dm) { - DM_update_materials(dm, ob); - } - - if (dm) { - has_faces = (dm->getNumPolys(dm) != 0); - } - else { - has_faces = BKE_displist_has_faces(&ob->curve_cache->disp); - } - - if (has_faces && ED_view3d_boundbox_clip(rv3d, ob->bb)) { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - if (dm) { - draw_mesh_object_outline(v3d, ob, dm, ob_wire_col); - } - else { - /* only draw 'solid' parts of the display list as wire. */ - drawDispListwire_ex(&ob->curve_cache->disp, (DL_INDEX3 | DL_INDEX4 | DL_SURF), ob_wire_col); - } - } - } - else if (ob->type == OB_MBALL) { - if (BKE_mball_is_basis(ob)) { - if ((base->flag_legacy & OB_FROMDUPLI) == 0) { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - drawDispListwire(&ob->curve_cache->disp, ob->type, ob_wire_col); - } - } - } - else if (ob->type == OB_ARMATURE) { - if (!(ob->mode & OB_MODE_POSE && base == view_layer->basact)) { - glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); - draw_armature(depsgraph, scene, view_layer, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true); - } - } - - glDepthMask(GL_TRUE); -} - -static void draw_wire_extra( - RegionView3D *rv3d, Object *ob, const bool is_obedit, const unsigned char ob_wire_col[4]) -{ - if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL)) { - unsigned char wire_edit_col[4]; - UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_edit_col); - - ED_view3d_polygon_offset(rv3d, 1.0); - glDepthMask(GL_FALSE); /* disable write in zbuffer, selected edge wires show better */ - glLineWidth(1.0f); - - if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { - if (ED_view3d_boundbox_clip(rv3d, ob->bb)) { - - if (ob->derivedFinal) { - drawCurveDMWired(ob); - } - else { - drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col); - } - } - } - else if (ob->type == OB_MBALL) { - if (BKE_mball_is_basis(ob)) { - drawDispListwire(&ob->curve_cache->disp, ob->type, is_obedit ? wire_edit_col : ob_wire_col); - } - } - - glDepthMask(GL_TRUE); - ED_view3d_polygon_offset(rv3d, 0.0); - } -} - -/* should be called in view space */ -static void draw_hooks(Object *ob, unsigned int pos) -{ - for (ModifierData *md = ob->modifiers.first; md; md = md->next) { - if (md->type == eModifierType_Hook) { - HookModifierData *hmd = (HookModifierData *) md; - float vec[3]; - - mul_v3_m4v3(vec, ob->obmat, hmd->cent); - - if (hmd->object) { - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, hmd->object->obmat[3]); - immVertex3fv(pos, vec); - immEnd(); - setlinestyle(0); - } - - glPointSize(3.0f); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, vec); - immEnd(); - } - } -} - -void draw_object_wire_color(ViewLayer *view_layer, Base *base, unsigned char r_ob_wire_col[4]) -{ - Object *ob = base->object; - int colindex = 0; - const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0; - /* confusing logic here, there are 2 methods of setting the color - * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. - * - * note: no theme yet for 'colindex' */ - int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE; - int theme_shade = 0; - - if (((ob->mode & OB_MODE_EDIT) == 0) && - (G.moving & G_TRANSFORM_OBJ) && - ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) - { - theme_id = TH_TRANSFORM; - } - else { - /* Sets the 'colindex' */ - if (ID_IS_LINKED(ob)) { - colindex = ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) ? 2 : 1; - } - /* Sets the 'theme_id' or fallback to wire */ - else { - if ((ob->flag & OB_FROMGROUP) != 0) { - if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) { - /* uses darker active color for non-active + selected */ - theme_id = TH_GROUP_ACTIVE; - - if (view_layer->basact != base) { - theme_shade = -32; - } - } - else { - theme_id = TH_GROUP; - } - } - else { - if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) { - theme_id = view_layer->basact == base ? TH_ACTIVE : TH_SELECT; - } - else { - if (ob->type == OB_LAMP) theme_id = TH_LAMP; - else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER; - else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA; - else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY; - /* fallback to TH_WIRE */ - } - } - } - } - - /* finally set the color */ - if (colindex == 0) { - if (theme_shade == 0) UI_GetThemeColor3ubv(theme_id, r_ob_wire_col); - else UI_GetThemeColorShade3ubv(theme_id, theme_shade, r_ob_wire_col); - } - else { - cpack_cpy_3ub(r_ob_wire_col, colortab[colindex]); - } - - /* no reason to use this but some functions take col[4] */ - r_ob_wire_col[3] = 255; -} - -static void draw_object_matcap_check(View3D *v3d, Object *ob) -{ - /* fixed rule, active object draws as matcap */ - BLI_assert((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) == 0); - (void)ob; - - if (v3d->defmaterial == NULL) { - extern Material defmaterial; - - v3d->defmaterial = MEM_mallocN(sizeof(Material), "matcap material"); - *(v3d->defmaterial) = defmaterial; - BLI_listbase_clear(&v3d->defmaterial->gpumaterial); - v3d->defmaterial->preview = NULL; - } - /* first time users */ - if (v3d->matcap_icon < ICON_MATCAP_01 || - v3d->matcap_icon > ICON_MATCAP_24) - { - v3d->matcap_icon = ICON_MATCAP_01; - } - - if (v3d->defmaterial->preview == NULL) - v3d->defmaterial->preview = UI_icon_to_preview(v3d->matcap_icon); - - /* signal to all material checks, gets cleared below */ - v3d->flag2 |= V3D_SHOW_SOLID_MATCAP; -} - -void draw_rigidbody_shape(Object *ob, const unsigned char ob_wire_col[4]) -{ - BoundBox *bb = NULL; - float size[3], vec[8][3]; - unsigned int pos; - - if (ob->type == OB_MESH) { - bb = BKE_mesh_boundbox_get(ob); - } - - if (bb == NULL) - return; - - switch (ob->rigidbody_object->shape) { - case RB_SHAPE_BOX: - BKE_boundbox_calc_size_aabb(bb, size); - - pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) immUniformColor3ubv(ob_wire_col); - - vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = -size[0]; - vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = +size[0]; - vec[0][1] = vec[1][1] = vec[4][1] = vec[5][1] = -size[1]; - vec[2][1] = vec[3][1] = vec[6][1] = vec[7][1] = +size[1]; - vec[0][2] = vec[3][2] = vec[4][2] = vec[7][2] = -size[2]; - vec[1][2] = vec[2][2] = vec[5][2] = vec[6][2] = +size[2]; - - imm_draw_box(vec, false, pos); - immUnbindProgram(); - break; - case RB_SHAPE_SPHERE: - imm_draw_bb(bb, OB_BOUND_SPHERE, true, ob_wire_col); - break; - case RB_SHAPE_CONE: - imm_draw_bb(bb, OB_BOUND_CONE, true, ob_wire_col); - break; - case RB_SHAPE_CYLINDER: - imm_draw_bb(bb, OB_BOUND_CYLINDER, true, ob_wire_col); - break; - case RB_SHAPE_CAPSULE: - imm_draw_bb(bb, OB_BOUND_CAPSULE, true, ob_wire_col); - break; - } -} - -/** - * main object drawing function, draws in selection - * \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET - */ -void draw_object( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, - Base *base, const short dflag) -{ - ModifierData *md = NULL; - Object *ob = base->object; - Curve *cu; - RegionView3D *rv3d = ar->regiondata; - unsigned char _ob_wire_col[4]; /* dont initialize this */ - const unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */ - bool zbufoff = false, is_paint = false, empty_object = false; - Object *ob_active = OBACT(view_layer); - const bool is_obact = (ob == ob_active); - /* this could be moved to a 'dflag'. */ - const bool is_obedit = (is_obact && (ob == OBEDIT_FROM_OBACT(ob_active))); - const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0; - const bool is_picking = (G.f & G_PICKSEL) != 0; - const bool has_particles = (ob->particlesystem.first != NULL); - bool skip_object = false; /* Draw particles but not their emitter object. */ - SmokeModifierData *smd = NULL; - - if (is_obedit == false) { - if (ob->restrictflag & OB_RESTRICT_VIEW) - return; - - if (render_override) { - if (ob->restrictflag & OB_RESTRICT_RENDER) - return; - - if (!has_particles && (ob->transflag & (OB_DUPLI & ~OB_DUPLIFRAMES))) - return; - } - } - - if (has_particles) { - /* XXX particles are not safe for simultaneous threaded render */ - if (G.is_rendering) { - return; - } - - if (ob->mode == OB_MODE_OBJECT) { - ParticleSystem *psys; - - skip_object = render_override; - for (psys = ob->particlesystem.first; psys; psys = psys->next) { - /* Once we have found a psys which renders its emitter object, we are done. */ - if (psys->part->draw & PART_DRAW_EMITTER) { - skip_object = false; - break; - } - } - } - } - - if (((base->flag_legacy & OB_FROMDUPLI) == 0) && - (md = modifiers_findByType(ob, eModifierType_Smoke)) && - (modifier_isEnabled(scene, md, eModifierMode_Realtime))) - { - smd = (SmokeModifierData *)md; - - if (smd->domain) { - if (!v3d->transp && (dflag & DRAW_PICKING) == 0) { - if (!v3d->xray && !(ob->dtx & OB_DRAWXRAY)) { - /* object has already been drawn so skip drawing it */ - ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); - return; - } - else if (v3d->xray) { - /* object has already been drawn so skip drawing it */ - ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag); - return; - } - } - } - } - - - /* xray delay? */ - if ((dflag & DRAW_PICKING) == 0 && (base->flag_legacy & OB_FROMDUPLI) == 0 && (v3d->flag2 & V3D_RENDER_SHADOW) == 0) { - /* don't do xray in particle mode, need the z-buffer */ - if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { - /* xray and transp are set when it is drawing the 2nd/3rd pass */ - if (!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) { - ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); - return; - } - - /* allow transp option for empty images */ - if (ob->type == OB_EMPTY && ob->empty_drawtype == OB_EMPTY_IMAGE) { - if (!v3d->xray && !v3d->transp && !(ob->dtx & OB_DRAWXRAY) && (ob->dtx & OB_DRAWTRANSP)) { - ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); - return; - } - } - } - } - - - /* -------------------------------------------------------------------- */ - /* no return after this point, otherwise leaks */ - - /* only once set now, will be removed too, should become a global standard */ - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - /* reset here to avoid having to call all over */ - glLineWidth(1.0f); - - view3d_cached_text_draw_begin(); - - /* draw motion paths (in view space) */ - if (ob->mpath && !render_override) { - bAnimVizSettings *avs = &ob->avs; - - /* setup drawing environment for paths */ - draw_motion_paths_init(v3d, ar); - - /* draw motion path for object */ - draw_motion_path_instance(scene, ob, NULL, avs, ob->mpath); - - /* cleanup after drawing */ - draw_motion_paths_cleanup(v3d); - } - - /* multiply view with object matrix. - * local viewmat and persmat, to calculate projections */ - ED_view3d_init_mats_rv3d_gl(ob, rv3d); - - /* which wire color */ - if ((dflag & DRAW_CONSTCOLOR) == 0) { - - ED_view3d_project_base(ar, base); - - draw_object_wire_color(view_layer, base, _ob_wire_col); - ob_wire_col = _ob_wire_col; - - //glColor3ubv(ob_wire_col); - } - - /* maximum drawtype */ - char dt = v3d->drawtype; - if (dt == OB_RENDER) dt = v3d->prev_drawtype; - dt = MIN2(dt, ob->dt); - if (v3d->zbuf == 0 && dt > OB_WIRE) dt = OB_WIRE; - short dtx = 0; - - - /* faceselect exception: also draw solid when (dt == wire), except in editmode */ - if (is_obact) { - if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) { - if (ob->type == OB_MESH) { - if (dt < OB_SOLID) { - zbufoff = true; - dt = OB_SOLID; - } - - if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) { - dt = OB_PAINT; - } - - is_paint = true; - glEnable(GL_DEPTH_TEST); - } - } - } - - /* matcap check - only when not painting color */ - if ((v3d->flag2 & V3D_SOLID_MATCAP) && - (dt == OB_SOLID) && - (is_paint == false && is_picking == false) && - ((v3d->flag2 & V3D_RENDER_SHADOW) == 0)) - { - draw_object_matcap_check(v3d, ob); - } - - /* draw-extra supported for boundbox drawmode too */ - if (dt >= OB_BOUNDBOX) { - dtx = ob->dtx; - if (ob->mode & OB_MODE_EDIT) { - /* the only 2 extra drawtypes alowed in editmode */ - dtx = dtx & (OB_DRAWWIRE | OB_TEXSPACE); - } - } - - if (!skip_object) { - /* draw outline for selected objects, mesh does itself */ - if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) { - if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) { - if (!(ob->dtx & OB_DRAWWIRE) && (base->flag & BASE_SELECTED) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) { - draw_object_selected_outline(depsgraph, scene, view_layer, v3d, ar, base, ob_wire_col); - } - } - } - - /* TODO Viewport: draw only for selection */ - if ((dflag & DRAW_PICKING) == 0) { - if ((dt == OB_BOUNDBOX) || ELEM(ob->type, OB_EMPTY, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { - goto afterdraw; - } - } - - switch (ob->type) { - case OB_MESH: - empty_object = draw_mesh_object(depsgraph, scene, view_layer, ar, v3d, rv3d, base, dt, ob_wire_col, dflag); - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* mesh draws wire itself */ - dtx &= ~OB_DRAWWIRE; - } - - break; - case OB_FONT: - cu = ob->data; - if (cu->editfont) { - draw_editfont(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - else if (dt == OB_BOUNDBOX) { - if ((render_override && v3d->drawtype >= OB_WIRE) == 0) { -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, base->object); -#endif - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - } - else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) { - empty_object = drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - - break; - case OB_CURVE: - case OB_SURF: - cu = ob->data; - - if (cu->editnurb) { - ListBase *nurbs = BKE_curve_editNurbs_get(cu); - draw_editnurb(depsgraph, scene, view_layer, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col); - } - else if (dt == OB_BOUNDBOX) { - if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) { -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, base->object); -#endif - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - } - else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) { - empty_object = drawDispList(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - } - break; - case OB_MBALL: - { - MetaBall *mb = ob->data; - - if (mb->editelems) - drawmball(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - else if (dt == OB_BOUNDBOX) { - if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) { -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, base->object); -#endif - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - } - else - empty_object = drawmball(depsgraph, scene, view_layer, v3d, rv3d, base, dt, dflag, ob_wire_col); - break; - } - case OB_EMPTY: - if (!render_override) { - if (ob->empty_drawtype == OB_EMPTY_IMAGE) { - draw_empty_image(ob, dflag, ob_wire_col, v3d->multiview_eye); - } - else { - drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, ob_wire_col); - } - } - break; - case OB_LAMP: - if (!render_override) { - drawlamp(v3d, rv3d, base, dt, dflag, ob_wire_col, is_obact); - } - break; - case OB_CAMERA: - if (!render_override || - (rv3d->persp == RV3D_CAMOB && v3d->camera == ob)) /* special exception for active camera */ - { - drawcamera(scene, v3d, rv3d, base, dflag, ob_wire_col); - } - break; - case OB_SPEAKER: - if (!render_override) - drawspeaker(ob_wire_col); - break; - case OB_LATTICE: - if (!render_override) { - /* Do not allow boundbox in edit nor pose mode! */ - if ((dt == OB_BOUNDBOX) && (ob->mode & OB_MODE_EDIT)) - dt = OB_WIRE; - if (dt == OB_BOUNDBOX) { - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - else { -#ifdef SEQUENCER_DAG_WORKAROUND - ensure_curve_cache(depsgraph, scene, ob); -#endif - drawlattice(v3d, ob, dflag, ob_wire_col); - } - } - break; - case OB_ARMATURE: - if (!render_override) { - /* Do not allow boundbox in edit nor pose mode! */ - if ((dt == OB_BOUNDBOX) && (ob->mode & (OB_MODE_EDIT | OB_MODE_POSE))) - dt = OB_WIRE; - if (dt == OB_BOUNDBOX) { - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - else { - unsigned char arm_col[4]; - glLineWidth(1.0f); - - if (ob_wire_col == NULL) { - float fcol[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - rgba_float_to_uchar(arm_col, fcol); - } - else - copy_v4_v4_uchar(arm_col, ob_wire_col); - - empty_object = draw_armature(depsgraph, scene, view_layer, v3d, ar, base, dt, dflag, arm_col, false); - } - } - break; - default: - if (!render_override) { - drawaxes(rv3d->viewmatob, 1.0, OB_ARROWS, ob_wire_col); - } - break; - } - - /* TODO Viewport: some elements are being drawn for object selection only */ -afterdraw: - - if (!render_override) { - if (ob->soft /*&& dflag & OB_SBMOTION*/) { - float mrt[3][3], msc[3][3], mtr[3][3]; - SoftBody *sb = NULL; - float tipw = 0.5f, tiph = 0.5f, drawsize = 4.0f; - if ((sb = ob->soft)) { - if (sb->solverflags & SBSO_ESTIMATEIPO) { - - gpuLoadMatrix(rv3d->viewmat); - copy_m3_m3(msc, sb->lscale); - copy_m3_m3(mrt, sb->lrot); - mul_m3_m3m3(mtr, mrt, msc); - ob_draw_RE_motion(sb->lcom, mtr, tipw, tiph, drawsize); - gpuMultMatrix(ob->obmat); - } - } - } - - if (ob->pd && ob->pd->forcefield) { - draw_forcefield(ob, rv3d, dflag, ob_wire_col); - } - } - } - - /* code for new particle system */ - if ((ob->particlesystem.first) && - (is_obedit == false)) - { - ParticleSystem *psys; - - //glDepthMask(GL_FALSE); - - gpuLoadMatrix(rv3d->viewmat); - - view3d_cached_text_draw_begin(); - - for (psys = ob->particlesystem.first; psys; psys = psys->next) { - /* run this so that possible child particles get cached */ - if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { - PTCacheEdit *edit = PE_create_current(depsgraph, scene, ob); - if (edit && edit->psys == psys) - draw_update_ptcache_edit(depsgraph, scene, ob, edit); - } - - draw_new_particle_system(depsgraph, scene, v3d, rv3d, base, psys, dt, dflag); - } - invert_m4_m4(ob->imat, ob->obmat); - view3d_cached_text_draw_end(v3d, ar, 0); - - gpuMultMatrix(ob->obmat); - - //glDepthMask(GL_TRUE); - } - - /* draw edit particles last so that they can draw over child particles */ - if ((dflag & DRAW_PICKING) == 0 && - (is_obedit == false)) - { - - if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { - PTCacheEdit *edit = PE_create_current(depsgraph, scene, ob); - if (edit) { - gpuLoadMatrix(rv3d->viewmat); - draw_update_ptcache_edit(depsgraph, scene, ob, edit); - draw_ptcache_edit(scene, v3d, edit); - gpuMultMatrix(ob->obmat); - } - } - } - - /* draw code for smoke, only draw domains */ - if (smd && smd->domain) { - SmokeDomainSettings *sds = smd->domain; - const bool show_smoke = (CFRA >= sds->point_cache[0]->startframe); - float viewnormal[3]; - - gpuLoadMatrix(rv3d->viewmat); - gpuMultMatrix(ob->obmat); - - if (!render_override) { - BoundBox bb; - float p0[3], p1[3]; - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - if (ob_wire_col) immUniformColor3ubv(ob_wire_col); - - /* draw max domain bounds */ - if ((sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN)) { - VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adapt_res); - VECADDFAC(p1, sds->p1, sds->cell_size, sds->adapt_res); - BKE_boundbox_init_from_minmax(&bb, p0, p1); - imm_draw_box(bb.vec, false, pos); - } - - /* draw a single voxel to hint the user about the resolution of the fluid */ - copy_v3_v3(p0, sds->p0); - - if (sds->flags & MOD_SMOKE_HIGHRES) { - madd_v3_v3v3fl(p1, p0, sds->cell_size, 1.0f / (sds->amplify + 1)); - } - else { - add_v3_v3v3(p1, p0, sds->cell_size); - } - - BKE_boundbox_init_from_minmax(&bb, p0, p1); - imm_draw_box(bb.vec, false, pos); - - immUnbindProgram(); - } - - /* don't show smoke before simulation starts, this could be made an option in the future */ - if (sds->fluid && show_smoke) { - float p0[3], p1[3]; - - /* get view vector */ - invert_m4_m4(ob->imat, ob->obmat); - mul_v3_mat3_m4v3(viewnormal, ob->imat, rv3d->viewinv[2]); - normalize_v3(viewnormal); - - /* set dynamic boundaries to draw the volume - * also scale cube to global space to equalize volume slicing on all axes - * (it's scaled back before drawing) */ - p0[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]); - p0[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]); - p0[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]); - p1[0] = (sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]) * fabsf(ob->size[0]); - p1[1] = (sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]) * fabsf(ob->size[1]); - p1[2] = (sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]) * fabsf(ob->size[2]); - - if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { - sds->tex = NULL; - GPU_create_smoke(smd, 0); - draw_smoke_volume(sds, ob, p0, p1, viewnormal); - GPU_free_smoke(smd); - } - else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { - sds->tex = NULL; - GPU_create_smoke(smd, 1); - draw_smoke_volume(sds, ob, p0, p1, viewnormal); - GPU_free_smoke(smd); - } - - /* smoke debug render */ - if (!render_override && sds->draw_velocity) { - draw_smoke_velocity(sds, viewnormal); - } - } - } - - if (!render_override) { - if (ob->rigidbody_object) { - draw_rigidbody_shape(ob, ob_wire_col); - } - - /* draw extra: after normal draw because of makeDispList */ - if (dtx && (G.f & G_RENDER_OGL) == 0) { - - if (dtx & OB_AXIS) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* prevent random colors being used */ - drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS, ob_wire_col); - } - else { - drawaxes(rv3d->viewmatob, 1.0f, OB_ARROWS, NULL); - } - } - if (dtx & OB_DRAWBOUNDOX) { - draw_bounding_volume(ob, ob->boundtype, ob_wire_col); - } - if (dtx & OB_TEXSPACE) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* prevent random colors being used */ - drawtexspace(ob, ob_wire_col); - } - else { - drawtexspace(ob, NULL); - } - } - if (dtx & OB_DRAWNAME) { - /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ - /* but, we also don't draw names for sets or duplicators */ - if (dflag == 0) { - const float zero[3] = {0, 0, 0}; - view3d_cached_text_draw_add(zero, ob->id.name + 2, strlen(ob->id.name + 2), 10, 0, ob_wire_col); - } - } - if ((dtx & OB_DRAWWIRE) && dt >= OB_SOLID) { - if ((dflag & DRAW_CONSTCOLOR) == 0) { - draw_wire_extra(rv3d, ob, is_obedit, ob_wire_col); - } - } - } - } - - /* return warning, this is cached text draw */ - invert_m4_m4(ob->imat, ob->obmat); - view3d_cached_text_draw_end(v3d, ar, 1); - /* return warning, clear temp flag */ - v3d->flag2 &= ~V3D_SHOW_SOLID_MATCAP; - - gpuLoadMatrix(rv3d->viewmat); - - if (zbufoff) { - glDisable(GL_DEPTH_TEST); - } - - if ((base->flag_legacy & OB_FROMDUPLI) || render_override) { - ED_view3d_clear_mats_rv3d(rv3d); - return; - } - - /* object centers, need to be drawn in viewmat space for speed, but OK for picking select */ - if (!is_obact || !(ob->mode & OB_MODE_ALL_PAINT)) { - int do_draw_center = -1; /* defines below are zero or positive... */ - - if (render_override) { - /* don't draw */ - } - else if (is_obact) - do_draw_center = ACTIVE; - else if (base->flag & BASE_SELECTED) - do_draw_center = SELECT; - else if (empty_object || (v3d->flag & V3D_DRAW_CENTERS)) - do_draw_center = DESELECT; - - if (do_draw_center != -1) { - if (dflag & DRAW_PICKING) { - /* draw a single point for opengl selection */ - if ((base->sx != IS_CLIPPED) && - (U.obcenter_dia != 0.0)) - { - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR); - /* TODO: short term, use DEPTH_ONLY shader or set appropriate color */ - /* TODO: long term, solve picking & selection problem better */ - glPointSize(U.obcenter_dia); - immBegin(GWN_PRIM_POINTS, 1); - immVertex3fv(pos, ob->obmat[3]); - immEnd(); - immUnbindProgram(); - } - } - else if ((dflag & DRAW_CONSTCOLOR) == 0) { - /* we don't draw centers for duplicators and sets */ - if ((base->sx != IS_CLIPPED) && - (U.obcenter_dia != 0.0) && - !(G.f & G_RENDER_OGL)) - { - /* check > 0 otherwise grease pencil can draw into the circle select which is annoying. */ - drawcentercircle(v3d, rv3d, ob->obmat[3], do_draw_center, ID_IS_LINKED(ob) || ob->id.us > 1); - } - } - } - } - - /* not for sets, duplicators or picking */ - if (dflag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && !render_override) { - ListBase *list; - RigidBodyCon *rbc = ob->rigidbody_constraint; - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(ob_wire_col); - - /* draw hook center and offset line */ - if (is_obedit == false) - draw_hooks(ob, pos); - - /* help lines and so */ - if ((is_obedit == false) && ob->parent) { - const eObjectVisibilityCheck mode = DEG_get_mode(depsgraph) != DAG_EVAL_VIEWPORT ? - OB_VISIBILITY_CHECK_FOR_RENDER : - OB_VISIBILITY_CHECK_FOR_VIEWPORT; - if (BKE_object_is_visible(ob->parent, mode)) { - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, ob->obmat[3]); - immVertex3fv(pos, ob->orig); - immEnd(); - setlinestyle(0); - } - } - - /* Drawing the constraint lines */ - if (ob->constraints.first) { - bConstraint *curcon; - bConstraintOb *cob; - unsigned char col1[4], col2[4]; - - list = &ob->constraints; - - UI_GetThemeColor3ubv(TH_GRID, col1); - UI_make_axis_color(col1, col2, 'Z'); - immUniformColor3ubv(col2); - - cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT); - - for (curcon = list->first; curcon; curcon = curcon->next) { - if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_OBJECTSOLVER)) { - /* special case for object solver and follow track constraints because they don't fill - * constraint targets properly (design limitation -- scene is needed for their target - * but it can't be accessed from get_targets callback) */ - - Object *camob = NULL; - - if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) { - bFollowTrackConstraint *data = (bFollowTrackConstraint *)curcon->data; - - camob = data->camera ? data->camera : scene->camera; - } - else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) { - bObjectSolverConstraint *data = (bObjectSolverConstraint *)curcon->data; - - camob = data->camera ? data->camera : scene->camera; - } - - if (camob) { - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, camob->obmat[3]); - immVertex3fv(pos, ob->obmat[3]); - immEnd(); - setlinestyle(0); - } - } - else { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon); - - if ((cti && cti->get_constraint_targets) && (curcon->flag & CONSTRAINT_EXPAND)) { - ListBase targets = {NULL, NULL}; - bConstraintTarget *ct; - - cti->get_constraint_targets(curcon, &targets); - - for (ct = targets.first; ct; ct = ct->next) { - /* calculate target's matrix */ - if (cti->get_target_matrix) - cti->get_target_matrix(depsgraph, curcon, cob, ct, BKE_scene_frame_get(scene)); - else - unit_m4(ct->matrix); - - setlinestyle(3); - immBegin(GWN_PRIM_LINES, 2); - immVertex3fv(pos, ct->matrix[3]); - immVertex3fv(pos, ob->obmat[3]); - immEnd(); - setlinestyle(0); - } - - if (cti->flush_constraint_targets) - cti->flush_constraint_targets(curcon, &targets, 1); - } - } - } - - BKE_constraints_clear_evalob(cob); - } - /* draw rigid body constraint lines */ - if (rbc && (rbc->ob1 || rbc->ob2)) { - immUniformThemeColor(TH_WIRE); - - setlinestyle(3); - immBegin(GWN_PRIM_LINES, ((int)((bool)rbc->ob1) + (int)((bool)rbc->ob2)) * 2); - if (rbc->ob1) { - immVertex3fv(pos, ob->obmat[3]); - immVertex3fv(pos, rbc->ob1->obmat[3]); - } - if (rbc->ob2) { - immVertex3fv(pos, ob->obmat[3]); - immVertex3fv(pos, rbc->ob2->obmat[3]); - } - immEnd(); - setlinestyle(0); - } - - immUnbindProgram(); - } - - ED_view3d_clear_mats_rv3d(rv3d); -} - - -/** - * Drawing for selection picking, - * caller must have called 'GPU_select_load_id(base->selcode)' first. - */ -void draw_object_select( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, - Base *base, const short dflag) -{ - BLI_assert(dflag & DRAW_PICKING && dflag & DRAW_CONSTCOLOR); - draw_object(depsgraph, scene, view_layer, ar, v3d, base, dflag); - - /* we draw duplicators for selection too */ - if ((base->object->transflag & OB_DUPLI)) { - ListBase *lb; - DupliObject *dob; - Base tbase; - - tbase.flag_legacy = OB_FROMDUPLI; - lb = object_duplilist(depsgraph, scene, base->object); - - for (dob = lb->first; dob; dob = dob->next) { - float omat[4][4]; - - tbase.object = dob->ob; - copy_m4_m4(omat, dob->ob->obmat); - copy_m4_m4(dob->ob->obmat, dob->mat); - - /* extra service: draw the duplicator in drawtype of parent */ - /* MIN2 for the drawtype to allow bounding box objects in groups for lods */ - char dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt); - short dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx; - - draw_object(depsgraph, scene, view_layer, ar, v3d, &tbase, dflag); - - tbase.object->dt = dt; - tbase.object->dtx = dtx; - - copy_m4_m4(dob->ob->obmat, omat); - } - free_object_duplilist(lb); - } -} - /* ***************** BACKBUF SEL (BBS) ********* */ #ifdef USE_MESH_DM_SELECT @@ -9476,24 +536,6 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, } } -static DMDrawOption bbs_mesh_solid__setDrawOpts(void *UNUSED(userData), int index) -{ - GPU_select_index_set(index + 1); - return DM_DRAW_OPTION_NORMAL; -} - -static DMDrawOption bbs_mesh_solid_hide__setDrawOpts(void *userData, int index) -{ - Mesh *me = userData; - - if (!(me->mpoly[index].flag & ME_HIDE)) { - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; - } -} - #ifdef USE_MESH_DM_SELECT /* must have called GPU_framebuffer_index_set beforehand */ static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index) @@ -9553,10 +595,9 @@ static void bbs_mesh_solid_verts(Depsgraph *UNUSED(depsgraph), Scene *UNUSED(sce } #endif -static void bbs_mesh_solid_faces(Scene *scene, Object *ob) +static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob) { Mesh *me = ob->data; - UNUSED_VARS(scene, bbs_mesh_solid_hide__setDrawOpts, bbs_mesh_solid__setDrawOpts); Gwn_Batch *batch; if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) { batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1); @@ -9644,81 +685,6 @@ void draw_object_backbufsel( } -/* ************* draw object instances for bones, for example ****************** */ -/* assumes all matrices/etc set OK */ - -/* helper function for drawing object instances - meshes */ -static void draw_object_mesh_instance( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, - Object *ob, const short dt, int outline, const unsigned char ob_wire_col[4]) -{ - Mesh *me = ob->data; - DerivedMesh *dm = NULL, *edm = NULL; - - if (ob->mode & OB_MODE_EDIT) { - edm = editbmesh_get_derived_base(ob, me->edit_btmesh, CD_MASK_BAREMESH); - DM_update_materials(edm, ob); - } - else { - dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_BAREMESH); - DM_update_materials(dm, ob); - } - - if (dt <= OB_WIRE) { - glColor4ubv(ob_wire_col); - if (dm) - dm->drawEdges(dm, 1, 0); - else if (edm) - edm->drawEdges(edm, 1, 0); - } - else { - if (outline) - draw_mesh_object_outline(v3d, ob, dm ? dm : edm, ob_wire_col); - - if (dm) { - bool glsl = draw_glsl_material(scene, view_layer, ob, v3d, dt); - GPU_begin_object_materials(v3d, rv3d, scene, view_layer, ob, glsl, NULL); - } - - glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); - - if (dm) { - dm->drawFacesSolid(dm, NULL, 0, GPU_object_material_bind); - GPU_end_object_materials(); - } - else if (edm) - edm->drawMappedFaces(edm, NULL, GPU_object_material_bind, NULL, NULL, DM_DRAW_NEED_NORMALS); - - GPU_object_material_unbind(); - } - - if (edm) edm->release(edm); - if (dm) dm->release(dm); -} - -void draw_object_instance(Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline, const float wire_col[4]) -{ - if (ob == NULL) - return; - - unsigned char bcol[4]; - rgba_float_to_uchar(bcol, wire_col); - - switch (ob->type) { - case OB_MESH: - draw_object_mesh_instance(depsgraph, scene, view_layer, v3d, rv3d, ob, dt, outline, bcol); - break; - case OB_EMPTY: - if (ob->empty_drawtype == OB_EMPTY_IMAGE) { - draw_empty_image(ob, 0, bcol, v3d->multiview_eye); - } - else { - drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, bcol); - } - break; - } -} - void ED_draw_object_facemap( Depsgraph *depsgraph, Scene *scene, Object *ob, const float col[4], const int facemap) { diff --git a/source/blender/editors/space_view3d/drawsimdebug.c b/source/blender/editors/space_view3d/drawsimdebug.c deleted file mode 100644 index 14708ca67bc..00000000000 --- a/source/blender/editors/space_view3d/drawsimdebug.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * 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) 2014 by the Blender Foundation. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/drawsimdebug.c - * \ingroup spview3d - */ - -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" -#include "DNA_object_types.h" - -#include "BLI_math.h" -#include "BLI_utildefines.h" -#include "BLI_ghash.h" - -#include "BKE_effect.h" - -#include "GPU_immediate.h" -#include "GPU_matrix.h" - -#include "view3d_intern.h" - - -static void draw_sim_debug_elements(SimDebugData *debug_data, float imat[4][4]) -{ - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - /* count element types */ - GHashIterator iter; - int num_dots = 0; - int num_circles = 0; - int num_lines = 0; - int num_vectors = 0; - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - switch (elem->type) { - case SIM_DEBUG_ELEM_DOT: ++num_dots; break; - case SIM_DEBUG_ELEM_CIRCLE: ++num_circles; break; - case SIM_DEBUG_ELEM_LINE: ++num_lines; break; - case SIM_DEBUG_ELEM_VECTOR: ++num_vectors; break; - } - } - - /**** dots ****/ - - glPointSize(3.0f); - immBegin(GWN_PRIM_POINTS, num_dots); - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - if (elem->type != SIM_DEBUG_ELEM_DOT) - continue; - - immAttrib3fv(color, elem->color); - immVertex3fv(pos, elem->v1); - } - immEnd(); - - /**** circles ****/ - - { -#define CIRCLERES 16 - float circle[CIRCLERES][2] = { - {0.000000, 1.000000}, {0.382683, 0.923880}, {0.707107, 0.707107}, {0.923880, 0.382683}, - {1.000000, -0.000000}, {0.923880, -0.382683}, {0.707107, -0.707107}, {0.382683, -0.923880}, - {-0.000000, -1.000000}, {-0.382683, -0.923880}, {-0.707107, -0.707107}, {-0.923879, -0.382684}, - {-1.000000, 0.000000}, {-0.923879, 0.382684}, {-0.707107, 0.707107}, {-0.382683, 0.923880} }; - - immBegin(GWN_PRIM_LINES, num_circles * CIRCLERES * 2); - - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - float radius = elem->v2[0]; - float co[3], nco[3]; - int i; - - if (elem->type != SIM_DEBUG_ELEM_CIRCLE) - continue; - - immAttrib3fv(color, elem->color); - zero_v3(co); - for (i = 0; i <= CIRCLERES; ++i) { - int ni = i % CIRCLERES; - nco[0] = radius * circle[ni][0]; - nco[1] = radius * circle[ni][1]; - nco[2] = 0.0f; - mul_mat3_m4_v3(imat, nco); - add_v3_v3(nco, elem->v1); - - if (i > 0) { - immVertex3fv(pos, co); - immVertex3fv(pos, nco); - } - - copy_v3_v3(co, nco); - } - } - - immEnd(); -#undef CIRCLERES - } - - /**** lines ****/ - - immBegin(GWN_PRIM_LINES, num_lines * 2); - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - if (elem->type != SIM_DEBUG_ELEM_LINE) - continue; - - immAttrib3fv(color, elem->color); - immVertex3fv(pos, elem->v1); - immVertex3fv(pos, elem->v2); - } - immEnd(); - - /**** vectors ****/ - - glPointSize(2.0f); - immBegin(GWN_PRIM_POINTS, num_vectors); - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - if (elem->type != SIM_DEBUG_ELEM_VECTOR) - continue; - - immAttrib3fv(color, elem->color); - immVertex3fv(pos, elem->v1); - } - immEnd(); - - immBegin(GWN_PRIM_LINES, num_vectors * 2); - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - float t[3]; - if (elem->type != SIM_DEBUG_ELEM_VECTOR) - continue; - - immAttrib3fv(color, elem->color); - immVertex3fv(pos, elem->v1); - add_v3_v3v3(t, elem->v1, elem->v2); - immVertex3fv(pos, t); - } - immEnd(); - - immUnbindProgram(); - - /**** strings ****/ - - for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - SimDebugElement *elem = BLI_ghashIterator_getValue(&iter); - if (elem->type != SIM_DEBUG_ELEM_STRING) - continue; - - unsigned char col[4]; - rgb_float_to_uchar(col, elem->color); - col[3] = 255; - view3d_cached_text_draw_add(elem->v1, elem->str, strlen(elem->str), - 0, V3D_CACHE_TEXT_GLOBALSPACE, col); - } -} - -void draw_sim_debug_data(Scene *UNUSED(scene), View3D *v3d, ARegion *ar) -{ - RegionView3D *rv3d = ar->regiondata; - /*Object *ob = base->object;*/ - float imat[4][4]; - - if (!_sim_debug_data) - return; - - invert_m4_m4(imat, rv3d->viewmatob); - - gpuPushMatrix(); - gpuLoadMatrix(rv3d->viewmat); - - view3d_cached_text_draw_begin(); - draw_sim_debug_elements(_sim_debug_data, imat); - view3d_cached_text_draw_end(v3d, ar, false); - - gpuPopMatrix(); -} diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 5e9d6f4ea1c..337d9c004ad 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -290,8 +290,6 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar) BPy_END_ALLOW_THREADS; #endif - if (rv3d->render_engine->re) - RE_Database_Free(rv3d->render_engine->re); RE_engine_free(rv3d->render_engine); rv3d->render_engine = NULL; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 1910f7e27c0..5316520ccab 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -98,23 +98,6 @@ /* ******************** general functions ***************** */ -static bool use_depth_doit(View3D *v3d, Object *obedit) -{ - if (v3d->drawtype > OB_WIRE) - return true; - - /* special case (depth for wire color) */ - if (v3d->drawtype <= OB_WIRE) { - if (obedit && obedit->type == OB_MESH) { - Mesh *me = obedit->data; - if (me->drawflag & ME_DRAWEIGHT) { - return true; - } - } - } - return false; -} - /** * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore */ @@ -742,16 +725,7 @@ void ED_view3d_draw_depth( v3d->zbuf = true; glEnable(GL_DEPTH_TEST); -#ifdef WITH_OPENGL_LEGACY - if (IS_VIEWPORT_LEGACY(vc->v3d)) { - /* temp, calls into view3d_draw_legacy.c */ - ED_view3d_draw_depth_loop(scene, ar, v3d); - } - else -#endif /* WITH_OPENGL_LEGACY */ - { - DRW_draw_depth_loop(depsgraph, ar, v3d); - } + DRW_draw_depth_loop(depsgraph, ar, v3d); if (rv3d->rflag & RV3D_CLIPPING) { ED_view3d_clipping_disable(); @@ -768,536 +742,8 @@ void ED_view3d_draw_depth( UI_Theme_Restore(&theme_state); } -/* ******************** background plates ***************** */ - -static void view3d_draw_background_gradient(void) -{ - /* TODO: finish 2D API & draw background with that */ - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - unsigned char col_hi[3], col_lo[3]; - - immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); - - UI_GetThemeColor3ubv(TH_LOW_GRAD, col_lo); - UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi); - - immBegin(GWN_PRIM_TRI_FAN, 4); - immAttrib3ubv(color, col_lo); - immVertex2f(pos, -1.0f, -1.0f); - immVertex2f(pos, 1.0f, -1.0f); - - immAttrib3ubv(color, col_hi); - immVertex2f(pos, 1.0f, 1.0f); - immVertex2f(pos, -1.0f, 1.0f); - immEnd(); - - immUnbindProgram(); -} - -static void view3d_draw_background_none(void) -{ - UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); -} - -static void view3d_draw_background_world(Scene *scene, RegionView3D *rv3d) -{ - if (scene->world) { - GPUMaterial *gpumat = GPU_material_world(scene, scene->world); - - /* calculate full shader for background */ - GPU_material_bind(gpumat, 1, 1, 1.0f, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac); - - if (GPU_material_bound(gpumat)) { - /* TODO viewport (dfelinto): GPU_material_bind relies on immediate mode, - * we can't get rid of the following code without a bigger refactor - * or we dropping this functionality. */ - - glBegin(GL_TRIANGLE_STRIP); - glVertex2f(-1.0f, -1.0f); - glVertex2f(1.0f, -1.0f); - glVertex2f(-1.0f, 1.0f); - glVertex2f(1.0f, 1.0f); - glEnd(); - - GPU_material_unbind(gpumat); - return; - } - } - - /* if any of the above fails */ - view3d_draw_background_none(); -} - /* ******************** other elements ***************** */ - -#define DEBUG_GRID 0 - -static void gridline_range(double x0, double dx, double max, int *r_first, int *r_count) -{ - /* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y - * x0 is gridline 0, the axis in screen space - * Area covers [0 .. max) pixels */ - - int first = (int)ceil(-x0 / dx); - int last = (int)floor((max - x0) / dx); - - if (first <= last) { - *r_first = first; - *r_count = last - first + 1; - } - else { - *r_first = 0; - *r_count = 0; - } - -#if DEBUG_GRID - printf(" first %d * dx = %f\n", first, x0 + first * dx); - printf(" last %d * dx = %f\n", last, x0 + last * dx); - printf(" count = %d\n", *count_out); -#endif -} - -static int gridline_count(ARegion *ar, double x0, double y0, double dx) -{ - /* x0 & y0 establish the "phase" of the grid within this 2D region - * dx is the frequency, shared by x & y directions - * pass in dx of smallest (highest precision) grid we want to draw */ - -#if DEBUG_GRID - printf(" %s(%f, %f, dx:%f)\n", __FUNCTION__, x0, y0, dx); -#endif - - int first, x_ct, y_ct; - - gridline_range(x0, dx, ar->winx, &first, &x_ct); - gridline_range(y0, dx, ar->winy, &first, &y_ct); - - int total_ct = x_ct + y_ct; - -#if DEBUG_GRID - printf(" %d + %d = %d gridlines\n", x_ct, y_ct, total_ct); -#endif - - return total_ct; -} - -static bool drawgrid_draw(ARegion *ar, double x0, double y0, double dx, int skip_mod, unsigned pos, unsigned col, GLubyte col_value[3]) -{ - /* skip every skip_mod lines relative to each axis; they will be overlaid by another drawgrid_draw - * always skip exact x0 & y0 axes; they will be drawn later in color - * - * set grid color once, just before the first line is drawn - * it's harmless to set same color for every line, or every vertex - * but if no lines are drawn, color must not be set! */ - -#if DEBUG_GRID - printf(" %s(%f, %f, dx:%f, skip_mod:%d)\n", __FUNCTION__, x0, y0, dx, skip_mod); -#endif - - const float x_max = (float)ar->winx; - const float y_max = (float)ar->winy; - - int first, ct; - int x_ct = 0, y_ct = 0; /* count of lines actually drawn */ - int lines_skipped_for_next_unit = 0; - - /* draw vertical lines */ - gridline_range(x0, dx, x_max, &first, &ct); - - for (int i = first; i < first + ct; ++i) { - if (i == 0) - continue; - else if (skip_mod && (i % skip_mod) == 0) { - ++lines_skipped_for_next_unit; - continue; - } - - if (x_ct == 0) - immAttrib3ub(col, col_value[0], col_value[1], col_value[2]); - - float x = (float)(x0 + i * dx); - immVertex2f(pos, x, 0.0f); - immVertex2f(pos, x, y_max); - ++x_ct; - } - - /* draw horizontal lines */ - gridline_range(y0, dx, y_max, &first, &ct); - - for (int i = first; i < first + ct; ++i) { - if (i == 0) - continue; - else if (skip_mod && (i % skip_mod) == 0) { - ++lines_skipped_for_next_unit; - continue; - } - - if (x_ct + y_ct == 0) - immAttrib3ub(col, col_value[0], col_value[1], col_value[2]); - - float y = (float)(y0 + i * dx); - immVertex2f(pos, 0.0f, y); - immVertex2f(pos, x_max, y); - ++y_ct; - } - -#if DEBUG_GRID - int total_ct = x_ct + y_ct; - printf(" %d + %d = %d gridlines drawn, %d skipped for next unit\n", x_ct, y_ct, total_ct, lines_skipped_for_next_unit); -#endif - - return lines_skipped_for_next_unit > 0; -} - -#define GRID_MIN_PX_D 6.0 -#define GRID_MIN_PX_F 6.0f - -static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit) -{ - RegionView3D *rv3d = ar->regiondata; - -#if DEBUG_GRID - printf("%s width %d, height %d\n", __FUNCTION__, ar->winx, ar->winy); -#endif - - double fx = rv3d->persmat[3][0]; - double fy = rv3d->persmat[3][1]; - double fw = rv3d->persmat[3][3]; - - const double wx = 0.5 * ar->winx; /* use double precision to avoid rounding errors */ - const double wy = 0.5 * ar->winy; - - double x = wx * fx / fw; - double y = wy * fy / fw; - - double vec4[4] = { v3d->grid, v3d->grid, 0.0, 1.0 }; - mul_m4_v4d(rv3d->persmat, vec4); - fx = vec4[0]; - fy = vec4[1]; - fw = vec4[3]; - - double dx = fabs(x - wx * fx / fw); - if (dx == 0) dx = fabs(y - wy * fy / fw); - - x += wx; - y += wy; - - /* now x, y, and dx have their final values - * (x,y) is the world origin (0,0,0) mapped to Area-relative screen space - * dx is the distance in pixels between grid lines -- same for horiz or vert grid lines */ - - glLineWidth(1.0f); - -#if 0 /* TODO: write to UI/widget depth buffer, not scene depth */ - glDepthMask(GL_FALSE); /* disable write in zbuffer */ -#endif - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - - unsigned char col[3], col2[3]; - UI_GetThemeColor3ubv(TH_GRID, col); - - if (unit->system) { - const void *usys; - int len; - - bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len); - - bool first = true; - - if (usys) { - int i = len; - while (i--) { - double scalar = bUnit_GetScaler(usys, i); - - double dx_scalar = dx * scalar / (double)unit->scale_length; - if (dx_scalar < (GRID_MIN_PX_D * 2.0)) { - /* very very small grid items are less useful when dealing with units */ - continue; - } - - if (first) { - first = false; - - /* Store the smallest drawn grid size units name so users know how big each grid cell is */ - *grid_unit = bUnit_GetNameDisplay(usys, i); - rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length); - - int gridline_ct = gridline_count(ar, x, y, dx_scalar); - if (gridline_ct == 0) - goto drawgrid_cleanup; /* nothing to draw */ - - immBegin(GWN_PRIM_LINES, gridline_ct * 2); - } - - float blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar); - /* tweak to have the fade a bit nicer */ - blend_fac = (blend_fac * blend_fac) * 2.0f; - CLAMP(blend_fac, 0.3f, 1.0f); - - UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, blend_fac, col2); - - const int skip_mod = (i == 0) ? 0 : (int)round(bUnit_GetScaler(usys, i - 1) / scalar); -#if DEBUG_GRID - printf("%s %f, ", bUnit_GetNameDisplay(usys, i), scalar); - if (i > 0) - printf("next unit is %d times larger\n", skip_mod); - else - printf("largest unit\n"); -#endif - if (!drawgrid_draw(ar, x, y, dx_scalar, skip_mod, pos, color, col2)) - break; - } - } - } - else { - const double sublines = v3d->gridsubdiv; - const float sublines_fl = v3d->gridsubdiv; - - int grids_to_draw = 2; /* first the faint fine grid, then the bold coarse grid */ - - if (dx < GRID_MIN_PX_D) { - rv3d->gridview *= sublines_fl; - dx *= sublines; - if (dx < GRID_MIN_PX_D) { - rv3d->gridview *= sublines_fl; - dx *= sublines; - if (dx < GRID_MIN_PX_D) { - rv3d->gridview *= sublines_fl; - dx *= sublines; - grids_to_draw = (dx < GRID_MIN_PX_D) ? 0 : 1; - } - } - } - else { - if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */ - rv3d->gridview /= sublines_fl; - dx /= sublines; - if (dx > (GRID_MIN_PX_D * 10.0)) { /* start blending in */ - rv3d->gridview /= sublines_fl; - dx /= sublines; - if (dx > (GRID_MIN_PX_D * 10.0)) { - grids_to_draw = 1; - } - } - } - } - - int gridline_ct = gridline_count(ar, x, y, dx); - if (gridline_ct == 0) - goto drawgrid_cleanup; /* nothing to draw */ - - immBegin(GWN_PRIM_LINES, gridline_ct * 2); - - if (grids_to_draw == 2) { - UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0), col2); - if (drawgrid_draw(ar, x, y, dx, v3d->gridsubdiv, pos, color, col2)) - drawgrid_draw(ar, x, y, dx * sublines, 0, pos, color, col); - } - else if (grids_to_draw == 1) { - drawgrid_draw(ar, x, y, dx, 0, pos, color, col); - } - } - - /* draw visible axes */ - /* horizontal line */ - if (0 <= y && y < ar->winy) { - UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT) ? 'Y' : 'X'); - immAttrib3ub(color, col2[0], col2[1], col2[2]); - immVertex2f(pos, 0.0f, y); - immVertex2f(pos, (float)ar->winx, y); - } - - /* vertical line */ - if (0 <= x && x < ar->winx) { - UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM) ? 'Y' : 'Z'); - immAttrib3ub(color, col2[0], col2[1], col2[2]); - immVertex2f(pos, x, 0.0f); - immVertex2f(pos, x, (float)ar->winy); - } - - immEnd(); - -drawgrid_cleanup: - immUnbindProgram(); - -#if 0 /* depth write is left enabled above */ - glDepthMask(GL_TRUE); /* enable write in zbuffer */ -#endif -} - -#undef DEBUG_GRID -#undef GRID_MIN_PX_D -#undef GRID_MIN_PX_F - -static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth) -{ - /* draw only if there is something to draw */ - if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) { - /* draw how many lines? - * trunc(v3d->gridlines / 2) * 4 - * + 2 for xy axes (possibly with special colors) - * + 1 for z axis (the only line not in xy plane) - * even v3d->gridlines are honored, odd rounded down */ - const int gridlines = v3d->gridlines / 2; - const float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit); - const float grid = gridlines * grid_scale; - - const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) && gridlines >= 1; - - bool show_axis_x = v3d->gridflag & V3D_SHOW_X; - bool show_axis_y = v3d->gridflag & V3D_SHOW_Y; - bool show_axis_z = v3d->gridflag & V3D_SHOW_Z; - - unsigned char col_grid[3], col_axis[3]; - - glLineWidth(1.0f); - - UI_GetThemeColor3ubv(TH_GRID, col_grid); - - if (!write_depth) - glDepthMask(GL_FALSE); - - if (show_floor) { - const unsigned vertex_ct = 2 * (gridlines * 4 + 2); - const int sublines = v3d->gridsubdiv; - - unsigned char col_bg[3], col_grid_emphasise[3], col_grid_light[3]; - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - - immBegin(GWN_PRIM_LINES, vertex_ct); - - /* draw normal grid lines */ - UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10); - - for (int a = 1; a <= gridlines; a++) { - /* skip emphasised divider lines */ - if (a % sublines != 0) { - const float line = a * grid_scale; - - immAttrib3ubv(color, col_grid_light); - - immVertex2f(pos, -grid, -line); - immVertex2f(pos, +grid, -line); - immVertex2f(pos, -grid, +line); - immVertex2f(pos, +grid, +line); - - immVertex2f(pos, -line, -grid); - immVertex2f(pos, -line, +grid); - immVertex2f(pos, +line, -grid); - immVertex2f(pos, +line, +grid); - } - } - - /* draw emphasised grid lines */ - UI_GetThemeColor3ubv(TH_BACK, col_bg); - /* emphasise division lines lighter instead of darker, if background is darker than grid */ - UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise, - (col_grid[0] + col_grid[1] + col_grid[2] + 30 > - col_bg[0] + col_bg[1] + col_bg[2]) ? 20 : -10); - - if (sublines <= gridlines) { - immAttrib3ubv(color, col_grid_emphasise); - - for (int a = sublines; a <= gridlines; a += sublines) { - const float line = a * grid_scale; - - immVertex2f(pos, -grid, -line); - immVertex2f(pos, +grid, -line); - immVertex2f(pos, -grid, +line); - immVertex2f(pos, +grid, +line); - - immVertex2f(pos, -line, -grid); - immVertex2f(pos, -line, +grid); - immVertex2f(pos, +line, -grid); - immVertex2f(pos, +line, +grid); - } - } - - /* draw X axis */ - if (show_axis_x) { - show_axis_x = false; /* drawing now, won't need to draw later */ - UI_make_axis_color(col_grid, col_axis, 'X'); - immAttrib3ubv(color, col_axis); - } - else - immAttrib3ubv(color, col_grid_emphasise); - - immVertex2f(pos, -grid, 0.0f); - immVertex2f(pos, +grid, 0.0f); - - /* draw Y axis */ - if (show_axis_y) { - show_axis_y = false; /* drawing now, won't need to draw later */ - UI_make_axis_color(col_grid, col_axis, 'Y'); - immAttrib3ubv(color, col_axis); - } - else - immAttrib3ubv(color, col_grid_emphasise); - - immVertex2f(pos, 0.0f, -grid); - immVertex2f(pos, 0.0f, +grid); - - immEnd(); - immUnbindProgram(); - - /* done with XY plane */ - } - - if (show_axis_x || show_axis_y || show_axis_z) { - /* draw axis lines -- sometimes grid floor is off, other times we still need to draw the Z axis */ - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR); - immBegin(GWN_PRIM_LINES, (show_axis_x + show_axis_y + show_axis_z) * 2); - - if (show_axis_x) { - UI_make_axis_color(col_grid, col_axis, 'X'); - immAttrib3ubv(color, col_axis); - immVertex3f(pos, -grid, 0.0f, 0.0f); - immVertex3f(pos, +grid, 0.0f, 0.0f); - } - - if (show_axis_y) { - UI_make_axis_color(col_grid, col_axis, 'Y'); - immAttrib3ubv(color, col_axis); - immVertex3f(pos, 0.0f, -grid, 0.0f); - immVertex3f(pos, 0.0f, +grid, 0.0f); - } - - if (show_axis_z) { - UI_make_axis_color(col_grid, col_axis, 'Z'); - immAttrib3ubv(color, col_axis); - immVertex3f(pos, 0.0f, 0.0f, -grid); - immVertex3f(pos, 0.0f, 0.0f, +grid); - } - - immEnd(); - immUnbindProgram(); - } - - if (!write_depth) - glDepthMask(GL_TRUE); - } -} - /** could move this elsewhere, but tied into #ED_view3d_grid_scale */ float ED_scene_grid_scale(Scene *scene, const char **grid_unit) { @@ -1324,102 +770,6 @@ float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit) return v3d->grid * ED_scene_grid_scale(scene, grid_unit); } -static bool is_cursor_visible(Scene *scene, ViewLayer *view_layer) -{ - if (U.app_flag & USER_APP_VIEW3D_HIDE_CURSOR) { - return false; - } - - Object *ob = OBACT(view_layer); - - /* don't draw cursor in paint modes, but with a few exceptions */ - if (ob && ob->mode & OB_MODE_ALL_PAINT) { - /* exception: object is in weight paint and has deforming armature in pose mode */ - if (ob->mode & OB_MODE_WEIGHT_PAINT) { - if (BKE_object_pose_armature_get(ob) != NULL) { - return true; - } - } - /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */ - else if (ob->mode & OB_MODE_TEXTURE_PAINT) { - const Paint *p = BKE_paint_get_active(scene, view_layer); - - if (p && p->brush && p->brush->imagepaint_tool == PAINT_TOOL_CLONE) { - if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) { - return true; - } - } - } - - /* no exception met? then don't draw cursor! */ - return false; - } - - return true; -} - -static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) -{ - int co[2]; - - /* we don't want the clipping for cursor */ - if (ED_view3d_project_int_global(ar, ED_view3d_cursor3d_get(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - const float f5 = 0.25f * U.widget_unit; - const float f10 = 0.5f * U.widget_unit; - const float f20 = U.widget_unit; - - glLineWidth(1.0f); - - Gwn_VertFormat *format = immVertexFormat(); - unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_U8, 3, GWN_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - - const int segments = 16; - - immBegin(GWN_PRIM_LINE_LOOP, segments); - - for (int i = 0; i < segments; ++i) { - float angle = 2 * M_PI * ((float)i / (float)segments); - float x = co[0] + f10 * cosf(angle); - float y = co[1] + f10 * sinf(angle); - - if (i % 2 == 0) - immAttrib3ub(color, 255, 0, 0); - else - immAttrib3ub(color, 255, 255, 255); - - immVertex2f(pos, x, y); - } - immEnd(); - - immUnbindProgram(); - - GWN_vertformat_clear(format); - pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - unsigned char crosshair_color[3]; - UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color); - immUniformColor3ubv(crosshair_color); - - immBegin(GWN_PRIM_LINES, 8); - immVertex2f(pos, co[0] - f20, co[1]); - immVertex2f(pos, co[0] - f5, co[1]); - immVertex2f(pos, co[0] + f5, co[1]); - immVertex2f(pos, co[0] + f20, co[1]); - immVertex2f(pos, co[0], co[1] - f20); - immVertex2f(pos, co[0], co[1] - f5); - immVertex2f(pos, co[0], co[1] + f5); - immVertex2f(pos, co[0], co[1] + f20); - immEnd(); - - immUnbindProgram(); - } -} - static void draw_view_axis(RegionView3D *rv3d, const rcti *rect) { const float k = U.rvisize * U.pixelsize; /* axis size */ @@ -1909,16 +1259,8 @@ RenderEngineType *ED_view3d_engine_type(Scene *scene, int drawtype) void view3d_main_region_draw(const bContext *C, ARegion *ar) { - Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = ar->regiondata; - RenderEngineType *type = ED_view3d_engine_type(scene, v3d->drawtype); - - /* Provisory Blender Internal drawing */ - if (type->flag & RE_USE_LEGACY_PIPELINE) { - view3d_main_region_draw_legacy(C, ar); - return; - } if (!rv3d->viewport) { rv3d->viewport = GPU_viewport_create(); @@ -1965,50 +1307,17 @@ static void view3d_stereo3d_setup_offscreen( } } -void ED_view3d_draw_offscreen_init(Depsgraph *depsgraph, - Scene *scene, - ViewLayer *view_layer, - View3D *v3d, - int drawtype) -{ - RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype); - - if (engine_type->flag & RE_USE_LEGACY_PIPELINE) { - /* shadow buffers, before we setup matrices */ - if (draw_glsl_material(scene, view_layer, NULL, v3d, drawtype)) { - VP_deprecated_gpu_update_lamps_shadows_world(depsgraph, scene, v3d); - } - } -} - -/* - * Function to clear the view - */ -static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar) -{ - glClear(GL_DEPTH_BUFFER_BIT); - - if (scene->world && (v3d->flag3 & V3D_SHOW_WORLD)) { - VP_view3d_draw_background_world(scene, ar->regiondata); - } - else { - VP_view3d_draw_background_none(); - } -} - -/* ED_view3d_draw_offscreen_init should be called before this to initialize - * stuff like shadow buffers - */ void ED_view3d_draw_offscreen( Depsgraph *depsgraph, Scene *scene, - ViewLayer *view_layer, int drawtype, + int drawtype, View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[4][4], float winmat[4][4], - bool do_bgpic, bool do_sky, bool UNUSED(is_persp), const char *viewname, + bool do_sky, bool UNUSED(is_persp), const char *viewname, GPUFXSettings *UNUSED(fx_settings), GPUOffScreen *ofs, GPUViewport *viewport) { RegionView3D *rv3d = ar->regiondata; + RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype); /* set temporary new size */ int bwinx = ar->winx; @@ -2046,29 +1355,9 @@ void ED_view3d_draw_offscreen( view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL); /* main drawing call */ - RenderEngineType *engine_type = ED_view3d_engine_type(scene, drawtype); - - if (engine_type->flag & RE_USE_LEGACY_PIPELINE) { - VP_deprecated_view3d_draw_objects(NULL, depsgraph, scene, v3d, ar, NULL, do_bgpic, true); - - if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) { - /* draw grease-pencil stuff */ - ED_region_pixelspace(ar); - - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - ED_gpencil_draw_view3d(NULL, scene, view_layer, depsgraph, v3d, ar, false); - } - - /* freeing the images again here could be done after the operator runs, leaving for now */ - GPU_free_images_anim(); - } - } - else { - DRW_draw_render_loop_offscreen( - depsgraph, engine_type, ar, v3d, - do_sky, ofs, viewport); - } + DRW_draw_render_loop_offscreen( + depsgraph, engine_type, ar, v3d, + do_sky, ofs, viewport); /* restore size */ ar->winx = bwinx; @@ -2091,7 +1380,7 @@ void ED_view3d_draw_offscreen( */ ImBuf *ED_view3d_draw_offscreen_imbuf( Depsgraph *depsgraph, Scene *scene, - ViewLayer *view_layer, int drawtype, + int drawtype, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag, unsigned int draw_flags, int alpha_mode, int samples, const char *viewname, @@ -2100,7 +1389,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( { RegionView3D *rv3d = ar->regiondata; const bool draw_sky = (alpha_mode == R_ADDSKY); - const bool draw_background = (draw_flags & V3D_OFSDRAW_USE_BACKGROUND); const bool use_full_sample = (draw_flags & V3D_OFSDRAW_USE_FULL_SAMPLE); /* view state */ @@ -2125,8 +1413,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( } } - ED_view3d_draw_offscreen_init(depsgraph, scene, view_layer, v3d, drawtype); - GPU_offscreen_bind(ofs, true); /* read in pixels & stamp */ @@ -2167,9 +1453,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( if ((samples && use_full_sample) == 0) { /* Single-pass render, common case */ ED_view3d_draw_offscreen( - depsgraph, scene, view_layer, drawtype, + depsgraph, scene, drawtype, v3d, ar, sizex, sizey, NULL, winmat, - draw_background, draw_sky, !is_ortho, viewname, + draw_sky, !is_ortho, viewname, &fx_settings, ofs, NULL); if (ibuf->rect_float) { @@ -2192,9 +1478,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( /* first sample buffer, also initializes 'rv3d->persmat' */ ED_view3d_draw_offscreen( - depsgraph, scene, view_layer, drawtype, + depsgraph, scene, drawtype, v3d, ar, sizex, sizey, NULL, winmat, - draw_background, draw_sky, !is_ortho, viewname, + draw_sky, !is_ortho, viewname, &fx_settings, ofs, viewport); GPU_offscreen_read_pixels(ofs, GL_FLOAT, accum_buffer); @@ -2207,9 +1493,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( (jit_ofs[j][1] * 2.0f) / sizey); ED_view3d_draw_offscreen( - depsgraph, scene, view_layer, drawtype, + depsgraph, scene, drawtype, v3d, ar, sizex, sizey, NULL, winmat_jitter, - draw_background, draw_sky, !is_ortho, viewname, + draw_sky, !is_ortho, viewname, &fx_settings, ofs, viewport); GPU_offscreen_read_pixels(ofs, GL_FLOAT, rect_temp); @@ -2272,7 +1558,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf( */ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( Depsgraph *depsgraph, Scene *scene, - ViewLayer *view_layer, int drawtype, + int drawtype, Object *camera, int width, int height, unsigned int flag, unsigned int draw_flags, int alpha_mode, int samples, const char *viewname, @@ -2298,9 +1584,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( if (draw_flags & V3D_OFSDRAW_USE_SOLID_TEX) { v3d.flag2 |= V3D_SOLID_TEX; } - if (draw_flags & V3D_OFSDRAW_USE_BACKGROUND) { - v3d.flag3 |= V3D_SHOW_WORLD; - } + + v3d.flag3 |= V3D_SHOW_WORLD; + if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) { if (camera->type == OB_CAMERA) { v3d.fx_settings.dof = &((Camera *)camera->data)->gpu_dof; @@ -2334,105 +1620,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple( invert_m4_m4(rv3d.persinv, rv3d.viewinv); return ED_view3d_draw_offscreen_imbuf( - depsgraph, scene, view_layer, drawtype, + depsgraph, scene, drawtype, &v3d, &ar, width, height, flag, draw_flags, alpha_mode, samples, viewname, ofs, err_out); } /** \} */ - - -/* -------------------------------------------------------------------- */ - -/** \name Legacy Interface - * - * This will be removed once the viewport gets replaced - * meanwhile it should keep the old viewport working. - * - * \{ */ - -void VP_legacy_drawcursor(Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d) -{ - if (is_cursor_visible(scene, view_layer)) { - drawcursor(scene, ar, v3d); - } -} - -void VP_legacy_draw_view_axis(RegionView3D *rv3d, const rcti *rect) -{ - draw_view_axis(rv3d, rect); -} - -void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect) -{ - draw_viewport_name(ar, v3d, rect); -} - -void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect) -{ - draw_selected_name(scene, ob, rect); -} - -void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit) -{ - drawgrid(unit, ar, v3d, grid_unit); -} - -void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth) -{ - drawfloor(scene, v3d, grid_unit, write_depth); -} - -void VP_legacy_view3d_main_region_setup_view( - Depsgraph *depsgraph, Scene *scene, View3D *v3d, - ARegion *ar, float viewmat[4][4], float winmat[4][4]) -{ - view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL); -} - -bool VP_legacy_view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d) -{ - return view3d_stereo3d_active(win, scene, v3d, rv3d); -} - -void VP_legacy_view3d_stereo3d_setup(Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar) -{ - view3d_stereo3d_setup(depsgraph, scene, v3d, ar, NULL); -} - -bool VP_legacy_use_depth(View3D *v3d, Object *obedit) -{ - return use_depth_doit(v3d, obedit); -} - -void VP_drawviewborder(Scene *scene, struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d) -{ - drawviewborder(scene, depsgraph, ar, v3d); -} - -void VP_drawrenderborder(ARegion *ar, View3D *v3d) -{ - drawrenderborder(ar, v3d); -} - -void VP_view3d_draw_background_none(void) -{ - if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { - view3d_draw_background_gradient(); - } - else { - view3d_draw_background_none(); - } -} - -void VP_view3d_draw_background_world(Scene *scene, RegionView3D *rv3d) -{ - view3d_draw_background_world(scene, rv3d); -} - -void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar) -{ - view3d_main_region_clear(scene, v3d, ar); -} - -/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 51adcc47b6c..1ba46453915 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -99,7 +99,6 @@ #include "GPU_draw.h" #include "GPU_framebuffer.h" -#include "GPU_lamp.h" #include "GPU_material.h" #include "GPU_extensions.h" #include "GPU_immediate.h" @@ -115,34 +114,6 @@ /* ********* custom clipping *********** */ -static void view3d_draw_clipping(RegionView3D *rv3d) -{ - BoundBox *bb = rv3d->clipbb; - - if (bb) { - const unsigned int clipping_index[6][4] = { - {0, 1, 2, 3}, - {0, 4, 5, 1}, - {4, 7, 6, 5}, - {7, 3, 2, 6}, - {1, 5, 6, 2}, - {7, 4, 0, 3} - }; - - /* fill in zero alpha for rendering & re-projection [#31530] */ - unsigned char col[4]; - UI_GetThemeColor4ubv(TH_V3D_CLIPPING_BORDER, col); - glColor4ubv(col); - - glEnable(GL_BLEND); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, bb->vec); - glDrawElements(GL_QUADS, sizeof(clipping_index) / sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index); - glDisableClientState(GL_VERTEX_ARRAY); - glDisable(GL_BLEND); - } -} - void ED_view3d_clipping_set(RegionView3D *rv3d) { double plane[4]; @@ -187,28 +158,6 @@ bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip); } -/* ********* end custom clipping *********** */ - -static void draw_view_icon(RegionView3D *rv3d, rcti *rect) -{ - BIFIconID icon; - - if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) - icon = ICON_AXIS_TOP; - else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) - icon = ICON_AXIS_FRONT; - else if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) - icon = ICON_AXIS_SIDE; - else return; - - glEnable(GL_BLEND); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon); - - glDisable(GL_BLEND); -} - /* *********************** backdraw for selection *************** */ static void backdrawview3d( @@ -807,253 +756,8 @@ void ED_view3d_draw_bgpic_test( } } -/* ****************** View3d afterdraw *************** */ - -typedef struct View3DAfter { - struct View3DAfter *next, *prev; - struct Base *base; - short dflag; -} View3DAfter; - -/* temp storage of Objects that need to be drawn as last */ -void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag) -{ - View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after"); - BLI_assert((base->flag_legacy & OB_FROMDUPLI) == 0); - BLI_addtail(lb, v3da); - v3da->base = base; - v3da->dflag = dflag; -} - -/* disables write in zbuffer and draws it over */ -static void view3d_draw_transp( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d) -{ - View3DAfter *v3da; - - glDepthMask(GL_FALSE); - v3d->transp = true; - - while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, v3da->dflag); - MEM_freeN(v3da); - } - v3d->transp = false; - - glDepthMask(GL_TRUE); - -} - -/* clears zbuffer and draws it over */ -static void view3d_draw_xray( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, bool *clear) -{ - if (*clear && v3d->zbuf) { - glClear(GL_DEPTH_BUFFER_BIT); - *clear = false; - } - - v3d->xray = true; - View3DAfter *v3da; - while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, v3da->dflag); - MEM_freeN(v3da); - } - v3d->xray = false; -} - - -/* clears zbuffer and draws it over */ -static void view3d_draw_xraytransp( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, const bool clear) -{ - if (clear && v3d->zbuf) - glClear(GL_DEPTH_BUFFER_BIT); - - v3d->xray = true; - v3d->transp = true; - - glDepthMask(GL_FALSE); - - View3DAfter *v3da; - while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, v3da->dflag); - MEM_freeN(v3da); - } - - v3d->transp = false; - v3d->xray = false; - - glDepthMask(GL_TRUE); -} - -/* clears zbuffer and draws it over, - * note that in the select version we don't care about transparent flag as with regular drawing */ -static void view3d_draw_xray_select( - struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, bool *clear) -{ - /* Not ideal, but we need to read from the previous depths before clearing - * otherwise we could have a function to load the depths after drawing. - * - * Clearing the depth buffer isn't all that common between drawing objects so accept this for now. - */ - if (U.gpu_select_pick_deph) { - GPU_select_load_id(-1); - } - - View3DAfter *v3da; - if (*clear && v3d->zbuf) { - glClear(GL_DEPTH_BUFFER_BIT); - *clear = false; - } - - v3d->xray = true; - while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { - if (GPU_select_load_id(v3da->base->object->select_color)) { - draw_object_select(depsgraph, scene, view_layer, ar, v3d, v3da->base, v3da->dflag); - } - MEM_freeN(v3da); - } - v3d->xray = false; -} - /* *********************** */ -/* - * In most cases call draw_dupli_objects, - * draw_dupli_objects_color was added because when drawing set dupli's - * we need to force the color - */ - -#if 0 -int dupli_ob_sort(void *arg1, void *arg2) -{ - void *p1 = ((DupliObject *)arg1)->ob; - void *p2 = ((DupliObject *)arg2)->ob; - int val = 0; - if (p1 < p2) val = -1; - else if (p1 > p2) val = 1; - return val; -} -#endif - - -static DupliObject *dupli_step(DupliObject *dob) -{ - while (dob && dob->no_draw) - dob = dob->next; - return dob; -} - -static void draw_dupli_objects_color( - Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Base *base, - const short dflag, const int color) -{ - RegionView3D *rv3d = ar->regiondata; - ListBase *lb; - LodLevel *savedlod; - Base tbase = {NULL}; - BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */ - unsigned char color_rgb[3]; - const short dflag_dupli = dflag | DRAW_CONSTCOLOR; - short transflag; - char dt; - short dtx; - DupliApplyData *apply_data; - - if ((base->flag & BASE_VISIBLED) == 0) return; - if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return; - - if (dflag & DRAW_CONSTCOLOR) { - BLI_assert(color == TH_UNDEFINED); - } - else { - UI_GetThemeColorBlend3ubv(color, TH_BACK, 0.5f, color_rgb); - } - - tbase.flag_legacy = OB_FROMDUPLI | base->flag_legacy; - tbase.flag = base->flag; - lb = object_duplilist(depsgraph, scene, base->object); - // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */ - - apply_data = duplilist_apply(depsgraph, base->object, scene, lb); - - DupliObject *dob_next = NULL; - DupliObject *dob = dupli_step(lb->first); - if (dob) dob_next = dupli_step(dob->next); - - for (; dob; dob = dob_next, dob_next = dob_next ? dupli_step(dob_next->next) : NULL) { - bool testbb = false; - - tbase.object = dob->ob; - - /* Make sure lod is updated from dupli's position */ - savedlod = dob->ob->currentlod; - - /* extra service: draw the duplicator in drawtype of parent, minimum taken - * to allow e.g. boundbox box objects in groups for LOD */ - dt = tbase.object->dt; - tbase.object->dt = MIN2(tbase.object->dt, base->object->dt); - - /* inherit draw extra, but not if a boundbox under the assumption that this - * is intended to speed up drawing, and drawing extra (especially wire) can - * slow it down too much */ - dtx = tbase.object->dtx; - if (tbase.object->dt != OB_BOUNDBOX) - tbase.object->dtx = base->object->dtx; - - /* negative scale flag has to propagate */ - transflag = tbase.object->transflag; - - if (is_negative_m4(dob->mat)) - tbase.object->transflag |= OB_NEG_SCALE; - else - tbase.object->transflag &= ~OB_NEG_SCALE; - - /* should move outside the loop but possible color is set in draw_object still */ - if ((dflag & DRAW_CONSTCOLOR) == 0) { - glColor3ubv(color_rgb); - } - - if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) { - bb = *bb_tmp; /* must make a copy */ - testbb = true; - } - - if (!testbb || ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) { - copy_m4_m4(dob->ob->obmat, dob->mat); - GPU_begin_dupli_object(dob); - draw_object(depsgraph, scene, view_layer, ar, v3d, &tbase, dflag_dupli); - GPU_end_dupli_object(); - } - - tbase.object->dt = dt; - tbase.object->dtx = dtx; - tbase.object->transflag = transflag; - tbase.object->currentlod = savedlod; - } - - if (apply_data) { - duplilist_restore(lb, apply_data); - duplilist_free_apply_data(apply_data); - } - - free_object_duplilist(lb); -} - -void draw_dupli_objects(Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Base *base) -{ - /* define the color here so draw_dupli_objects_color can be called - * from the set loop */ - - int color = (base->flag & BASE_SELECTED) ? TH_SELECT : TH_WIRE; - /* debug */ - if (base->object->dup_group && base->object->dup_group->id.us < 1) - color = TH_REDALERT; - - draw_dupli_objects_color(depsgraph, scene, view_layer, ar, v3d, base, 0, color); -} - /* XXX warning, not using gpu offscreen here */ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) { @@ -1186,265 +890,9 @@ void ED_view3d_draw_depth_gpencil( if (!zbuf) glDisable(GL_DEPTH_TEST); } -void ED_view3d_draw_depth_loop(Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d) -{ - Base *base; - ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - /* no need for color when drawing depth buffer */ - const short dflag_depth = DRAW_CONSTCOLOR; - - /* draw set first */ - if (scene->set) { - Scene *sce_iter; - for (SETLOOPER(scene->set, sce_iter, base)) { - if ((base->flag & BASE_VISIBLED) != 0) { - draw_object(depsgraph, scene, view_layer, ar, v3d, base, 0); - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(depsgraph, scene, view_layer, ar, v3d, base, dflag_depth, TH_UNDEFINED); - } - } - } - } - - for (base = view_layer->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_VISIBLED) != 0) { - /* dupli drawing */ - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(depsgraph, scene, view_layer, ar, v3d, base, dflag_depth, TH_UNDEFINED); - } - draw_object(depsgraph, scene, view_layer, ar, v3d, base, dflag_depth); - } - } - - /* this isn't that nice, draw xray objects as if they are normal */ - if (v3d->afterdraw_transp.first || - v3d->afterdraw_xray.first || - v3d->afterdraw_xraytransp.first) - { - View3DAfter *v3da; - int mask_orig; - - v3d->xray = true; - - /* transp materials can change the depth mask, see #21388 */ - glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); - - - if (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) { - glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */ - for (v3da = v3d->afterdraw_xray.first; v3da; v3da = v3da->next) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, dflag_depth); - } - glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */ - } - - /* draw 3 passes, transp/xray/xraytransp */ - v3d->xray = false; - v3d->transp = true; - while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, dflag_depth); - MEM_freeN(v3da); - } - - v3d->xray = true; - v3d->transp = false; - while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, dflag_depth); - MEM_freeN(v3da); - } - - v3d->xray = true; - v3d->transp = true; - while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) { - draw_object(depsgraph, scene, view_layer, ar, v3d, v3da->base, dflag_depth); - MEM_freeN(v3da); - } - - - v3d->xray = false; - v3d->transp = false; - - glDepthMask(mask_orig); - } -} - -void ED_view3d_draw_select_loop( - struct Depsgraph *depsgraph, ViewContext *vc, Scene *scene, ViewLayer *view_layer, - View3D *v3d, ARegion *ar, bool use_obedit_skip, bool use_nearest) -{ - struct bThemeState theme_state; - - short code = 1; - const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR; - - /* Tools may request depth outside of regular drawing code. */ - UI_Theme_Store(&theme_state); - UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW); - - if (vc->obedit && vc->obedit->type == OB_MBALL) { - draw_object(depsgraph, scene, view_layer, ar, v3d, BASACT(view_layer), dflag); - } - else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) { - /* if not drawing sketch, draw bones */ - if (!BDR_drawSketchNames(vc)) { - draw_object(depsgraph, scene, view_layer, ar, v3d, BASACT(view_layer), dflag); - } - } - else { - Base *base; - - for (base = view_layer->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_VISIBLED) != 0) { - if (((base->flag & BASE_SELECTABLED) == 0) || - (use_obedit_skip && (vc->obedit->data == base->object->data))) - { - base->object->select_color = 0; - } - else { - base->object->select_color = code; - - if (use_nearest && (base->object->dtx & OB_DRAWXRAY)) { - ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); - } - else { - if (GPU_select_load_id(code)) { - draw_object(depsgraph, scene, view_layer, ar, v3d, base, dflag); - } - } - code++; - } - } - } - - if (use_nearest) { - bool xrayclear = true; - if (v3d->afterdraw_xray.first) { - view3d_draw_xray_select(depsgraph, scene, view_layer, ar, v3d, &xrayclear); - } - } - } - - UI_Theme_Restore(&theme_state); -} - -typedef struct View3DShadow { - struct View3DShadow *next, *prev; - GPULamp *lamp; -} View3DShadow; - -static void gpu_render_lamp_update(Scene *scene, View3D *v3d, - Object *ob, Object *par, - float obmat[4][4], unsigned int lay, - ListBase *shadows) -{ - GPULamp *lamp = GPU_lamp_from_blender(scene, ob, par); - - if (lamp) { - Lamp *la = (Lamp *)ob->data; - - GPU_lamp_update(lamp, lay, (ob->restrictflag & OB_RESTRICT_RENDER), obmat); - GPU_lamp_update_colors(lamp, la->r, la->g, la->b, la->energy); - - unsigned int layers = lay & v3d->lay; - - if (layers && - GPU_lamp_has_shadow_buffer(lamp) && - /* keep last, may do string lookup */ - GPU_lamp_visible(lamp, NULL)) - { - View3DShadow *shadow = MEM_callocN(sizeof(View3DShadow), "View3DShadow"); - shadow->lamp = lamp; - BLI_addtail(shadows, shadow); - } - } -} - -static void gpu_update_lamps_shadows_world(Depsgraph *depsgraph, Scene *scene, View3D *v3d) -{ - ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - ListBase shadows; - Scene *sce_iter; - Base *base; - World *world = scene->world; - - BLI_listbase_clear(&shadows); - - /* update lamp transform and gather shadow lamps */ - for (SETLOOPER(scene, sce_iter, base)) { - Object *ob = base->object; - - if (ob->type == OB_LAMP) - gpu_render_lamp_update(scene, v3d, ob, NULL, ob->obmat, ob->lay, &shadows); - - if (ob->transflag & OB_DUPLI) { - DupliObject *dob; - ListBase *lb = object_duplilist(depsgraph, scene, ob); - - for (dob = lb->first; dob; dob = dob->next) - if (dob->ob->type == OB_LAMP) - gpu_render_lamp_update(scene, v3d, dob->ob, ob, dob->mat, ob->lay, &shadows); - - free_object_duplilist(lb); - } - } - - /* render shadows after updating all lamps, nested object_duplilist - * don't work correct since it's replacing object matrices */ - for (View3DShadow *shadow = shadows.first; shadow; shadow = shadow->next) { - /* this needs to be done better .. */ - float viewmat[4][4], winmat[4][4]; - ARegion ar = {NULL}; - RegionView3D rv3d = {{{0}}}; - - int drawtype = v3d->drawtype; - int lay = v3d->lay; - int flag2 = v3d->flag2; - - v3d->drawtype = OB_SOLID; - v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp); - v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP); - v3d->flag2 |= V3D_RENDER_OVERRIDE | V3D_RENDER_SHADOW; - - int winsize; - GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat); - - ar.regiondata = &rv3d; - ar.regiontype = RGN_TYPE_WINDOW; - rv3d.persp = RV3D_CAMOB; - copy_m4_m4(rv3d.winmat, winmat); - copy_m4_m4(rv3d.viewmat, viewmat); - invert_m4_m4(rv3d.viewinv, rv3d.viewmat); - mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat); - invert_m4_m4(rv3d.persinv, rv3d.viewinv); - - /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */ - ED_view3d_draw_offscreen( - depsgraph, scene, view_layer, v3d->drawtype, - v3d, &ar, winsize, winsize, viewmat, winmat, - false, false, true, - NULL, NULL, NULL, NULL); - GPU_lamp_shadow_buffer_unbind(shadow->lamp); - - v3d->drawtype = drawtype; - v3d->lay = lay; - v3d->flag2 = flag2; - } - - BLI_freelistN(&shadows); - - /* update world values */ - if (world) { - GPU_mist_update_enable(world->mode & WO_MIST); - GPU_mist_update_values(world->mistype, world->miststa, world->mistdist, world->misi, &world->horr); - GPU_horizon_update_color(&world->horr); - GPU_ambient_update_color(&world->ambr); - GPU_zenith_update_color(&world->zenr); - } -} - /* *********************** customdata **************** */ -CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d) +CustomDataMask ED_view3d_datamask(const Scene *UNUSED(scene), const View3D *v3d) { CustomDataMask mask = 0; const int drawtype = view3d_effective_drawtype(v3d); @@ -1454,15 +902,8 @@ CustomDataMask ED_view3d_datamask(const Scene *scene, const View3D *v3d) { mask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; - if (BKE_scene_use_new_shading_nodes(scene)) { - if (drawtype == OB_MATERIAL) - mask |= CD_MASK_ORCO; - } - else { - if (drawtype == OB_MATERIAL) { - mask |= CD_MASK_ORCO; - } - } + if (drawtype == OB_MATERIAL) + mask |= CD_MASK_ORCO; } return mask; @@ -1484,178 +925,6 @@ CustomDataMask ED_view3d_screen_datamask(const Scene *scene, const bScreen *scre } /** - * Shared by #ED_view3d_draw_offscreen and #view3d_main_region_draw_objects - * - * \note \a C and \a grid_unit will be NULL when \a draw_offscreen is set. - * \note Drawing lamps and opengl render uses this, so dont do grease pencil or view widgets here. - */ -static void view3d_draw_objects( - const bContext *C, - Depsgraph *depsgraph, - Scene *scene, View3D *v3d, ARegion *ar, - const char **grid_unit, - const bool do_bgpic, const bool draw_offscreen) -{ - ViewLayer *view_layer = C ? CTX_data_view_layer(C) : BKE_view_layer_from_scene_get(scene); - RegionView3D *rv3d = ar->regiondata; - Base *base; - Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer); - const bool do_camera_frame = !draw_offscreen; - const bool draw_grids = !draw_offscreen && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0; - const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO); - /* only draw grids after in solid modes, else it hovers over mesh wires */ - const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE); - bool xrayclear = true; - - if (!draw_offscreen) { - ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); - } - - if (rv3d->rflag & RV3D_CLIPPING) - view3d_draw_clipping(rv3d); - - /* set zbuffer after we draw clipping region */ - v3d->zbuf = VP_legacy_use_depth(v3d, obedit); - - if (v3d->zbuf) { - glEnable(GL_DEPTH_TEST); - } - - /* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override - * objects if done last */ - if (draw_grids) { - /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */ - rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit); - - if (!draw_floor) { - ED_region_pixelspace(ar); - *grid_unit = NULL; /* drawgrid need this to detect/affect smallest valid unit... */ - VP_legacy_drawgrid(&scene->unit, ar, v3d, grid_unit); - gpuLoadProjectionMatrix(rv3d->winmat); - gpuLoadMatrix(rv3d->viewmat); - } - else if (!draw_grids_after) { - VP_legacy_drawfloor(scene, v3d, grid_unit, true); - } - } - - /* important to do before clipping */ - if (do_bgpic) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, do_camera_frame); - } - - if (rv3d->rflag & RV3D_CLIPPING) { - ED_view3d_clipping_set(rv3d); - } - - /* draw set first */ - if (scene->set) { - const short dflag = DRAW_CONSTCOLOR | DRAW_SCENESET; - Scene *sce_iter; - for (SETLOOPER(scene->set, sce_iter, base)) { - if ((base->flag & BASE_VISIBLED) != 0) { - UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); - draw_object(depsgraph, scene, view_layer, ar, v3d, base, dflag); - - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects_color(depsgraph, scene, view_layer, ar, v3d, base, dflag, TH_UNDEFINED); - } - } - } - - /* Transp and X-ray afterdraw stuff for sets is done later */ - } - - if (draw_offscreen) { - for (base = view_layer->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_VISIBLED) != 0) { - /* dupli drawing */ - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects(depsgraph, scene, view_layer, ar, v3d, base); - } - - draw_object(depsgraph, scene, view_layer, ar, v3d, base, 0); - } - } - } - else { - unsigned int lay_used = 0; - - /* then draw not selected and the duplis, but skip editmode object */ - for (base = view_layer->object_bases.first; base; base = base->next) { - lay_used |= base->lay; - - if ((base->flag & BASE_VISIBLED) != 0) { - - /* dupli drawing */ - if (base->object->transflag & OB_DUPLI) { - draw_dupli_objects(depsgraph, scene, view_layer, ar, v3d, base); - } - if ((base->flag & BASE_SELECTED) == 0) { - if (base->object != obedit) - draw_object(depsgraph, scene, view_layer, ar, v3d, base, 0); - } - } - } - - /* mask out localview */ - v3d->lay_used = lay_used & ((1 << 20) - 1); - - /* draw selected and editmode */ - for (base = view_layer->object_bases.first; base; base = base->next) { - if ((base->flag & BASE_VISIBLED) != 0) { - if (base->object == obedit || (base->flag & BASE_SELECTED)) { - draw_object(depsgraph, scene, view_layer, ar, v3d, base, 0); - } - } - } - } - - /* perspective floor goes last to use scene depth and avoid writing to depth buffer */ - if (draw_grids_after) { - VP_legacy_drawfloor(scene, v3d, grid_unit, false); - } - - /* must be before xray draw which clears the depth buffer */ - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - wmWindowManager *wm = (C != NULL) ? CTX_wm_manager(C) : NULL; - - /* must be before xray draw which clears the depth buffer */ - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - ED_gpencil_draw_view3d(wm, scene, view_layer, depsgraph, v3d, ar, true); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - } - - /* transp and X-ray afterdraw stuff */ - if (v3d->afterdraw_transp.first) view3d_draw_transp(depsgraph, scene, view_layer, ar, v3d); - - if (v3d->afterdraw_xray.first) view3d_draw_xray(depsgraph, scene, view_layer, ar, v3d, &xrayclear); - if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(depsgraph, scene, view_layer, ar, v3d, xrayclear); - - if (!draw_offscreen) { - ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - } - - if (rv3d->rflag & RV3D_CLIPPING) - ED_view3d_clipping_disable(); - - /* important to do after clipping */ - if (do_bgpic) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, true, do_camera_frame); - } - - /* cleanup */ - if (v3d->zbuf) { - v3d->zbuf = false; - glDisable(GL_DEPTH_TEST); - } - - if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) { - GPU_free_images_old(); - } -} - -/** * Store values from #RegionView3D, set when drawing. * This is needed when we draw with to a viewport using a different matrix (offscreen drawing for example). * @@ -1800,310 +1069,3 @@ bool ED_view3d_calc_render_border(const Scene *scene, Depsgraph *depsgraph, View return true; } - -/** - * IMPORTANT: this is deprecated, any changes made in this function should - * be mirrored in view3d_draw_render_draw() in view3d_draw.c - */ -static bool view3d_main_region_draw_engine( - const bContext *C, Depsgraph *depsgraph, Scene *scene, - ARegion *ar, View3D *v3d, - bool clip_border, const rcti *border_rect) -{ - RegionView3D *rv3d = ar->regiondata; - RenderEngineType *type; - GLint scissor[4]; - - /* create render engine */ - if (!rv3d->render_engine) { - RenderEngine *engine; - type = RE_engines_find(scene->r.engine); - - if (!(type->view_update && type->render_to_view)) - return false; - - engine = RE_engine_create_ex(type, true); - - engine->tile_x = scene->r.tilex; - engine->tile_y = scene->r.tiley; - - type->view_update(engine, C); - - rv3d->render_engine = engine; - } - - /* setup view matrices */ - VP_legacy_view3d_main_region_setup_view(depsgraph, scene, v3d, ar, NULL, NULL); - - /* background draw */ - ED_region_pixelspace(ar); - - if (clip_border) { - /* for border draw, we only need to clear a subset of the 3d view */ - if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) { - glGetIntegerv(GL_SCISSOR_BOX, scissor); - glScissor(border_rect->xmin, border_rect->ymin, - BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect)); - } - else { - return false; - } - } - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - bool show_image = false; - { - Camera *cam = ED_view3d_camera_data_get(v3d, rv3d); - if (cam->flag & CAM_SHOW_BG_IMAGE) { - show_image = true; - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, true); - } - else { - imm_draw_box_checker_2d(0, 0, ar->winx, ar->winy); - } - } - - if (show_image) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, true); - } - else { - imm_draw_box_checker_2d(0, 0, ar->winx, ar->winy); - } - - /* render result draw */ - type = rv3d->render_engine->type; - type->render_to_view(rv3d->render_engine, C); - - if (show_image) { - ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, true, true); - } - - if (clip_border) { - /* restore scissor as it was before */ - glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); - } - - return true; -} - -static void view3d_main_region_draw_engine_info(View3D *v3d, RegionView3D *rv3d, ARegion *ar, bool render_border) -{ - float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f}; - - if (!rv3d->render_engine || !rv3d->render_engine->text[0]) - return; - - if (render_border) { - /* draw darkened background color. no alpha because border render does - * partial redraw and will not redraw the region behind this info bar */ - float alpha = 1.0f - fill_color[3]; - Camera *camera = ED_view3d_camera_data_get(v3d, rv3d); - - if (camera) { - if (camera->flag & CAM_SHOWPASSEPARTOUT) { - alpha *= (1.0f - camera->passepartalpha); - } - } - - UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color); - mul_v3_fl(fill_color, alpha); - fill_color[3] = 1.0f; - } - - ED_region_info_draw(ar, rv3d->render_engine->text, fill_color, true); -} - -static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, ViewLayer *view_layer, View3D *v3d, - ARegion *ar, const char **grid_unit) -{ - wmWindow *win = CTX_wm_window(C); - Depsgraph *depsgraph = CTX_data_depsgraph(C); - RegionView3D *rv3d = ar->regiondata; - unsigned int lay_used = v3d->lay_used; - - /* shadow buffers, before we setup matrices */ - if (draw_glsl_material(scene, view_layer, NULL, v3d, v3d->drawtype)) - gpu_update_lamps_shadows_world(depsgraph, scene, v3d); - - /* reset default OpenGL lights if needed (i.e. after preferences have been altered) */ - if (rv3d->rflag & RV3D_GPULIGHT_UPDATE) { - rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE; - GPU_default_lights(); - } - - /* setup the view matrix */ - if (VP_legacy_view3d_stereo3d_active(win, scene, v3d, rv3d)) { - VP_legacy_view3d_stereo3d_setup(depsgraph, scene, v3d, ar); - } - else { - VP_legacy_view3d_main_region_setup_view(depsgraph, scene, v3d, ar, NULL, NULL); - } - - /* main drawing call */ - view3d_draw_objects(C, depsgraph, scene, v3d, ar, grid_unit, true, false); - - if (v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */ - /* find header and force tag redraw */ - ScrArea *sa = CTX_wm_area(C); - ARegion *ar_header = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); - ED_region_tag_redraw(ar_header); /* can be NULL */ - } - - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - BDR_drawSketch(C); - } -} - -static void view3d_main_region_draw_info(const bContext *C, Scene *scene, - ARegion *ar, View3D *v3d, - const char *grid_unit, bool render_border) -{ - Depsgraph *depsgraph = CTX_data_depsgraph(C); - ViewLayer *view_layer = CTX_data_view_layer(C); - wmWindowManager *wm = CTX_wm_manager(C); - RegionView3D *rv3d = ar->regiondata; - rcti rect; - - /* local coordinate visible rect inside region, to accomodate overlapping ui */ - ED_region_visible_rect(ar, &rect); - - if (rv3d->persp == RV3D_CAMOB) { - VP_drawviewborder(scene, depsgraph, ar, v3d); - } - else if (v3d->flag2 & V3D_RENDER_BORDER) { - VP_drawrenderborder(ar, v3d); - } - - if (v3d->flag2 & V3D_SHOW_GPENCIL) { - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - ED_gpencil_draw_view3d(wm, scene, view_layer, depsgraph, v3d, ar, false); - } - - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - VP_legacy_drawcursor(scene, view_layer, ar, v3d); /* 3D cursor */ - - if (U.uiflag & USER_SHOW_ROTVIEWICON) - VP_legacy_draw_view_axis(rv3d, &rect); - else - draw_view_icon(rv3d, &rect); - - if (U.uiflag & USER_DRAWVIEWINFO) { - Object *ob = OBACT(view_layer); - VP_legacy_draw_selected_name(scene, ob, &rect); - } - } - - if (rv3d->render_engine) { - view3d_main_region_draw_engine_info(v3d, rv3d, ar, render_border); - return; - } - - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) { - ED_scene_draw_fps(scene, &rect); - } - else if (U.uiflag & USER_SHOW_VIEWPORTNAME) { - VP_legacy_draw_viewport_name(ar, v3d, &rect); - } - - if (grid_unit) { /* draw below the viewport name */ - char numstr[32] = ""; - - UI_FontThemeColor(BLF_default(), TH_TEXT_HI); - if (v3d->grid != 1.0f) { - BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid); - } - - BLF_draw_default_ascii(rect.xmin + U.widget_unit, - rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f, - numstr[0] ? numstr : grid_unit, sizeof(numstr)); - } - } -} - -void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar) -{ - Depsgraph *depsgraph = CTX_data_depsgraph(C); - Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); - View3D *v3d = CTX_wm_view3d(C); - const char *grid_unit = NULL; - rcti border_rect; - - /* if we only redraw render border area, skip opengl draw and also - * don't do scissor because it's already set */ - bool render_border = ED_view3d_calc_render_border(scene, depsgraph, v3d, ar, &border_rect); - bool clip_border = (render_border && !BLI_rcti_compare(&ar->drawrct, &border_rect)); - - gpuPushProjectionMatrix(); - gpuLoadIdentityProjectionMatrix(); - gpuPushMatrix(); - gpuLoadIdentity(); - - /* draw viewport using opengl */ - if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene) || clip_border) { - VP_view3d_main_region_clear(scene, v3d, ar); /* background */ - view3d_main_region_draw_objects(C, scene, view_layer, v3d, ar, &grid_unit); - - if (G.debug & G_DEBUG_SIMDATA) - draw_sim_debug_data(scene, v3d, ar); - - glDisable(GL_DEPTH_TEST); - ED_region_pixelspace(ar); - } - - /* draw viewport using external renderer */ - if (v3d->drawtype == OB_RENDER) { - view3d_main_region_draw_engine(C, depsgraph, scene, ar, v3d, clip_border, &border_rect); - } - - VP_legacy_view3d_main_region_setup_view(depsgraph, scene, v3d, ar, NULL, NULL); - glClear(GL_DEPTH_BUFFER_BIT); - - WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_3D); - - ED_region_pixelspace(ar); - - view3d_main_region_draw_info(C, scene, ar, v3d, grid_unit, render_border); - - WM_manipulatormap_draw(ar->manipulator_map, C, WM_MANIPULATORMAP_DRAWSTEP_2D); - - gpuPopProjectionMatrix(); - gpuPopMatrix(); - - v3d->flag |= V3D_INVALID_BACKBUF; - - BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_transp)); - BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xray)); - BLI_assert(BLI_listbase_is_empty(&v3d->afterdraw_xraytransp)); -} - - -/* -------------------------------------------------------------------- */ - -/** \name Deprecated Interface - * - * New viewport sometimes has a check for new/old viewport code. - * Use these functions so new viewport can *optionally* call. - * - * \{ */ - - -void VP_deprecated_view3d_draw_objects( - const bContext *C, - Depsgraph *depsgraph, - Scene *scene, View3D *v3d, ARegion *ar, - const char **grid_unit, - const bool do_bgpic, const bool draw_offscreen) -{ - view3d_draw_objects(C, depsgraph, scene, v3d, ar, grid_unit, do_bgpic, draw_offscreen); -} - -void VP_deprecated_gpu_update_lamps_shadows_world(Depsgraph *depsgraph, Scene *scene, View3D *v3d) -{ - gpu_update_lamps_shadows_world(depsgraph, scene, v3d); -} - -/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 64927ff55c7..58bf05299ea 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -63,12 +63,6 @@ enum { DRAW_SCENESET = (1 << 2) }; -/* draw_mesh_fancy/draw_mesh_textured draw_flags */ -enum { - DRAW_MODIFIERS_PREVIEW = (1 << 0), - DRAW_FACE_SELECT = (1 << 1) -}; - /* view3d_header.c */ void VIEW3D_OT_layers(struct wmOperatorType *ot); @@ -138,84 +132,11 @@ void VIEW3D_OT_walk(struct wmOperatorType *ot); /* view3d_ruler.c */ void VIEW3D_OT_ruler(struct wmOperatorType *ot); -/* drawanim.c */ -void draw_motion_paths_init(View3D *v3d, struct ARegion *ar); -void draw_motion_path_instance(Scene *scene, - struct Object *ob, struct bPoseChannel *pchan, - struct bAnimVizSettings *avs, struct bMotionPath *mpath); -void draw_motion_paths_cleanup(View3D *v3d); - - - /* drawobject.c */ -void draw_object( - struct Depsgraph *depsgraph, Scene *scene, struct ViewLayer *view_layer, struct ARegion *ar, View3D *v3d, - struct Base *base, const short dflag); -void draw_object_select( - struct Depsgraph *depsgraph, Scene *scene, struct ViewLayer *view_layer, struct ARegion *ar, View3D *v3d, - Base *base, const short dflag); - -void draw_mesh_object_outline(View3D *v3d, struct Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]); - -bool draw_glsl_material(Scene *scene, struct ViewLayer *view_layer, struct Object *ob, View3D *v3d, const char dt); -void draw_object_instance(struct Depsgraph *depsgraph, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]); void draw_object_backbufsel(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob); -void draw_object_wire_color(struct ViewLayer *, Base *base, unsigned char r_ob_wire_col[4]); -void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]); -void drawlamp(View3D *v3d, RegionView3D *rv3d, Base *base, - const char dt, const short dflag, const unsigned char ob_wire_col[4], - const bool is_obact); -void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, - const short dflag, const unsigned char ob_wire_col[4]); -void drawspeaker(const unsigned char ob_wire_col[3]); -void draw_bounding_volume(struct Object *ob, char type, const unsigned char ob_wire_col[4]); -void draw_rigidbody_shape(struct Object *ob, const unsigned char ob_wire_col[4]); - -void view3d_cached_text_draw_begin(void); -void view3d_cached_text_draw_add(const float co[3], - const char *str, const size_t str_len, - short xoffs, short flag, const unsigned char col[4]); -void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write); - -bool check_object_draw_texture(struct Scene *scene, struct View3D *v3d, const char drawtype); - -enum { - V3D_CACHE_TEXT_ZBUF = (1 << 0), - V3D_CACHE_TEXT_WORLDSPACE = (1 << 1), - V3D_CACHE_TEXT_ASCII = (1 << 2), - V3D_CACHE_TEXT_GLOBALSPACE = (1 << 3), - V3D_CACHE_TEXT_LOCALCLIP = (1 << 4) -}; - int view3d_effective_drawtype(const struct View3D *v3d); -/* drawarmature.c */ -bool draw_armature( - struct Depsgraph *depsgraph, Scene *scene, struct ViewLayer *view_layer, View3D *v3d, ARegion *ar, Base *base, - const short dt, const short dflag, const unsigned char ob_wire_col[4], - const bool is_outline); - -/* drawmesh.c */ -void draw_mesh_textured(Scene *scene, struct ViewLayer *view_layer, View3D *v3d, RegionView3D *rv3d, - struct Object *ob, struct DerivedMesh *dm, const int draw_flags); -void draw_mesh_face_select( - struct RegionView3D *rv3d, struct Mesh *me, struct DerivedMesh *dm, - bool draw_select_edges); -void draw_mesh_paint_weight_faces(struct DerivedMesh *dm, const bool do_light, - void *facemask_cb, void *user_data); -void draw_mesh_paint_vcolor_faces(struct DerivedMesh *dm, const bool use_light, - void *facemask_cb, void *user_data, - const struct Mesh *me); -void draw_mesh_paint_weight_edges(RegionView3D *rv3d, struct DerivedMesh *dm, - const bool use_depth, const bool use_alpha, - void *edgemask_cb, void *user_data); -void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, - struct Object *ob, struct DerivedMesh *dm, const int draw_flags); - -/* drawsimdebug.c */ -void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar); - /* view3d_draw.c */ void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar); void view3d_draw_region_info(const struct bContext *C, struct ARegion *ar, const int offset); @@ -225,7 +146,6 @@ void ED_view3d_draw_depth( struct ARegion *ar, View3D *v3d, bool alphaoverride); /* view3d_draw_legacy.c */ -void view3d_main_region_draw_legacy(const struct bContext *C, struct ARegion *ar); void ED_view3d_draw_depth_gpencil(struct Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d); void ED_view3d_draw_select_loop( @@ -365,31 +285,4 @@ extern unsigned char view3d_camera_border_hack_col[3]; extern bool view3d_camera_border_hack_test; #endif -/* temporary for legacy viewport to work */ -void VP_legacy_drawcursor(Scene *scene, struct ViewLayer *view_layer, ARegion *ar, View3D *v3d); -void VP_legacy_draw_view_axis(RegionView3D *rv3d, const rcti *rect); -void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, const rcti *rect); -void VP_legacy_draw_selected_name(Scene *scene, struct Object *ob, rcti *rect); -void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit); -void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth); -void VP_legacy_view3d_main_region_setup_view(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]); -bool VP_legacy_view3d_stereo3d_active(struct wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d); -void VP_legacy_view3d_stereo3d_setup(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, ARegion *ar); -void draw_dupli_objects(struct Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, ARegion *ar, View3D *v3d, Base *base); -bool VP_legacy_use_depth(View3D *v3d, struct Object *obedit); -void VP_drawviewborder(Scene *scene, struct Depsgraph *depsgraph, ARegion *ar, View3D *v3d); -void VP_drawrenderborder(ARegion *ar, View3D *v3d); -void VP_view3d_draw_background_none(void); -void VP_view3d_draw_background_world(Scene *scene, RegionView3D *rv3d); -void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar); - -/* temporary legacy calls, only when there is a switch between new/old draw calls */ -void VP_deprecated_gpu_update_lamps_shadows_world(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d); -void VP_deprecated_view3d_draw_objects( - const struct bContext *C, - struct Depsgraph *depsgraph, - Scene *scene, View3D *v3d, ARegion *ar, - const char **grid_unit, - const bool do_bgpic, const bool draw_offscreen); - #endif /* __VIEW3D_INTERN_H__ */ diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c index 0b77006afb7..18366f87b59 100644 --- a/source/blender/editors/undo/ed_undo.c +++ b/source/blender/editors/undo/ed_undo.c @@ -336,8 +336,6 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) { int retval; - ED_viewport_render_kill_jobs(wm, CTX_data_main(C), true); - if (G.debug & G_DEBUG) printf("redo_cb: operator redo %s\n", op->type->name); diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.c index 511f4bc72f1..d45470ab0a1 100644 --- a/source/blender/editors/undo/memfile_undo.c +++ b/source/blender/editors/undo/memfile_undo.c @@ -85,8 +85,6 @@ static void memfile_undosys_step_decode(struct bContext *C, UndoStep *us_p, int /* Loading the content will correctly switch into compatible non-object modes. */ ED_object_mode_set(C, OB_MODE_OBJECT); - /* This is needed so undoing/redoing doesn't crash with threaded previews going */ - ED_viewport_render_kill_jobs(CTX_wm_manager(C), CTX_data_main(C), true); MemFileUndoStep *us = (MemFileUndoStep *)us_p; BKE_memfile_undo_decode(us->data, C); diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index bcdc8193137..945d30eabb5 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -436,43 +436,8 @@ static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos) immEnd(); } -static void draw_uvs_other_mesh_texface(Object *ob, const Image *curimage, const int other_uv_filter, unsigned int pos) -{ - Mesh *me = ob->data; - MPoly *mpoly = me->mpoly; - int a; - - if (me->mloopuv == NULL) { - return; - } - - Image **image_array = NULL; - - if (other_uv_filter == SI_FILTER_SAME_IMAGE) { - image_array = BKE_object_material_edit_image_get_array(ob); - } - - for (a = me->totpoly; a != 0; a--, mpoly++) { - if (other_uv_filter == SI_FILTER_ALL) { - /* Nothing to compare, all UV faces are visible. */ - } - else if (other_uv_filter == SI_FILTER_SAME_IMAGE) { - if (mpoly[a].mat_nr >= ob->totcol) { - continue; - } - if (image_array[mpoly[a].mat_nr] != curimage) { - continue; - } - } - - draw_uvs_lineloop_mpoly(me, mpoly, pos); - } - - if (image_array) { - MEM_freeN(image_array); - } -} -static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, const int other_uv_filter, unsigned int pos) +static void draw_uvs_other_mesh(Object *ob, const Image *curimage, + const int other_uv_filter, unsigned int pos) { Mesh *me = ob->data; MPoly *mpoly = me->mpoly; @@ -527,18 +492,8 @@ static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, c draw_uvs_lineloop_mpoly(me, mpoly, pos); } } -static void draw_uvs_other_mesh(Object *ob, const Image *curimage, const bool new_shading_nodes, - const int other_uv_filter, unsigned int pos) -{ - if (new_shading_nodes) { - draw_uvs_other_mesh_new_shading(ob, curimage, other_uv_filter, pos); - } - else { - draw_uvs_other_mesh_texface(ob, curimage, other_uv_filter, pos); - } -} -static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *curimage, const bool new_shading_nodes, +static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *curimage, const int other_uv_filter) { unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -553,7 +508,7 @@ static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *c { Object *ob = base->object; if ((ob->type == OB_MESH) && (ob != obedit) && ((Mesh *)ob->data)->mloopuv) { - draw_uvs_other_mesh(ob, curimage, new_shading_nodes, other_uv_filter, pos); + draw_uvs_other_mesh(ob, curimage, other_uv_filter, pos); } } } @@ -562,13 +517,12 @@ static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *c static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Object *ob) { - const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); Image *curimage = ED_space_image(sima); Mesh *me = ob->data; Material *ma; if (sima->flag & SI_DRAW_OTHER) { - draw_uvs_other(view_layer, ob, curimage, new_shading_nodes, sima->other_uv_filter); + draw_uvs_other(view_layer, ob, curimage, sima->other_uv_filter); } ma = give_current_material(ob, ob->actcol); @@ -627,7 +581,6 @@ static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const i /* draws uv's in the image space */ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Object *obedit, Depsgraph *depsgraph) { - const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); ToolSettings *ts; Mesh *me = obedit->data; BMEditMesh *em = me->edit_btmesh; @@ -658,19 +611,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje if (sima->flag & SI_DRAW_OTHER) { Image *curimage; - if (new_shading_nodes) { - if (efa_act) { - ED_object_get_active_image(obedit, efa_act->mat_nr + 1, &curimage, NULL, NULL, NULL); - } - else { - curimage = ima; - } + if (efa_act) { + ED_object_get_active_image(obedit, efa_act->mat_nr + 1, &curimage, NULL, NULL, NULL); } else { - curimage = (efa_act) ? BKE_object_material_edit_image_get(obedit, efa_act->mat_nr) : ima; + curimage = ima; } - draw_uvs_other(view_layer, obedit, curimage, new_shading_nodes, sima->other_uv_filter); + draw_uvs_other(view_layer, obedit, curimage, sima->other_uv_filter); } /* 1. draw shadow mesh */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 06b408a04ae..6fa75b0a2b3 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -195,93 +195,6 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i //#define USE_SWITCH_ASPECT -void ED_uvedit_assign_image(Main *UNUSED(bmain), Scene *scene, Object *obedit, Image *ima, Image *previma) -{ - BMEditMesh *em; - BMIter iter; - bool update = false; - const bool selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION); - - /* skip assigning these procedural images... */ - if (ima && (ima->type == IMA_TYPE_R_RESULT || ima->type == IMA_TYPE_COMPOSITE)) - return; - - /* verify we have a mesh we can work with */ - if (!obedit || (obedit->type != OB_MESH)) - return; - - em = BKE_editmesh_from_object(obedit); - if (!em || !em->bm->totface) { - return; - } - - if (BKE_scene_use_new_shading_nodes(scene)) { - /* new shading system, do not assign anything */ - } - else { - BMFace *efa; - - int cd_loop_uv_offset; - /* old shading system, assign image to selected faces */ -#ifdef USE_SWITCH_ASPECT - float prev_aspect[2], fprev_aspect; - float aspect[2], faspect; - - ED_image_get_uv_aspect(previma, prev_aspect, prev_aspect + 1); - ED_image_get_uv_aspect(ima, aspect, aspect + 1); - - fprev_aspect = prev_aspect[0] / prev_aspect[1]; - faspect = aspect[0] / aspect[1]; -#endif - - /* ensure we have a uv map */ - if (!CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) { - BM_data_layer_add(em->bm, &em->bm->ldata, CD_MLOOPUV); - /* make UVs all nice 0-1 */ - ED_mesh_uv_loop_reset_ex(obedit->data, CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPUV)); - update = true; - } - - cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - - /* now assign to all visible faces */ - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (uvedit_face_visible_test(scene, obedit, previma, efa) && - (selected == true || uvedit_face_select_test(scene, efa, cd_loop_uv_offset))) - { -#ifdef USE_SWITCH_ASPECT - if (ima) { - /* we also need to correct the aspect of uvs */ - if (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) { - /* do nothing */ - } - else { - BMIter liter; - BMLoop *l; - - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - - luv->uv[0] *= fprev_aspect; - luv->uv[0] /= faspect; - } - } - } -#endif - BKE_object_material_edit_image_set(obedit, efa->mat_nr, ima); - - update = true; - } - } - - /* and update depdency graph */ - if (update) { - DEG_id_tag_update(obedit->data, 0); - } - } - -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -340,7 +253,8 @@ bool uvedit_face_visible_test(Scene *scene, Object *obedit, Image *ima, BMFace * ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_SHOW_SAME_IMAGE) { - const Image *face_image = BKE_object_material_edit_image_get(obedit, efa->mat_nr); + Image *face_image; + ED_object_get_active_image(obedit, efa->mat_nr + 1, &face_image, NULL, NULL, NULL); return (face_image == ima) ? uvedit_face_visible_nolocal(scene, efa) : false; } else { diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 7c87905775b..1442266a3aa 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -103,9 +103,8 @@ static void modifier_unwrap_state(Object *obedit, Scene *scene, bool *r_use_subs *r_use_subsurf = subsurf; } -static bool ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) +static bool ED_uvedit_ensure_uvs(bContext *C, Scene *UNUSED(scene), Object *obedit) { - Main *bmain = CTX_data_main(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; BMIter iter; @@ -149,9 +148,6 @@ static bool ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) } } - if (ima) - ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL); - /* select new UV's (ignore UV_SYNC_SELECTION in this case) */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BMIter liter; @@ -218,7 +214,7 @@ static bool uvedit_have_selection_multi( return have_select; } -void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, float *aspy) +void ED_uvedit_get_aspect(Scene *UNUSED(scene), Object *ob, BMesh *bm, float *aspx, float *aspy) { bool sloppy = true; bool selected = false; @@ -228,12 +224,7 @@ void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, floa efa = BM_mesh_active_face_get(bm, sloppy, selected); if (efa) { - if (BKE_scene_use_new_shading_nodes(scene)) { - ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL); - } - else { - ima = BKE_object_material_edit_image_get(ob, efa->mat_nr); - } + ED_object_get_active_image(ob, efa->mat_nr + 1, &ima, NULL, NULL, NULL); ED_image_get_uv_aspect(ima, NULL, aspx, aspy); } |